From c973c13afa5d423d47a30744ea4294093738b3e3 Mon Sep 17 00:00:00 2001 From: Sharu Goel <30777678+thephantomthief@users.noreply.github.com> Date: Tue, 16 Jul 2024 13:27:59 +0530 Subject: [PATCH 01/15] Fix permission leak in sys.database_principals (#2672) (#2741) Currently, sys.database_principals T-SQL view shows all the T-SQL users irrespective of the current user. The expectation is that current user should only be able to see the system users and users it has permission of. This commit fixes the sys.database_principals view to align with the expected T-SQL behaviour. Task: BABEL-4935 Signed-off-by: Sharu Goel goelshar@amazon.com --- contrib/babelfishpg_tsql/sql/ownership.sql | 2 + .../babelfishpg_tsql--4.2.0--4.3.0.sql | 56 +++++++ test/JDBC/expected/BABEL-LOGIN-USER-EXT.out | 145 ++++++++++++++++++ test/JDBC/input/BABEL-LOGIN-USER-EXT.mix | 80 ++++++++++ 4 files changed, 283 insertions(+) diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index 5964087c6fc..2705ade2fe3 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -435,6 +435,8 @@ ON Base.rolname = Ext.rolname LEFT OUTER JOIN pg_catalog.pg_roles Base2 ON Ext.login_name = Base2.rolname WHERE Ext.database_name = DB_NAME() + AND (Ext.orig_username IN ('dbo', 'db_owner', 'guest') -- system users should always be visible + OR pg_has_role(Ext.rolname, 'MEMBER')) -- Current user should be able to see users it has permission of UNION ALL SELECT CAST(name AS SYS.SYSNAME) AS name, diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 1022a9befe1..126d0d7475b 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -231,6 +231,62 @@ WHERE ps.dbid = sys.db_id(); GRANT SELECT ON sys.partition_schemes TO PUBLIC; +CREATE OR REPLACE VIEW sys.database_principals AS +SELECT +CAST(Ext.orig_username AS SYS.SYSNAME) AS name, +CAST(Base.oid AS INT) AS principal_id, +CAST(Ext.type AS CHAR(1)) as type, +CAST( + CASE + WHEN Ext.type = 'S' THEN 'SQL_USER' + WHEN Ext.type = 'R' THEN 'DATABASE_ROLE' + WHEN Ext.type = 'U' THEN 'WINDOWS_USER' + ELSE NULL + END + AS SYS.NVARCHAR(60)) AS type_desc, +CAST(Ext.default_schema_name AS SYS.SYSNAME) AS default_schema_name, +CAST(Ext.create_date AS SYS.DATETIME) AS create_date, +CAST(Ext.modify_date AS SYS.DATETIME) AS modify_date, +CAST(Ext.owning_principal_id AS INT) AS owning_principal_id, +CAST(CAST(Base2.oid AS INT) AS SYS.VARBINARY(85)) AS SID, +CAST(Ext.is_fixed_role AS SYS.BIT) AS is_fixed_role, +CAST(Ext.authentication_type AS INT) AS authentication_type, +CAST(Ext.authentication_type_desc AS SYS.NVARCHAR(60)) AS authentication_type_desc, +CAST(Ext.default_language_name AS SYS.SYSNAME) AS default_language_name, +CAST(Ext.default_language_lcid AS INT) AS default_language_lcid, +CAST(Ext.allow_encrypted_value_modifications AS SYS.BIT) AS allow_encrypted_value_modifications +FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_user_ext AS Ext +ON Base.rolname = Ext.rolname +LEFT OUTER JOIN pg_catalog.pg_roles Base2 +ON Ext.login_name = Base2.rolname +WHERE Ext.database_name = DB_NAME() + AND (Ext.orig_username IN ('dbo', 'db_owner', 'guest') -- system users should always be visible + OR pg_has_role(Ext.rolname, 'MEMBER')) -- Current user should be able to see users it has permission of +UNION ALL +SELECT +CAST(name AS SYS.SYSNAME) AS name, +CAST(-1 AS INT) AS principal_id, +CAST(type AS CHAR(1)) as type, +CAST( + CASE + WHEN type = 'S' THEN 'SQL_USER' + WHEN type = 'R' THEN 'DATABASE_ROLE' + WHEN type = 'U' THEN 'WINDOWS_USER' + ELSE NULL + END + AS SYS.NVARCHAR(60)) AS type_desc, +CAST(NULL AS SYS.SYSNAME) AS default_schema_name, +CAST(NULL AS SYS.DATETIME) AS create_date, +CAST(NULL AS SYS.DATETIME) AS modify_date, +CAST(-1 AS INT) AS owning_principal_id, +CAST(CAST(0 AS INT) AS SYS.VARBINARY(85)) AS SID, +CAST(0 AS SYS.BIT) AS is_fixed_role, +CAST(-1 AS INT) AS authentication_type, +CAST(NULL AS SYS.NVARCHAR(60)) AS authentication_type_desc, +CAST(NULL AS SYS.SYSNAME) AS default_language_name, +CAST(-1 AS INT) AS default_language_lcid, +CAST(0 AS SYS.BIT) AS allow_encrypted_value_modifications +FROM (VALUES ('public', 'R'), ('sys', 'S'), ('INFORMATION_SCHEMA', 'S')) as dummy_principals(name, type); -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. diff --git a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out index ff48fb129f9..78b174aca3a 100644 --- a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out @@ -1399,3 +1399,148 @@ void ~~END~~ + +-- tsql +CREATE DATABASE babel_4935_db +GO + +USE babel_4935_db +GO + +-- Login that is member sysadmin +CREATE LOGIN babel_4935_sysadmin WITH PASSWORD = '123' +GO + +ALTER ROLE sysadmin ADD MEMBER babel_4935_sysadmin +GO + +-- Logins that are not a member of sysadmin but have users associated +CREATE LOGIN babel_4935_no_sysadmin1 WITH PASSWORD = '123' +CREATE LOGIN babel_4935_no_sysadmin2 WITH PASSWORD = '123' +GO + +CREATE USER babel_4935_no_sysadmin1 +CREATE USER babel_4935_no_sysadmin2 +GO + +-- Login that is not a member of sysadmin and has no user associated +CREATE LOGIN babel_4935_guest WITH PASSWORD = '123' +GO + +GRANT CONNECT TO guest +GO + +-- jdbc_user is superuser so should see all the users +SELECT name FROM sys.database_principals ORDER BY name +GO +~~START~~ +varchar +babel_4935_no_sysadmin1 +babel_4935_no_sysadmin2 +db_owner +dbo +guest +INFORMATION_SCHEMA +public +sys +~~END~~ + + +-- tsql user=babel_4935_sysadmin password=123 database=babel_4935_db +-- login is member of sysadmin so should see all the users +SELECT name FROM sys.database_principals ORDER BY name +GO +~~START~~ +varchar +babel_4935_no_sysadmin1 +babel_4935_no_sysadmin2 +db_owner +dbo +guest +INFORMATION_SCHEMA +public +sys +~~END~~ + + +-- tsql user=babel_4935_no_sysadmin1 password=123 database=babel_4935_db +-- login is not member of sysadmin so should see all the system users and only it's own user +SELECT name FROM sys.database_principals ORDER BY name +GO +~~START~~ +varchar +babel_4935_no_sysadmin1 +db_owner +dbo +guest +INFORMATION_SCHEMA +public +sys +~~END~~ + + +-- tsql user=babel_4935_guest password=123 database=babel_4935_db +-- login is not member of sysadmin and no user associated so should only see system users +SELECT name FROM sys.database_principals ORDER BY name +GO +~~START~~ +varchar +db_owner +dbo +guest +INFORMATION_SCHEMA +public +sys +~~END~~ + + +-- 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_4935_sysadmin' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'babel_4935_no_sysadmin1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'babel_4935_guest' 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 +USE master +GO + +DROP DATABASE babel_4935_db +GO + +DROP LOGIN babel_4935_sysadmin +DROP LOGIN babel_4935_no_sysadmin1 +DROP LOGIN babel_4935_no_sysadmin2 +DROP LOGIN babel_4935_guest +GO diff --git a/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix b/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix index 41f6c3c9629..491391cc22d 100644 --- a/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix +++ b/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix @@ -715,3 +715,83 @@ GO SELECT pg_sleep(1); GO + +-- tsql +CREATE DATABASE babel_4935_db +GO + +USE babel_4935_db +GO + +-- Login that is member sysadmin +CREATE LOGIN babel_4935_sysadmin WITH PASSWORD = '123' +GO + +ALTER ROLE sysadmin ADD MEMBER babel_4935_sysadmin +GO + +-- Logins that are not a member of sysadmin but have users associated +CREATE LOGIN babel_4935_no_sysadmin1 WITH PASSWORD = '123' +CREATE LOGIN babel_4935_no_sysadmin2 WITH PASSWORD = '123' +GO + +CREATE USER babel_4935_no_sysadmin1 +CREATE USER babel_4935_no_sysadmin2 +GO + +-- Login that is not a member of sysadmin and has no user associated +CREATE LOGIN babel_4935_guest WITH PASSWORD = '123' +GO + +GRANT CONNECT TO guest +GO + +-- jdbc_user is superuser so should see all the users +SELECT name FROM sys.database_principals ORDER BY name +GO + +-- tsql user=babel_4935_sysadmin password=123 database=babel_4935_db +-- login is member of sysadmin so should see all the users +SELECT name FROM sys.database_principals ORDER BY name +GO + +-- tsql user=babel_4935_no_sysadmin1 password=123 database=babel_4935_db +-- login is not member of sysadmin so should see all the system users and only it's own user +SELECT name FROM sys.database_principals ORDER BY name +GO + +-- tsql user=babel_4935_guest password=123 database=babel_4935_db +-- login is not member of sysadmin and no user associated so should only see system users +SELECT name FROM sys.database_principals ORDER BY name +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_4935_sysadmin' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'babel_4935_no_sysadmin1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'babel_4935_guest' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +-- Wait to sync with another session +SELECT pg_sleep(1); +GO + +-- tsql +USE master +GO + +DROP DATABASE babel_4935_db +GO + +DROP LOGIN babel_4935_sysadmin +DROP LOGIN babel_4935_no_sysadmin1 +DROP LOGIN babel_4935_no_sysadmin2 +DROP LOGIN babel_4935_guest +GO From 8ddd794c5e90042a8c1c7b0dd9d335830c1bee6a Mon Sep 17 00:00:00 2001 From: Sharu Goel <30777678+thephantomthief@users.noreply.github.com> Date: Tue, 16 Jul 2024 17:05:09 +0530 Subject: [PATCH 02/15] [OSS-ONLY] Add support for windows roles in T-SQL IS_MEMBER() (#2583) (#2745) * [OSS-ONLY] Add support for windows roles in T-SQL IS_MEMBER() (#2583) This commits adds support in T-SQL IS_MEMBER() function to show membership information for windows roles. The re-implemented IS_MEMBER() function relies on views sys.login_token and sys.user_token to see if current session user is member of a given role. The sys.user_token view has also been modified as part of this commit to show all the roles current_user is member of. Task: BABEL-4822 Signed-off-by: Sharu Goel goelshar@amazon.com --- contrib/babelfishpg_tsql/sql/ownership.sql | 5 +- .../babelfishpg_tsql/sql/sys_functions.sql | 30 ++++++++- .../babelfishpg_tsql--4.2.0--4.3.0.sql | 61 +++++++++++++++++++ .../expected/BABEL-ROLE-MEMBER-vu-verify.out | 4 +- test/JDBC/expected/BABEL-ROLE-MEMBER.out | 57 ++++++++++++++++- test/JDBC/expected/login_token.out | 13 ++++ .../input/BABEL-ROLE-MEMBER-vu-verify.mix | 2 +- test/JDBC/input/BABEL-ROLE-MEMBER.mix | 29 +++++++++ test/JDBC/input/login_token.mix | 12 ++++ 9 files changed, 205 insertions(+), 8 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index 2705ade2fe3..8f6661f4fe8 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -499,6 +499,7 @@ CAST(CAST(Base2.oid AS INT) AS SYS.VARBINARY(85)) AS SID, CAST(Ext.orig_username AS SYS.NVARCHAR(128)) AS NAME, CAST(CASE WHEN Ext.type = 'U' THEN 'WINDOWS LOGIN' +WHEN Ext.type = 'R' THEN 'ROLE' ELSE 'SQL USER' END AS SYS.NVARCHAR(128)) AS TYPE, CAST('GRANT OR DENY' as SYS.NVARCHAR(128)) as USAGE @@ -507,8 +508,8 @@ ON Base.rolname = Ext.rolname LEFT OUTER JOIN pg_catalog.pg_roles Base2 ON Ext.login_name = Base2.rolname WHERE Ext.database_name = sys.DB_NAME() -AND Ext.rolname = CURRENT_USER -AND Ext.type in ('S','U') +AND ((Ext.rolname = CURRENT_USER AND Ext.type in ('S','U')) OR +((SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) != 'dbo' AND Ext.type = 'R' AND pg_has_role(current_user, Ext.rolname, 'MEMBER'))) UNION ALL SELECT CAST(-1 AS INT) AS principal_id, diff --git a/contrib/babelfishpg_tsql/sql/sys_functions.sql b/contrib/babelfishpg_tsql/sql/sys_functions.sql index 5bc97245950..f1b18961f5e 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -3423,9 +3423,35 @@ LANGUAGE C STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.is_member(IN role sys.SYSNAME) RETURNS INT AS $$ - SELECT sys.is_rolemember_internal(role, NULL); +DECLARE + is_windows_grp boolean := (CHARINDEX('\', role) != 0); +BEGIN + -- Always return 1 for 'public' + IF (role = 'public') + THEN RETURN 1; + END IF; + + IF EXISTS (SELECT orig_loginname FROM sys.babelfish_authid_login_ext WHERE orig_loginname = role AND type != 'S') -- do not consider sql logins + THEN + IF ((EXISTS (SELECT name FROM sys.login_token WHERE name = role AND type IN ('SERVER ROLE', 'SQL LOGIN'))) OR is_windows_grp) -- do not consider sql logins, server roles + THEN RETURN NULL; -- Also return NULL if session is not a windows auth session but argument is a windows group + ELSIF EXISTS (SELECT name FROM sys.login_token WHERE name = role AND type NOT IN ('SERVER ROLE', 'SQL LOGIN')) + THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group + ELSE RETURN 0; -- Return 0 if current session user is not a member of role or windows group + END IF; + ELSIF EXISTS (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE orig_username = role) + THEN + IF EXISTS (SELECT name FROM sys.user_token WHERE name = role) + THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group + ELSIF (is_windows_grp) + THEN RETURN NULL; -- Return NULL if session is not a windows auth session but argument is a windows group + ELSE RETURN 0; -- Return 0 if current session user is not a member of role or windows group + END IF; + ELSE RETURN NULL; -- Return NULL if role/group does not exist + END IF; +END; $$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; +LANGUAGE plpgsql STRICT STABLE; CREATE OR REPLACE FUNCTION sys.is_rolemember(IN role sys.SYSNAME) RETURNS INT AS diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 126d0d7475b..0caffa37023 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -288,6 +288,67 @@ CAST(-1 AS INT) AS default_language_lcid, CAST(0 AS SYS.BIT) AS allow_encrypted_value_modifications FROM (VALUES ('public', 'R'), ('sys', 'S'), ('INFORMATION_SCHEMA', 'S')) as dummy_principals(name, type); +CREATE OR REPLACE VIEW sys.user_token AS +SELECT +CAST(Base.oid AS INT) AS principal_id, +CAST(CAST(Base2.oid AS INT) AS SYS.VARBINARY(85)) AS SID, +CAST(Ext.orig_username AS SYS.NVARCHAR(128)) AS NAME, +CAST(CASE +WHEN Ext.type = 'U' THEN 'WINDOWS LOGIN' +WHEN Ext.type = 'R' THEN 'ROLE' +ELSE 'SQL USER' END +AS SYS.NVARCHAR(128)) AS TYPE, +CAST('GRANT OR DENY' as SYS.NVARCHAR(128)) as USAGE +FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_user_ext AS Ext +ON Base.rolname = Ext.rolname +LEFT OUTER JOIN pg_catalog.pg_roles Base2 +ON Ext.login_name = Base2.rolname +WHERE Ext.database_name = sys.DB_NAME() +AND ((Ext.rolname = CURRENT_USER AND Ext.type in ('S','U')) OR +((SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) != 'dbo' AND Ext.type = 'R' AND pg_has_role(current_user, Ext.rolname, 'MEMBER'))) +UNION ALL +SELECT +CAST(-1 AS INT) AS principal_id, +CAST(CAST(-1 AS INT) AS SYS.VARBINARY(85)) AS SID, +CAST('public' AS SYS.NVARCHAR(128)) AS NAME, +CAST('ROLE' AS SYS.NVARCHAR(128)) AS TYPE, +CAST('GRANT OR DENY' as SYS.NVARCHAR(128)) as USAGE +WHERE (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) != 'dbo'; + +GRANT SELECT ON sys.user_token TO PUBLIC; + +CREATE OR REPLACE FUNCTION sys.is_member(IN role sys.SYSNAME) +RETURNS INT AS +$$ +DECLARE + is_windows_grp boolean := (CHARINDEX('\', role) != 0); +BEGIN + -- Always return 1 for 'public' + IF (role = 'public') + THEN RETURN 1; + END IF; + IF EXISTS (SELECT orig_loginname FROM sys.babelfish_authid_login_ext WHERE orig_loginname = role AND type != 'S') -- do not consider sql logins + THEN + IF ((EXISTS (SELECT name FROM sys.login_token WHERE name = role AND type IN ('SERVER ROLE', 'SQL LOGIN'))) OR is_windows_grp) -- do not consider sql logins, server roles + THEN RETURN NULL; -- Also return NULL if session is not a windows auth session but argument is a windows group + ELSIF EXISTS (SELECT name FROM sys.login_token WHERE name = role AND type NOT IN ('SERVER ROLE', 'SQL LOGIN')) + THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group + ELSE RETURN 0; -- Return 0 if current session user is not a member of role or windows group + END IF; + ELSIF EXISTS (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE orig_username = role) + THEN + IF EXISTS (SELECT name FROM sys.user_token WHERE name = role) + THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group + ELSIF (is_windows_grp) + THEN RETURN NULL; -- Return NULL if session is not a windows auth session but argument is a windows group + ELSE RETURN 0; -- Return 0 if current session user is not a member of role or windows group + END IF; + ELSE RETURN NULL; -- Return NULL if role/group does not exist + END IF; +END; +$$ +LANGUAGE plpgsql STRICT STABLE; + -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar); diff --git a/test/JDBC/expected/BABEL-ROLE-MEMBER-vu-verify.out b/test/JDBC/expected/BABEL-ROLE-MEMBER-vu-verify.out index 3d55340c26e..140c76a56ec 100644 --- a/test/JDBC/expected/BABEL-ROLE-MEMBER-vu-verify.out +++ b/test/JDBC/expected/BABEL-ROLE-MEMBER-vu-verify.out @@ -262,12 +262,12 @@ int ~~END~~ --- Given role name is not a real role, should return NULL +-- Given name is a real user but not associated with login, should return 0 SELECT IS_MEMBER('BABEL_ROLE_MEMBER_vu_prepare_user1') GO ~~START~~ int - +0 ~~END~~ SELECT IS_ROLEMEMBER('BABEL_ROLE_MEMBER_vu_prepare_user1') diff --git a/test/JDBC/expected/BABEL-ROLE-MEMBER.out b/test/JDBC/expected/BABEL-ROLE-MEMBER.out index 57f7c3c47e9..b1a1a06467c 100644 --- a/test/JDBC/expected/BABEL-ROLE-MEMBER.out +++ b/test/JDBC/expected/BABEL-ROLE-MEMBER.out @@ -49,6 +49,13 @@ GO CREATE USER test_user3 FOR LOGIN test_login3 GO +-- check for roles with name > 64 characters +CREATE ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111 +GO + +CREATE ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111_dup +GO + -- role1 -> role2 -> role3 -> role4 ALTER ROLE test_role1 ADD MEMBER test_role2 GO @@ -66,6 +73,9 @@ GO ALTER ROLE test_role3 ADD MEMBER test_user3 GO +ALTER ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111 ADD MEMBER test_user3 +GO + -- Print the current membership status EXEC babel_role_members GO @@ -78,6 +88,7 @@ test_role2#!#R#!#test_role3#!#R test_role2#!#R#!#test_user2#!#S test_role3#!#R#!#test_role4#!#R test_role3#!#R#!#test_user3#!#S +thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111#!#R#!#test_user3#!#S ~~END~~ @@ -204,6 +215,32 @@ int ~~END~~ +-- Return NULL for server roles other than public +SELECT IS_MEMBER('sysadmin') +GO +~~START~~ +int + +~~END~~ + + +-- Return NULL for SQL logins and users +SELECT IS_MEMBER('test_login1') +GO +~~START~~ +int + +~~END~~ + + +SELECT IS_MEMBER('test_user1') +GO +~~START~~ +int +0 +~~END~~ + + -- Should return 0 SELECT IS_ROLEMEMBER('db_owner', 'test_role1') GO @@ -269,7 +306,7 @@ SELECT IS_MEMBER('test_user1') GO ~~START~~ int - +0 ~~END~~ SELECT IS_ROLEMEMBER('test_user1') @@ -550,6 +587,13 @@ int 1 ~~END~~ +SELECT IS_MEMBER('thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111') +GO +~~START~~ +int +1 +~~END~~ + -- Should return 0 SELECT IS_MEMBER('test_role4') @@ -559,6 +603,13 @@ int 0 ~~END~~ +SELECT IS_MEMBER('thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111_dup') +GO +~~START~~ +int +0 +~~END~~ + -- Doesn't have permission, should return NULL SELECT IS_ROLEMEMBER('test_role3', 'test_role4') @@ -615,6 +666,10 @@ DROP ROLE test_role2 GO DROP ROLE test_role1 GO +DROP ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111 +GO +DROP ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111_dup +GO -- psql -- Need to terminate active session before cleaning up the login diff --git a/test/JDBC/expected/login_token.out b/test/JDBC/expected/login_token.out index 5eefbea0b23..2fe016d9116 100644 --- a/test/JDBC/expected/login_token.out +++ b/test/JDBC/expected/login_token.out @@ -8,6 +8,12 @@ go create user login_token2; go +create role login_token_role +go + +alter role login_token_role add member login_token2 +go + create login login_token3 with password = '12345678' go @@ -60,6 +66,7 @@ select name, type, usage from sys.user_token order by name; go ~~START~~ nvarchar#!#nvarchar#!#nvarchar +login_token_role#!#ROLE#!#GRANT OR DENY login_token2#!#SQL USER#!#GRANT OR DENY public#!#ROLE#!#GRANT OR DENY ~~END~~ @@ -83,6 +90,12 @@ dbo#!#SQL USER#!#GRANT OR DENY -- tsql +alter role login_token_role drop member login_token2 +go + +drop role login_token_role +go + drop user login_token2; go diff --git a/test/JDBC/input/BABEL-ROLE-MEMBER-vu-verify.mix b/test/JDBC/input/BABEL-ROLE-MEMBER-vu-verify.mix index 65faccd7fda..f8ce2a45240 100644 --- a/test/JDBC/input/BABEL-ROLE-MEMBER-vu-verify.mix +++ b/test/JDBC/input/BABEL-ROLE-MEMBER-vu-verify.mix @@ -86,7 +86,7 @@ GO SELECT IS_ROLEMEMBER('BABEL_ROLE_MEMBER_vu_prepare_role1', NULL) GO --- Given role name is not a real role, should return NULL +-- Given name is a real user but not associated with login, should return 0 SELECT IS_MEMBER('BABEL_ROLE_MEMBER_vu_prepare_user1') GO SELECT IS_ROLEMEMBER('BABEL_ROLE_MEMBER_vu_prepare_user1') diff --git a/test/JDBC/input/BABEL-ROLE-MEMBER.mix b/test/JDBC/input/BABEL-ROLE-MEMBER.mix index c0bf23ff5ba..7d8c113085e 100644 --- a/test/JDBC/input/BABEL-ROLE-MEMBER.mix +++ b/test/JDBC/input/BABEL-ROLE-MEMBER.mix @@ -44,6 +44,13 @@ GO CREATE USER test_user3 FOR LOGIN test_login3 GO +-- check for roles with name > 64 characters +CREATE ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111 +GO + +CREATE ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111_dup +GO + -- role1 -> role2 -> role3 -> role4 ALTER ROLE test_role1 ADD MEMBER test_role2 GO @@ -61,6 +68,9 @@ GO ALTER ROLE test_role3 ADD MEMBER test_user3 GO +ALTER ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111 ADD MEMBER test_user3 +GO + -- Print the current membership status EXEC babel_role_members GO @@ -108,6 +118,17 @@ GO SELECT IS_ROLEMEMBER('public', 'test_user1') GO +-- Return NULL for server roles other than public +SELECT IS_MEMBER('sysadmin') +GO + +-- Return NULL for SQL logins and users +SELECT IS_MEMBER('test_login1') +GO + +SELECT IS_MEMBER('test_user1') +GO + -- Should return 0 SELECT IS_ROLEMEMBER('db_owner', 'test_role1') GO @@ -239,10 +260,14 @@ SELECT IS_ROLEMEMBER('test_role1', 'test_role3') GO SELECT IS_MEMBER('test_user3') GO +SELECT IS_MEMBER('thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111') +GO -- Should return 0 SELECT IS_MEMBER('test_role4') GO +SELECT IS_MEMBER('thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111_dup') +GO -- Doesn't have permission, should return NULL SELECT IS_ROLEMEMBER('test_role3', 'test_role4') @@ -281,6 +306,10 @@ DROP ROLE test_role2 GO DROP ROLE test_role1 GO +DROP ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111 +GO +DROP ROLE thisroleisaveryuniquerolewhereitsnamelengthisveryveryverylongandspansonehundredandelevencharacterswhichis__111_dup +GO -- psql -- Need to terminate active session before cleaning up the login diff --git a/test/JDBC/input/login_token.mix b/test/JDBC/input/login_token.mix index 29f2f2985cf..e3abf1968b2 100644 --- a/test/JDBC/input/login_token.mix +++ b/test/JDBC/input/login_token.mix @@ -8,6 +8,12 @@ go create user login_token2; go +create role login_token_role +go + +alter role login_token_role add member login_token2 +go + create login login_token3 with password = '12345678' go @@ -39,6 +45,12 @@ select name, type, usage from sys.user_token order by name; go -- tsql +alter role login_token_role drop member login_token2 +go + +drop role login_token_role +go + drop user login_token2; go From acf59f819850f2bff6e9edb7050e810df493dc80 Mon Sep 17 00:00:00 2001 From: Zhibai Song Date: Thu, 18 Jul 2024 10:19:48 -0700 Subject: [PATCH 03/15] Fix crash issue in pre transforming column name (#2750) Fix the crash happen when column ref is followed by a comment without space like : 'SELECT table1.c2--table1.REPGETTEXT('. Previously, the column transform didn't consider '--' will directly followed with column ref and will wrongly regard the comment part as the column ref, thus will cause crash later in finding the column name. This fix add the check for '--' at the end of column def in the sql string to avoid this crash. Task: BABEL-5070 Signed-off-by: Zhibai Song --- contrib/babelfishpg_tsql/src/hooks.c | 12 ++++++- test/JDBC/expected/BABEL-4484-vu-verify.out | 40 +++++++++++++++++++++ test/JDBC/input/BABEL-4484-vu-verify.sql | 20 +++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 947891271b9..0d05adecf87 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -1952,7 +1952,17 @@ pre_transform_target_entry(ResTarget *res, ParseState *pstate, colname_start = pstate->p_sourcetext + res->location; last_dot = colname_start; while(*colname_start != '\0') - { + { + /* + * comment follow up with column like : + * + * 'SELECT table1.c2--table1.REPGETTEXT(' + * + * will cause crash if we don't break the searching + * for the last_dot position + */ + if (*colname_start == '-' && *(colname_start+1) == '-') + break; if(open_square_bracket == 0 && *colname_start == '"') { double_quotes++; diff --git a/test/JDBC/expected/BABEL-4484-vu-verify.out b/test/JDBC/expected/BABEL-4484-vu-verify.out index b3961349aa8..4ef1b538d34 100644 --- a/test/JDBC/expected/BABEL-4484-vu-verify.out +++ b/test/JDBC/expected/BABEL-4484-vu-verify.out @@ -26,3 +26,43 @@ GO varchar ~~END~~ + +SELECT test_babel_4484_t1.ced--table1.REPGETTEXT( +FROM test_babel_4484_t1 +GO +~~START~~ +varchar +~~END~~ + + +select test_babel_4484_t1.您您--table1.a.b.c +from test_babel_4484_t1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column test_babel_4484_t1.您您 does not exist)~~ + + +select test_babel_4484_t2.您您--table1.a.b.c +from test_babel_4484_t2 +GO +~~START~~ +varchar +~~END~~ + + +select test_babel_4484_t1.您您 as kk--table1.a.b.c +from test_babel_4484_t1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column test_babel_4484_t1.您您 does not exist)~~ + + +select test_babel_4484_t2.您您 as kk--table1.a.b.c +from test_babel_4484_t2 +GO +~~START~~ +varchar +~~END~~ + diff --git a/test/JDBC/input/BABEL-4484-vu-verify.sql b/test/JDBC/input/BABEL-4484-vu-verify.sql index 5c5f6a2e636..474ae42cd31 100644 --- a/test/JDBC/input/BABEL-4484-vu-verify.sql +++ b/test/JDBC/input/BABEL-4484-vu-verify.sql @@ -9,3 +9,23 @@ GO SELECT test_babel_4484_t1.ced FROM test_babel_4484_t1 INNER JOIN test_babel_4484_t2 ON test_babel_4484_t1.ABC = test_babel_4484_t2.ABC WHERE test_babel_4484_t1.ABC = 1; GO + +SELECT test_babel_4484_t1.ced--table1.REPGETTEXT( +FROM test_babel_4484_t1 +GO + +select test_babel_4484_t1.您您--table1.a.b.c +from test_babel_4484_t1 +GO + +select test_babel_4484_t2.您您--table1.a.b.c +from test_babel_4484_t2 +GO + +select test_babel_4484_t1.您您 as kk--table1.a.b.c +from test_babel_4484_t1 +GO + +select test_babel_4484_t2.您您 as kk--table1.a.b.c +from test_babel_4484_t2 +GO \ No newline at end of file From 6e224b1a117fdac80f4270c5f691bda861cb001c Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Thu, 18 Jul 2024 14:20:39 -0400 Subject: [PATCH 04/15] Update upgrade schedule files and gitignore (#2749) When BABEL_4_X_DEV was originally cut for 16.4 development, the upgrade schedule file for 15.7 and 16.3 were mistakenly copied from 15.6 and 16.2 instead of using the (at the time) latest schedule files. This commit updates the 15.7 and 16.3 schedule files to match the previous latest schedule files. Also update the gitignore file to properly ignore the autogenerated upgrade scripts, as we have now hit double digits for the minor versions. Signed-off-by: Jason Teng --- .gitignore | 1 + test/JDBC/upgrade/15_7/schedule | 18 +++++++++++++----- test/JDBC/upgrade/16_3/schedule | 31 ++++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index e2b9f4e9c60..8fccb744b1e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ contrib/babelfishpg_tsql/antlr/cmake_install.cmake contrib/babelfishpg_tsql/pl_reserved_kwlist_d.h contrib/babelfishpg_tsql/pl_unreserved_kwlist_d.h contrib/babelfishpg_tsql/sql/babelfishpg_tsql--[0-9].[0-9].[0-9]--[0-9].[0-9].[0-9].sql +contrib/babelfishpg_tsql/sql/babelfishpg_tsql--[0-9].[0-9][0-9].[0-9]--[0-9].[0-9].[0-9].sql contrib/babelfishpg_tsql/sql/babelfishpg_tsql--[0-9].[0-9].[0-9].sql contrib/babelfishpg_tsql/src/backend_parser/gram-backend.c contrib/babelfishpg_tsql/src/backend_parser/gram-backend.h diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 240610fc424..115ccac5aee 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -151,6 +151,7 @@ babelfish_authid_user_ext babelfish_cast_floor babelfish_inconsistent_metadata babelfish_integrity_checker +check_for_inconsistent_metadata babelfish_migration_mode babelfish_namespace_ext babelfish_sysdatabases @@ -270,7 +271,7 @@ sys_all_objects-dep sys-all_parameters sys-all_parameters-dep sys-all_sql_modules -sys-all_sql_modules-before-15_7-or-16_2-dep +sys-all_sql_modules-dep sys-all_views sys-assemblies sys-assembly_modules @@ -367,7 +368,7 @@ sys-sp_statistics-dep sys-sp_tables_view sys-sp_tables_view-dep sys-sql_modules -sys-sql_modules-before-15_7-or-16_2-dep +sys-sql_modules-dep sys-stats sys-suser_sid sys-suser_sname @@ -510,17 +511,24 @@ sys_availability_replicas BABEL-730 babel-4475 babel-4517 -BABEL-4815 +alter-procedure +babel_table_type +1_GRANT_SCHEMA +BABEL-4707 +BABEL_4817 BABEL-4641 BABEL-4863 babel_test_int4_numeric_oper babel_test_int8_numeric_oper babel_test_int2_numeric_oper BABEL_3571 +login_token-dep test_like_for_AI +babel_726 BABEL-4869 +BABEL-4815 +BABEL-3401 babel_4328_datetime babel_4328_datetime2 babel_4328_datetimeoffset -BABEL-3401 -babel_726 +BABEL-3820 diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 0d76e8b2ab1..5187010eeec 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -40,7 +40,6 @@ BABEL-1994-VARCHAR BABEL-2086 BABEL-2170 BABEL-2203 -BABEL-4390 BABEL-2208 BABEL-2257 BABEL-2449 @@ -67,6 +66,7 @@ BABEL-3117 BABEL-3118 BABEL-3121 BABEL-3144 +BABEL-3147 BABEL-3166 BABEL-3192 BABEL-3204 @@ -115,6 +115,7 @@ BABEL-3914 BABEL-3938 BABEL-3952 BABEL-3953-datetrunc +BABEL-404 BABEL-405 BABEL-4078 BABEL-4098 @@ -122,8 +123,8 @@ BABEL-4214 BABEL-4516 babel_417 BABEL-493 -BABEL-4888 BABEL_539 +BABEL-621 BABEL-728 BABEL-733 BABEL-741 @@ -148,6 +149,7 @@ babelfish_authid_user_ext babelfish_cast_floor babelfish_inconsistent_metadata babelfish_integrity_checker +check_for_inconsistent_metadata babelfish_migration_mode babelfish_namespace_ext babelfish_sysdatabases @@ -224,6 +226,7 @@ fulltextserviceproperty FULLTEXT_INDEX fts-contains fts-contains-utils +BABEL-4785 get_tds_id HAS_DBACCESS identity_function @@ -246,6 +249,7 @@ msdb-dbo-syspolicy_configuration msdb-dbo-syspolicy_system_health_state nested_trigger_inside_proc nested_trigger_with_dml +newid_before_15_8_or_16_4 objectpropertyex openjson openquery_upgrd_before_15_4 @@ -449,6 +453,7 @@ TestTableType TestText TestTime TestTinyInt +TestUDD TestUniqueIdentifier Test_user_from_win_login TestVarChar @@ -512,9 +517,21 @@ BABEL-730 babel-4475 babel-3254 babel-4517 -BABEL-4815 -Test_alter_db_rename -Test_sp_renamedb -Test_sp_rename_database +babel_table_type +alter-procedure +1_GRANT_SCHEMA +BABEL-4707 +BABEL_4817 +BABEL-4641 +BABEL-4863 +babel_test_int4_numeric_oper +babel_test_int8_numeric_oper +babel_test_int2_numeric_oper +login_token-dep +test_like_for_AI BABEL-4869 -BABEL-5071 \ No newline at end of file +babel_4328_datetime +babel_4328_datetime2 +babel_4328_datetimeoffset +babel_726 +BABEL-3401 \ No newline at end of file From 7fb4f6b5ed16181e1283905d4039eabb6b64820b Mon Sep 17 00:00:00 2001 From: Alex Kasko Date: Fri, 19 Jul 2024 11:57:55 +0100 Subject: [PATCH 05/15] BCP import - open and close indices for every batch (#2487) In `ExecuteBulkCopy` indices on the target table are opened for every incoming batch, but never closed. It is proposed to open indices instead for every executor batch just before the call to `table_multi_insert` and close them after they are updated with tuples from this batch. Backend memory usage (with both this patch and #2469 patch included) while importing 16 million varchar records (4x the table from the linked issue): ![Figure_3](https://github.com/babelfish-for-postgresql/babelfish_extensions/assets/9497509/4b36faab-79d7-4a82-aef1-8404a3ee2c49) Signed-off-by: Alex Kasko --- .../babelfishpg_tsql/src/pltsql_bulkcopy.c | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c b/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c index 878edf10242..967807f215e 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c +++ b/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c @@ -350,6 +350,8 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, */ save_cur_lineno = cstate->cur_rowno; + /* Open indices to update them after the multi insert */ + ExecOpenIndices(resultRelInfo, false); /* * table_multi_insert may leak memory, so switch to short-lived memory * context before calling it. @@ -361,7 +363,6 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, mycid, ti_options, buffer->bistate); - MemoryContextSwitchTo(oldcontext); for (i = 0; i < nused; i++) { @@ -383,6 +384,36 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, ExecClearTuple(slots[i]); } + /* + * ExecInsertIndexTuples also leaks memory, so only switch back to old + * context after it. + */ + MemoryContextSwitchTo(oldcontext); + + /* Close the indices we've opened before multi insert */ + ExecCloseIndices(resultRelInfo); + + /* + * ExecCloseIndices does not free neither resulsting arrays, allocated + * in ExecOpenIndices, nor its contents. Instead of moving open/close into + * short-lived context lets clean it up explicitly, so indices open/close + * can be untied from batch handling in future if needed. + * + * There is an additional call to ExecCloseIndices in + * EndBulkCopy->ExecCloseResultRelations, we reset ri_NumIndices to make + * it no-op. + */ + if (resultRelInfo->ri_NumIndices > 0) + { + for (i = 0; i < resultRelInfo->ri_NumIndices; i++) + { + pfree(resultRelInfo->ri_IndexRelationInfo[i]); + } + pfree(resultRelInfo->ri_IndexRelationInfo); + pfree(resultRelInfo->ri_IndexRelationDescs); + resultRelInfo->ri_NumIndices = 0; + } + /* Mark that all slots are free. */ buffer->nused = 0; @@ -587,8 +618,6 @@ ExecuteBulkCopy(BulkCopyState cstate, int rowCount, int colCount, RelationGetRelationName(cstate->rel)))); } - ExecOpenIndices(cstate->resultRelInfo, false); - econtext = GetPerTupleExprContext(cstate->estate); /* Set up callback to identify error line number. */ From 43ca4906a763c432d6657739544c0c4745fc16e8 Mon Sep 17 00:00:00 2001 From: Roshan Kanwar Date: Mon, 22 Jul 2024 18:56:00 +0530 Subject: [PATCH 06/15] Fix sp_tables output for '%' table_qualifier and default parameter values (#2746) This commit addresses issues with sp_tables in handling '%' as the table_qualifier, ensuring consistent output when using default parameters (NULL or ''). The procedure definition has been updated to correctly interpret '%' as table_qualifier, and default parameter values have been adjusted to resolve output inconsistencies. Previously, EXEC master.dbo.sp_catalogs in SSMS was producing unexpected results, leading to ambiguous behavior. This commit resolves these issues and ensures the correct functionality of the internal RPC call. Changes Made: Updated sp_tables to handle '%' appropriately. Adjusted default parameter values for consistent output. Corrected behavior of EXEC master.dbo.sp_catalogs in SSMS. Testing: Tested functionality thoroughly using SSMS. Issues Resolved Task: BABEL-5010 --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 56 ++-- .../babelfishpg_tsql--4.2.0--4.3.0.sql | 97 +++++++ .../expected/SP_TABLES-dep-vu-cleanup.out | 23 ++ .../expected/SP_TABLES-dep-vu-prepare.out | 29 ++ .../JDBC/expected/SP_TABLES-dep-vu-verify.out | 266 ++++++++++++++++++ test/JDBC/input/SP_TABLES-dep-vu-cleanup.sql | 23 ++ test/JDBC/input/SP_TABLES-dep-vu-prepare.sql | 29 ++ test/JDBC/input/SP_TABLES-dep-vu-verify.sql | 132 +++++++++ test/JDBC/upgrade/13_4/schedule | 1 + test/JDBC/upgrade/13_5/schedule | 1 + test/JDBC/upgrade/13_6/schedule | 1 + test/JDBC/upgrade/13_7/schedule | 1 + test/JDBC/upgrade/13_8/schedule | 1 + test/JDBC/upgrade/13_9/schedule | 1 + test/JDBC/upgrade/14_10/schedule | 1 + test/JDBC/upgrade/14_11/schedule | 1 + test/JDBC/upgrade/14_12/schedule | 1 + test/JDBC/upgrade/14_13/schedule | 1 + test/JDBC/upgrade/14_3/schedule | 1 + test/JDBC/upgrade/14_5/schedule | 1 + test/JDBC/upgrade/14_6/schedule | 1 + test/JDBC/upgrade/14_7/schedule | 1 + test/JDBC/upgrade/14_8/schedule | 1 + test/JDBC/upgrade/14_9/schedule | 1 + test/JDBC/upgrade/15_1/schedule | 1 + test/JDBC/upgrade/15_2/schedule | 1 + test/JDBC/upgrade/15_3/schedule | 1 + test/JDBC/upgrade/15_4/schedule | 1 + test/JDBC/upgrade/15_5/schedule | 1 + test/JDBC/upgrade/15_6/schedule | 1 + test/JDBC/upgrade/15_7/schedule | 1 + test/JDBC/upgrade/15_8/schedule | 1 + test/JDBC/upgrade/16_1/schedule | 1 + test/JDBC/upgrade/16_2/schedule | 1 + test/JDBC/upgrade/16_3/schedule | 1 + test/JDBC/upgrade/latest/schedule | 1 + 36 files changed, 659 insertions(+), 24 deletions(-) create mode 100644 test/JDBC/expected/SP_TABLES-dep-vu-cleanup.out create mode 100644 test/JDBC/expected/SP_TABLES-dep-vu-prepare.out create mode 100644 test/JDBC/expected/SP_TABLES-dep-vu-verify.out create mode 100644 test/JDBC/input/SP_TABLES-dep-vu-cleanup.sql create mode 100644 test/JDBC/input/SP_TABLES-dep-vu-prepare.sql create mode 100644 test/JDBC/input/SP_TABLES-dep-vu-verify.sql diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index cb16798e271..afcdfe75cf6 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -983,10 +983,10 @@ AND has_table_privilege(t1.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER'); GRANT SELECT ON sys.sp_tables_view TO PUBLIC; CREATE OR REPLACE FUNCTION sys.sp_tables_internal( - in_table_name sys.nvarchar(384) = '', - in_table_owner sys.nvarchar(384) = '', - in_table_qualifier sys.sysname = '', - in_table_type sys.varchar(100) = '', + in_table_name sys.nvarchar(384) = NULL, + in_table_owner sys.nvarchar(384) = NULL, + in_table_qualifier sys.sysname = NULL, + in_table_type sys.varchar(100) = NULL, in_fusepattern sys.bit = '1') RETURNS TABLE ( out_table_qualifier sys.sysname, @@ -1015,12 +1015,10 @@ CREATE OR REPLACE FUNCTION sys.sp_tables_internal( CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE, CAST(remarks AS sys.varchar(254)) AS REMARKS FROM sys.sp_tables_view - WHERE ((SELECT coalesce(in_table_name,'')) = '' OR table_name LIKE in_table_name collate sys.database_default) - AND ((SELECT coalesce(in_table_owner,'')) = '' OR table_owner LIKE in_table_owner collate sys.database_default) - AND ((SELECT coalesce(in_table_qualifier,'')) = '' OR table_qualifier LIKE in_table_qualifier collate sys.database_default) - AND ((SELECT coalesce(cs_as_in_table_type,'')) = '' - OR table_type = opt_table - OR table_type = opt_view) + WHERE (in_table_name IS NULL OR table_name LIKE in_table_name collate sys.database_default) + AND (in_table_owner IS NULL OR table_owner LIKE in_table_owner collate sys.database_default) + AND (in_table_qualifier IS NULL OR table_qualifier LIKE in_table_qualifier collate sys.database_default) + AND (cs_as_in_table_type IS NULL OR table_type = opt_table OR table_type = opt_view) ORDER BY table_qualifier, table_owner, table_name; ELSE RETURN query @@ -1031,30 +1029,40 @@ CREATE OR REPLACE FUNCTION sys.sp_tables_internal( CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE, CAST(remarks AS sys.varchar(254)) AS REMARKS FROM sys.sp_tables_view - WHERE ((SELECT coalesce(in_table_name,'')) = '' OR table_name = in_table_name collate sys.database_default) - AND ((SELECT coalesce(in_table_owner,'')) = '' OR table_owner = in_table_owner collate sys.database_default) - AND ((SELECT coalesce(in_table_qualifier,'')) = '' OR table_qualifier = in_table_qualifier collate sys.database_default) - AND ((SELECT coalesce(cs_as_in_table_type,'')) = '' - OR table_type = opt_table - OR table_type = opt_view) + WHERE (in_table_name IS NULL OR table_name = in_table_name collate sys.database_default) + AND (in_table_owner IS NULL OR table_owner = in_table_owner collate sys.database_default) + AND (in_table_qualifier IS NULL OR table_qualifier = in_table_qualifier collate sys.database_default) + AND (cs_as_in_table_type IS NULL OR table_type = opt_table OR table_type = opt_view) ORDER BY table_qualifier, table_owner, table_name; END IF; END; $$ LANGUAGE plpgsql STABLE; - CREATE OR REPLACE PROCEDURE sys.sp_tables ( - "@table_name" sys.nvarchar(384) = '', - "@table_owner" sys.nvarchar(384) = '', - "@table_qualifier" sys.sysname = '', - "@table_type" sys.nvarchar(100) = '', + "@table_name" sys.nvarchar(384) = NULL, + "@table_owner" sys.nvarchar(384) = NULL, + "@table_qualifier" sys.sysname = NULL, + "@table_type" sys.nvarchar(100) = NULL, "@fusepattern" sys.bit = '1') AS $$ - DECLARE @opt_table sys.varchar(16) = ''; - DECLARE @opt_view sys.varchar(16) = ''; BEGIN - IF (@table_qualifier != '') AND (LOWER(@table_qualifier) != LOWER(sys.db_name())) + + -- Handle special case: Enumerate all databases when name and owner are blank but qualifier is '%' + IF (@table_qualifier = '%' AND @table_owner = '' AND @table_name = '') + BEGIN + SELECT + d.name AS TABLE_QUALIFIER, + CAST(NULL AS sys.sysname) AS TABLE_OWNER, + CAST(NULL AS sys.sysname) AS TABLE_NAME, + CAST(NULL AS sys.varchar(32)) AS TABLE_TYPE, + CAST(NULL AS sys.varchar(254)) AS REMARKS + FROM sys.databases d ORDER BY TABLE_QUALIFIER; + + RETURN; + END; + + IF (@table_qualifier != '' AND LOWER(@table_qualifier) != LOWER(sys.db_name())) BEGIN THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1; END diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 0caffa37023..895cf392f9f 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -45,6 +45,103 @@ ALTER TABLE sys.babelfish_function_ext DROP CONSTRAINT babelfish_function_ext_pk ALTER TABLE sys.babelfish_function_ext ADD CONSTRAINT babelfish_function_ext_pkey PRIMARY KEY (funcname, nspname, funcsignature); RESET allow_system_table_mods; +CREATE OR REPLACE FUNCTION sys.sp_tables_internal( + in_table_name sys.nvarchar(384) = NULL, + in_table_owner sys.nvarchar(384) = NULL, + in_table_qualifier sys.sysname = NULL, + in_table_type sys.varchar(100) = NULL, + in_fusepattern sys.bit = '1') + RETURNS TABLE ( + out_table_qualifier sys.sysname, + out_table_owner sys.sysname, + out_table_name sys.sysname, + out_table_type sys.varchar(32), + out_remarks sys.varchar(254) + ) + AS $$ + DECLARE opt_table sys.varchar(16) = ''; + DECLARE opt_view sys.varchar(16) = ''; + DECLARE cs_as_in_table_type varchar COLLATE "C" = in_table_type; + BEGIN + IF upper(cs_as_in_table_type) LIKE '%''TABLE''%' THEN + opt_table = 'TABLE'; + END IF; + IF upper(cs_as_in_table_type) LIKE '%''VIEW''%' THEN + opt_view = 'VIEW'; + END IF; + IF in_fusepattern = 1 THEN + RETURN query + SELECT + CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER, + CAST(table_owner AS sys.sysname) AS TABLE_OWNER, + CAST(table_name AS sys.sysname) AS TABLE_NAME, + CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE, + CAST(remarks AS sys.varchar(254)) AS REMARKS + FROM sys.sp_tables_view + WHERE (in_table_name IS NULL OR table_name LIKE in_table_name collate sys.database_default) + AND (in_table_owner IS NULL OR table_owner LIKE in_table_owner collate sys.database_default) + AND (in_table_qualifier IS NULL OR table_qualifier LIKE in_table_qualifier collate sys.database_default) + AND (cs_as_in_table_type IS NULL OR table_type = opt_table OR table_type = opt_view) + ORDER BY table_qualifier, table_owner, table_name; + ELSE + RETURN query + SELECT + CAST(table_qualifier AS sys.sysname) AS TABLE_QUALIFIER, + CAST(table_owner AS sys.sysname) AS TABLE_OWNER, + CAST(table_name AS sys.sysname) AS TABLE_NAME, + CAST(table_type AS sys.varchar(32)) AS TABLE_TYPE, + CAST(remarks AS sys.varchar(254)) AS REMARKS + FROM sys.sp_tables_view + WHERE (in_table_name IS NULL OR table_name = in_table_name collate sys.database_default) + AND (in_table_owner IS NULL OR table_owner = in_table_owner collate sys.database_default) + AND (in_table_qualifier IS NULL OR table_qualifier = in_table_qualifier collate sys.database_default) + AND (cs_as_in_table_type IS NULL OR table_type = opt_table OR table_type = opt_view) + ORDER BY table_qualifier, table_owner, table_name; + END IF; + END; +$$ +LANGUAGE plpgsql STABLE; + +CREATE OR REPLACE PROCEDURE sys.sp_tables ( + "@table_name" sys.nvarchar(384) = NULL, + "@table_owner" sys.nvarchar(384) = NULL, + "@table_qualifier" sys.sysname = NULL, + "@table_type" sys.nvarchar(100) = NULL, + "@fusepattern" sys.bit = '1') +AS $$ +BEGIN + + -- Handle special case: Enumerate all databases when name and owner are blank but qualifier is '%' + IF (@table_qualifier = '%' AND @table_owner = '' AND @table_name = '') + BEGIN + SELECT + d.name AS TABLE_QUALIFIER, + CAST(NULL AS sys.sysname) AS TABLE_OWNER, + CAST(NULL AS sys.sysname) AS TABLE_NAME, + CAST(NULL AS sys.varchar(32)) AS TABLE_TYPE, + CAST(NULL AS sys.varchar(254)) AS REMARKS + FROM sys.databases d ORDER BY TABLE_QUALIFIER; + + RETURN; + END; + + IF (@table_qualifier != '' AND LOWER(@table_qualifier) != LOWER(sys.db_name())) + BEGIN + THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1; + END + + SELECT + CAST(out_table_qualifier AS sys.sysname) AS TABLE_QUALIFIER, + CAST(out_table_owner AS sys.sysname) AS TABLE_OWNER, + CAST(out_table_name AS sys.sysname) AS TABLE_NAME, + CAST(out_table_type AS sys.varchar(32)) AS TABLE_TYPE, + CAST(out_remarks AS sys.varchar(254)) AS REMARKS + FROM sys.sp_tables_internal(@table_name, @table_owner, @table_qualifier, CAST(@table_type AS varchar(100)), @fusepattern); +END; +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE ON PROCEDURE sys.sp_tables TO PUBLIC; + -- BBF_PARTITION_FUNCTION -- This catalog stores the metadata of partition funtions. CREATE TABLE sys.babelfish_partition_function diff --git a/test/JDBC/expected/SP_TABLES-dep-vu-cleanup.out b/test/JDBC/expected/SP_TABLES-dep-vu-cleanup.out new file mode 100644 index 00000000000..2607f66033b --- /dev/null +++ b/test/JDBC/expected/SP_TABLES-dep-vu-cleanup.out @@ -0,0 +1,23 @@ +USE babel_5010_vu_prepare_db1; +GO + +DROP TABLE IF EXISTS babel_5010_temp_table; +GO + +DROP TABLE IF EXISTS babel_5010_vu_prepare_t1; +GO + +DROP TABLE IF EXISTS babel_5010_vu_prepare_t2; +GO + +DROP VIEW IF EXISTS babel_5010_vu_prepare_v1; +GO + +DROP VIEW IF EXISTS babel_5010_vu_prepare_v2; +GO + +USE master; +GO + +DROP DATABASE IF EXISTS babel_5010_vu_prepare_db1; +GO diff --git a/test/JDBC/expected/SP_TABLES-dep-vu-prepare.out b/test/JDBC/expected/SP_TABLES-dep-vu-prepare.out new file mode 100644 index 00000000000..efacf6942e0 --- /dev/null +++ b/test/JDBC/expected/SP_TABLES-dep-vu-prepare.out @@ -0,0 +1,29 @@ +CREATE DATABASE babel_5010_vu_prepare_db1; +GO + +USE babel_5010_vu_prepare_db1; +GO + +CREATE TABLE babel_5010_temp_table ( + TABLE_QUALIFIER sys.sysname, + TABLE_OWNER sys.nvarchar(384), + TABLE_NAME sys.nvarchar(384), + TABLE_TYPE sys.nvarchar(100), + REMARKS sys.bit +); +GO + +CREATE TABLE babel_5010_vu_prepare_t1(a INT) +GO + +CREATE TABLE babel_5010_vu_prepare_t2(a INT) +GO + +CREATE VIEW babel_5010_vu_prepare_v1 AS SELECT 1; +GO + +CREATE VIEW babel_5010_vu_prepare_v2 AS SELECT 1; +GO + +USE master; +GO diff --git a/test/JDBC/expected/SP_TABLES-dep-vu-verify.out b/test/JDBC/expected/SP_TABLES-dep-vu-verify.out new file mode 100644 index 00000000000..83113ae6386 --- /dev/null +++ b/test/JDBC/expected/SP_TABLES-dep-vu-verify.out @@ -0,0 +1,266 @@ +USE babel_5010_vu_prepare_db1; +GO + +SET NOCOUNT ON; +GO + + +-- special case: when table_qualifier only contains one % wildcard character and 0 or more space characters +-- should enumerate all databases +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar='% ' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO +~~START~~ +varchar#!#nvarchar#!#nvarchar#!#nvarchar#!#bit +babel_5010_vu_prepare_db1#!##!##!##!# +master#!##!##!##!# +msdb#!##!##!##!# +tempdb#!##!##!##!# +~~END~~ + + +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar='%' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO +~~START~~ +varchar#!#nvarchar#!#nvarchar#!#nvarchar#!#bit +babel_5010_vu_prepare_db1#!##!##!##!# +master#!##!##!##!# +msdb#!##!##!##!# +tempdb#!##!##!##!# +~~END~~ + + +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '% ', @table_type = NULL, @fUsePattern = 1; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO +~~START~~ +varchar#!#nvarchar#!#nvarchar#!#nvarchar#!#bit +babel_5010_vu_prepare_db1#!##!##!##!# +master#!##!##!##!# +msdb#!##!##!##!# +tempdb#!##!##!##!# +~~END~~ + + +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%', @table_type = NULL, @fUsePattern = 1; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO +~~START~~ +varchar#!#nvarchar#!#nvarchar#!#nvarchar#!#bit +babel_5010_vu_prepare_db1#!##!##!##!# +master#!##!##!##!# +msdb#!##!##!##!# +tempdb#!##!##!##!# +~~END~~ + + +-- should return empty set +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar=' %' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +~~END~~ + + +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar=' % ' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +~~END~~ + + +declare @p1 sys.nvarchar=' ' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar=NULL +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +~~END~~ + + +-- should throw error +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = ' %', @table_type = NULL, @fUsePattern = 1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The database name component of the object qualifier must be the name of the current database.)~~ + + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = ' % ', @table_type = NULL, @fUsePattern = 1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The database name component of the object qualifier must be the name of the current database.)~~ + + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%%', @table_type = NULL, @fUsePattern = 1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The database name component of the object qualifier must be the name of the current database.)~~ + + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%_', @table_type = NULL, @fUsePattern = 1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The database name component of the object qualifier must be the name of the current database.)~~ + + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = 'mast%', @table_type = NULL, @fUsePattern = 1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The database name component of the object qualifier must be the name of the current database.)~~ + + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%db', @table_type = NULL, @fUsePattern = 1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The database name component of the object qualifier must be the name of the current database.)~~ + + +-- special case: when all parameters are empty string, should return empty set +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '', @table_type = '', @fUsePattern = 0; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +~~END~~ + + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '', @table_type = ''; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +~~END~~ + + +-- special case: when all parameters are NULL, should return all tables and views of current database i.e. babel_5010_vu_prepare_db1 +EXEC [sys].sp_tables; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_temp_table#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t1#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t2#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v1#!#VIEW#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v2#!#VIEW#!# +babel_5010_vu_prepare_db1#!#dbo#!#sysdatabases#!#VIEW#!# +~~END~~ + + + +-- NULL value tests +-- case 1: when table name is NULL +-- should return matching objects +EXEC [sys].sp_tables @table_owner = 'dbo', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_temp_table#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t1#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t2#!#TABLE#!# +~~END~~ + + +EXEC [sys].sp_tables @table_owner = 'dbo', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'VIEW'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v1#!#VIEW#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v2#!#VIEW#!# +babel_5010_vu_prepare_db1#!#dbo#!#sysdatabases#!#VIEW#!# +~~END~~ + + +EXEC [sys].sp_tables @table_owner = 'dbo', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE','VIEW'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_temp_table#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t1#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t2#!#TABLE#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v1#!#VIEW#!# +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v2#!#VIEW#!# +babel_5010_vu_prepare_db1#!#dbo#!#sysdatabases#!#VIEW#!# +~~END~~ + + +-- case 2: when table owner is NULL +-- should return matching objects +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_t1', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t1#!#TABLE#!# +~~END~~ + + +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_v1', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'VIEW'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v1#!#VIEW#!# +~~END~~ + + +-- should return empty set +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_v1', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +~~END~~ + + +-- case 3: when table qualifier is NULL +-- should return matching objects +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_t1', @table_owner = 'dbo', @table_type = "'TABLE'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_t1#!#TABLE#!# +~~END~~ + + +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_v1', @table_owner = 'dbo', @table_type = "'VIEW'"; +GO +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +babel_5010_vu_prepare_db1#!#dbo#!#babel_5010_vu_prepare_v1#!#VIEW#!# +~~END~~ + + +SET NOCOUNT OFF; +GO + +USE master; +GO diff --git a/test/JDBC/input/SP_TABLES-dep-vu-cleanup.sql b/test/JDBC/input/SP_TABLES-dep-vu-cleanup.sql new file mode 100644 index 00000000000..2abfe444892 --- /dev/null +++ b/test/JDBC/input/SP_TABLES-dep-vu-cleanup.sql @@ -0,0 +1,23 @@ +USE babel_5010_vu_prepare_db1; +GO + +DROP TABLE IF EXISTS babel_5010_temp_table; +GO + +DROP TABLE IF EXISTS babel_5010_vu_prepare_t1; +GO + +DROP TABLE IF EXISTS babel_5010_vu_prepare_t2; +GO + +DROP VIEW IF EXISTS babel_5010_vu_prepare_v1; +GO + +DROP VIEW IF EXISTS babel_5010_vu_prepare_v2; +GO + +USE master; +GO + +DROP DATABASE IF EXISTS babel_5010_vu_prepare_db1; +GO \ No newline at end of file diff --git a/test/JDBC/input/SP_TABLES-dep-vu-prepare.sql b/test/JDBC/input/SP_TABLES-dep-vu-prepare.sql new file mode 100644 index 00000000000..3cca03af301 --- /dev/null +++ b/test/JDBC/input/SP_TABLES-dep-vu-prepare.sql @@ -0,0 +1,29 @@ +CREATE DATABASE babel_5010_vu_prepare_db1; +GO + +USE babel_5010_vu_prepare_db1; +GO + +CREATE TABLE babel_5010_temp_table ( + TABLE_QUALIFIER sys.sysname, + TABLE_OWNER sys.nvarchar(384), + TABLE_NAME sys.nvarchar(384), + TABLE_TYPE sys.nvarchar(100), + REMARKS sys.bit +); +GO + +CREATE TABLE babel_5010_vu_prepare_t1(a INT) +GO + +CREATE TABLE babel_5010_vu_prepare_t2(a INT) +GO + +CREATE VIEW babel_5010_vu_prepare_v1 AS SELECT 1; +GO + +CREATE VIEW babel_5010_vu_prepare_v2 AS SELECT 1; +GO + +USE master; +GO \ No newline at end of file diff --git a/test/JDBC/input/SP_TABLES-dep-vu-verify.sql b/test/JDBC/input/SP_TABLES-dep-vu-verify.sql new file mode 100644 index 00000000000..8bf5bf9d5a4 --- /dev/null +++ b/test/JDBC/input/SP_TABLES-dep-vu-verify.sql @@ -0,0 +1,132 @@ +USE babel_5010_vu_prepare_db1; +GO + +SET NOCOUNT ON; +GO + +-- special case: when table_qualifier only contains one % wildcard character and 0 or more space characters + +-- should enumerate all databases +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar='% ' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO + +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar='%' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO + +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '% ', @table_type = NULL, @fUsePattern = 1; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO + +INSERT INTO babel_5010_temp_table EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%', @table_type = NULL, @fUsePattern = 1; +SELECT * FROM babel_5010_temp_table WHERE TABLE_QUALIFIER IN ('master', 'tempdb', 'msdb', 'babel_5010_vu_prepare_db1'); +DELETE FROM babel_5010_temp_table; +GO + +-- should return empty set +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar=' %' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern +GO + +declare @p1 sys.nvarchar='' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar=' % ' +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern +GO + +declare @p1 sys.nvarchar=' ' +declare @P2 sys.nvarchar='' +declare @P3 sys.nvarchar=NULL +declare @P4 sys.nvarchar=NULL +declare @fUsePattern bit = 1 +EXEC [sys].sp_tables @p1, @P2, @P3, @P4, @fUsePattern = @fUsePattern +GO + +-- should throw error +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = ' %', @table_type = NULL, @fUsePattern = 1; +GO + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = ' % ', @table_type = NULL, @fUsePattern = 1; +GO + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%%', @table_type = NULL, @fUsePattern = 1; +GO + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%_', @table_type = NULL, @fUsePattern = 1; +GO + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = 'mast%', @table_type = NULL, @fUsePattern = 1; +GO + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '%db', @table_type = NULL, @fUsePattern = 1; +GO + +-- special case: when all parameters are empty string, should return empty set +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '', @table_type = '', @fUsePattern = 0; +GO + +EXEC [sys].sp_tables @table_name = '', @table_owner = '', @table_qualifier = '', @table_type = ''; +GO + +-- special case: when all parameters are NULL, should return all tables and views of current database i.e. babel_5010_vu_prepare_db1 +EXEC [sys].sp_tables; +GO + +-- NULL value tests + +-- case 1: when table name is NULL +-- should return matching objects +EXEC [sys].sp_tables @table_owner = 'dbo', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE'"; +GO + +EXEC [sys].sp_tables @table_owner = 'dbo', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'VIEW'"; +GO + +EXEC [sys].sp_tables @table_owner = 'dbo', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE','VIEW'"; +GO + +-- case 2: when table owner is NULL +-- should return matching objects +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_t1', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE'"; +GO + +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_v1', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'VIEW'"; +GO + +-- should return empty set +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_v1', @table_qualifier = 'babel_5010_vu_prepare_db1', @table_type = "'TABLE'"; +GO + +-- case 3: when table qualifier is NULL +-- should return matching objects +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_t1', @table_owner = 'dbo', @table_type = "'TABLE'"; +GO + +EXEC [sys].sp_tables @table_name = 'babel_5010_vu_prepare_v1', @table_owner = 'dbo', @table_type = "'VIEW'"; +GO + +SET NOCOUNT OFF; +GO + +USE master; +GO \ No newline at end of file diff --git a/test/JDBC/upgrade/13_4/schedule b/test/JDBC/upgrade/13_4/schedule index 882daa53b88..c03f4408ebb 100644 --- a/test/JDBC/upgrade/13_4/schedule +++ b/test/JDBC/upgrade/13_4/schedule @@ -97,6 +97,7 @@ BABEL-SP_SPROC_COLUMNS BABEL-SP_STORED_PROCEDURES BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/13_5/schedule b/test/JDBC/upgrade/13_5/schedule index 71dcf82521e..be23c26e591 100644 --- a/test/JDBC/upgrade/13_5/schedule +++ b/test/JDBC/upgrade/13_5/schedule @@ -105,6 +105,7 @@ BABEL-SP_SPROC_COLUMNS BABEL-SP_STORED_PROCEDURES BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/13_6/schedule b/test/JDBC/upgrade/13_6/schedule index f6eedfd5699..ddf5bfae305 100644 --- a/test/JDBC/upgrade/13_6/schedule +++ b/test/JDBC/upgrade/13_6/schedule @@ -137,6 +137,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/13_7/schedule b/test/JDBC/upgrade/13_7/schedule index 0947db5a065..4424e1b95fb 100644 --- a/test/JDBC/upgrade/13_7/schedule +++ b/test/JDBC/upgrade/13_7/schedule @@ -133,6 +133,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/13_8/schedule b/test/JDBC/upgrade/13_8/schedule index 29db95e16c9..0b65bb893b9 100644 --- a/test/JDBC/upgrade/13_8/schedule +++ b/test/JDBC/upgrade/13_8/schedule @@ -133,6 +133,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index d0a265f9e71..c99e5b9b5f9 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -134,6 +134,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index 2925d6aaea1..03f4adcb888 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -254,6 +254,7 @@ BABEL-1438 BABEL-SP_DATATYPE_INFO BABEL-SPCOLUMNS BABEL-SP_TABLES +SP_TABLES-dep BABEL-SP_SPECIAL_COLUMNS BABEL-SP_TABLE_PRIVILIGES BABEL-SP_FKEYS diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 882e3a3a4f5..6fd8e9e14b5 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -254,6 +254,7 @@ BABEL-APPLOCK BABEL-1438 BABEL-SP_DATATYPE_INFO BABEL-SPCOLUMNS +SP_TABLES-dep BABEL-SP_TABLES BABEL-SP_SPECIAL_COLUMNS BABEL-SP_TABLE_PRIVILIGES diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index 92e94106ffe..bad7b3f4f2a 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -252,6 +252,7 @@ BABEL-APPLOCK BABEL-1438 BABEL-SP_DATATYPE_INFO BABEL-SPCOLUMNS +SP_TABLES-dep BABEL-SP_TABLES BABEL-SP_SPECIAL_COLUMNS BABEL-SP_TABLE_PRIVILIGES diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index 82c73e9ae6e..9da3682ed58 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -252,6 +252,7 @@ BABEL-APPLOCK BABEL-1438 BABEL-SP_DATATYPE_INFO BABEL-SPCOLUMNS +SP_TABLES-dep BABEL-SP_TABLES BABEL-SP_SPECIAL_COLUMNS BABEL-SP_TABLE_PRIVILIGES diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index c6d3a0b31a4..f024fa904ec 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -142,6 +142,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index 415336123c2..c41157dad33 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -138,6 +138,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index 5a58e126223..daaf2288105 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -156,6 +156,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index b8e5f16d85f..696973674a1 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -169,6 +169,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 78fee5ca6f0..5078b78093e 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -167,6 +167,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 7ba6903d3d6..606da86407a 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -253,6 +253,7 @@ BABEL-APPLOCK BABEL-1438 BABEL-SP_DATATYPE_INFO BABEL-SPCOLUMNS +SP_TABLES-dep BABEL-SP_TABLES BABEL-SP_SPECIAL_COLUMNS BABEL-SP_TABLE_PRIVILIGES diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 853cac98c33..e7c7d60e1d2 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -155,6 +155,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 7f9bd4c3a3f..979ef5dfe25 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -168,6 +168,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index f3d0bdc10b9..f13c4ee20b5 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -178,6 +178,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index 1a2abbdfda9..9f99685837a 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -180,6 +180,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index e5f5b883edb..853228c17dd 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -184,6 +184,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index e318efd4ebe..1931228e8e6 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -187,6 +187,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 115ccac5aee..514511e13ab 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -188,6 +188,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 41f4a68eda8..1d31eddd56b 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -187,6 +187,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index 70542141380..4e6c19061cf 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -186,6 +186,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index e1605da03dc..69326b652f6 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -187,6 +187,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 5187010eeec..65854906a15 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -186,6 +186,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 34b27b85600..a7c3fb366eb 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -187,6 +187,7 @@ BABEL-SP_STORED_PROCEDURES BABEL-SP_STORED_PROCEDURES-dep BABEL-SP_TABLE_PRIVILIGES BABEL-SP_TABLES +SP_TABLES-dep babel_sqlvariant_cast_compare BABEL-SQUARE BABEL-TABLEOPTIONS From 6ac43eee99d6af5ea7dc35915ae666dbcec694d5 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan <140405735+tanscorpio7@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:51:15 +0530 Subject: [PATCH 07/15] Fix error when OUTPUT INTO table variable statement fires trigger (#2639) Fix error portal snapshots (1) did not account for all active snapshots (2) when OUTPUT INTO table variable statement fires triggers. pltsql statements that could fire trigger must always run inside a transaction block. If a txn block is not active, we create one. We exclude some types of statements from this, one of them being DML on table variables since they can never fire a trigger. We detect this using the variable mod_stmt_tablevar. Now an edge case here is OUTPUT into table variable stmt. Which we internally transform into two DML nodes. TOP INSERT NODE (signifies the output into clause) Another DELETE / UPDATE / INSERT node inside the top insert node -> with clause (specifies the first part of the output into clause ) As a fix we simply skip transaction commands inside pltsql UDFs and not rely on mod_stmt_tablevar on anymore. Also blocked certain cases of OUTPUT clause which should not be allowed inside pltsql UDFs. OUTPUT clause flushes results to client (INTO clause is missing) OUTPUT INTO clause has a non local object as its target. (UDFs only allow DML on local objects) Issues Resolved: BABEL-4859 Signed-off-by: Tanzeel Khan tzlkhan@amazon.com --- contrib/babelfishpg_tsql/src/pl_exec.c | 10 +- contrib/babelfishpg_tsql/src/tsqlIface.cpp | 17 + .../expected/output_into_fires_trigger.out | 418 ++++++++++++++++++ test/JDBC/input/output_into_fires_trigger.sql | 295 ++++++++++++ 4 files changed, 735 insertions(+), 5 deletions(-) create mode 100644 test/JDBC/expected/output_into_fires_trigger.out create mode 100644 test/JDBC/input/output_into_fires_trigger.sql diff --git a/contrib/babelfishpg_tsql/src/pl_exec.c b/contrib/babelfishpg_tsql/src/pl_exec.c index 9d2ea93c733..168f98bb288 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec.c +++ b/contrib/babelfishpg_tsql/src/pl_exec.c @@ -4612,6 +4612,9 @@ exec_stmt_execsql(PLtsql_execstate *estate, /* fetch current search_path */ char *old_search_path = NULL; + bool ro_func = (estate->func->fn_prokind == PROKIND_FUNCTION) && + (estate->func->fn_is_trigger == PLTSQL_NOT_TRIGGER) && + (strcmp(estate->func->fn_signature, "inline_code_block") != 0); if (stmt->original_query) original_query_string = stmt->original_query; @@ -4786,7 +4789,7 @@ exec_stmt_execsql(PLtsql_execstate *estate, * tsql_select_assign_stmt (select @a=1). with ANTLR=off, it is * handled in PLtsql_stmt_query_set. */ - if (stmt->need_to_push_result || stmt->is_tsql_select_assign_stmt || stmt->mod_stmt_tablevar) + if (stmt->need_to_push_result || stmt->is_tsql_select_assign_stmt || ro_func) enable_txn_in_triggers = false; if (enable_txn_in_triggers) @@ -5055,10 +5058,7 @@ exec_stmt_execsql(PLtsql_execstate *estate, if ((!pltsql_disable_batch_auto_commit || (stmt->txn_data != NULL)) && pltsql_support_tsql_transactions() && (enable_txn_in_triggers || estate->trigdata == NULL) && - !(estate->func->fn_prokind == PROKIND_FUNCTION && - estate->func->fn_is_trigger == PLTSQL_NOT_TRIGGER && - strcmp(estate->func->fn_signature, "inline_code_block") != 0) && - !estate->insert_exec) + !ro_func && !estate->insert_exec) { commit_stmt(estate, (estate->tsql_trigger_flags & TSQL_TRAN_STARTED)); diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index 06a9d32d96c..b742ec06677 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -1808,6 +1808,23 @@ class tsqlBuilder : public tsqlCommonMutator else if (ctx->delete_statement() && ctx->delete_statement()->delete_statement_from()->ddl_object() && !ctx->delete_statement()->delete_statement_from()->ddl_object()->local_id() && (ctx->delete_statement()->table_sources() ? ::getFullText(ctx->delete_statement()->table_sources()).c_str()[0] != '@' : true)) /* delete non-local object, table variables are allowed */ throw PGErrorWrapperException(ERROR, ERRCODE_INVALID_FUNCTION_DEFINITION, "'DELETE' cannot be used within a function", getLineAndPos(ctx->delete_statement()->delete_statement_from()->ddl_object())); + + /* + * Reject if OUTPUT clause is missing INTO (returning to client) or OUTPUT INTO non local object + */ + + if (ctx->insert_statement() && ctx->insert_statement()->output_clause() && (!ctx->insert_statement()->output_clause()->INTO() || !ctx->insert_statement()->output_clause()->LOCAL_ID())) + { + throw PGErrorWrapperException(ERROR, ERRCODE_INVALID_FUNCTION_DEFINITION, "Invalid use of a side-effecting operator 'INSERT' within a function.", getLineAndPos(ctx->insert_statement()->output_clause())); + } + else if (ctx->update_statement() && ctx->update_statement()->output_clause() && (!ctx->update_statement()->output_clause()->INTO() || !ctx->update_statement()->output_clause()->LOCAL_ID())) + { + throw PGErrorWrapperException(ERROR, ERRCODE_INVALID_FUNCTION_DEFINITION, "Invalid use of a side-effecting operator 'UPDATE' within a function.", getLineAndPos(ctx->update_statement()->output_clause())); + } + else if (ctx->delete_statement() && ctx->delete_statement()->output_clause() && (!ctx->delete_statement()->output_clause()->INTO() || !ctx->delete_statement()->output_clause()->LOCAL_ID())) + { + throw PGErrorWrapperException(ERROR, ERRCODE_INVALID_FUNCTION_DEFINITION, "Invalid use of a side-effecting operator 'DELETE' within a function.", getLineAndPos(ctx->delete_statement()->output_clause())); + } } /* we must add previous rewrite at first. */ diff --git a/test/JDBC/expected/output_into_fires_trigger.out b/test/JDBC/expected/output_into_fires_trigger.out new file mode 100644 index 00000000000..d3700778b02 --- /dev/null +++ b/test/JDBC/expected/output_into_fires_trigger.out @@ -0,0 +1,418 @@ + + + + + +-- Below statements will fire an after trigger +-- INSERT non local table OUTPUT ... INTO local table +-- UPDATE non local table OUTPUT ... INTO local table +-- DELETE non local table OUTPUT ... INTO local table +-- REPEAT THE ABOVE INSIDE + -- PROCEDURE + -- TRIGGER + -- FUNCTION (functions should not be allowed to create for output to client or non local object) +-- SOME MORE CASES OF OUTPUT CLAUSE WHICH SHOULD NOT BE ALLOWED INSIDE PLTSQL FUNCTIONS +-- OUTPUT TO CLIENT & OUTPUT INTO NON LOCAL OBJECT +CREATE TABLE babel_4859_t (id INT) +GO + + +-- INSERT table OUTPUT ... INTO table variable +CREATE TRIGGER [dbo].[babel_4859_trigger_insert] + ON [dbo].[babel_4859_t] +AFTER INSERT +AS +SET NOCOUNT ON +SELECT 1; +GO + +DECLARE @babel_4859_tabvar TABLE (id INT); +INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) +GO +~~START~~ +int +1 +~~END~~ + +~~ROW COUNT: 4~~ + + +-- UPDATE table OUTPUT ... INTO table variable +CREATE TRIGGER [dbo].[babel_4859_trigger_update] + ON [dbo].[babel_4859_t] +AFTER UPDATE +AS +SET NOCOUNT ON +SELECT 1; +GO + +DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); +UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar +GO +~~START~~ +int +1 +~~END~~ + +~~ROW COUNT: 4~~ + + +-- DELETE table OUTPUT ... INTO table variable +CREATE TRIGGER [dbo].[babel_4859_trigger_delete] + ON [dbo].[babel_4859_t] +AFTER delete +AS +SET NOCOUNT ON +SELECT 1; +GO + +DECLARE @babel_4859_tabvar TABLE (id_old INT); +DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar +GO +~~START~~ +int +1 +~~END~~ + +~~ROW COUNT: 4~~ + + +-- INSERT table OUTPUT ... INTO table variable INSIDE PROCEDURE +CREATE PROCEDURE babel_4859_p +AS +DECLARE @babel_4859_tabvar TABLE (id INT); +INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) +GO + +EXEC babel_4859_p +GO +~~START~~ +int +1 +~~END~~ + +~~ROW COUNT: 4~~ + + +DROP PROC babel_4859_p +GO + +-- UPDATE table OUTPUT ... INTO table variable INSIDE PROCEDURE +CREATE PROCEDURE babel_4859_p +AS +DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); +UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar +GO + +EXEC babel_4859_p +GO +~~START~~ +int +1 +~~END~~ + +~~ROW COUNT: 4~~ + + +DROP PROC babel_4859_p +GO + +-- DELETE table OUTPUT ... INTO table variable INSIDE PROCEDURE +CREATE PROCEDURE babel_4859_p +AS +DECLARE @babel_4859_tabvar TABLE (id_old INT); +DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar +GO + +EXEC babel_4859_p +GO +~~START~~ +int +1 +~~END~~ + +~~ROW COUNT: 4~~ + + +DROP PROC babel_4859_p +GO + +CREATE TABLE babel_4859_t2 (id INT) +GO + +-- INSERT table OUTPUT ... INTO table variable INSIDE TRIGGER which will in turn fire another trigger +CREATE TRIGGER [dbo].[babel_4859_t2_trigger_insert] + ON [dbo].[babel_4859_t2] +AFTER INSERT +AS +SET NOCOUNT ON +DECLARE @babel_4859_tabvar TABLE (id INT); +INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) +SELECT * FROM @babel_4859_tabvar +GO + +INSERT INTO babel_4859_t2 VALUES (1) +GO +~~START~~ +int +1 +~~END~~ + +~~START~~ +int +4859 +9584 +2 +3 +~~END~~ + +~~ROW COUNT: 1~~ + + +DROP TRIGGER [dbo].[babel_4859_t2_trigger_insert] +GO + +-- UPDATE table OUTPUT ... INTO table variable INSIDE TRIGGER which will in turn fire another trigger +CREATE TRIGGER [dbo].[babel_4859_t2_trigger_insert] + ON [dbo].[babel_4859_t2] +AFTER INSERT +AS +SET NOCOUNT ON +DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); +UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar +SELECT * FROM @babel_4859_tabvar +GO + +INSERT INTO babel_4859_t2 VALUES (1) +GO +~~START~~ +int +1 +~~END~~ + +~~START~~ +int#!#int +77#!#4859 +77#!#9584 +77#!#2 +77#!#3 +~~END~~ + +~~ROW COUNT: 1~~ + + +DROP TRIGGER [dbo].[babel_4859_t2_trigger_insert] +GO + +-- DELETE table OUTPUT ... INTO table variable INSIDE TRIGGER which will in turn fire another trigger +CREATE TRIGGER [dbo].[babel_4859_t2_trigger_insert] + ON [dbo].[babel_4859_t2] +AFTER INSERT +AS +SET NOCOUNT ON +DECLARE @babel_4859_tabvar TABLE (id_old INT); +DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar +SELECT * FROM @babel_4859_tabvar +GO + +INSERT INTO babel_4859_t2 VALUES (1) +GO +~~START~~ +int +1 +~~END~~ + +~~START~~ +int +77 +77 +77 +77 +~~END~~ + +~~ROW COUNT: 1~~ + + +DROP TRIGGER [dbo].[babel_4859_t2_trigger_insert] +GO + + +-- INSERT table OUTPUT ... INTO table variable INSIDE FUNCTION +-- Should fail because inserting into non local object +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'INSERT' cannot be used within a function)~~ + + +-- UPDATE table OUTPUT ... INTO table variable INSIDE FUNCTION +-- Should fail because updating non local object +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); + UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'UPDATE' cannot be used within a function)~~ + + +-- DELETE table OUTPUT ... INTO table variable INSIDE FUNCTION +-- Should fail because deleting from non local object +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id_old INT); + DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'DELETE' cannot be used within a function)~~ + + + + +-- OUTPUT TO CLIENT SHOUD BE BLOCKED INSIDE FUNCTIONS +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + INSERT INTO @babel_4859_tabvar OUTPUT INSERTED.id VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'INSERT' within a function.)~~ + + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + UPDATE @babel_4859_tabvar SET id = 77 OUTPUT INSERTED.id, DELETED.id + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'UPDATE' within a function.)~~ + + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DELETE @babel_4859_tabvar OUTPUT DELETED.id + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'DELETE' within a function.)~~ + + + +-- OUTPUT INTO NON LOCAL OBJECTS SHOULD NOT BE ALLOWED INSIDE FUNCTIONS +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + INSERT INTO @babel_4859_tabvar OUTPUT INSERTED.id INTO babel_4859_t2 VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'INSERT' within a function.)~~ + + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + UPDATE @babel_4859_tabvar SET id = 77 OUTPUT INSERTED.id INTO babel_4859_t2 + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'UPDATE' within a function.)~~ + + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DELETE @babel_4859_tabvar OUTPUT DELETED.id INTO babel_4859_t2 + RETURN 1 +END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'DELETE' within a function.)~~ + + +-- OUTPUT INTO LOCAL OBJECTS SHOULD BE ALLOWED INSIDE FUNCTIONS +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DECLARE @babel_4859_tabvar_2 TABLE (id INT); + INSERT INTO @babel_4859_tabvar OUTPUT INSERTED.id INTO @babel_4859_tabvar_2 VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO +DROP FUNCTION babel_4859_f1 +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DECLARE @babel_4859_tabvar_2 TABLE (id INT); + UPDATE @babel_4859_tabvar SET id = 77 OUTPUT INSERTED.id INTO @babel_4859_tabvar_2 + RETURN 1 +END +GO +DROP FUNCTION babel_4859_f1 +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DECLARE @babel_4859_tabvar_2 TABLE (id INT); + DELETE @babel_4859_tabvar OUTPUT DELETED.id INTO @babel_4859_tabvar_2 + RETURN 1 +END +GO +DROP FUNCTION babel_4859_f1 +GO + +DROP TABLE babel_4859_t, babel_4859_t2 +GO diff --git a/test/JDBC/input/output_into_fires_trigger.sql b/test/JDBC/input/output_into_fires_trigger.sql new file mode 100644 index 00000000000..181aedb9863 --- /dev/null +++ b/test/JDBC/input/output_into_fires_trigger.sql @@ -0,0 +1,295 @@ +-- Below statements will fire an after trigger +-- INSERT non local table OUTPUT ... INTO local table +-- UPDATE non local table OUTPUT ... INTO local table +-- DELETE non local table OUTPUT ... INTO local table + +-- REPEAT THE ABOVE INSIDE + -- PROCEDURE + -- TRIGGER + -- FUNCTION (functions should not be allowed to create for output to client or non local object) + +-- SOME MORE CASES OF OUTPUT CLAUSE WHICH SHOULD NOT BE ALLOWED INSIDE PLTSQL FUNCTIONS +-- OUTPUT TO CLIENT & OUTPUT INTO NON LOCAL OBJECT + + + +CREATE TABLE babel_4859_t (id INT) +GO + + +-- INSERT table OUTPUT ... INTO table variable +CREATE TRIGGER [dbo].[babel_4859_trigger_insert] + ON [dbo].[babel_4859_t] +AFTER INSERT +AS +SET NOCOUNT ON +SELECT 1; +GO + +DECLARE @babel_4859_tabvar TABLE (id INT); +INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) +GO + +-- UPDATE table OUTPUT ... INTO table variable +CREATE TRIGGER [dbo].[babel_4859_trigger_update] + ON [dbo].[babel_4859_t] +AFTER UPDATE +AS +SET NOCOUNT ON +SELECT 1; +GO + +DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); +UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar +GO + +-- DELETE table OUTPUT ... INTO table variable +CREATE TRIGGER [dbo].[babel_4859_trigger_delete] + ON [dbo].[babel_4859_t] +AFTER delete +AS +SET NOCOUNT ON +SELECT 1; +GO + +DECLARE @babel_4859_tabvar TABLE (id_old INT); +DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar +GO + +-- INSERT table OUTPUT ... INTO table variable INSIDE PROCEDURE +CREATE PROCEDURE babel_4859_p +AS +DECLARE @babel_4859_tabvar TABLE (id INT); +INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) +GO + +EXEC babel_4859_p +GO + +DROP PROC babel_4859_p +GO + +-- UPDATE table OUTPUT ... INTO table variable INSIDE PROCEDURE +CREATE PROCEDURE babel_4859_p +AS +DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); +UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar +GO + +EXEC babel_4859_p +GO + +DROP PROC babel_4859_p +GO + +-- DELETE table OUTPUT ... INTO table variable INSIDE PROCEDURE +CREATE PROCEDURE babel_4859_p +AS +DECLARE @babel_4859_tabvar TABLE (id_old INT); +DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar +GO + +EXEC babel_4859_p +GO + +DROP PROC babel_4859_p +GO + +CREATE TABLE babel_4859_t2 (id INT) +GO + +-- INSERT table OUTPUT ... INTO table variable INSIDE TRIGGER which will in turn fire another trigger +CREATE TRIGGER [dbo].[babel_4859_t2_trigger_insert] + ON [dbo].[babel_4859_t2] +AFTER INSERT +AS +SET NOCOUNT ON +DECLARE @babel_4859_tabvar TABLE (id INT); +INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) +SELECT * FROM @babel_4859_tabvar +GO + +INSERT INTO babel_4859_t2 VALUES (1) +GO + +DROP TRIGGER [dbo].[babel_4859_t2_trigger_insert] +GO + +-- UPDATE table OUTPUT ... INTO table variable INSIDE TRIGGER which will in turn fire another trigger +CREATE TRIGGER [dbo].[babel_4859_t2_trigger_insert] + ON [dbo].[babel_4859_t2] +AFTER INSERT +AS +SET NOCOUNT ON +DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); +UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar +SELECT * FROM @babel_4859_tabvar +GO + +INSERT INTO babel_4859_t2 VALUES (1) +GO + +DROP TRIGGER [dbo].[babel_4859_t2_trigger_insert] +GO + +-- DELETE table OUTPUT ... INTO table variable INSIDE TRIGGER which will in turn fire another trigger +CREATE TRIGGER [dbo].[babel_4859_t2_trigger_insert] + ON [dbo].[babel_4859_t2] +AFTER INSERT +AS +SET NOCOUNT ON +DECLARE @babel_4859_tabvar TABLE (id_old INT); +DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar +SELECT * FROM @babel_4859_tabvar +GO + +INSERT INTO babel_4859_t2 VALUES (1) +GO + +DROP TRIGGER [dbo].[babel_4859_t2_trigger_insert] +GO + + +-- INSERT table OUTPUT ... INTO table variable INSIDE FUNCTION +-- Should fail because inserting into non local object +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + INSERT INTO babel_4859_t OUTPUT INSERTED.id INTO @babel_4859_tabvar VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO + +-- UPDATE table OUTPUT ... INTO table variable INSIDE FUNCTION +-- Should fail because updating non local object +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT, id_old INT); + UPDATE babel_4859_t SET id = 77 OUTPUT INSERTED.id, DELETED.id INTO @babel_4859_tabvar + RETURN 1 +END +GO + +-- DELETE table OUTPUT ... INTO table variable INSIDE FUNCTION +-- Should fail because deleting from non local object +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id_old INT); + DELETE babel_4859_t OUTPUT DELETED.id INTO @babel_4859_tabvar + RETURN 1 +END +GO + + + +-- OUTPUT TO CLIENT SHOUD BE BLOCKED INSIDE FUNCTIONS +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + INSERT INTO @babel_4859_tabvar OUTPUT INSERTED.id VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + UPDATE @babel_4859_tabvar SET id = 77 OUTPUT INSERTED.id, DELETED.id + RETURN 1 +END +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DELETE @babel_4859_tabvar OUTPUT DELETED.id + RETURN 1 +END +GO + + +-- OUTPUT INTO NON LOCAL OBJECTS SHOULD NOT BE ALLOWED INSIDE FUNCTIONS +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + INSERT INTO @babel_4859_tabvar OUTPUT INSERTED.id INTO babel_4859_t2 VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + UPDATE @babel_4859_tabvar SET id = 77 OUTPUT INSERTED.id INTO babel_4859_t2 + RETURN 1 +END +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DELETE @babel_4859_tabvar OUTPUT DELETED.id INTO babel_4859_t2 + RETURN 1 +END +GO + +-- OUTPUT INTO LOCAL OBJECTS SHOULD BE ALLOWED INSIDE FUNCTIONS +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DECLARE @babel_4859_tabvar_2 TABLE (id INT); + INSERT INTO @babel_4859_tabvar OUTPUT INSERTED.id INTO @babel_4859_tabvar_2 VALUES (4859), (9584), (2), (3) + RETURN 1 +END +GO +DROP FUNCTION babel_4859_f1 +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DECLARE @babel_4859_tabvar_2 TABLE (id INT); + UPDATE @babel_4859_tabvar SET id = 77 OUTPUT INSERTED.id INTO @babel_4859_tabvar_2 + RETURN 1 +END +GO +DROP FUNCTION babel_4859_f1 +GO + +CREATE FUNCTION babel_4859_f1() +RETURNS INT +AS +BEGIN + DECLARE @babel_4859_tabvar TABLE (id INT); + DECLARE @babel_4859_tabvar_2 TABLE (id INT); + DELETE @babel_4859_tabvar OUTPUT DELETED.id INTO @babel_4859_tabvar_2 + RETURN 1 +END +GO +DROP FUNCTION babel_4859_f1 +GO + +DROP TABLE babel_4859_t, babel_4859_t2 +GO \ No newline at end of file From 6b45d4964c67c83b845a6503b2cec12ee0a2ed23 Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Tue, 23 Jul 2024 13:01:21 -0400 Subject: [PATCH 08/15] Test changes for 'Fix error when trying to drop columns from temp tables.' (#2753) Tests for babelfish-for-postgresql/postgresql_modified_for_babelfish#410 Task: BABEL-4912 Signed-off-by: Jason Teng --- test/JDBC/expected/temp_table.out | 89 +++++++++++++++++++ .../temp_table_rollback-vu-verify.out | 22 +---- ...le_rollback_isolation_read_uncommitted.out | 22 +---- ...temp_table_rollback_isolation_snapshot.out | 22 +---- .../temp_table_rollback_xact_abort_on.out | 22 +---- test/JDBC/input/temp_tables/temp_table.sql | 48 ++++++++++ .../temp_table_rollback-vu-verify.sql | 6 +- 7 files changed, 152 insertions(+), 79 deletions(-) create mode 100644 test/JDBC/expected/temp_table.out create mode 100644 test/JDBC/input/temp_tables/temp_table.sql diff --git a/test/JDBC/expected/temp_table.out b/test/JDBC/expected/temp_table.out new file mode 100644 index 00000000000..64018079d48 --- /dev/null +++ b/test/JDBC/expected/temp_table.out @@ -0,0 +1,89 @@ +-- BABEL-4912 test ALTER TABLE for temp tables +CREATE TABLE #t1 (a INT IDENTITY PRIMARY KEY NOT NULL, b INT) +GO + +INSERT INTO #t1 (b) values (1) +GO +~~ROW COUNT: 1~~ + + +SELECT * FROM #t1 +GO +~~START~~ +int#!#int +1#!#1 +~~END~~ + + +ALTER TABLE #t1 DROP COLUMN b +GO + +SELECT * FROM #t1 +GO +~~START~~ +int +1 +~~END~~ + + +ALTER TABLE #t1 ADD b varchar(20) +GO + +SELECT * FROM #t1 +GO +~~START~~ +int#!#varchar +1#!# +~~END~~ + + +ALTER TABLE #t1 ADD c AS a + 1 +GO + +SELECT * FROM #t1 +GO +~~START~~ +int#!#varchar#!#int +1#!##!#2 +~~END~~ + + +ALTER TABLE #t1 DROP COLUMN a +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot drop a column used by a generated column)~~ + + +SELECT * FROM #t1 +GO +~~START~~ +int#!#varchar#!#int +1#!##!#2 +~~END~~ + + +ALTER TABLE #t1 DROP COLUMN b +GO + +SELECT * FROM #t1 +GO +~~START~~ +int#!#int +1#!#2 +~~END~~ + + +ALTER TABLE #t1 DROP COLUMN c +GO + +SELECT * FROM #t1 +GO +~~START~~ +int +1 +~~END~~ + + +DROP TABLE #t1 +GO diff --git a/test/JDBC/expected/temp_table_rollback-vu-verify.out b/test/JDBC/expected/temp_table_rollback-vu-verify.out index da649155143..199b6d3bd62 100644 --- a/test/JDBC/expected/temp_table_rollback-vu-verify.out +++ b/test/JDBC/expected/temp_table_rollback-vu-verify.out @@ -144,7 +144,7 @@ COMMIT GO ---------------------------------------------------------- --- ALTER TABLE (should fail due to BABEL-4912) +-- ALTER TABLE (BABEL-4912) ---------------------------------------------------------- CREATE TABLE #temp_table_rollback_t1 (a int, b int) GO @@ -153,37 +153,21 @@ BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b ROLLBACK GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR ROLLBACK GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b +ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR COMMIT GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR +ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b COMMIT GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - DROP TABLE #temp_table_rollback_t1 GO diff --git a/test/JDBC/expected/temp_table_rollback_isolation_read_uncommitted.out b/test/JDBC/expected/temp_table_rollback_isolation_read_uncommitted.out index a69d701906b..9f8a489859e 100644 --- a/test/JDBC/expected/temp_table_rollback_isolation_read_uncommitted.out +++ b/test/JDBC/expected/temp_table_rollback_isolation_read_uncommitted.out @@ -212,7 +212,7 @@ COMMIT GO ---------------------------------------------------------- --- ALTER TABLE (should fail due to BABEL-4912) +-- ALTER TABLE (BABEL-4912) ---------------------------------------------------------- CREATE TABLE #temp_table_rollback_t1 (a int, b int) GO @@ -221,37 +221,21 @@ BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b ROLLBACK GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR ROLLBACK GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b +ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR COMMIT GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR +ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b COMMIT GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - DROP TABLE #temp_table_rollback_t1 GO diff --git a/test/JDBC/expected/temp_table_rollback_isolation_snapshot.out b/test/JDBC/expected/temp_table_rollback_isolation_snapshot.out index b155ec955a1..f8dfa0e45bc 100644 --- a/test/JDBC/expected/temp_table_rollback_isolation_snapshot.out +++ b/test/JDBC/expected/temp_table_rollback_isolation_snapshot.out @@ -212,7 +212,7 @@ COMMIT GO ---------------------------------------------------------- --- ALTER TABLE (should fail due to BABEL-4912) +-- ALTER TABLE (BABEL-4912) ---------------------------------------------------------- CREATE TABLE #temp_table_rollback_t1 (a int, b int) GO @@ -221,37 +221,21 @@ BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b ROLLBACK GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR ROLLBACK GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b +ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR COMMIT GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR +ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b COMMIT GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - DROP TABLE #temp_table_rollback_t1 GO diff --git a/test/JDBC/expected/temp_table_rollback_xact_abort_on.out b/test/JDBC/expected/temp_table_rollback_xact_abort_on.out index a219ad4cb0d..bc1a1f39612 100644 --- a/test/JDBC/expected/temp_table_rollback_xact_abort_on.out +++ b/test/JDBC/expected/temp_table_rollback_xact_abort_on.out @@ -212,7 +212,7 @@ COMMIT GO ---------------------------------------------------------- --- ALTER TABLE (should fail due to BABEL-4912) +-- ALTER TABLE (BABEL-4912) ---------------------------------------------------------- CREATE TABLE #temp_table_rollback_t1 (a int, b int) GO @@ -221,37 +221,21 @@ BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b ROLLBACK GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR ROLLBACK GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b +ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR COMMIT GO -~~ERROR (Code: 3726)~~ - -~~ERROR (Message: cannot drop column b of table "#temp_table_rollback_t1" because other objects depend on it)~~ - BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR +ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b COMMIT GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: unexpected object depending on column: type "#temp_table_rollback_t1")~~ - DROP TABLE #temp_table_rollback_t1 GO diff --git a/test/JDBC/input/temp_tables/temp_table.sql b/test/JDBC/input/temp_tables/temp_table.sql new file mode 100644 index 00000000000..50603b2bc45 --- /dev/null +++ b/test/JDBC/input/temp_tables/temp_table.sql @@ -0,0 +1,48 @@ +-- BABEL-4912 test ALTER TABLE for temp tables +CREATE TABLE #t1 (a INT IDENTITY PRIMARY KEY NOT NULL, b INT) +GO + +INSERT INTO #t1 (b) values (1) +GO + +SELECT * FROM #t1 +GO + +ALTER TABLE #t1 DROP COLUMN b +GO + +SELECT * FROM #t1 +GO + +ALTER TABLE #t1 ADD b varchar(20) +GO + +SELECT * FROM #t1 +GO + +ALTER TABLE #t1 ADD c AS a + 1 +GO + +SELECT * FROM #t1 +GO + +ALTER TABLE #t1 DROP COLUMN a +GO + +SELECT * FROM #t1 +GO + +ALTER TABLE #t1 DROP COLUMN b +GO + +SELECT * FROM #t1 +GO + +ALTER TABLE #t1 DROP COLUMN c +GO + +SELECT * FROM #t1 +GO + +DROP TABLE #t1 +GO diff --git a/test/JDBC/input/temp_tables/temp_table_rollback-vu-verify.sql b/test/JDBC/input/temp_tables/temp_table_rollback-vu-verify.sql index ba99ebd2f3f..d8bc7e02c5c 100644 --- a/test/JDBC/input/temp_tables/temp_table_rollback-vu-verify.sql +++ b/test/JDBC/input/temp_tables/temp_table_rollback-vu-verify.sql @@ -79,7 +79,7 @@ COMMIT GO ---------------------------------------------------------- --- ALTER TABLE (should fail due to BABEL-4912) +-- ALTER TABLE (BABEL-4912) ---------------------------------------------------------- CREATE TABLE #temp_table_rollback_t1 (a int, b int) GO @@ -95,12 +95,12 @@ ROLLBACK GO BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b +ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR COMMIT GO BEGIN TRAN -ALTER TABLE #temp_table_rollback_t1 ALTER COLUMN b VARCHAR +ALTER TABLE #temp_table_rollback_t1 DROP COLUMN b COMMIT GO From 1570cc67db8f76d87d6ac04f9c7340ed2cb899b8 Mon Sep 17 00:00:00 2001 From: HarshLunagariya <40052763+HarshLunagariya@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:13:51 +0530 Subject: [PATCH 09/15] Block cross-db 'SELECT ... INTO table FROM ...' statement (#2744) Before this commit, Cross-db 'SELECT ... INTO table FROM ...' was allowed to be executed unintentionally since it was missed to be blocked when cross-db DMLs got supported. Due to this unblocked behaviour, It creates a table whose owner is current session's login since internally cross-db statement execution sets current role to current session's login. This commit blocks cross-db 'SELECT ... INTO table FROM ...' statement by adding relevant check on ANTLR parser. Task: BABEL-4934 Signed-off-by: Harsh Lunagariya lunharsh@amazon.com --- contrib/babelfishpg_tsql/src/tsqlIface.cpp | 16 ++ test/JDBC/expected/BABEL-CROSS-DB.out | 203 +++++++++++++++++++++ test/JDBC/input/BABEL-CROSS-DB.mix | 139 ++++++++++++++ 3 files changed, 358 insertions(+) diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index b742ec06677..582ce935d3f 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -1787,6 +1787,22 @@ class tsqlBuilder : public tsqlCommonMutator if (is_schema_specified) stmt->is_schema_specified = true; + if (is_cross_db) + { + if (ctx->select_statement_standalone() && + ctx->select_statement_standalone()->select_statement() && + ctx->select_statement_standalone()->select_statement()->query_expression() && + ctx->select_statement_standalone()->select_statement()->query_expression()->query_specification() && + ctx->select_statement_standalone()->select_statement()->query_expression()->query_specification()->INTO() && + ctx->select_statement_standalone()->select_statement()->query_expression()->query_specification()->table_name()) + { + throw PGErrorWrapperException(ERROR, + ERRCODE_FEATURE_NOT_SUPPORTED, + "cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.", + getLineAndPos(ctx->select_statement_standalone())); + } + } + if (is_compiling_create_function()) { /* select without destination should be blocked. We can use already information about desitnation, which is already processed. */ diff --git a/test/JDBC/expected/BABEL-CROSS-DB.out b/test/JDBC/expected/BABEL-CROSS-DB.out index 36c32036ab4..2dfe297e91c 100644 --- a/test/JDBC/expected/BABEL-CROSS-DB.out +++ b/test/JDBC/expected/BABEL-CROSS-DB.out @@ -541,6 +541,209 @@ GO DROP DATABASE db2; GO +-- BABEL-4934 Test blocking cross-db SELECT-INTO statement +CREATE DATABASE db_4934_1; +GO + +CREATE DATABASE db_4934_2; +GO + +USE master; +GO + +CREATE TABLE t1(a int); +GO + +CREATE TABLE t2(b int); +GO + +USE db_4934_1; +GO + +CREATE TABLE t1(a int); +GO + +CREATE TABLE t2(b int); +GO + +USE db_4934_2; +GO + +CREATE TABLE t1(a int); +GO + +CREATE TABLE t2(b int); +GO + +USE db_4934_1; +GO + +-- #4934.1 It should be blocked +SELECT * INTO t222 FROM master.dbo.t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM master..t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM db_4934_2..t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM db_4934_2.dbo.t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM db_4934_2..t1, t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM t1, db_4934_1..t2; +GO + +SELECT * INTO t222 FROM master..t1, db_4934_2..t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM (SELECT * FROM master..t1); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM (SELECT * FROM t1, master..t1); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM (SELECT *, (SELECT * FROM master..t1) FROM t1); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO t222 FROM (SELECT *, (SELECT * FROM t1) FROM master..t3); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO master..t222 FROM db_4934_2..t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO db_4934_1..t222 FROM db_4934_2..t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +SELECT * INTO master..t222 FROM master..t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + +-- #4934.2 Following statements will succeed across same database +SELECT * INTO t3 FROM db_4934_1.dbo.t1; +GO + +SELECT * INTO t4 FROM dbo.t1; +GO + +SELECT * INTO t5 FROM db_4934_1..t1; +GO + +SELECT * INTO t6 FROM db_4934_1..t1, db_4934_1..t2; +GO + +SELECT * INTO t7 FROM (SELECT * FROM db_4934_1..t1); +GO + +SELECT * INTO t8 FROM (SELECT *, (SELECT * FROM db_4934_1..t2) FROM db_4934_1..t1); +GO + +-- validate the access +SELECT * FROM t3, t4, t5, t6, t7, t8; +GO +~~START~~ +int#!#int#!#int#!#int#!#int#!#int#!#int#!#int +~~END~~ + + +DROP TABLE t3, t4, t5, t6, t7, t8; +GO + +-- #4934.3 Temporary table should not be blocked +SELECT * INTO #t1 FROM db_4934_1.dbo.t1; +GO + +SELECT * INTO #t2 FROM (SELECT * FROM db_4934_1.dbo.t1); +GO + +-- validate the access +SELECT * FROM #t1, #t2; +GO +~~START~~ +int#!#int +~~END~~ + + +DROP TABLE #t1, #t2; +GO + +-- Even though this is same as above statement, this will still fail since +-- internally it considers as cross-db statement (This behaviour is general to +-- all of the applicable DMLs) +SELECT * INTO tempdb..#t3 FROM db_4934_1.dbo.t1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cross-db 'SELECT INTO' statement is not supported in Babelfish. As a workaround, consider running CREATE TABLE and INSERT-SELECT statements.)~~ + + + +USE master; +GO + +DROP TABLE t1, t2; +GO + +DROP DATABASE db_4934_1; +GO + +DROP DATABASE db_4934_2; +GO + -- psql ALTER SYSTEM SET babelfishpg_tsql.migration_mode = 'single-db'; SELECT pg_reload_conf(); diff --git a/test/JDBC/input/BABEL-CROSS-DB.mix b/test/JDBC/input/BABEL-CROSS-DB.mix index c86e7cd128d..1957d7ff2a2 100644 --- a/test/JDBC/input/BABEL-CROSS-DB.mix +++ b/test/JDBC/input/BABEL-CROSS-DB.mix @@ -359,6 +359,145 @@ GO DROP DATABASE db2; GO +-- BABEL-4934 Test blocking cross-db SELECT-INTO statement +CREATE DATABASE db_4934_1; +GO + +CREATE DATABASE db_4934_2; +GO + +USE master; +GO + +CREATE TABLE t1(a int); +GO + +CREATE TABLE t2(b int); +GO + +USE db_4934_1; +GO + +CREATE TABLE t1(a int); +GO + +CREATE TABLE t2(b int); +GO + +USE db_4934_2; +GO + +CREATE TABLE t1(a int); +GO + +CREATE TABLE t2(b int); +GO + +USE db_4934_1; +GO + +-- #4934.1 It should be blocked +SELECT * INTO t222 FROM master.dbo.t1; +GO + +SELECT * INTO t222 FROM master..t1; +GO + +SELECT * INTO t222 FROM db_4934_2..t1; +GO + +SELECT * INTO t222 FROM db_4934_2.dbo.t1; +GO + +SELECT * INTO t222 FROM db_4934_2..t1, t1; +GO + +SELECT * INTO t222 FROM t1, db_4934_1..t2; +GO + +SELECT * INTO t222 FROM master..t1, db_4934_2..t1; +GO + +SELECT * INTO t222 FROM (SELECT * FROM master..t1); +GO + +SELECT * INTO t222 FROM (SELECT * FROM t1, master..t1); +GO + +SELECT * INTO t222 FROM (SELECT *, (SELECT * FROM master..t1) FROM t1); +GO + +SELECT * INTO t222 FROM (SELECT *, (SELECT * FROM t1) FROM master..t3); +GO + +SELECT * INTO master..t222 FROM db_4934_2..t1; +GO + +SELECT * INTO db_4934_1..t222 FROM db_4934_2..t1; +GO + +SELECT * INTO master..t222 FROM master..t1; +GO + +-- #4934.2 Following statements will succeed across same database +SELECT * INTO t3 FROM db_4934_1.dbo.t1; +GO + +SELECT * INTO t4 FROM dbo.t1; +GO + +SELECT * INTO t5 FROM db_4934_1..t1; +GO + +SELECT * INTO t6 FROM db_4934_1..t1, db_4934_1..t2; +GO + +SELECT * INTO t7 FROM (SELECT * FROM db_4934_1..t1); +GO + +SELECT * INTO t8 FROM (SELECT *, (SELECT * FROM db_4934_1..t2) FROM db_4934_1..t1); +GO + +-- validate the access +SELECT * FROM t3, t4, t5, t6, t7, t8; +GO + +DROP TABLE t3, t4, t5, t6, t7, t8; +GO + +-- #4934.3 Temporary table should not be blocked +SELECT * INTO #t1 FROM db_4934_1.dbo.t1; +GO + +SELECT * INTO #t2 FROM (SELECT * FROM db_4934_1.dbo.t1); +GO + +-- validate the access +SELECT * FROM #t1, #t2; +GO + +DROP TABLE #t1, #t2; +GO + +-- Even though this is same as above statement, this will still fail since +-- internally it considers as cross-db statement (This behaviour is general to +-- all of the applicable DMLs) +SELECT * INTO tempdb..#t3 FROM db_4934_1.dbo.t1; +GO + + +USE master; +GO + +DROP TABLE t1, t2; +GO + +DROP DATABASE db_4934_1; +GO + +DROP DATABASE db_4934_2; +GO + -- psql ALTER SYSTEM SET babelfishpg_tsql.migration_mode = 'single-db'; SELECT pg_reload_conf(); From a1b5bce987f957ed2070682fe92f4f4f61e91048 Mon Sep 17 00:00:00 2001 From: Rohit bhagat <65351720+rohit01010@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:50:52 +0530 Subject: [PATCH 10/15] Added wrapper function for TRIM, LTRIM, RTRIM, LEFT and RIGHT (#2481) Currently, for string functions TRIM, LTRIM, RTRIM, LEFT and RIGHT underlying Postgres function is being used which leads to incorrect output behaviour. This commit will fix this issue by adding wrapper functions for these string functions. Changes included in this commit are as follows:- 1. Added wrapper functions for TRIM, LTRIM, RTRIM, LEFT and RIGHT. 2. Added hook func_select_candidate_for_special_hook for selecting best candidate among list of functions definitions based on return type for string functions which are in special function list. 3. Updated definition of function pltsql_report_proc_not_found_error to include input_typeids of function. 4. Added PG_CATALOG namespace before TRIM, LTRIM, RTRIM, LEFT or RIGHT function invocations in some of the system functions as with these wrapper definitions of TRIM, LTRIM, RTRIM, LEFT and RIGHT functions in sys namespace, any function invocation of TRIM, LTRIM, RTRIM, LEFT or RIGHT function without namespace, by default it will call the function in sys namespace. 4. Added new test files and updated existing test files expected output as the output behaviour of these functions will change with this fix. 5. In case of Inline Table Valued Function(ITVF), made changes such that if the return type of body is different than return type stored for during creation of ITVF, an implicit cast will occur and return type of body will be casted to return type stored. 6. fixed composite actions to avoid replacing partial word for test files present in schedule file of upgrades. Engine PR: babelfish-for-postgresql/postgresql_modified_for_babelfish#342 Task: BABEL-4489 Signed-off-by: Rohit Bhagat --- .../minor-version-upgrade-util/action.yml | 2 +- .../run-verify-tests/action.yml | 2 +- .../setup-base-version/action.yml | 2 +- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 18 +- .../sql/sys_function_helpers.sql | 142 +- .../babelfishpg_tsql/sql/sys_functions.sql | 659 ++- .../babelfishpg_tsql--4.2.0--4.3.0.sql | 4852 +++++++++++++++++ contrib/babelfishpg_tsql/src/hooks.c | 24 +- contrib/babelfishpg_tsql/src/pl_exec.c | 18 + contrib/babelfishpg_tsql/src/pl_handler.c | 1 + contrib/babelfishpg_tsql/src/pltsql.h | 6 + contrib/babelfishpg_tsql/src/pltsql_coerce.c | 313 +- contrib/babelfishpg_tsql/src/tsqlIface.cpp | 46 +- .../expected/BABEL-1994-CHAR-vu-verify.out | 4 +- test/JDBC/expected/BABEL-1994-CHAR.out | 4 +- .../expected/BABEL-1994-VARCHAR-vu-verify.out | 4 +- test/JDBC/expected/BABEL-1994-VARCHAR.out | 4 +- .../TestProcedureWithTransactions.out | 4 +- ...cleanup__13_6__sys-host_name-vu-verify.out | 2 +- ...cleanup__13_7__sys-host_name-vu-verify.out | 2 +- ...cleanup__13_8__sys-host_name-vu-verify.out | 2 +- ...cleanup__13_9__sys-host_name-vu-verify.out | 2 +- ...cleanup__14_3__sys-host_name-vu-verify.out | 2 +- ..._14_5__ISC-Check-Constraints-vu-verify.out | 4 +- .../left-before-15_8-or-16_4-vu-cleanup.out | 80 + .../left-before-15_8-or-16_4-vu-prepare.out | 156 + .../left-before-15_8-or-16_4-vu-verify.out | 745 +++ test/JDBC/expected/left-vu-cleanup.out | 80 + test/JDBC/expected/left-vu-prepare.out | 156 + test/JDBC/expected/left-vu-verify.out | 745 +++ .../ltrim-before-15_8-or-16_4-vu-cleanup.out | 80 + .../ltrim-before-15_8-or-16_4-vu-prepare.out | 156 + .../ltrim-before-15_8-or-16_4-vu-verify.out | 610 +++ test/JDBC/expected/ltrim-vu-cleanup.out | 80 + test/JDBC/expected/ltrim-vu-prepare.out | 156 + test/JDBC/expected/ltrim-vu-verify.out | 610 +++ .../left-before-15_8-or-16_4-vu-verify.out | 745 +++ .../chinese_prc_ci_as/left-vu-verify.out | 745 +++ .../ltrim-before-15_8-or-16_4-vu-verify.out | 610 +++ .../chinese_prc_ci_as/ltrim-vu-verify.out | 610 +++ .../right-before-15_8-or-16_4-vu-verify.out | 716 +++ .../chinese_prc_ci_as/right-vu-verify.out | 716 +++ .../rtrim-before-15_8-or-16_4-vu-verify.out | 610 +++ .../chinese_prc_ci_as/rtrim-vu-verify.out | 610 +++ .../trim-before-15_8-or-16_4-vu-verify.out | 1364 +++++ .../chinese_prc_ci_as/trim-vu-verify.out | 1365 +++++ .../left-before-15_8-or-16_4-vu-verify.out | 745 +++ .../japanese_ci_as/left-vu-verify.out | 745 +++ .../ltrim-before-15_8-or-16_4-vu-verify.out | 610 +++ .../japanese_ci_as/ltrim-vu-verify.out | 610 +++ .../right-before-15_8-or-16_4-vu-verify.out | 716 +++ .../japanese_ci_as/right-vu-verify.out | 716 +++ .../rtrim-before-15_8-or-16_4-vu-verify.out | 610 +++ .../japanese_ci_as/rtrim-vu-verify.out | 610 +++ .../trim-before-15_8-or-16_4-vu-verify.out | 1364 +++++ .../japanese_ci_as/trim-vu-verify.out | 1365 +++++ .../right-before-15_8-or-16_4-vu-cleanup.out | 80 + .../right-before-15_8-or-16_4-vu-prepare.out | 156 + .../right-before-15_8-or-16_4-vu-verify.out | 716 +++ test/JDBC/expected/right-vu-cleanup.out | 80 + test/JDBC/expected/right-vu-prepare.out | 156 + test/JDBC/expected/right-vu-verify.out | 716 +++ .../rtrim-before-15_8-or-16_4-vu-cleanup.out | 80 + .../rtrim-before-15_8-or-16_4-vu-prepare.out | 156 + .../rtrim-before-15_8-or-16_4-vu-verify.out | 610 +++ test/JDBC/expected/rtrim-vu-cleanup.out | 80 + test/JDBC/expected/rtrim-vu-prepare.out | 156 + test/JDBC/expected/rtrim-vu-verify.out | 610 +++ ...st_name-before-15_8-or-16_4-vu-cleanup.out | 26 + ...st_name-before-15_8-or-16_4-vu-prepare.out | 42 + ...ost_name-before-15_8-or-16_4-vu-verify.out | 83 + .../JDBC/expected/sys-host_name-vu-verify.out | 6 +- .../trim-before-15_8-or-16_4-vu-cleanup.out | 77 + .../trim-before-15_8-or-16_4-vu-prepare.out | 152 + .../trim-before-15_8-or-16_4-vu-verify.out | 1364 +++++ test/JDBC/expected/trim-vu-cleanup.out | 77 + test/JDBC/expected/trim-vu-prepare.out | 152 + test/JDBC/expected/trim-vu-verify.out | 1365 +++++ .../left-before-15_8-or-16_4-vu-cleanup.sql | 80 + .../left-before-15_8-or-16_4-vu-prepare.sql | 126 + .../left-before-15_8-or-16_4-vu-verify.sql | 328 ++ .../string_functions/left-vu-cleanup.sql | 80 + .../string_functions/left-vu-prepare.sql | 126 + .../string_functions/left-vu-verify.sql | 328 ++ .../ltrim-before-15_8-or-16_4-vu-cleanup.sql | 80 + .../ltrim-before-15_8-or-16_4-vu-prepare.sql | 126 + .../ltrim-before-15_8-or-16_4-vu-verify.sql | 270 + .../string_functions/ltrim-vu-cleanup.sql | 80 + .../string_functions/ltrim-vu-prepare.sql | 126 + .../string_functions/ltrim-vu-verify.sql | 270 + .../right-before-15_8-or-16_4-vu-cleanup.sql | 80 + .../right-before-15_8-or-16_4-vu-prepare.sql | 126 + .../right-before-15_8-or-16_4-vu-verify.sql | 314 ++ .../string_functions/right-vu-cleanup.sql | 80 + .../string_functions/right-vu-prepare.sql | 126 + .../string_functions/right-vu-verify.sql | 314 ++ .../rtrim-before-15_8-or-16_4-vu-cleanup.sql | 80 + .../rtrim-before-15_8-or-16_4-vu-prepare.sql | 126 + .../rtrim-before-15_8-or-16_4-vu-verify.sql | 270 + .../string_functions/rtrim-vu-cleanup.sql | 80 + .../string_functions/rtrim-vu-prepare.sql | 126 + .../string_functions/rtrim-vu-verify.sql | 270 + .../trim-before-15_8-or-16_4-vu-cleanup.sql | 77 + .../trim-before-15_8-or-16_4-vu-prepare.sql | 122 + .../trim-before-15_8-or-16_4-vu-verify.sql | 619 +++ .../string_functions/trim-vu-cleanup.sql | 77 + .../string_functions/trim-vu-prepare.sql | 122 + .../string_functions/trim-vu-verify.sql | 619 +++ ...st_name-before-15_8-or-16_4-vu-cleanup.sql | 26 + ...st_name-before-15_8-or-16_4-vu-prepare.sql | 42 + ...ost_name-before-15_8-or-16_4-vu-verify.mix | 33 + test/JDBC/jdbc_schedule | 22 +- test/JDBC/upgrade/13_4/schedule | 5 + test/JDBC/upgrade/13_5/schedule | 5 + test/JDBC/upgrade/13_6/schedule | 5 + test/JDBC/upgrade/13_7/schedule | 5 + test/JDBC/upgrade/13_8/schedule | 5 + test/JDBC/upgrade/13_9/schedule | 5 + test/JDBC/upgrade/14_10/schedule | 7 +- test/JDBC/upgrade/14_11/schedule | 7 +- test/JDBC/upgrade/14_12/schedule | 7 +- test/JDBC/upgrade/14_13/schedule | 7 +- test/JDBC/upgrade/14_3/schedule | 5 + test/JDBC/upgrade/14_5/schedule | 7 +- test/JDBC/upgrade/14_6/schedule | 7 +- test/JDBC/upgrade/14_7/schedule | 7 +- test/JDBC/upgrade/14_8/schedule | 7 +- test/JDBC/upgrade/14_9/schedule | 7 +- test/JDBC/upgrade/15_1/schedule | 7 +- test/JDBC/upgrade/15_2/schedule | 7 +- test/JDBC/upgrade/15_3/schedule | 7 +- test/JDBC/upgrade/15_4/schedule | 7 +- test/JDBC/upgrade/15_5/schedule | 7 +- test/JDBC/upgrade/15_6/schedule | 7 +- test/JDBC/upgrade/15_7/schedule | 7 +- test/JDBC/upgrade/15_8/schedule | 5 + test/JDBC/upgrade/16_1/schedule | 7 +- test/JDBC/upgrade/16_2/schedule | 7 +- test/JDBC/upgrade/16_3/schedule | 9 +- test/JDBC/upgrade/latest/schedule | 5 + test/odbc/psqlodbc/test/text.cpp | 5 + .../expected_drop.out | 1 + .../expected_dependency.out | 5 +- 143 files changed, 38713 insertions(+), 144 deletions(-) create mode 100644 test/JDBC/expected/left-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/left-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/left-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/left-vu-cleanup.out create mode 100644 test/JDBC/expected/left-vu-prepare.out create mode 100644 test/JDBC/expected/left-vu-verify.out create mode 100644 test/JDBC/expected/ltrim-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/ltrim-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/ltrim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/ltrim-vu-cleanup.out create mode 100644 test/JDBC/expected/ltrim-vu-prepare.out create mode 100644 test/JDBC/expected/ltrim-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/left-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/left-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/ltrim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/ltrim-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/trim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/trim-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/left-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/left-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/ltrim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/ltrim-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/trim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/trim-vu-verify.out create mode 100644 test/JDBC/expected/right-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/right-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/right-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/right-vu-cleanup.out create mode 100644 test/JDBC/expected/right-vu-prepare.out create mode 100644 test/JDBC/expected/right-vu-verify.out create mode 100644 test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/rtrim-vu-cleanup.out create mode 100644 test/JDBC/expected/rtrim-vu-prepare.out create mode 100644 test/JDBC/expected/rtrim-vu-verify.out create mode 100644 test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/trim-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/trim-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/trim-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/trim-vu-cleanup.out create mode 100644 test/JDBC/expected/trim-vu-prepare.out create mode 100644 test/JDBC/expected/trim-vu-verify.out create mode 100644 test/JDBC/input/functions/string_functions/left-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/left-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/left-before-15_8-or-16_4-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/left-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/left-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/left-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/ltrim-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/ltrim-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/ltrim-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/right-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/right-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/right-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/rtrim-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/rtrim-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/rtrim-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/trim-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/trim-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/trim-vu-verify.sql create mode 100644 test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-verify.mix diff --git a/.github/composite-actions/minor-version-upgrade-util/action.yml b/.github/composite-actions/minor-version-upgrade-util/action.yml index 5588f9101b9..d2425074168 100644 --- a/.github/composite-actions/minor-version-upgrade-util/action.yml +++ b/.github/composite-actions/minor-version-upgrade-util/action.yml @@ -82,7 +82,7 @@ runs: mvn test export inputFilesPath=input for filename in $(grep -v "^ignore.*\|^#.*\|^cmd.*\|^all.*\|^$" upgrade/$base_dir/schedule); do - sed -i "s/$filename[ ]*$/$filename-vu-verify\\n$filename-vu-cleanup/g" upgrade/$base_dir/schedule + sed -i "s/\b$filename[ ]*\b$/$filename-vu-verify\\n$filename-vu-cleanup/g" upgrade/$base_dir/schedule done export scheduleFile=upgrade/$base_dir/schedule mvn test diff --git a/.github/composite-actions/run-verify-tests/action.yml b/.github/composite-actions/run-verify-tests/action.yml index ababf801345..aaf86c53fca 100644 --- a/.github/composite-actions/run-verify-tests/action.yml +++ b/.github/composite-actions/run-verify-tests/action.yml @@ -71,7 +71,7 @@ runs: fi for filename in $(grep -v "^ignore.*\|^#.*\|^cmd.*\|^all.*\|^$" upgrade/$base_dir/schedule); do - sed -i "s/$filename[ ]*$/$filename-vu-verify\\n$filename-vu-cleanup/g" upgrade/$base_dir/schedule + sed -i "s/\b$filename[ ]*\b$/$filename-vu-verify\\n$filename-vu-cleanup/g" upgrade/$base_dir/schedule done export scheduleFile=upgrade/$base_dir/schedule mvn test diff --git a/.github/composite-actions/setup-base-version/action.yml b/.github/composite-actions/setup-base-version/action.yml index 1aac13c1b63..283a40a337b 100644 --- a/.github/composite-actions/setup-base-version/action.yml +++ b/.github/composite-actions/setup-base-version/action.yml @@ -208,7 +208,7 @@ runs: export isUpgradeTestMode=false export inputFilesPath=input for filename in $(grep -v "^ignore.*\|^#.*\|^cmd.*\|^all.*\|^$" upgrade/$base_dir/schedule); do - sed -i "s/$filename[ ]*$/$filename-vu-prepare/g" upgrade/$base_dir/schedule + sed -i "s/\b$filename[ ]*\b$/$filename-vu-prepare/g" upgrade/$base_dir/schedule done export scheduleFile=upgrade/$base_dir/schedule mvn test diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index afcdfe75cf6..26428f147f4 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2130,7 +2130,7 @@ BEGIN BEGIN IF EXISTS ( -- Search in the sys schema SELECT * FROM sys.sp_stored_procedures_view - WHERE (LOWER(LEFT(procedure_name, -2)) = LOWER(@sp_name)) + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) AND (LOWER(procedure_owner) = 'sys')) BEGIN SELECT PROCEDURE_QUALIFIER, @@ -2141,13 +2141,13 @@ BEGIN NUM_RESULT_SETS, REMARKS, PROCEDURE_TYPE FROM sys.sp_stored_procedures_view - WHERE (LOWER(LEFT(procedure_name, -2)) = LOWER(@sp_name)) + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) AND (LOWER(procedure_owner) = 'sys') ORDER BY procedure_qualifier, procedure_owner, procedure_name; END ELSE IF EXISTS ( SELECT * FROM sys.sp_stored_procedures_view - WHERE (LOWER(LEFT(procedure_name, -2)) = LOWER(@sp_name)) + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) AND (LOWER(procedure_owner) = LOWER(SCHEMA_NAME())) ) BEGIN @@ -2159,7 +2159,7 @@ BEGIN NUM_RESULT_SETS, REMARKS, PROCEDURE_TYPE FROM sys.sp_stored_procedures_view - WHERE (LOWER(LEFT(procedure_name, -2)) = LOWER(@sp_name)) + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) AND (LOWER(procedure_owner) = LOWER(SCHEMA_NAME())) ORDER BY procedure_qualifier, procedure_owner, procedure_name; END @@ -2173,7 +2173,7 @@ BEGIN NUM_RESULT_SETS, REMARKS, PROCEDURE_TYPE FROM sys.sp_stored_procedures_view - WHERE (LOWER(LEFT(procedure_name, -2)) = LOWER(@sp_name)) + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) AND (LOWER(procedure_owner) = 'dbo') ORDER BY procedure_qualifier, procedure_owner, procedure_name; END @@ -2190,7 +2190,7 @@ BEGIN NUM_RESULT_SETS, REMARKS, PROCEDURE_TYPE FROM sys.sp_stored_procedures_view - WHERE (LOWER(LEFT(procedure_name, -2)) = LOWER(@sp_name)) + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) AND (LOWER(procedure_owner) = LOWER(@sp_owner)) ORDER BY procedure_qualifier, procedure_owner, procedure_name; END @@ -2205,7 +2205,7 @@ BEGIN NUM_RESULT_SETS, REMARKS, PROCEDURE_TYPE FROM sys.sp_stored_procedures_view - WHERE ((SELECT COALESCE(@sp_name,'')) = '' OR LOWER(LEFT(procedure_name, -2)) LIKE LOWER(@sp_name)) + WHERE ((SELECT COALESCE(@sp_name,'')) = '' OR LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) LIKE LOWER(@sp_name)) AND ((SELECT COALESCE(@sp_owner,'')) = '' OR LOWER(procedure_owner) LIKE LOWER(@sp_owner)) ORDER BY procedure_qualifier, procedure_owner, procedure_name; END @@ -3471,9 +3471,9 @@ BEGIN -- Get the executing statement for each spid and extract the main stmt type -- This is for informational purposes only - SELECT pid, query INTO #sp_who_tmp FROM pg_stat_activity pgsa + SELECT pid, CAST(query AS sys.VARCHAR(MAX)) INTO #sp_who_tmp FROM pg_stat_activity pgsa - UPDATE #sp_who_tmp SET query = ' ' + TRIM(UPPER(query)) + UPDATE #sp_who_tmp SET query = ' ' + TRIM(CAST(UPPER(query) AS sys.VARCHAR(MAX))) UPDATE #sp_who_tmp SET query = sys.REPLACE(query, chr(9), ' ') UPDATE #sp_who_tmp SET query = sys.REPLACE(query, chr(10), ' ') UPDATE #sp_who_tmp SET query = sys.REPLACE(query, chr(13), ' ') diff --git a/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql b/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql index a0e9fb8719a..672d0ac192e 100644 --- a/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql +++ b/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql @@ -131,7 +131,7 @@ BEGIN END IF; IF (v_datatype ~* DATATYPE_MASK_REGEXP) THEN - v_res_datatype := rtrim(split_part(v_datatype, '(', 1)); + v_res_datatype := PG_CATALOG.rtrim(split_part(v_datatype, '(', 1)); v_maxlength := CASE WHEN (v_res_datatype IN ('CHAR', 'VARCHAR')) THEN VARCHAR_MAX @@ -159,7 +159,7 @@ BEGIN ELSE sys.babelfish_conv_greg_to_hijri(p_dateval) + 1 END; - v_day := ltrim(to_char(v_dateval, 'DD'), '0'); + v_day := PG_CATALOG.ltrim(to_char(v_dateval, 'DD'), '0'); v_month := to_char(v_dateval, 'MM')::SMALLINT; v_language := CASE @@ -307,7 +307,7 @@ BEGIN THEN v_scale := substring(v_src_datatype, SRCDATATYPE_MASK_REGEXP)::SMALLINT; - v_src_datatype := rtrim(split_part(v_src_datatype, '(', 1)); + v_src_datatype := PG_CATALOG.rtrim(split_part(v_src_datatype, '(', 1)); IF (v_src_datatype <> 'DATETIME2' AND v_scale IS NOT NULL) THEN RAISE invalid_indicator_parameter_value; @@ -331,7 +331,7 @@ BEGIN END IF; IF (v_datatype ~* DATATYPE_MASK_REGEXP) THEN - v_res_datatype := rtrim(split_part(v_datatype, '(', 1)); + v_res_datatype := PG_CATALOG.rtrim(split_part(v_datatype, '(', 1)); v_maxlength := CASE WHEN (v_res_datatype IN ('CHAR', 'VARCHAR')) THEN VARCHAR_MAX @@ -360,8 +360,8 @@ BEGIN ELSE sys.babelfish_conv_greg_to_hijri(p_datetimeval) + INTERVAL '1 day' END; - v_day := ltrim(to_char(v_datetimeval, 'DD'), '0'); - v_hour := ltrim(to_char(v_datetimeval, 'HH12'), '0'); + v_day := PG_CATALOG.ltrim(to_char(v_datetimeval, 'DD'), '0'); + v_hour := PG_CATALOG.ltrim(to_char(v_datetimeval, 'HH12'), '0'); v_month := to_char(v_datetimeval, 'MM')::SMALLINT; v_language := CASE @@ -1982,7 +1982,7 @@ BEGIN IF (v_datatype ~* DATATYPE_MASK_REGEXP) THEN - v_res_datatype := rtrim(split_part(v_datatype, '(', 1)); + v_res_datatype := PG_CATALOG.rtrim(split_part(v_datatype, '(', 1)); v_res_maxlength := CASE WHEN (v_res_datatype IN ('CHAR', 'VARCHAR')) THEN VARCHAR_MAX @@ -2022,7 +2022,7 @@ BEGIN RAISE invalid_datetime_format; END IF; - v_hours := ltrim(to_char(p_timeval, 'HH12'), '0'); + v_hours := PG_CATALOG.ltrim(to_char(p_timeval, 'HH12'), '0'); v_fseconds := sys.babelfish_get_microsecs_from_fractsecs(to_char(p_timeval, 'US'), v_scale); IF (v_scale = 7) THEN @@ -2105,7 +2105,7 @@ EXCEPTION WHEN invalid_datetime_format THEN RAISE USING MESSAGE := pg_catalog.format('Error converting data type TIME to %s.', - rtrim(split_part(trim(p_datatype), '(', 1))), + PG_CATALOG.rtrim(split_part(trim(p_datatype), '(', 1))), DETAIL := 'Incorrect using of pair of input parameters values during conversion process.', HINT := 'Check the input parameters values, correct them if needed, and try again.'; END; @@ -2688,26 +2688,26 @@ BEGIN IF name IN('[' COLLATE "C", ']' COLLATE "C", '"' COLLATE "C") THEN RETURN NULL; - ELSIF length(name) >= 2 AND left(name, 1) = '[' COLLATE "C" AND right(name, 1) = ']' COLLATE "C" THEN + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '[' COLLATE "C" AND PG_CATALOG.right(name, 1) = ']' COLLATE "C" THEN IF length(name) = 2 THEN RETURN ''; ELSE RETURN substring(name from 2 for length(name)-2); END IF; - ELSIF length(name) >= 2 AND left(name, 1) = '[' COLLATE "C" AND right(name, 1) != ']' COLLATE "C" THEN + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '[' COLLATE "C" AND PG_CATALOG.right(name, 1) != ']' COLLATE "C" THEN RETURN NULL; - ELSIF length(name) >= 2 AND left(name, 1) != '[' COLLATE "C" AND right(name, 1) = ']' COLLATE "C" THEN + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) != '[' COLLATE "C" AND PG_CATALOG.right(name, 1) = ']' COLLATE "C" THEN RETURN NULL; - ELSIF length(name) >= 2 AND left(name, 1) = '"' COLLATE "C" AND right(name, 1) = '"' COLLATE "C" THEN + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '"' COLLATE "C" AND PG_CATALOG.right(name, 1) = '"' COLLATE "C" THEN IF length(name) = 2 THEN RETURN ''; ELSE RETURN substring(name from 2 for length(name)-2); END IF; - ELSIF length(name) >= 2 AND left(name, 1) = '"' COLLATE "C" AND right(name, 1) != '"' COLLATE "C" THEN + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '"' COLLATE "C" AND PG_CATALOG.right(name, 1) != '"' COLLATE "C" THEN RETURN NULL; - ELSIF length(name) >= 2 AND left(name, 1) != '"' COLLATE "C" AND right(name, 1) = '"' COLLATE "C" THEN + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) != '"' COLLATE "C" AND PG_CATALOG.right(name, 1) = '"' COLLATE "C" THEN RETURN NULL; END IF; @@ -5923,14 +5923,14 @@ DECLARE var_originating_server_id INT DEFAULT 0; BEGIN /* Remove any leading/trailing spaces from parameters (except @owner_login_name) */ - SELECT UPPER(LTRIM(RTRIM(par_originating_server))) INTO par_originating_server; - SELECT LTRIM(RTRIM(par_job_name)) INTO par_job_name; - SELECT LTRIM(RTRIM(par_description)) INTO par_description; + SELECT UPPER(PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_originating_server))) INTO par_originating_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_job_name)) INTO par_job_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_description)) INTO par_description; SELECT '[Uncategorized (Local)]' INTO par_category_name; SELECT 0 INTO par_category_id; - SELECT LTRIM(RTRIM(par_notify_email_operator_name)) INTO par_notify_email_operator_name; - SELECT LTRIM(RTRIM(par_notify_netsend_operator_name)) INTO par_notify_netsend_operator_name; - SELECT LTRIM(RTRIM(par_notify_page_operator_name)) INTO par_notify_page_operator_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_email_operator_name)) INTO par_notify_email_operator_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_netsend_operator_name)) INTO par_notify_netsend_operator_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_page_operator_name)) INTO par_notify_page_operator_name; SELECT NULL INTO var_originating_server_id; /* Turn [nullable] empty string parameters into NULLs */ SELECT NULL INTO par_job_id; @@ -6418,9 +6418,9 @@ DECLARE var_orig_server_id INT; BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_schedule_name)) - , LTRIM(RTRIM(par_owner_login_name)) - , UPPER(LTRIM(RTRIM(par_originating_server))) + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_schedule_name)) + , PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_owner_login_name)) + , UPPER(PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_originating_server))) , 0 INTO par_schedule_name , par_owner_login_name @@ -6912,7 +6912,7 @@ DECLARE var_job_owner_sid CHAR(85); BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_name)) INTO par_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; /* Check that we can uniquely identify the job */ SELECT t.par_job_name @@ -7636,25 +7636,25 @@ BEGIN /* Not updatable */ /* Remove any leading/trailing spaces from parameters (except @owner_login_name) */ SELECT - LTRIM(RTRIM(par_job_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_job_name)) INTO par_job_name; SELECT - LTRIM(RTRIM(par_new_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_new_name)) INTO par_new_name; SELECT - LTRIM(RTRIM(par_description)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_description)) INTO par_description; SELECT - LTRIM(RTRIM(par_category_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_category_name)) INTO par_category_name; SELECT - LTRIM(RTRIM(par_notify_email_operator_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_email_operator_name)) INTO par_notify_email_operator_name; SELECT - LTRIM(RTRIM(par_notify_netsend_operator_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_netsend_operator_name)) INTO par_notify_netsend_operator_name; SELECT - LTRIM(RTRIM(par_notify_page_operator_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_page_operator_name)) INTO par_notify_page_operator_name /* Are we modifying an attribute which tsql agent caches? */; @@ -7890,10 +7890,10 @@ DECLARE BEGIN /* Remove any leading/trailing spaces from parameters */ SELECT - LTRIM(RTRIM(par_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; SELECT - LTRIM(RTRIM(par_new_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_new_name)) INTO par_new_name /* Turn [nullable] empty string parameters into NULLs */; @@ -8104,14 +8104,14 @@ DECLARE BEGIN SELECT NULL INTO var_new_proxy_id; /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_step_name)) INTO par_step_name; - SELECT LTRIM(RTRIM(par_subsystem)) INTO par_subsystem; - SELECT LTRIM(RTRIM(par_command)) INTO par_command; - SELECT LTRIM(RTRIM(par_server)) INTO par_server; - SELECT LTRIM(RTRIM(par_database_name)) INTO par_database_name; - SELECT LTRIM(RTRIM(par_database_user_name)) INTO par_database_user_name; - SELECT LTRIM(RTRIM(par_output_file_name)) INTO par_output_file_name; - SELECT LTRIM(RTRIM(par_proxy_name)) INTO par_proxy_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_step_name)) INTO par_step_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_subsystem)) INTO par_subsystem; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_command)) INTO par_command; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_server)) INTO par_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_database_name)) INTO par_database_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_database_user_name)) INTO par_database_user_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_output_file_name)) INTO par_output_file_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_proxy_name)) INTO par_proxy_name; /* Make sure Dts is translated into new subsystem's name SSIS */ /* IF (@subsystem IS NOT NULL AND UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'DTS') */ /* BEGIN */ @@ -8331,13 +8331,13 @@ DECLARE BEGIN /* Remove any leading/trailing spaces from parameters */ SELECT - LTRIM(RTRIM(par_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; SELECT - LTRIM(RTRIM(par_new_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_new_name)) INTO par_new_name; SELECT - LTRIM(RTRIM(par_owner_login_name)) + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_owner_login_name)) INTO par_owner_login_name /* Turn [nullable] empty string parameters into NULLs */; @@ -8535,9 +8535,9 @@ DECLARE var_valid_range VARCHAR(50); BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_name)) INTO par_name; - SELECT LTRIM(RTRIM(par_category_name)) INTO par_category_name; - SELECT UPPER(LTRIM(RTRIM(par_originating_server))) INTO par_originating_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_category_name)) INTO par_category_name; + SELECT UPPER(PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_originating_server))) INTO par_originating_server; IF ( EXISTS ( @@ -8615,7 +8615,7 @@ RETURNS integer AS $body$ BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_date_name)) INTO par_date_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_date_name)) INTO par_date_name; /* Success */ returncode := 0; @@ -8641,9 +8641,9 @@ DECLARE var_job_id_as_char VARCHAR(36); BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_name_of_name_parameter)) INTO par_name_of_name_parameter; - SELECT LTRIM(RTRIM(par_name_of_id_parameter)) INTO par_name_of_id_parameter; - SELECT LTRIM(RTRIM(par_job_name)) INTO par_job_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_name_parameter)) INTO par_name_of_name_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_id_parameter)) INTO par_name_of_id_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_job_name)) INTO par_job_name; IF (par_job_name = '') THEN @@ -8728,7 +8728,7 @@ DECLARE var_second INT; BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_time_name)) INTO par_time_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_time_name)) INTO par_time_name; IF ((par_time < 0) OR (par_time > 235959)) THEN @@ -8803,9 +8803,9 @@ DECLARE var_owner_name VARCHAR(128); BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_subsystem)) INTO par_subsystem; - SELECT LTRIM(RTRIM(par_server)) INTO par_server; - SELECT LTRIM(RTRIM(par_output_file_name)) INTO par_output_file_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_subsystem)) INTO par_subsystem; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_server)) INTO par_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_output_file_name)) INTO par_output_file_name; /* Get current maximum step id */ SELECT COALESCE(MAX(step_id), 0) @@ -8937,7 +8937,7 @@ DECLARE var_isAdmin INT; BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_name)) INTO par_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; /* Make sure that NULL input/output parameters - if NULL - are initialized to 0 */ SELECT COALESCE(par_freq_interval, 0) INTO par_freq_interval; @@ -9226,9 +9226,9 @@ DECLARE var_sch_name_count INT; BEGIN /* Remove any leading/trailing spaces from parameters */ - SELECT LTRIM(RTRIM(par_name_of_name_parameter)) INTO par_name_of_name_parameter; - SELECT LTRIM(RTRIM(par_name_of_id_parameter)) INTO par_name_of_id_parameter; - SELECT LTRIM(RTRIM(par_schedule_name)) INTO par_schedule_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_name_parameter)) INTO par_name_of_name_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_id_parameter)) INTO par_name_of_id_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_schedule_name)) INTO par_schedule_name; SELECT 0 INTO var_sch_name_count; IF (par_schedule_name = '') @@ -10122,7 +10122,7 @@ BEGIN IF (length(name) <= 2 AND (position('"' IN name) != 0 OR position(']' IN name) != 0 OR position('[' IN name) != 0)) -- invalid name THEN RETURN 0; - ELSIF left(name, 1) = '[' THEN + ELSIF PG_CATALOG.left(name, 1) = '[' THEN pos = position('].' IN name); IF pos = 0 THEN -- invalid name @@ -10130,9 +10130,9 @@ BEGIN ELSE RETURN pos + 1; END IF; - ELSIF left(name, 1) = '"' THEN + ELSIF PG_CATALOG.left(name, 1) = '"' THEN -- search from position 1 in case name starts with a double quote. - pos = position('".' IN right(name, length(name) - 1)); + pos = position('".' IN PG_CATALOG.right(name, length(name) - 1)); IF pos = 0 THEN -- invalid name RETURN 0; @@ -10160,7 +10160,7 @@ DECLARE counter int; cur_pos int; BEGIN - lower_object_name = lower(rtrim(name)); + lower_object_name = lower(PG_CATALOG.rtrim(name)); counter = 1; cur_pos = babelfish_get_name_delimiter_pos(lower_object_name); @@ -10172,7 +10172,7 @@ BEGIN RETURN; END IF; - names[counter] = babelfish_remove_delimiter_pair(rtrim(left(lower_object_name, cur_pos - 1))); + names[counter] = babelfish_remove_delimiter_pair(PG_CATALOG.rtrim(PG_CATALOG.left(lower_object_name, cur_pos - 1))); -- invalid name IF names[counter] IS NULL THEN @@ -10199,7 +10199,7 @@ BEGIN END CASE; -- Assign each name accordingly - object_name = sys.babelfish_truncate_identifier(babelfish_remove_delimiter_pair(rtrim(lower_object_name))); + object_name = sys.babelfish_truncate_identifier(babelfish_remove_delimiter_pair(PG_CATALOG.rtrim(lower_object_name))); END; $$ LANGUAGE plpgsql @@ -10360,3 +10360,13 @@ LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION sys.bbf_get_context_info() RETURNS sys.VARBINARY(128) AS 'babelfishpg_tsql', 'bbf_get_context_info' LANGUAGE C STABLE; + +/* + * bbf_get_immediate_base_type_of_UDT() + * This function returns the Immediate base type for UDT. + * Returns NULL if given type is not an UDT + */ +CREATE OR REPLACE FUNCTION sys.bbf_get_immediate_base_type_of_UDT(OID) +RETURNS OID +AS 'babelfishpg_tsql', 'get_immediate_base_type_of_UDT' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; diff --git a/contrib/babelfishpg_tsql/sql/sys_functions.sql b/contrib/babelfishpg_tsql/sql/sys_functions.sql index f1b18961f5e..e96476a55b3 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -1151,10 +1151,10 @@ BEGIN result := (SELECT input_expr_tmz AT TIME ZONE tz_name)::TEXT; tz_diff := (SELECT result::TIMESTAMPTZ - input_expr_tmz)::TEXT; - if LEFT(tz_diff,1) <> '-' THEN + if PG_CATALOG.LEFT(tz_diff,1) <> '-' THEN tz_diff := concat('+',tz_diff); END IF; - tz_offset := left(tz_diff,6); + tz_offset := PG_CATALOG.left(tz_diff,6); input_expr_tx := concat(input_expr_tx,tz_offset); return cast(input_expr_tx as sys.datetimeoffset); ELSIF pg_typeof(input_expr) = 'sys.DATETIMEOFFSET'::regtype THEN @@ -1162,10 +1162,10 @@ BEGIN input_expr_tmz := input_expr_tx :: TIMESTAMPTZ; result := (SELECT input_expr_tmz AT TIME ZONE tz_name)::TEXT; tz_diff := (SELECT result::TIMESTAMPTZ - input_expr_tmz)::TEXT; - if LEFT(tz_diff,1) <> '-' THEN + if PG_CATALOG.LEFT(tz_diff,1) <> '-' THEN tz_diff := concat('+',tz_diff); END IF; - tz_offset := left(tz_diff,6); + tz_offset := PG_CATALOG.left(tz_diff,6); result := concat(result,tz_offset); return cast(result as sys.datetimeoffset); ELSE @@ -1564,13 +1564,13 @@ begin if pattern is null or expression is null then return null; end if; - if left(pattern, 1) = '%' collate sys.database_default then + if PG_CATALOG.left(pattern, 1) = '%' collate sys.database_default then v_regexp_pattern := regexp_replace(pattern, '^%', '%#"', 'i'); else v_regexp_pattern := '#"' || pattern; end if; - if right(pattern, 1) = '%' collate sys.database_default then + if PG_CATALOG.right(pattern, 1) = '%' collate sys.database_default then v_regexp_pattern := regexp_replace(v_regexp_pattern, '%$', '#"%', 'i'); else v_regexp_pattern := v_regexp_pattern || '#"'; @@ -2739,11 +2739,11 @@ BEGIN -- Lower-case to avoid case issues, remove trailing whitespace to match SQL SERVER behavior -- Objects created in Babelfish are stored in lower-case in pg_class/pg_proc - cs_as_securable = lower(rtrim(cs_as_securable)); - cs_as_securable_class = lower(rtrim(cs_as_securable_class)); - cs_as_permission = lower(rtrim(cs_as_permission)); - cs_as_sub_securable = lower(rtrim(cs_as_sub_securable)); - cs_as_sub_securable_class = lower(rtrim(cs_as_sub_securable_class)); + cs_as_securable = lower(PG_CATALOG.rtrim(cs_as_securable)); + cs_as_securable_class = lower(PG_CATALOG.rtrim(cs_as_securable_class)); + cs_as_permission = lower(PG_CATALOG.rtrim(cs_as_permission)); + cs_as_sub_securable = lower(PG_CATALOG.rtrim(cs_as_sub_securable)); + cs_as_sub_securable_class = lower(PG_CATALOG.rtrim(cs_as_sub_securable_class)); -- Assert that sub_securable and sub_securable_class are either both NULL or both defined IF cs_as_sub_securable IS NOT NULL AND cs_as_sub_securable_class IS NULL THEN @@ -3080,6 +3080,635 @@ CREATE OR REPLACE FUNCTION sys.substring(string sys.NCHAR, i INTEGER, j INTEGER) RETURNS sys.NVARCHAR AS 'babelfishpg_tsql', 'tsql_varchar_substr' LANGUAGE C IMMUTABLE PARALLEL SAFE; +-- wrapper functions for TRIM +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.BPCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for trim function + IF string_arg_datatype NOT IN ('char', 'varchar', 'nchar', 'nvarchar', 'text', 'ntext') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of Trim function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.btrim(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Additional handling is added for TRIM function with 2 arguments, +-- hence only following two definitions are required. +CREATE OR REPLACE FUNCTION sys.TRIM(characters sys.VARCHAR, string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string, characters); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(characters sys.VARCHAR, string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string, characters); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- wrapper functions for LTRIM +CREATE OR REPLACE FUNCTION sys.LTRIM(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for ltrim function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of ltrim function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.ltrim(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.BPCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that ltrim with text input +-- will use following definition instead of PG ltrim +CREATE OR REPLACE FUNCTION sys.LTRIM(string TEXT) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that ltrim with ntext input +-- will use following definition instead of PG ltrim +CREATE OR REPLACE FUNCTION sys.LTRIM(string NTEXT) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- wrapper functions for RTRIM +CREATE OR REPLACE FUNCTION sys.RTRIM(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for rtrim function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of rtrim function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.rtrim(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.BPCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that rtrim with text input +-- will use following definition instead of PG rtrim +CREATE OR REPLACE FUNCTION sys.RTRIM(string TEXT) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that rtrim with ntext input +-- will use following definition instead of PG rtrim +CREATE OR REPLACE FUNCTION sys.RTRIM(string NTEXT) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + + +-- wrapper functions for LEFT +CREATE OR REPLACE FUNCTION sys.LEFT(string ANYELEMENT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for left function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of left function.', string_arg_datatype; + END IF; + + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string::sys.varchar, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.BPCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.VARCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.NCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.NVARCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that left with text input +-- will use following definition instead of PG left +CREATE OR REPLACE FUNCTION sys.LEFT(string TEXT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that left with ntext input +-- will use following definition instead of PG left +CREATE OR REPLACE FUNCTION sys.LEFT(string NTEXT, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + + +-- wrapper functions for RIGHT +CREATE OR REPLACE FUNCTION sys.RIGHT(string ANYELEMENT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for right function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of right function.', string_arg_datatype; + END IF; + + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + RETURN PG_CATALOG.right(string::sys.varchar, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.BPCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.VARCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.NCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.NVARCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that right with text input +-- will use following definition instead of PG right +CREATE OR REPLACE FUNCTION sys.RIGHT(string TEXT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that right with ntext input +-- will use following definition instead of PG right +CREATE OR REPLACE FUNCTION sys.RIGHT(string NTEXT, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + -- For getting host os from PG_VERSION_STR CREATE OR REPLACE FUNCTION sys.get_host_os() RETURNS sys.NVARCHAR @@ -3501,7 +4130,7 @@ CREATE OR REPLACE FUNCTION OBJECTPROPERTYEX( RETURNS SYS.SQL_VARIANT AS $$ BEGIN - property := RTRIM(LOWER(COALESCE(property, ''))); + property := PG_CATALOG.RTRIM(LOWER(COALESCE(property, ''))); IF NOT EXISTS(SELECT ao.object_id FROM sys.all_objects ao WHERE object_id = id) THEN @@ -4054,7 +4683,7 @@ BEGIN -- Here, converting TIMESTAMP into datetimeoffset datatype with the same timezone as of date argument. IF date_arg_datatype = 'sys.datetimeoffset'::regtype THEN timezone = sys.babelfish_get_datetimeoffset_tzoffset(date)::INTEGER; - offset_string = right(date::PG_CATALOG.TEXT, 6); + offset_string = PG_CATALOG.right(date::PG_CATALOG.TEXT, 6); result_date = result_date + make_interval(mins => timezone); RETURN concat(result_date, ' ', offset_string)::sys.datetimeoffset; ELSE @@ -4177,8 +4806,8 @@ BEGIN input_expr_timestamp = date::timestamp; -- preserving offset_string value in the case of datetimeoffset datatype before converting it to timestamps IF date_arg_datatype = 'sys.datetimeoffset'::regtype THEN - offset_string = RIGHT(date::PG_CATALOG.TEXT, 6); - input_expr_timestamp := LEFT(date::PG_CATALOG.TEXT, -6)::timestamp; + offset_string = PG_CATALOG.RIGHT(date::PG_CATALOG.TEXT, 6); + input_expr_timestamp := PG_CATALOG.LEFT(date::PG_CATALOG.TEXT, -6)::timestamp; END IF; CASE WHEN datepart IN ('year', 'quarter', 'month', 'week', 'hour', 'minute', 'second', 'millisecond', 'microsecond') THEN diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 895cf392f9f..77dafa5aa22 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -446,6 +446,4858 @@ END; $$ LANGUAGE plpgsql STRICT STABLE; +-- Update deprecated object_id function(s) since left function now restricts TEXT datatype +DO $$ +BEGIN + -- Update body of object_id_deprecated_in_2_4_0 to use PG_CATALOG.LEFT instead, if function exists + IF EXISTS(SELECT count(*) + FROM pg_proc p + JOIN pg_namespace nsp + ON p.pronamespace = nsp.oid + WHERE p.proname='object_id_deprecated_in_2_4_0' AND nsp.nspname='sys') THEN + + CREATE OR REPLACE FUNCTION sys.object_id_deprecated_in_2_4_0(IN object_name TEXT, IN object_type char(2) DEFAULT '') + RETURNS INTEGER AS + $BODY$ + DECLARE + id oid; + db_name text collate "C"; + bbf_schema_name text collate "C"; + schema_name text collate "C"; + schema_oid oid; + obj_name text collate "C"; + is_temp_object boolean; + obj_type char(2) collate "C"; + cs_as_object_name text collate "C" := object_name; + BEGIN + obj_type = object_type; + id = null; + schema_oid = NULL; + + SELECT s.db_name, s.schema_name, s.object_name INTO db_name, bbf_schema_name, obj_name + FROM babelfish_split_object_name(cs_as_object_name) s; + + -- Invalid object_name + IF obj_name IS NULL OR obj_name = '' collate sys.database_default THEN + RETURN NULL; + END IF; + + IF bbf_schema_name IS NULL OR bbf_schema_name = '' collate sys.database_default THEN + bbf_schema_name := sys.schema_name(); + END IF; + + schema_name := sys.bbf_get_current_physical_schema_name(bbf_schema_name); + + -- Check if looking for temp object. + is_temp_object = PG_CATALOG.left(obj_name, 1) = '#' collate sys.database_default; + + -- Can only search in current database. Allowing tempdb for temp objects. + IF db_name IS NOT NULL AND db_name collate sys.database_default <> db_name() AND db_name collate sys.database_default <> 'tempdb' THEN + RAISE EXCEPTION 'Can only do lookup in current database.'; + END IF; + + IF schema_name IS NULL OR schema_name = '' collate sys.database_default THEN + RETURN NULL; + END IF; + + -- Searching within a schema. Get schema oid. + schema_oid = (SELECT oid FROM pg_namespace WHERE nspname = schema_name); + IF schema_oid IS NULL THEN + RETURN NULL; + END IF; + + if obj_type <> '' then + case + -- Schema does not apply as much to temp objects. + when upper(object_type) in ('S', 'U', 'V', 'IT', 'ET', 'SO') and is_temp_object then + id := (select reloid from sys.babelfish_get_enr_list() where lower(relname) collate sys.database_default = obj_name limit 1); + + when upper(object_type) in ('S', 'U', 'V', 'IT', 'ET', 'SO') and not is_temp_object then + id := (select oid from pg_class where lower(relname) collate sys.database_default = obj_name + and relnamespace = schema_oid limit 1); + + when upper(object_type) in ('C', 'D', 'F', 'PK', 'UQ') then + id := (select oid from pg_constraint where lower(conname) collate sys.database_default = obj_name + and connamespace = schema_oid limit 1); + + when upper(object_type) in ('AF', 'FN', 'FS', 'FT', 'IF', 'P', 'PC', 'TF', 'RF', 'X') then + id := (select oid from pg_proc where lower(proname) collate sys.database_default = obj_name + and pronamespace = schema_oid limit 1); + + when upper(object_type) in ('TR', 'TA') then + id := (select oid from pg_trigger where lower(tgname) collate sys.database_default = obj_name limit 1); + + -- Throwing exception as a reminder to add support in the future. + when upper(object_type) collate sys.database_default in ('R', 'EC', 'PG', 'SN', 'SQ', 'TT') then + RAISE EXCEPTION 'Object type currently unsupported.'; + + -- unsupported obj_type + else id := null; + end case; + else + if not is_temp_object then + id := ( + select oid from pg_class where lower(relname) = obj_name + and relnamespace = schema_oid + union + select oid from pg_constraint where lower(conname) = obj_name + and connamespace = schema_oid + union + select oid from pg_proc where lower(proname) = obj_name + and pronamespace = schema_oid + union + select oid from pg_trigger where lower(tgname) = obj_name + limit 1 + ); + else + -- temp object without "object_type" in-argument + id := (select reloid from sys.babelfish_get_enr_list() where lower(relname) collate sys.database_default = obj_name limit 1); + end if; + end if; + + RETURN id::integer; + END; + $BODY$ + LANGUAGE plpgsql STABLE RETURNS NULL ON NULL INPUT; + END IF; + + -- Update body of object_id_deprecated_in_3_1_0 to use PG_CATALOG.LEFT instead, if function exists + IF EXISTS(SELECT count(*) + FROM pg_proc p + JOIN pg_namespace nsp + ON p.pronamespace = nsp.oid + WHERE p.proname='object_id_deprecated_in_3_1_0' AND nsp.nspname='sys') THEN + + CREATE OR REPLACE FUNCTION sys.object_id_deprecated_in_3_1_0(IN object_name TEXT, IN object_type char(2) DEFAULT '') + RETURNS INTEGER AS + $BODY$ + DECLARE + id oid; + db_name text collate "C"; + bbf_schema_name text collate "C"; + schema_name text collate "C"; + schema_oid oid; + obj_name text collate "C"; + is_temp_object boolean; + obj_type char(2) collate "C"; + cs_as_object_name text collate "C" := object_name; + BEGIN + obj_type = object_type; + id = null; + schema_oid = NULL; + + SELECT s.db_name, s.schema_name, s.object_name INTO db_name, bbf_schema_name, obj_name + FROM babelfish_split_object_name(cs_as_object_name) s; + + -- Invalid object_name + IF obj_name IS NULL OR obj_name = '' collate sys.database_default THEN + RETURN NULL; + END IF; + + IF bbf_schema_name IS NULL OR bbf_schema_name = '' collate sys.database_default THEN + bbf_schema_name := sys.schema_name(); + END IF; + + schema_name := sys.bbf_get_current_physical_schema_name(bbf_schema_name); + + -- Check if looking for temp object. + is_temp_object = PG_CATALOG.left(obj_name, 1) = '#' collate sys.database_default; + + -- Can only search in current database. Allowing tempdb for temp objects. + IF db_name IS NOT NULL AND db_name collate sys.database_default <> db_name() AND db_name collate sys.database_default <> 'tempdb' THEN + RAISE EXCEPTION 'Can only do lookup in current database.'; + END IF; + + IF schema_name IS NULL OR schema_name = '' collate sys.database_default THEN + RETURN NULL; + END IF; + + -- Searching within a schema. Get schema oid. + schema_oid = (SELECT oid FROM pg_namespace WHERE nspname = schema_name); + IF schema_oid IS NULL THEN + RETURN NULL; + END IF; + + if obj_type <> '' then + case + -- Schema does not apply as much to temp objects. + when upper(object_type) in ('S', 'U', 'V', 'IT', 'ET', 'SO') and is_temp_object then + id := (select reloid from sys.babelfish_get_enr_list() where lower(relname) collate sys.database_default = obj_name limit 1); + + when upper(object_type) in ('S', 'U', 'V', 'IT', 'ET', 'SO') and not is_temp_object then + id := (select oid from pg_class where lower(relname) collate sys.database_default = obj_name + and relnamespace = schema_oid limit 1); + + when upper(object_type) in ('C', 'D', 'F', 'PK', 'UQ') then + id := (select oid from pg_constraint where lower(conname) collate sys.database_default = obj_name + and connamespace = schema_oid limit 1); + + when upper(object_type) in ('AF', 'FN', 'FS', 'FT', 'IF', 'P', 'PC', 'TF', 'RF', 'X') then + id := (select oid from pg_proc where lower(proname) collate sys.database_default = obj_name + and pronamespace = schema_oid limit 1); + + when upper(object_type) in ('TR', 'TA') then + id := (select oid from pg_trigger where lower(tgname) collate sys.database_default = obj_name limit 1); + + -- Throwing exception as a reminder to add support in the future. + when upper(object_type) collate sys.database_default in ('R', 'EC', 'PG', 'SN', 'SQ', 'TT') then + RAISE EXCEPTION 'Object type currently unsupported.'; + + -- unsupported obj_type + else id := null; + end case; + else + if not is_temp_object then + id := ( + select oid from pg_class where lower(relname) = obj_name + and relnamespace = schema_oid + union + select oid from pg_constraint where lower(conname) = obj_name + and connamespace = schema_oid + union + select oid from pg_proc where lower(proname) = obj_name + and pronamespace = schema_oid + union + select oid from pg_trigger where lower(tgname) = obj_name + limit 1 + ); + else + -- temp object without "object_type" in-argument + id := (select reloid from sys.babelfish_get_enr_list() where lower(relname) collate sys.database_default = obj_name limit 1); + end if; + end if; + + RETURN id::integer; + END; + $BODY$ + LANGUAGE plpgsql STABLE RETURNS NULL ON NULL INPUT; + END IF; +END; +$$; + +-- wrapper functions for TRIM +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.BPCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for trim function + IF string_arg_datatype NOT IN ('char', 'varchar', 'nchar', 'nvarchar', 'text', 'ntext') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of Trim function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.btrim(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Additional handling is added for TRIM function with 2 arguments, +-- hence only following two definitions are required. +CREATE OR REPLACE FUNCTION sys.TRIM(characters sys.VARCHAR, string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string, characters); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.TRIM(characters sys.VARCHAR, string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.btrim(string, characters); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- wrapper functions for LTRIM +CREATE OR REPLACE FUNCTION sys.LTRIM(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for ltrim function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of ltrim function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.ltrim(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.BPCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LTRIM(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that ltrim with text input +-- will use following definition instead of PG ltrim +CREATE OR REPLACE FUNCTION sys.LTRIM(string TEXT) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that ltrim with ntext input +-- will use following definition instead of PG ltrim +CREATE OR REPLACE FUNCTION sys.LTRIM(string NTEXT) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.ltrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- wrapper functions for RTRIM +CREATE OR REPLACE FUNCTION sys.RTRIM(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for rtrim function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of rtrim function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.rtrim(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.BPCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.VARCHAR) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RTRIM(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that rtrim with text input +-- will use following definition instead of PG rtrim +CREATE OR REPLACE FUNCTION sys.RTRIM(string TEXT) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that rtrim with ntext input +-- will use following definition instead of PG rtrim +CREATE OR REPLACE FUNCTION sys.RTRIM(string NTEXT) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.rtrim(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + + +-- wrapper functions for LEFT +CREATE OR REPLACE FUNCTION sys.LEFT(string ANYELEMENT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for left function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of left function.', string_arg_datatype; + END IF; + + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string::sys.varchar, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.BPCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.VARCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.NCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.LEFT(string sys.NVARCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that left with text input +-- will use following definition instead of PG left +CREATE OR REPLACE FUNCTION sys.LEFT(string TEXT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that left with ntext input +-- will use following definition instead of PG left +CREATE OR REPLACE FUNCTION sys.LEFT(string NTEXT, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the left function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.left(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + + +-- wrapper functions for RIGHT +CREATE OR REPLACE FUNCTION sys.RIGHT(string ANYELEMENT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_basetype oid; +BEGIN + string_arg_datatype := sys.translate_pg_type_to_tsql(pg_typeof(string)::oid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(pg_typeof(string)::oid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for right function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of right function.', string_arg_datatype; + END IF; + + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + RETURN PG_CATALOG.right(string::sys.varchar, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.BPCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.VARCHAR, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.NCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.RIGHT(string sys.NVARCHAR, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that right with text input +-- will use following definition instead of PG right +CREATE OR REPLACE FUNCTION sys.RIGHT(string TEXT, i INTEGER) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that right with ntext input +-- will use following definition instead of PG right +CREATE OR REPLACE FUNCTION sys.RIGHT(string NTEXT, i INTEGER) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + IF i IS NULL THEN + RETURN NULL; + END IF; + + IF i < 0 THEN + RAISE EXCEPTION 'Invalid length parameter passed to the right function.'; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.right(string, i); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE PROCEDURE sys.sp_who( + IN "@loginame" sys.sysname DEFAULT NULL, + IN "@option" sys.VARCHAR(30) DEFAULT NULL) +LANGUAGE 'pltsql' +AS $$ +BEGIN + SET NOCOUNT ON + DECLARE @msg sys.VARCHAR(200) + DECLARE @show_pg BIT = 0 + DECLARE @hide_col sys.VARCHAR(50) + + IF @option IS NOT NULL + BEGIN + IF LOWER(TRIM(@option)) <> 'postgres' + BEGIN + RAISERROR('Parameter @option can only be ''postgres''', 16, 1) + RETURN + END + END + + -- Take a copy of sysprocesses so that we reference it only once + SELECT DISTINCT * INTO #sp_who_sysprocesses FROM sys.sysprocesses + + -- Get the executing statement for each spid and extract the main stmt type + -- This is for informational purposes only + SELECT pid, CAST(query AS sys.VARCHAR(MAX)) INTO #sp_who_tmp FROM pg_stat_activity pgsa + + UPDATE #sp_who_tmp SET query = ' ' + TRIM(CAST(UPPER(query) AS sys.VARCHAR(MAX))) + UPDATE #sp_who_tmp SET query = sys.REPLACE(query, chr(9), ' ') + UPDATE #sp_who_tmp SET query = sys.REPLACE(query, chr(10), ' ') + UPDATE #sp_who_tmp SET query = sys.REPLACE(query, chr(13), ' ') + WHILE (SELECT count(*) FROM #sp_who_tmp WHERE sys.CHARINDEX(' ',query)>0) > 0 + BEGIN + UPDATE #sp_who_tmp SET query = sys.REPLACE(query, ' ', ' ') + END + + -- Determine type of stmt to report by sp_who: very basic only + -- NB: not handling presence of comments in the query string + UPDATE #sp_who_tmp + SET query = + CASE + WHEN PATINDEX('%[^a-zA-Z0-9_]UPDATE[^a-zA-Z0-9_]%', query) > 0 THEN 'UPDATE' + WHEN PATINDEX('%[^a-zA-Z0-9_]DELETE[^a-zA-Z0-9_]%', query) > 0 THEN 'DELETE' + WHEN PATINDEX('%[^a-zA-Z0-9_]INSERT[^a-zA-Z0-9_]%', query) > 0 THEN 'INSERT' + WHEN PATINDEX('%[^a-zA-Z0-9_]SELECT[^a-zA-Z0-9_]%', query) > 0 THEN 'SELECT' + WHEN PATINDEX('%[^a-zA-Z0-9_]WAITFOR[^a-zA-Z0-9_]%', query) > 0 THEN 'WAITFOR' + WHEN PATINDEX('%[^a-zA-Z0-9_]CREATE ]%', query) > 0 THEN sys.SUBSTRING(query,1,sys.CHARINDEX('CREATE ', query)) + WHEN PATINDEX('%[^a-zA-Z0-9_]ALTER ]%', query) > 0 THEN sys.SUBSTRING(query,1,sys.CHARINDEX('ALTER ', query)) + WHEN PATINDEX('%[^a-zA-Z0-9_]DROP ]%', query) > 0 THEN sys.SUBSTRING(query,1,sys.CHARINDEX('DROP ', query)) + ELSE sys.SUBSTRING(query, 1, sys.CHARINDEX(' ', query)) + END + + UPDATE #sp_who_tmp + SET query = sys.SUBSTRING(query,1, 8-1 + sys.CHARINDEX(' ', sys.SUBSTRING(query,8,99))) + WHERE query LIKE 'CREATE %' OR query LIKE 'ALTER %' OR query LIKE 'DROP %' + + -- The executing spid is always shown as doing a SELECT + UPDATE #sp_who_tmp SET query = 'SELECT' WHERE pid = @@spid + UPDATE #sp_who_tmp SET query = TRIM(query) + + -- Get all current connections + SELECT + spid, + MAX(blocked) AS blocked, + 0 AS ecid, + CAST('' AS sys.VARCHAR(100)) AS status, + CAST('' AS sys.VARCHAR(100)) AS loginname, + CAST('' AS sys.VARCHAR(100)) AS hostname, + 0 AS dbid, + CAST('' AS sys.VARCHAR(100)) AS cmd, + 0 AS request_id, + CAST('TDS' AS sys.VARCHAR(20)) AS connection, + hostprocess + INTO #sp_who_proc + FROM #sp_who_sysprocesses + GROUP BY spid, status, hostprocess + + -- Add attributes to each connection + UPDATE #sp_who_proc + SET ecid = sp.ecid, + status = sp.status, + loginname = sp.loginname, + hostname = sp.hostname, + dbid = sp.dbid, + request_id = sp.request_id + FROM #sp_who_sysprocesses sp + WHERE #sp_who_proc.spid = sp.spid + + -- Identify PG connections: the hostprocess PID comes from the TDS login packet + -- and therefore PG connections do not have a value here + UPDATE #sp_who_proc + SET connection = 'PostgreSQL' + WHERE hostprocess IS NULL + + -- Keep or delete PG connections + IF (LOWER(@loginame) = 'postgres' OR LOWER(@option) = 'postgres') + begin + -- Show PG connections; these have dbid = 0 + -- This is a Babelfish-specific enhancement, since PG connections may also be active in the Babelfish DB + -- and it may be useful to see these displayed + SET @show_pg = 1 + + -- blank out the loginame parameter for the tests below + IF LOWER(@loginame) = 'postgres' SET @loginame = NULL + END + + -- By default, do not show the column indicating the connection type since SQL Server does not have this column + SET @hide_col = 'connection' + + IF (@show_pg = 1) + BEGIN + SET @hide_col = '' + END + ELSE + BEGIN + -- Delete PG connections + DELETE #sp_who_proc + WHERE dbid = 0 + END + + -- Apply filter if specified + IF (@loginame IS NOT NULL) + BEGIN + IF (TRIM(@loginame) = '') + BEGIN + -- Raise error + SET @msg = ''''+@loginame+''' is not a valid login or you do not have permission.' + RAISERROR(@msg, 16, 1) + RETURN + END + + IF (sys.ISNUMERIC(@loginame) = 1) + BEGIN + -- Remove all connections except the specified one + DELETE #sp_who_proc + WHERE spid <> CAST(@loginame AS INT) + END + ELSE + BEGIN + IF (LOWER(@loginame) = 'active') + BEGIN + -- Remove all 'idle' connections + DELETE #sp_who_proc + WHERE status = 'idle' + END + ELSE + BEGIN + -- Verify the specified login name exists + IF (sys.SUSER_ID(@loginame) IS NULL) + BEGIN + SET @msg = ''''+@loginame+''' is not a valid login or you do not have permission.' + RAISERROR(@msg, 16, 1) + RETURN + END + ELSE + BEGIN + -- Keep only connections for the specified login + DELETE #sp_who_proc + WHERE sys.SUSER_ID(loginname) <> sys.SUSER_ID(@loginame) + END + END + END + END + + -- Create final result set; use DISTINCT since there are usually duplicate rows from the PG catalogs + SELECT distinct + p.spid AS spid, + p.ecid AS ecid, + CAST(LEFT(p.status,20) AS sys.VARCHAR(20)) AS status, + CAST(LEFT(p.loginname,40) AS sys.VARCHAR(40)) AS loginame, + CAST(LEFT(p.hostname,60) AS sys.VARCHAR(60)) AS hostname, + p.blocked AS blk, + CAST(LEFT(db_name(p.dbid),40) AS sys.VARCHAR(40)) AS dbname, + CAST(LEFT(#sp_who_tmp.query,30)as sys.VARCHAR(30)) AS cmd, + p.request_id AS request_id, + connection + INTO #sp_who_tmp2 + FROM #sp_who_proc p, #sp_who_tmp + WHERE p.spid = #sp_who_tmp.pid + ORDER BY spid + + -- Patch up remaining cases + UPDATE #sp_who_tmp2 + SET cmd = 'AWAITING COMMAND' + WHERE TRIM(ISNULL(cmd,'')) = '' AND status = 'idle' + + UPDATE #sp_who_tmp2 + SET cmd = 'UNKNOWN' + WHERE TRIM(cmd) = '' + + -- Format the result set as narrow as possible for readability + SET @hide_col += ',hostprocess' + EXECUTE sys.sp_babelfish_autoformat @tab='#sp_who_tmp2', @orderby='ORDER BY spid', @hiddencols=@hide_col, @printrc=0 + RETURN +END +$$; +GRANT EXECUTE ON PROCEDURE sys.sp_who(IN sys.sysname, IN sys.VARCHAR(30)) TO PUBLIC; + +CREATE OR REPLACE PROCEDURE sys.sp_stored_procedures( + "@sp_name" sys.nvarchar(390) = '', + "@sp_owner" sys.nvarchar(384) = '', + "@sp_qualifier" sys.sysname = '', + "@fusepattern" sys.bit = '1' +) +AS $$ +BEGIN + IF (@sp_qualifier != '') AND LOWER(sys.db_name()) != LOWER(@sp_qualifier) + BEGIN + THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1; + END + + -- If @sp_name or @sp_owner = '%', it gets converted to NULL or '' regardless of @fusepattern + IF @sp_name = '%' + BEGIN + SELECT @sp_name = '' + END + + IF @sp_owner = '%' + BEGIN + SELECT @sp_owner = '' + END + + -- Changes fusepattern to 0 if no wildcards are used. NOTE: Need to add [] wildcard pattern when it is implemented. Wait for BABEL-2452 + IF @fusepattern = 1 + BEGIN + IF (CHARINDEX('%', @sp_name) != 0 AND CHARINDEX('_', @sp_name) != 0 AND CHARINDEX('%', @sp_owner) != 0 AND CHARINDEX('_', @sp_owner) != 0 ) + BEGIN + SELECT @fusepattern = 0; + END + END + + -- Condition for when sp_name argument is not given or is null, or is just a wildcard (same order) + IF COALESCE(@sp_name, '') = '' + BEGIN + IF @fusepattern=1 + BEGIN + SELECT + PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE ((SELECT COALESCE(@sp_owner,'')) = '' OR LOWER(procedure_owner) LIKE LOWER(@sp_owner)) + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + ELSE + BEGIN + SELECT + PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE ((SELECT COALESCE(@sp_owner,'')) = '' OR LOWER(procedure_owner) LIKE LOWER(@sp_owner)) + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + END + -- When @sp_name is not null + ELSE + BEGIN + -- When sp_owner is null and fusepattern = 0 + IF (@fusepattern = 0 AND COALESCE(@sp_owner,'') = '') + BEGIN + IF EXISTS ( -- Search in the sys schema + SELECT * FROM sys.sp_stored_procedures_view + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) + AND (LOWER(procedure_owner) = 'sys')) + BEGIN + SELECT PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) + AND (LOWER(procedure_owner) = 'sys') + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + ELSE IF EXISTS ( + SELECT * FROM sys.sp_stored_procedures_view + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) + AND (LOWER(procedure_owner) = LOWER(SCHEMA_NAME())) + ) + BEGIN + SELECT PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) + AND (LOWER(procedure_owner) = LOWER(SCHEMA_NAME())) + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + ELSE -- Search in the dbo schema (if nothing exists it should just return nothing). + BEGIN + SELECT PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) + AND (LOWER(procedure_owner) = 'dbo') + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + + END + ELSE IF (@fusepattern = 0 AND COALESCE(@sp_owner,'') != '') + BEGIN + SELECT + PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE (LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) = LOWER(@sp_name)) + AND (LOWER(procedure_owner) = LOWER(@sp_owner)) + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + ELSE -- fusepattern = 1 + BEGIN + SELECT + PROCEDURE_QUALIFIER, + PROCEDURE_OWNER, + PROCEDURE_NAME, + NUM_INPUT_PARAMS, + NUM_OUTPUT_PARAMS, + NUM_RESULT_SETS, + REMARKS, + PROCEDURE_TYPE FROM sys.sp_stored_procedures_view + WHERE ((SELECT COALESCE(@sp_name,'')) = '' OR LOWER(LEFT(procedure_name, LEN(procedure_name)-2)) LIKE LOWER(@sp_name)) + AND ((SELECT COALESCE(@sp_owner,'')) = '' OR LOWER(procedure_owner) LIKE LOWER(@sp_owner)) + ORDER BY procedure_qualifier, procedure_owner, procedure_name; + END + END +END; +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE on PROCEDURE sys.sp_stored_procedures TO PUBLIC; + +CREATE OR REPLACE FUNCTION sys.babelfish_conv_date_to_string(IN p_datatype TEXT, + IN p_dateval DATE, + IN p_style NUMERIC DEFAULT 20) +RETURNS TEXT +AS +$BODY$ +DECLARE + v_day VARCHAR COLLATE "C"; + v_dateval DATE; + v_style SMALLINT; + v_month SMALLINT; + v_resmask VARCHAR COLLATE "C"; + v_datatype VARCHAR COLLATE "C"; + v_language VARCHAR COLLATE "C"; + v_monthname VARCHAR COLLATE "C"; + v_resstring VARCHAR COLLATE "C"; + v_lengthexpr VARCHAR COLLATE "C"; + v_maxlength SMALLINT; + v_res_length SMALLINT; + v_err_message VARCHAR COLLATE "C"; + v_res_datatype VARCHAR COLLATE "C"; + v_lang_metadata_json JSONB; + VARCHAR_MAX CONSTANT SMALLINT := 8000; + NVARCHAR_MAX CONSTANT SMALLINT := 4000; + CONVERSION_LANG CONSTANT VARCHAR COLLATE "C" := ''; + DATATYPE_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(CHAR|NCHAR|VARCHAR|NVARCHAR|CHARACTER VARYING)\s*$'; + DATATYPE_MASK_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(?:CHAR|NCHAR|VARCHAR|NVARCHAR|CHARACTER VARYING)\s*\(\s*(\d+|MAX)\s*\)\s*$'; +BEGIN + v_datatype := upper(trim(p_datatype)); + v_style := floor(p_style)::SMALLINT; + + IF (scale(p_style) > 0) THEN + RAISE most_specific_type_mismatch; + ELSIF (NOT ((v_style BETWEEN 0 AND 13) OR + (v_style BETWEEN 20 AND 25) OR + (v_style BETWEEN 100 AND 113) OR + v_style IN (120, 121, 126, 127, 130, 131))) + THEN + RAISE invalid_parameter_value; + ELSIF (v_style IN (8, 24, 108)) THEN + RAISE invalid_datetime_format; + END IF; + + IF (v_datatype ~* DATATYPE_MASK_REGEXP) THEN + v_res_datatype := PG_CATALOG.rtrim(split_part(v_datatype, '(', 1)); + + v_maxlength := CASE + WHEN (v_res_datatype IN ('CHAR', 'VARCHAR')) THEN VARCHAR_MAX + ELSE NVARCHAR_MAX + END; + + v_lengthexpr := substring(v_datatype, DATATYPE_MASK_REGEXP); + + IF (v_lengthexpr <> 'MAX' AND char_length(v_lengthexpr) > 4) THEN + RAISE interval_field_overflow; + END IF; + + v_res_length := CASE v_lengthexpr + WHEN 'MAX' THEN v_maxlength + ELSE v_lengthexpr::SMALLINT + END; + ELSIF (v_datatype ~* DATATYPE_REGEXP) THEN + v_res_datatype := v_datatype; + ELSE + RAISE datatype_mismatch; + END IF; + + v_dateval := CASE + WHEN (v_style NOT IN (130, 131)) THEN p_dateval + ELSE sys.babelfish_conv_greg_to_hijri(p_dateval) + 1 + END; + + v_day := PG_CATALOG.ltrim(to_char(v_dateval, 'DD'), '0'); + v_month := to_char(v_dateval, 'MM')::SMALLINT; + + v_language := CASE + WHEN (v_style IN (130, 131)) THEN 'HIJRI' + ELSE CONVERSION_LANG + END; + RAISE NOTICE 'v_language=[%]', v_language; + BEGIN + v_lang_metadata_json := sys.babelfish_get_lang_metadata_json(v_language); + EXCEPTION + WHEN OTHERS THEN + RAISE invalid_character_value_for_cast; + END; + + v_monthname := (v_lang_metadata_json -> 'months_shortnames') ->> v_month - 1; + + v_resmask := CASE + WHEN (v_style IN (1, 22)) THEN 'MM/DD/YY' + WHEN (v_style = 101) THEN 'MM/DD/YYYY' + WHEN (v_style = 2) THEN 'YY.MM.DD' + WHEN (v_style = 102) THEN 'YYYY.MM.DD' + WHEN (v_style = 3) THEN 'DD/MM/YY' + WHEN (v_style = 103) THEN 'DD/MM/YYYY' + WHEN (v_style = 4) THEN 'DD.MM.YY' + WHEN (v_style = 104) THEN 'DD.MM.YYYY' + WHEN (v_style = 5) THEN 'DD-MM-YY' + WHEN (v_style = 105) THEN 'DD-MM-YYYY' + WHEN (v_style = 6) THEN 'DD $mnme$ YY' + WHEN (v_style IN (13, 106, 113)) THEN 'DD $mnme$ YYYY' + WHEN (v_style = 7) THEN '$mnme$ DD, YY' + WHEN (v_style = 107) THEN '$mnme$ DD, YYYY' + WHEN (v_style = 10) THEN 'MM-DD-YY' + WHEN (v_style = 110) THEN 'MM-DD-YYYY' + WHEN (v_style = 11) THEN 'YY/MM/DD' + WHEN (v_style = 111) THEN 'YYYY/MM/DD' + WHEN (v_style = 12) THEN 'YYMMDD' + WHEN (v_style = 112) THEN 'YYYYMMDD' + WHEN (v_style IN (20, 21, 23, 25, 120, 121, 126, 127)) THEN 'YYYY-MM-DD' + WHEN (v_style = 130) THEN 'DD $mnme$ YYYY' + WHEN (v_style = 131) THEN pg_catalog.format('%s/MM/YYYY', lpad(v_day, 2, ' ')) + WHEN (v_style IN (0, 9, 100, 109)) THEN pg_catalog.format('$mnme$ %s YYYY', lpad(v_day, 2, ' ')) + END; + + v_resstring := to_char(v_dateval, v_resmask); + v_resstring := pg_catalog.replace(v_resstring, '$mnme$', v_monthname); + v_resstring := substring(v_resstring, 1, coalesce(v_res_length, char_length(v_resstring))); + v_res_length := coalesce(v_res_length, + CASE v_res_datatype + WHEN 'CHAR' THEN 30 + ELSE 60 + END); + RETURN CASE + WHEN (v_res_datatype NOT IN ('CHAR', 'NCHAR')) THEN v_resstring + ELSE rpad(v_resstring, v_res_length, ' ') + END; +EXCEPTION + WHEN most_specific_type_mismatch THEN + RAISE USING MESSAGE := 'Argument data type NUMERIC is invalid for argument 3 of convert function.', + DETAIL := 'Use of incorrect "style" parameter value during conversion process.', + HINT := 'Change "style" parameter to the proper value and try again.'; + + WHEN invalid_parameter_value THEN + RAISE USING MESSAGE := pg_catalog.format('%s is not a valid style number when converting from DATE to a character string.', v_style), + DETAIL := 'Use of incorrect "style" parameter value during conversion process.', + HINT := 'Change "style" parameter to the proper value and try again.'; + + WHEN invalid_datetime_format THEN + RAISE USING MESSAGE := pg_catalog.format('Error converting data type DATE to %s.', trim(p_datatype)), + DETAIL := 'Incorrect using of pair of input parameters values during conversion process.', + HINT := 'Check the input parameters values, correct them if needed, and try again.'; + + WHEN interval_field_overflow THEN + RAISE USING MESSAGE := pg_catalog.format('The size (%s) given to the convert specification ''%s'' exceeds the maximum allowed for any data type (%s).', + v_lengthexpr, + lower(v_res_datatype), + v_maxlength), + DETAIL := 'Use of incorrect size value of data type parameter during conversion process.', + HINT := 'Change size component of data type parameter to the allowable value and try again.'; + + WHEN datatype_mismatch THEN + RAISE USING MESSAGE := 'Data type should be one of these values: ''CHAR(n|MAX)'', ''NCHAR(n|MAX)'', ''VARCHAR(n|MAX)'', ''NVARCHAR(n|MAX)''.', + DETAIL := 'Use of incorrect "datatype" parameter value during conversion process.', + HINT := 'Change "datatype" parameter to the proper value and try again.'; + + WHEN invalid_character_value_for_cast THEN + RAISE USING MESSAGE := pg_catalog.format('Invalid CONVERSION_LANG constant value - ''%s''. Allowed values are: ''English'', ''Deutsch'', etc.', + CONVERSION_LANG), + DETAIL := 'Compiled incorrect CONVERSION_LANG constant value in function''s body.', + HINT := 'Correct CONVERSION_LANG constant value in function''s body, recompile it and try again.'; + + WHEN invalid_text_representation THEN + GET STACKED DIAGNOSTICS v_err_message = MESSAGE_TEXT; + v_err_message := substring(lower(v_err_message), 'integer\:\s\"(.*)\"'); + + RAISE USING MESSAGE := pg_catalog.format('Error while trying to convert "%s" value to SMALLINT (or INTEGER) data type.', + v_err_message), + DETAIL := 'Supplied value contains illegal characters.', + HINT := 'Correct supplied value, remove all illegal characters.'; +END; +$BODY$ +LANGUAGE plpgsql +STABLE +RETURNS NULL ON NULL INPUT; + +CREATE OR REPLACE FUNCTION sys.babelfish_conv_datetime_to_string(IN p_datatype TEXT, + IN p_src_datatype TEXT, + IN p_datetimeval TIMESTAMP(6) WITHOUT TIME ZONE, + IN p_style NUMERIC DEFAULT -1) +RETURNS TEXT +AS +$BODY$ +DECLARE + v_day VARCHAR COLLATE "C"; + v_hour VARCHAR COLLATE "C"; + v_month SMALLINT; + v_style SMALLINT; + v_scale SMALLINT; + v_resmask VARCHAR COLLATE "C"; + v_language VARCHAR COLLATE "C"; + v_datatype VARCHAR COLLATE "C"; + v_fseconds VARCHAR COLLATE "C"; + v_fractsep VARCHAR COLLATE "C"; + v_monthname VARCHAR COLLATE "C"; + v_resstring VARCHAR COLLATE "C"; + v_lengthexpr VARCHAR COLLATE "C"; + v_maxlength SMALLINT; + v_res_length SMALLINT; + v_err_message VARCHAR COLLATE "C"; + v_src_datatype VARCHAR COLLATE "C"; + v_res_datatype VARCHAR COLLATE "C"; + v_lang_metadata_json JSONB; + VARCHAR_MAX CONSTANT SMALLINT := 8000; + NVARCHAR_MAX CONSTANT SMALLINT := 4000; + CONVERSION_LANG CONSTANT VARCHAR COLLATE "C" := ''; + DATATYPE_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(CHAR|NCHAR|VARCHAR|NVARCHAR|CHARACTER VARYING)\s*$'; + SRCDATATYPE_MASK_REGEXP VARCHAR COLLATE "C" := '^(?:DATETIME|SMALLDATETIME|DATETIME2)\s*(?:\s*\(\s*(\d+)\s*\)\s*)?$'; + DATATYPE_MASK_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(?:CHAR|NCHAR|VARCHAR|NVARCHAR|CHARACTER VARYING)\s*\(\s*(\d+|MAX)\s*\)\s*$'; + v_datetimeval TIMESTAMP(6) WITHOUT TIME ZONE; +BEGIN + v_datatype := upper(trim(p_datatype)); + v_src_datatype := upper(trim(p_src_datatype)); + v_style := floor(p_style)::SMALLINT; + + IF (v_src_datatype ~* SRCDATATYPE_MASK_REGEXP) + THEN + v_scale := substring(v_src_datatype, SRCDATATYPE_MASK_REGEXP)::SMALLINT; + + v_src_datatype := PG_CATALOG.rtrim(split_part(v_src_datatype, '(', 1)); + + IF (v_src_datatype <> 'DATETIME2' AND v_scale IS NOT NULL) THEN + RAISE invalid_indicator_parameter_value; + ELSIF (v_scale NOT BETWEEN 0 AND 7) THEN + RAISE invalid_regular_expression; + END IF; + + v_scale := coalesce(v_scale, 7); + ELSE + RAISE most_specific_type_mismatch; + END IF; + + IF (scale(p_style) > 0) THEN + RAISE escape_character_conflict; + ELSIF (NOT ((v_style BETWEEN 0 AND 14) OR + (v_style BETWEEN 20 AND 25) OR + (v_style BETWEEN 100 AND 114) OR + v_style IN (-1, 120, 121, 126, 127, 130, 131))) + THEN + RAISE invalid_parameter_value; + END IF; + + IF (v_datatype ~* DATATYPE_MASK_REGEXP) THEN + v_res_datatype := PG_CATALOG.rtrim(split_part(v_datatype, '(', 1)); + + v_maxlength := CASE + WHEN (v_res_datatype IN ('CHAR', 'VARCHAR')) THEN VARCHAR_MAX + ELSE NVARCHAR_MAX + END; + + v_lengthexpr := substring(v_datatype, DATATYPE_MASK_REGEXP); + + IF (v_lengthexpr <> 'MAX' AND char_length(v_lengthexpr) > 4) + THEN + RAISE interval_field_overflow; + END IF; + + v_res_length := CASE v_lengthexpr + WHEN 'MAX' THEN v_maxlength + ELSE v_lengthexpr::SMALLINT + END; + ELSIF (v_datatype ~* DATATYPE_REGEXP) THEN + v_res_datatype := v_datatype; + ELSE + RAISE datatype_mismatch; + END IF; + + v_datetimeval := CASE + WHEN (v_style NOT IN (130, 131)) THEN p_datetimeval + ELSE sys.babelfish_conv_greg_to_hijri(p_datetimeval) + INTERVAL '1 day' + END; + + v_day := PG_CATALOG.ltrim(to_char(v_datetimeval, 'DD'), '0'); + v_hour := PG_CATALOG.ltrim(to_char(v_datetimeval, 'HH12'), '0'); + v_month := to_char(v_datetimeval, 'MM')::SMALLINT; + + v_language := CASE + WHEN (v_style IN (130, 131)) THEN 'HIJRI' + ELSE CONVERSION_LANG + END; + BEGIN + v_lang_metadata_json := sys.babelfish_get_lang_metadata_json(v_language); + EXCEPTION + WHEN OTHERS THEN + RAISE invalid_character_value_for_cast; + END; + + v_monthname := (v_lang_metadata_json -> 'months_shortnames') ->> v_month - 1; + + IF (v_src_datatype IN ('DATETIME', 'SMALLDATETIME')) THEN + v_fseconds := sys.babelfish_round_fractseconds(to_char(v_datetimeval, 'MS')); + + IF (v_fseconds::INTEGER = 1000) THEN + v_fseconds := '000'; + v_datetimeval := v_datetimeval + INTERVAL '1 second'; + ELSE + v_fseconds := lpad(v_fseconds, 3, '0'); + END IF; + ELSE + v_fseconds := sys.babelfish_get_microsecs_from_fractsecs(to_char(v_datetimeval, 'US'), v_scale); + + IF (v_scale = 7) THEN + v_fseconds := concat(v_fseconds, '0'); + END IF; + END IF; + + v_fractsep := CASE v_src_datatype + WHEN 'DATETIME2' THEN '.' + ELSE ':' + END; + + IF ((v_style = -1 AND v_src_datatype <> 'DATETIME2') OR + v_style IN (0, 9, 100, 109)) + THEN + v_resmask := pg_catalog.format('$mnme$ %s YYYY %s:MI%s', + lpad(v_day, 2, ' '), + lpad(v_hour, 2, ' '), + CASE + WHEN (v_style IN (-1, 0, 100)) THEN 'AM' + ELSE pg_catalog.format(':SS:%sAM', v_fseconds) + END); + ELSIF (v_style = 1) THEN + v_resmask := 'MM/DD/YY'; + ELSIF (v_style = 101) THEN + v_resmask := 'MM/DD/YYYY'; + ELSIF (v_style = 2) THEN + v_resmask := 'YY.MM.DD'; + ELSIF (v_style = 102) THEN + v_resmask := 'YYYY.MM.DD'; + ELSIF (v_style = 3) THEN + v_resmask := 'DD/MM/YY'; + ELSIF (v_style = 103) THEN + v_resmask := 'DD/MM/YYYY'; + ELSIF (v_style = 4) THEN + v_resmask := 'DD.MM.YY'; + ELSIF (v_style = 104) THEN + v_resmask := 'DD.MM.YYYY'; + ELSIF (v_style = 5) THEN + v_resmask := 'DD-MM-YY'; + ELSIF (v_style = 105) THEN + v_resmask := 'DD-MM-YYYY'; + ELSIF (v_style = 6) THEN + v_resmask := 'DD $mnme$ YY'; + ELSIF (v_style = 106) THEN + v_resmask := 'DD $mnme$ YYYY'; + ELSIF (v_style = 7) THEN + v_resmask := '$mnme$ DD, YY'; + ELSIF (v_style = 107) THEN + v_resmask := '$mnme$ DD, YYYY'; + ELSIF (v_style IN (8, 24, 108)) THEN + v_resmask := 'HH24:MI:SS'; + ELSIF (v_style = 10) THEN + v_resmask := 'MM-DD-YY'; + ELSIF (v_style = 110) THEN + v_resmask := 'MM-DD-YYYY'; + ELSIF (v_style = 11) THEN + v_resmask := 'YY/MM/DD'; + ELSIF (v_style = 111) THEN + v_resmask := 'YYYY/MM/DD'; + ELSIF (v_style = 12) THEN + v_resmask := 'YYMMDD'; + ELSIF (v_style = 112) THEN + v_resmask := 'YYYYMMDD'; + ELSIF (v_style IN (13, 113)) THEN + v_resmask := pg_catalog.format('DD $mnme$ YYYY HH24:MI:SS%s%s', v_fractsep, v_fseconds); + ELSIF (v_style IN (14, 114)) THEN + v_resmask := pg_catalog.format('HH24:MI:SS%s%s', v_fractsep, v_fseconds); + ELSIF (v_style IN (20, 120)) THEN + v_resmask := 'YYYY-MM-DD HH24:MI:SS'; + ELSIF ((v_style = -1 AND v_src_datatype = 'DATETIME2') OR + v_style IN (21, 25, 121)) + THEN + v_resmask := pg_catalog.format('YYYY-MM-DD HH24:MI:SS.%s', v_fseconds); + ELSIF (v_style = 22) THEN + v_resmask := pg_catalog.format('MM/DD/YY %s:MI:SS AM', lpad(v_hour, 2, ' ')); + ELSIF (v_style = 23) THEN + v_resmask := 'YYYY-MM-DD'; + ELSIF (v_style IN (126, 127)) THEN + v_resmask := CASE v_src_datatype + WHEN 'SMALLDATETIME' THEN 'YYYY-MM-DDT$rem$HH24:MI:SS' + ELSE pg_catalog.format('YYYY-MM-DDT$rem$HH24:MI:SS.%s', v_fseconds) + END; + ELSIF (v_style IN (130, 131)) THEN + v_resmask := concat(CASE p_style + WHEN 131 THEN pg_catalog.format('%s/MM/YYYY ', lpad(v_day, 2, ' ')) + ELSE pg_catalog.format('%s $mnme$ YYYY ', lpad(v_day, 2, ' ')) + END, + pg_catalog.format('%s:MI:SS%s%sAM', lpad(v_hour, 2, ' '), v_fractsep, v_fseconds)); + END IF; + + v_resstring := to_char(v_datetimeval, v_resmask); + v_resstring := pg_catalog.replace(v_resstring, '$mnme$', v_monthname); + v_resstring := pg_catalog.replace(v_resstring, '$rem$', ''); + + v_resstring := substring(v_resstring, 1, coalesce(v_res_length, char_length(v_resstring))); + v_res_length := coalesce(v_res_length, + CASE v_res_datatype + WHEN 'CHAR' THEN 30 + ELSE 60 + END); + RETURN CASE + WHEN (v_res_datatype NOT IN ('CHAR', 'NCHAR')) THEN v_resstring + ELSE rpad(v_resstring, v_res_length, ' ') + END; +EXCEPTION + WHEN most_specific_type_mismatch THEN + RAISE USING MESSAGE := 'Source data type should be one of these values: ''DATETIME'', ''SMALLDATETIME'', ''DATETIME2'' or ''DATETIME2(n)''.', + DETAIL := 'Use of incorrect "src_datatype" parameter value during conversion process.', + HINT := 'Change "srcdatatype" parameter to the proper value and try again.'; + + WHEN invalid_regular_expression THEN + RAISE USING MESSAGE := pg_catalog.format('The source data type scale (%s) given to the convert specification exceeds the maximum allowable value (7).', + v_scale), + DETAIL := 'Use of incorrect scale value of source data type parameter during conversion process.', + HINT := 'Change scale component of source data type parameter to the allowable value and try again.'; + + WHEN invalid_indicator_parameter_value THEN + RAISE USING MESSAGE := pg_catalog.format('Invalid attributes specified for data type %s.', v_src_datatype), + DETAIL := 'Use of incorrect scale value, which is not corresponding to specified data type.', + HINT := 'Change data type scale component or select different data type and try again.'; + + WHEN escape_character_conflict THEN + RAISE USING MESSAGE := 'Argument data type NUMERIC is invalid for argument 4 of convert function.', + DETAIL := 'Use of incorrect "style" parameter value during conversion process.', + HINT := 'Change "style" parameter to the proper value and try again.'; + + WHEN invalid_parameter_value THEN + RAISE USING MESSAGE := pg_catalog.format('%s is not a valid style number when converting from %s to a character string.', + v_style, v_src_datatype), + DETAIL := 'Use of incorrect "style" parameter value during conversion process.', + HINT := 'Change "style" parameter to the proper value and try again.'; + + WHEN interval_field_overflow THEN + RAISE USING MESSAGE := pg_catalog.format('The size (%s) given to the convert specification ''%s'' exceeds the maximum allowed for any data type (%s).', + v_lengthexpr, lower(v_res_datatype), v_maxlength), + DETAIL := 'Use of incorrect size value of data type parameter during conversion process.', + HINT := 'Change size component of data type parameter to the allowable value and try again.'; + + WHEN datatype_mismatch THEN + RAISE USING MESSAGE := 'Data type should be one of these values: ''CHAR(n|MAX)'', ''NCHAR(n|MAX)'', ''VARCHAR(n|MAX)'', ''NVARCHAR(n|MAX)''.', + DETAIL := 'Use of incorrect "datatype" parameter value during conversion process.', + HINT := 'Change "datatype" parameter to the proper value and try again.'; + + WHEN invalid_character_value_for_cast THEN + RAISE USING MESSAGE := pg_catalog.format('Invalid CONVERSION_LANG constant value - ''%s''. Allowed values are: ''English'', ''Deutsch'', etc.', + CONVERSION_LANG), + DETAIL := 'Compiled incorrect CONVERSION_LANG constant value in function''s body.', + HINT := 'Correct CONVERSION_LANG constant value in function''s body, recompile it and try again.'; + + WHEN invalid_text_representation THEN + GET STACKED DIAGNOSTICS v_err_message = MESSAGE_TEXT; + v_err_message := substring(lower(v_err_message), 'integer\:\s\"(.*)\"'); + + RAISE USING MESSAGE := pg_catalog.format('Error while trying to convert "%s" value to SMALLINT data type.', + v_err_message), + DETAIL := 'Supplied value contains illegal characters.', + HINT := 'Correct supplied value, remove all illegal characters.'; +END; +$BODY$ +LANGUAGE plpgsql +STABLE +RETURNS NULL ON NULL INPUT; + +CREATE OR REPLACE FUNCTION sys.babelfish_conv_time_to_string(IN p_datatype TEXT, + IN p_src_datatype TEXT, + IN p_timeval TIME(6) WITHOUT TIME ZONE, + IN p_style NUMERIC DEFAULT 25) +RETURNS TEXT +AS +$BODY$ +DECLARE + v_hours VARCHAR COLLATE "C"; + v_style SMALLINT; + v_scale SMALLINT; + v_resmask VARCHAR COLLATE "C"; + v_fseconds VARCHAR COLLATE "C"; + v_datatype VARCHAR COLLATE "C"; + v_resstring VARCHAR COLLATE "C"; + v_lengthexpr VARCHAR COLLATE "C"; + v_res_length SMALLINT; + v_res_datatype VARCHAR COLLATE "C"; + v_src_datatype VARCHAR COLLATE "C"; + v_res_maxlength SMALLINT; + VARCHAR_MAX CONSTANT SMALLINT := 8000; + NVARCHAR_MAX CONSTANT SMALLINT := 4000; + -- We use the regex below to make sure input p_datatype is one of them + DATATYPE_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(CHAR|NCHAR|VARCHAR|NVARCHAR|CHARACTER VARYING)\s*$'; + -- We use the regex below to get the length of the datatype, if specified + -- For example, to get the '10' out of 'varchar(10)' + DATATYPE_MASK_REGEXP CONSTANT VARCHAR COLLATE "C" := '^\s*(?:CHAR|NCHAR|VARCHAR|NVARCHAR|CHARACTER VARYING)\s*\(\s*(\d+|MAX)\s*\)\s*$'; + SRCDATATYPE_MASK_REGEXP VARCHAR COLLATE "C" := '^\s*(?:TIME)\s*(?:\s*\(\s*(\d+)\s*\)\s*)?\s*$'; +BEGIN + v_datatype := upper(trim(p_datatype)); + v_src_datatype := upper(trim(p_src_datatype)); + v_style := floor(p_style)::SMALLINT; + + IF (v_src_datatype ~* SRCDATATYPE_MASK_REGEXP) + THEN + v_scale := coalesce(substring(v_src_datatype, SRCDATATYPE_MASK_REGEXP)::SMALLINT, 7); + + IF (v_scale NOT BETWEEN 0 AND 7) THEN + RAISE invalid_regular_expression; + END IF; + ELSE + RAISE most_specific_type_mismatch; + END IF; + + IF (v_datatype ~* DATATYPE_MASK_REGEXP) + THEN + v_res_datatype := PG_CATALOG.rtrim(split_part(v_datatype, '(', 1)); + + v_res_maxlength := CASE + WHEN (v_res_datatype IN ('CHAR', 'VARCHAR')) THEN VARCHAR_MAX + ELSE NVARCHAR_MAX + END; + + v_lengthexpr := substring(v_datatype, DATATYPE_MASK_REGEXP); + + IF (v_lengthexpr <> 'MAX' AND char_length(v_lengthexpr) > 4) THEN + RAISE interval_field_overflow; + END IF; + + v_res_length := CASE v_lengthexpr + WHEN 'MAX' THEN v_res_maxlength + ELSE v_lengthexpr::SMALLINT + END; + ELSIF (v_datatype ~* DATATYPE_REGEXP) THEN + v_res_datatype := v_datatype; + ELSE + RAISE datatype_mismatch; + END IF; + + IF (scale(p_style) > 0) THEN + RAISE escape_character_conflict; + ELSIF (NOT ((v_style BETWEEN 0 AND 14) OR + (v_style BETWEEN 20 AND 25) OR + (v_style BETWEEN 100 AND 114) OR + v_style IN (120, 121, 126, 127, 130, 131))) + THEN + RAISE invalid_parameter_value; + ELSIF ((v_style BETWEEN 1 AND 7) OR + (v_style BETWEEN 10 AND 12) OR + (v_style BETWEEN 101 AND 107) OR + (v_style BETWEEN 110 AND 112) OR + v_style = 23) + THEN + RAISE invalid_datetime_format; + END IF; + + v_hours := PG_CATALOG.ltrim(to_char(p_timeval, 'HH12'), '0'); + v_fseconds := sys.babelfish_get_microsecs_from_fractsecs(to_char(p_timeval, 'US'), v_scale); + + IF (v_scale = 7) THEN + v_fseconds := concat(v_fseconds, '0'); + END IF; + + IF (v_style IN (0, 100)) + THEN + v_resmask := concat(v_hours, ':MIAM'); + ELSIF (v_style IN (8, 20, 24, 108, 120)) + THEN + v_resmask := 'HH24:MI:SS'; + ELSIF (v_style IN (9, 109)) + THEN + v_resmask := CASE + WHEN (char_length(v_fseconds) = 0) THEN concat(v_hours, ':MI:SSAM') + ELSE pg_catalog.format('%s:MI:SS.%sAM', v_hours, v_fseconds) + END; + ELSIF (v_style IN (13, 14, 21, 25, 113, 114, 121, 126, 127)) + THEN + v_resmask := CASE + WHEN (char_length(v_fseconds) = 0) THEN 'HH24:MI:SS' + ELSE concat('HH24:MI:SS.', v_fseconds) + END; + ELSIF (v_style = 22) + THEN + v_resmask := pg_catalog.format('%s:MI:SS AM', lpad(v_hours, 2, ' ')); + ELSIF (v_style IN (130, 131)) + THEN + v_resmask := CASE + WHEN (char_length(v_fseconds) = 0) THEN concat(lpad(v_hours, 2, ' '), ':MI:SSAM') + ELSE pg_catalog.format('%s:MI:SS.%sAM', lpad(v_hours, 2, ' '), v_fseconds) + END; + END IF; + + v_resstring := to_char(p_timeval, v_resmask); + + v_resstring := substring(v_resstring, 1, coalesce(v_res_length, char_length(v_resstring))); + v_res_length := coalesce(v_res_length, + CASE v_res_datatype + WHEN 'CHAR' THEN 30 + ELSE 60 + END); + RETURN CASE + WHEN (v_res_datatype NOT IN ('CHAR', 'NCHAR')) THEN v_resstring + ELSE rpad(v_resstring, v_res_length, ' ') + END; +EXCEPTION + WHEN most_specific_type_mismatch THEN + RAISE USING MESSAGE := 'Source data type should be ''TIME'' or ''TIME(n)''.', + DETAIL := 'Use of incorrect "src_datatype" parameter value during conversion process.', + HINT := 'Change "src_datatype" parameter to the proper value and try again.'; + + WHEN invalid_regular_expression THEN + RAISE USING MESSAGE := pg_catalog.format('The source data type scale (%s) given to the convert specification exceeds the maximum allowable value (7).', + v_scale), + DETAIL := 'Use of incorrect scale value of source data type parameter during conversion process.', + HINT := 'Change scale component of source data type parameter to the allowable value and try again.'; + + WHEN interval_field_overflow THEN + RAISE USING MESSAGE := pg_catalog.format('The size (%s) given to the convert specification ''%s'' exceeds the maximum allowed for any data type (%s).', + v_lengthexpr, lower(v_res_datatype), v_res_maxlength), + DETAIL := 'Use of incorrect size value of target data type parameter during conversion process.', + HINT := 'Change size component of data type parameter to the allowable value and try again.'; + + WHEN escape_character_conflict THEN + RAISE USING MESSAGE := 'Argument data type NUMERIC is invalid for argument 4 of convert function.', + DETAIL := 'Use of incorrect "style" parameter value during conversion process.', + HINT := 'Change "style" parameter to the proper value and try again.'; + + WHEN invalid_parameter_value THEN + RAISE USING MESSAGE := pg_catalog.format('%s is not a valid style number when converting from TIME to a character string.', v_style), + DETAIL := 'Use of incorrect "style" parameter value during conversion process.', + HINT := 'Change "style" parameter to the proper value and try again.'; + + WHEN datatype_mismatch THEN + RAISE USING MESSAGE := 'Data type should be one of these values: ''CHAR(n|MAX)'', ''NCHAR(n|MAX)'', ''VARCHAR(n|MAX)'', ''NVARCHAR(n|MAX)''.', + DETAIL := 'Use of incorrect "datatype" parameter value during conversion process.', + HINT := 'Change "datatype" parameter to the proper value and try again.'; + + WHEN invalid_datetime_format THEN + RAISE USING MESSAGE := pg_catalog.format('Error converting data type TIME to %s.', + PG_CATALOG.rtrim(split_part(trim(p_datatype), '(', 1))), + DETAIL := 'Incorrect using of pair of input parameters values during conversion process.', + HINT := 'Check the input parameters values, correct them if needed, and try again.'; +END; +$BODY$ +LANGUAGE plpgsql +STABLE +RETURNS NULL ON NULL INPUT; + +CREATE OR REPLACE FUNCTION babelfish_remove_delimiter_pair(IN name TEXT) +RETURNS TEXT AS +$BODY$ +BEGIN + IF name IN('[' COLLATE "C", ']' COLLATE "C", '"' COLLATE "C") THEN + RETURN NULL; + + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '[' COLLATE "C" AND PG_CATALOG.right(name, 1) = ']' COLLATE "C" THEN + IF length(name) = 2 THEN + RETURN ''; + ELSE + RETURN substring(name from 2 for length(name)-2); + END IF; + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '[' COLLATE "C" AND PG_CATALOG.right(name, 1) != ']' COLLATE "C" THEN + RETURN NULL; + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) != '[' COLLATE "C" AND PG_CATALOG.right(name, 1) = ']' COLLATE "C" THEN + RETURN NULL; + + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '"' COLLATE "C" AND PG_CATALOG.right(name, 1) = '"' COLLATE "C" THEN + IF length(name) = 2 THEN + RETURN ''; + ELSE + RETURN substring(name from 2 for length(name)-2); + END IF; + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) = '"' COLLATE "C" AND PG_CATALOG.right(name, 1) != '"' COLLATE "C" THEN + RETURN NULL; + ELSIF length(name) >= 2 AND PG_CATALOG.left(name, 1) != '"' COLLATE "C" AND PG_CATALOG.right(name, 1) = '"' COLLATE "C" THEN + RETURN NULL; + + END IF; + RETURN name; +END; +$BODY$ +LANGUAGE plpgsql +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_add_job ( + par_job_name varchar, + par_enabled smallint = 1, + par_description varchar = NULL::character varying, + par_start_step_id integer = 1, + par_category_name varchar = NULL::character varying, + par_category_id integer = NULL::integer, + par_owner_login_name varchar = NULL::character varying, + par_notify_level_eventlog integer = 2, + par_notify_level_email integer = 0, + par_notify_level_netsend integer = 0, + par_notify_level_page integer = 0, + par_notify_email_operator_name varchar = NULL::character varying, + par_notify_netsend_operator_name varchar = NULL::character varying, + par_notify_page_operator_name varchar = NULL::character varying, + par_delete_level integer = 0, + inout par_job_id integer = NULL::integer, + par_originating_server varchar = NULL::character varying, + out returncode integer +) +RETURNS record AS +$body$ +DECLARE + var_retval INT DEFAULT 0; + var_notify_email_operator_id INT DEFAULT 0; + var_notify_email_operator_name VARCHAR(128); + var_notify_netsend_operator_id INT DEFAULT 0; + var_notify_page_operator_id INT DEFAULT 0; + var_owner_sid CHAR(85) ; + var_originating_server_id INT DEFAULT 0; +BEGIN + /* Remove any leading/trailing spaces from parameters (except @owner_login_name) */ + SELECT UPPER(PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_originating_server))) INTO par_originating_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_job_name)) INTO par_job_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_description)) INTO par_description; + SELECT '[Uncategorized (Local)]' INTO par_category_name; + SELECT 0 INTO par_category_id; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_email_operator_name)) INTO par_notify_email_operator_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_netsend_operator_name)) INTO par_notify_netsend_operator_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_page_operator_name)) INTO par_notify_page_operator_name; + SELECT NULL INTO var_originating_server_id; /* Turn [nullable] empty string parameters into NULLs */ + SELECT NULL INTO par_job_id; + + IF (par_originating_server = '') + THEN + SELECT NULL INTO par_originating_server; + END IF; + + IF (par_description = '') + THEN + SELECT NULL INTO par_description; + END IF; + + IF (par_category_name = '') + THEN + SELECT NULL INTO par_category_name; + END IF; + + IF (par_notify_email_operator_name = '') + THEN + SELECT NULL INTO par_notify_email_operator_name; + END IF; + + IF (par_notify_netsend_operator_name = '') + THEN + SELECT NULL INTO par_notify_netsend_operator_name; + END IF; + + IF (par_notify_page_operator_name = '') + THEN + SELECT NULL INTO par_notify_page_operator_name; + END IF; + + /* Check parameters */ + SELECT t.par_owner_sid + , t.par_notify_level_email + , t.par_notify_level_netsend + , t.par_notify_level_page + , t.par_category_id + , t.par_notify_email_operator_id + , t.par_notify_netsend_operator_id + , t.par_notify_page_operator_id + , t.par_originating_server + , t.returncode + FROM sys.babelfish_sp_verify_job( + par_job_id /* NULL::integer */ + , par_job_name + , par_enabled + , par_start_step_id + , par_category_name + , var_owner_sid /* par_owner_sid */ + , par_notify_level_eventlog + , par_notify_level_email + , par_notify_level_netsend + , par_notify_level_page + , par_notify_email_operator_name + , par_notify_netsend_operator_name + , par_notify_page_operator_name + , par_delete_level + , par_category_id + , var_notify_email_operator_id /* par_notify_email_operator_id */ + , var_notify_netsend_operator_id /* par_notify_netsend_operator_id */ + , var_notify_page_operator_id /* par_notify_page_operator_id */ + , par_originating_server + ) t + INTO var_owner_sid + , par_notify_level_email + , par_notify_level_netsend + , par_notify_level_page + , par_category_id + , var_notify_email_operator_id + , var_notify_netsend_operator_id + , var_notify_page_operator_id + , par_originating_server + , var_retval; + + IF (var_retval <> 0) /* Failure */ + THEN + returncode := 1; + RETURN; + END IF; + + var_notify_email_operator_name := par_notify_email_operator_name; + + /* Default the description (if not supplied) */ + IF (par_description IS NULL) + THEN + SELECT 'No description available.' INTO par_description; + END IF; + + var_originating_server_id := 0; + var_owner_sid := ''; + + INSERT + INTO sys.sysjobs ( + originating_server_id + , name + , enabled + , description + , start_step_id + , category_id + , owner_sid + , notify_level_eventlog + , notify_level_email + , notify_level_netsend + , notify_level_page + , notify_email_operator_id + , notify_email_operator_name + , notify_netsend_operator_id + , notify_page_operator_id + , delete_level + , version_number + ) + VALUES ( + var_originating_server_id + , par_job_name + , par_enabled + , par_description + , par_start_step_id + , par_category_id + , var_owner_sid + , par_notify_level_eventlog + , par_notify_level_email + , par_notify_level_netsend + , par_notify_level_page + , var_notify_email_operator_id + , var_notify_email_operator_name + , var_notify_netsend_operator_id + , var_notify_page_operator_id + , par_delete_level + , 1); + + /* scope_identity() */ + SELECT LASTVAL() INTO par_job_id; + + /* Version number 1 */ + /* SELECT @retval = @@error */ + /* 0 means success */ + returncode := var_retval; + RETURN; + +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_add_schedule ( + par_schedule_name varchar, + par_enabled smallint = 1, + par_freq_type integer = 0, + par_freq_interval integer = 0, + par_freq_subday_type integer = 0, + par_freq_subday_interval integer = 0, + par_freq_relative_interval integer = 0, + par_freq_recurrence_factor integer = 0, + par_active_start_date integer = NULL::integer, + par_active_end_date integer = 99991231, + par_active_start_time integer = 0, + par_active_end_time integer = 235959, + par_owner_login_name varchar = NULL::character varying, + inout par_schedule_uid char = NULL::bpchar, + inout par_schedule_id integer = NULL::integer, + par_originating_server varchar = NULL::character varying, + out returncode integer +) +AS +$body$ +DECLARE + var_retval INT; + var_owner_sid CHAR(85); + var_orig_server_id INT; +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_schedule_name)) + , PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_owner_login_name)) + , UPPER(PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_originating_server))) + , 0 + INTO par_schedule_name + , par_owner_login_name + , par_originating_server + , par_schedule_id; + + /* Check schedule (frequency and owner) parameters */ + SELECT t.par_freq_interval + , t.par_freq_subday_type + , t.par_freq_subday_interval + , t.par_freq_relative_interval + , t.par_freq_recurrence_factor + , t.par_active_start_date + , t.par_active_start_time + , t.par_active_end_date + , t.par_active_end_time + , t.returncode + FROM sys.babelfish_sp_verify_schedule( + NULL::integer /* @schedule_id -- schedule_id does not exist for the new schedule */ + , par_schedule_name /* @name */ + , par_enabled /* @enabled */ + , par_freq_type /* @freq_type */ + , par_freq_interval /* @freq_interval */ + , par_freq_subday_type /* @freq_subday_type */ + , par_freq_subday_interval /* @freq_subday_interval */ + , par_freq_relative_interval /* @freq_relative_interval */ + , par_freq_recurrence_factor /* @freq_recurrence_factor */ + , par_active_start_date /* @active_start_date */ + , par_active_start_time /* @active_start_time */ + , par_active_end_date /* @active_end_date */ + , par_active_end_time /* @active_end_time */ + , var_owner_sid + ) t + INTO par_freq_interval + , par_freq_subday_type + , par_freq_subday_interval + , par_freq_relative_interval + , par_freq_recurrence_factor + , par_active_start_date + , par_active_start_time + , par_active_end_date + , par_active_end_time + , var_retval /* @owner_sid */; + + IF (var_retval <> 0) THEN /* Failure */ + returncode := 1; + RETURN; + END IF; + + IF (par_schedule_uid IS NULL) + THEN /* Assign the GUID */ + /* uuid without extensions uuid-ossp (cheat) */ + SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring) INTO par_schedule_uid; + END IF; + + var_orig_server_id := 0; + var_owner_sid := uuid_in(md5(random()::text || clock_timestamp()::text)::cstring); + + + INSERT + INTO sys.sysschedules ( + schedule_uid + , originating_server_id + , name + , owner_sid + , enabled + , freq_type + , freq_interval + , freq_subday_type + , freq_subday_interval + , freq_relative_interval + , freq_recurrence_factor + , active_start_date + , active_end_date + , active_start_time + , active_end_time + ) + VALUES ( + par_schedule_uid + , var_orig_server_id + , par_schedule_name + , var_owner_sid + , par_enabled + , par_freq_type + , par_freq_interval + , par_freq_subday_type + , par_freq_subday_interval + , par_freq_relative_interval + , par_freq_recurrence_factor + , par_active_start_date + , par_active_end_date + , par_active_start_time + , par_active_end_time + ); + + /* ZZZ */ + SELECT 0 /* @@ERROR, */, LASTVAL() + INTO var_retval, par_schedule_id; + + /* 0 means success */ + returncode := var_retval; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_delete_jobschedule ( + par_job_id integer = NULL::integer, + par_job_name varchar = NULL::character varying, + par_name varchar = NULL::character varying, + par_keep_schedule integer = 0, + par_automatic_post smallint = 1, + out returncode integer +) +RETURNS integer AS +$body$ +DECLARE + var_retval INT; + var_sched_count INT; + var_schedule_id INT; + var_job_owner_sid CHAR(85); +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; + + /* Check that we can uniquely identify the job */ + SELECT t.par_job_name + , t.par_job_id + , t.par_owner_sid + , t.returncode + FROM sys.babelfish_sp_verify_job_identifiers( + '@job_name' + , '@job_id' + , par_job_name + , par_job_id + , 'TEST' + , var_job_owner_sid + ) t + INTO par_job_name + , par_job_id + , var_job_owner_sid + , var_retval; + + IF (var_retval <> 0) THEN /* Failure */ + returncode := 1; + RETURN; + END IF; + + IF (LOWER(UPPER(par_name)) = LOWER('ALL')) + THEN + SELECT - 1 INTO var_schedule_id; + + /* We use this in the call to sp_sqlagent_notify */ + /* Delete the schedule(s) if it isn't being used by other jobs */ + CREATE TEMPORARY TABLE "#temp_schedules_to_delete" (schedule_id INT NOT NULL) + /* If user requests that the schedules be removed (the legacy behavoir) */ + /* make sure it isnt being used by other jobs */; + + IF (par_keep_schedule = 0) + THEN + /* Get the list of schedules to delete */ + INSERT INTO "#temp_schedules_to_delete" + SELECT DISTINCT schedule_id + FROM sys.sysschedules + WHERE (schedule_id IN (SELECT schedule_id + FROM sys.sysjobschedules + WHERE (job_id = par_job_id))); + /* make sure no other jobs use these schedules */ + IF (EXISTS (SELECT * + FROM sys.sysjobschedules + WHERE (job_id <> par_job_id) + AND (schedule_id IN (SELECT schedule_id + FROM "#temp_schedules_to_delete")))) + THEN /* Failure */ + RAISE 'One or more schedules were not deleted because they are being used by at least one other job. Use "sp_detach_schedule" to remove schedules from a job.' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + /* OK to delete the jobschedule */ + DELETE FROM sys.sysjobschedules + WHERE (job_id = par_job_id); + + /* OK to delete the schedule - temp_schedules_to_delete is empty if @keep_schedule <> 0 */ + DELETE FROM sys.sysschedules + WHERE schedule_id IN (SELECT schedule_id FROM "#temp_schedules_to_delete"); + ELSE ---- IF (LOWER(UPPER(par_name)) = LOWER('ALL')) + + -- Need to use sp_detach_schedule to remove this ambiguous schedule name + IF(var_sched_count > 1) /* Failure */ + THEN + RAISE 'More than one schedule named "%" is attached to job "%". Use "sp_detach_schedule" to remove schedules from a job.', par_name, par_job_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + --If user requests that the schedule be removed (the legacy behavoir) + --make sure it isnt being used by another job + IF (par_keep_schedule = 0) + THEN + IF(EXISTS(SELECT * + FROM sys.sysjobschedules + WHERE (schedule_id = var_schedule_id) + AND (job_id <> par_job_id))) + THEN /* Failure */ + RAISE 'Schedule "%" was not deleted because it is being used by at least one other job. Use "sp_detach_schedule" to remove schedules from a job.', par_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + /* Delete the job schedule link first */ + DELETE FROM sys.sysjobschedules + WHERE (job_id = par_job_id) + AND (schedule_id = var_schedule_id); + + /* Delete schedule if required */ + IF (par_keep_schedule = 0) + THEN + /* Now delete the schedule if required */ + DELETE FROM sys.sysschedules + WHERE (schedule_id = var_schedule_id); + END IF; + + SELECT t.returncode + FROM sys.babelfish_sp_aws_del_jobschedule(par_job_id, var_schedule_id) t + INTO var_retval; + + + END IF; + + /* Update the job's version/last-modified information */ + UPDATE sys.sysjobs + SET version_number = version_number + 1 + -- , date_modified = GETDATE() / + WHERE job_id = par_job_id; + + DROP TABLE IF EXISTS "#temp_schedules_to_delete"; + + + /* 0 means success */ + returncode := var_retval; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_update_job ( + par_job_id integer = NULL::integer, + par_job_name varchar = NULL::character varying, + par_new_name varchar = NULL::character varying, + par_enabled smallint = NULL::smallint, + par_description varchar = NULL::character varying, + par_start_step_id integer = NULL::integer, + par_category_name varchar = NULL::character varying, + par_owner_login_name varchar = NULL::character varying, + par_notify_level_eventlog integer = NULL::integer, + par_notify_level_email integer = NULL::integer, + par_notify_level_netsend integer = NULL::integer, + par_notify_level_page integer = NULL::integer, + par_notify_email_operator_name varchar = NULL::character varying, + par_notify_netsend_operator_name varchar = NULL::character varying, + par_notify_page_operator_name varchar = NULL::character varying, + par_delete_level integer = NULL::integer, + par_automatic_post smallint = 1, + out returncode integer +) +RETURNS integer AS +$body$ +DECLARE + var_retval INT; + var_category_id INT; + var_notify_email_operator_id INT; + var_notify_netsend_operator_id INT; + var_notify_page_operator_id INT; + var_owner_sid CHAR(85); + var_alert_id INT; + var_cached_attribute_modified INT; + var_is_sysadmin INT; + var_current_owner VARCHAR(128); + var_enable_only_used INT; + var_x_new_name VARCHAR(128); + var_x_enabled SMALLINT; + var_x_description VARCHAR(512); + var_x_start_step_id INT; + var_x_category_name VARCHAR(128); + var_x_category_id INT; + var_x_owner_sid CHAR(85); + var_x_notify_level_eventlog INT; + var_x_notify_level_email INT; + var_x_notify_level_netsend INT; + var_x_notify_level_page INT; + var_x_notify_email_operator_name VARCHAR(128); + var_x_notify_netsnd_operator_name VARCHAR(128); + var_x_notify_page_operator_name VARCHAR(128); + var_x_delete_level INT; + var_x_originating_server_id INT; + var_x_master_server SMALLINT; +BEGIN + /* Not updatable */ + /* Remove any leading/trailing spaces from parameters (except @owner_login_name) */ + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_job_name)) + INTO par_job_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_new_name)) + INTO par_new_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_description)) + INTO par_description; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_category_name)) + INTO par_category_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_email_operator_name)) + INTO par_notify_email_operator_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_netsend_operator_name)) + INTO par_notify_netsend_operator_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_notify_page_operator_name)) + INTO par_notify_page_operator_name + /* Are we modifying an attribute which tsql agent caches? */; + + IF ((par_new_name IS NOT NULL) OR (par_enabled IS NOT NULL) OR (par_start_step_id IS NOT NULL) OR (par_owner_login_name IS NOT NULL) OR (par_notify_level_eventlog IS NOT NULL) OR (par_notify_level_email IS NOT NULL) OR (par_notify_level_netsend IS NOT NULL) OR (par_notify_level_page IS NOT NULL) OR (par_notify_email_operator_name IS NOT NULL) OR (par_notify_netsend_operator_name IS NOT NULL) OR (par_notify_page_operator_name IS NOT NULL) OR (par_delete_level IS NOT NULL)) THEN + SELECT + 1 + INTO var_cached_attribute_modified; + ELSE + SELECT + 0 + INTO var_cached_attribute_modified; + END IF + /* Is @enable the only parameter used beside jobname and jobid? */; + + IF ((par_enabled IS NOT NULL) AND (par_new_name IS NULL) AND (par_description IS NULL) AND (par_start_step_id IS NULL) AND (par_category_name IS NULL) AND (par_owner_login_name IS NULL) AND (par_notify_level_eventlog IS NULL) AND (par_notify_level_email IS NULL) AND (par_notify_level_netsend IS NULL) AND (par_notify_level_page IS NULL) AND (par_notify_email_operator_name IS NULL) AND (par_notify_netsend_operator_name IS NULL) AND (par_notify_page_operator_name IS NULL) AND (par_delete_level IS NULL)) THEN + SELECT + 1 + INTO var_enable_only_used; + ELSE + SELECT + 0 + INTO var_enable_only_used; + END IF; + + IF (par_new_name = '') THEN + SELECT + NULL + INTO par_new_name; + END IF + /* Fill out the values for all non-supplied parameters from the existing values */; + + IF (par_new_name IS NULL) THEN + SELECT + var_x_new_name + INTO par_new_name; + END IF; + + IF (par_enabled IS NULL) THEN + SELECT + var_x_enabled + INTO par_enabled; + END IF; + + IF (par_description IS NULL) THEN + SELECT + var_x_description + INTO par_description; + END IF; + + IF (par_start_step_id IS NULL) THEN + SELECT + var_x_start_step_id + INTO par_start_step_id; + END IF; + + IF (par_category_name IS NULL) THEN + SELECT + var_x_category_name + INTO par_category_name; + END IF; + + IF (var_owner_sid IS NULL) THEN + SELECT + var_x_owner_sid + INTO var_owner_sid; + END IF; + + IF (par_notify_level_eventlog IS NULL) THEN + SELECT + var_x_notify_level_eventlog + INTO par_notify_level_eventlog; + END IF; + + IF (par_notify_level_email IS NULL) THEN + SELECT + var_x_notify_level_email + INTO par_notify_level_email; + END IF; + + IF (par_notify_level_netsend IS NULL) THEN + SELECT + var_x_notify_level_netsend + INTO par_notify_level_netsend; + END IF; + + IF (par_notify_level_page IS NULL) THEN + SELECT + var_x_notify_level_page + INTO par_notify_level_page; + END IF; + + IF (par_notify_email_operator_name IS NULL) THEN + SELECT + var_x_notify_email_operator_name + INTO par_notify_email_operator_name; + END IF; + + IF (par_notify_netsend_operator_name IS NULL) THEN + SELECT + var_x_notify_netsnd_operator_name + INTO par_notify_netsend_operator_name; + END IF; + + IF (par_notify_page_operator_name IS NULL) THEN + SELECT + var_x_notify_page_operator_name + INTO par_notify_page_operator_name; + END IF; + + IF (par_delete_level IS NULL) THEN + SELECT + var_x_delete_level + INTO par_delete_level; + END IF + /* Turn [nullable] empty string parameters into NULLs */; + + IF (LOWER(par_description) = LOWER('')) THEN + SELECT + NULL + INTO par_description; + END IF; + + IF (par_category_name = '') THEN + SELECT + NULL + INTO par_category_name; + END IF; + + IF (par_notify_email_operator_name = '') THEN + SELECT + NULL + INTO par_notify_email_operator_name; + END IF; + + IF (par_notify_netsend_operator_name = '') THEN + SELECT + NULL + INTO par_notify_netsend_operator_name; + END IF; + + IF (par_notify_page_operator_name = '') THEN + SELECT + NULL + INTO par_notify_page_operator_name; + END IF + /* Check new values */; + SELECT + t.par_owner_sid, t.par_notify_level_email, t.par_notify_level_netsend, t.par_notify_level_page, + t.par_category_id, t.par_notify_email_operator_id, t.par_notify_netsend_operator_id, t.par_notify_page_operator_id, t.par_originating_server, t.ReturnCode + FROM sys.babelfish_sp_verify_job(par_job_id, par_new_name, par_enabled, par_start_step_id, par_category_name, var_owner_sid, par_notify_level_eventlog, par_notify_level_email, par_notify_level_netsend, par_notify_level_page, par_notify_email_operator_name, par_notify_netsend_operator_name, par_notify_page_operator_name, par_delete_level, var_category_id, var_notify_email_operator_id, var_notify_netsend_operator_id, var_notify_page_operator_id, NULL) t + INTO var_owner_sid, par_notify_level_email, par_notify_level_netsend, par_notify_level_page, var_category_id, var_notify_email_operator_id, var_notify_netsend_operator_id, var_notify_page_operator_id, var_retval; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF + /* Failure */ + /* BEGIN TRANSACTION */ + /* If the job is being re-assigned, modify sysjobsteps.database_user_name as necessary */; + + IF (par_owner_login_name IS NOT NULL) THEN + IF (EXISTS (SELECT + 1 + FROM sys.sysjobsteps + WHERE (job_id = par_job_id) AND (LOWER(subsystem) = LOWER('TSQL')))) THEN + /* The job is being re-assigned to an non-SA */ + UPDATE sys.sysjobsteps + SET database_user_name = NULL + WHERE (job_id = par_job_id) AND (LOWER(subsystem) = LOWER('TSQL')); + END IF; + END IF; + UPDATE sys.sysjobs + SET name = par_new_name, enabled = par_enabled, description = par_description, start_step_id = par_start_step_id, category_id = var_category_id + /* Returned from sp_verify_job */, owner_sid = var_owner_sid, notify_level_eventlog = par_notify_level_eventlog, notify_level_email = par_notify_level_email, notify_level_netsend = par_notify_level_netsend, notify_level_page = par_notify_level_page, notify_email_operator_id = var_notify_email_operator_id + /* Returned from sp_verify_job */, notify_netsend_operator_id = var_notify_netsend_operator_id + /* Returned from sp_verify_job */, notify_page_operator_id = var_notify_page_operator_id + /* Returned from sp_verify_job */, delete_level = par_delete_level, version_number = version_number + 1 + /* , -- Update the job's version */ + /* date_modified = GETDATE() -- Update the job's last-modified information */ + WHERE (job_id = par_job_id); + SELECT + 0 + INTO var_retval + /* @@error */ + /* COMMIT TRANSACTION */; + ReturnCode := (var_retval); + RETURN + /* 0 means success */; +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_update_jobschedule ( + par_job_id integer = NULL::integer, + par_job_name varchar = NULL::character varying, + par_name varchar = NULL::character varying, + par_new_name varchar = NULL::character varying, + par_enabled smallint = NULL::smallint, + par_freq_type integer = NULL::integer, + par_freq_interval integer = NULL::integer, + par_freq_subday_type integer = NULL::integer, + par_freq_subday_interval integer = NULL::integer, + par_freq_relative_interval integer = NULL::integer, + par_freq_recurrence_factor integer = NULL::integer, + par_active_start_date integer = NULL::integer, + par_active_end_date integer = NULL::integer, + par_active_start_time integer = NULL::integer, + par_active_end_time integer = NULL::integer, + par_automatic_post smallint = 1, + out returncode integer +) +RETURNS integer AS +$body$ +DECLARE + var_retval INT; + var_sched_count INT; + var_schedule_id INT; + var_job_owner_sid CHAR(85); + var_enable_only_used INT; + var_x_name VARCHAR(128); + var_x_enabled SMALLINT; + var_x_freq_type INT; + var_x_freq_interval INT; + var_x_freq_subday_type INT; + var_x_freq_subday_interval INT; + var_x_freq_relative_interval INT; + var_x_freq_recurrence_factor INT; + var_x_active_start_date INT; + var_x_active_end_date INT; + var_x_active_start_time INT; + var_x_active_end_time INT; + var_owner_sid CHAR(85); +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) + INTO par_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_new_name)) + INTO par_new_name + /* Turn [nullable] empty string parameters into NULLs */; + + IF (par_new_name = '') THEN + SELECT + NULL + INTO par_new_name; + END IF + /* Check that we can uniquely identify the job */; + SELECT + t.par_job_name, t.par_job_id, t.par_owner_sid, t.ReturnCode + FROM sys.babelfish_sp_verify_job_identifiers('@job_name', '@job_id', par_job_name, par_job_id, 'TEST', var_job_owner_sid) t + INTO par_job_name, par_job_id, var_job_owner_sid, var_retval; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF + /* Failure */ + /* Is @enable the only parameter used beside jobname and jobid? */; + + IF ((par_enabled IS NOT NULL) AND (par_name IS NULL) AND (par_new_name IS NULL) AND (par_freq_type IS NULL) AND (par_freq_interval IS NULL) AND (par_freq_subday_type IS NULL) AND (par_freq_subday_interval IS NULL) AND (par_freq_relative_interval IS NULL) AND (par_freq_recurrence_factor IS NULL) AND (par_active_start_date IS NULL) AND (par_active_end_date IS NULL) AND (par_active_start_time IS NULL) AND (par_active_end_time IS NULL)) THEN + SELECT + 1 + INTO var_enable_only_used; + ELSE + SELECT + 0 + INTO var_enable_only_used; + END IF; + + IF (par_new_name IS NULL) THEN + SELECT + var_x_name + INTO par_new_name; + END IF; + + IF (par_enabled IS NULL) THEN + SELECT + var_x_enabled + INTO par_enabled; + END IF; + + IF (par_freq_type IS NULL) THEN + SELECT + var_x_freq_type + INTO par_freq_type; + END IF; + + IF (par_freq_interval IS NULL) THEN + SELECT + var_x_freq_interval + INTO par_freq_interval; + END IF; + + IF (par_freq_subday_type IS NULL) THEN + SELECT + var_x_freq_subday_type + INTO par_freq_subday_type; + END IF; + + IF (par_freq_subday_interval IS NULL) THEN + SELECT + var_x_freq_subday_interval + INTO par_freq_subday_interval; + END IF; + + IF (par_freq_relative_interval IS NULL) THEN + SELECT + var_x_freq_relative_interval + INTO par_freq_relative_interval; + END IF; + + IF (par_freq_recurrence_factor IS NULL) THEN + SELECT + var_x_freq_recurrence_factor + INTO par_freq_recurrence_factor; + END IF; + + IF (par_active_start_date IS NULL) THEN + SELECT + var_x_active_start_date + INTO par_active_start_date; + END IF; + + IF (par_active_end_date IS NULL) THEN + SELECT + var_x_active_end_date + INTO par_active_end_date; + END IF; + + IF (par_active_start_time IS NULL) THEN + SELECT + var_x_active_start_time + INTO par_active_start_time; + END IF; + + IF (par_active_end_time IS NULL) THEN + SELECT + var_x_active_end_time + INTO par_active_end_time; + END IF + /* Check schedule (frequency and owner) parameters */; + SELECT + t.par_freq_interval, t.par_freq_subday_type, t.par_freq_subday_interval, t.par_freq_relative_interval, t.par_freq_recurrence_factor, t.par_active_start_date, t.par_active_start_time, + t.par_active_end_date, t.par_active_end_time, t.ReturnCode + FROM sys.babelfish_sp_verify_schedule(var_schedule_id + /* @schedule_id */, par_new_name + /* @name */, par_enabled + /* @enabled */, par_freq_type + /* @freq_type */, par_freq_interval + /* @freq_interval */, par_freq_subday_type + /* @freq_subday_type */, par_freq_subday_interval + /* @freq_subday_interval */, par_freq_relative_interval + /* @freq_relative_interval */, par_freq_recurrence_factor + /* @freq_recurrence_factor */, par_active_start_date + /* @active_start_date */, par_active_start_time + /* @active_start_time */, par_active_end_date + /* @active_end_date */, par_active_end_time + /* @active_end_time */, var_owner_sid) t + INTO par_freq_interval, par_freq_subday_type, par_freq_subday_interval, par_freq_relative_interval, par_freq_recurrence_factor, par_active_start_date, par_active_start_time, par_active_end_date, par_active_end_time, var_retval /* @owner_sid */; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF + /* Failure */ + /* Update the JobSchedule */; + UPDATE sys.sysschedules + SET name = par_new_name, enabled = par_enabled, freq_type = par_freq_type, freq_interval = par_freq_interval, freq_subday_type = par_freq_subday_type, freq_subday_interval = par_freq_subday_interval, freq_relative_interval = par_freq_relative_interval, freq_recurrence_factor = par_freq_recurrence_factor, active_start_date = par_active_start_date, active_end_date = par_active_end_date, active_start_time = par_active_start_time, active_end_time = par_active_end_time + /* date_modified = GETDATE(), */, version_number = version_number + 1 + WHERE (schedule_id = var_schedule_id); + SELECT + 0 + INTO var_retval + /* @@error */ + /* Update the job's version/last-modified information */; + UPDATE sys.sysjobs + SET version_number = version_number + 1 + /* date_modified = GETDATE() */ + WHERE (job_id = par_job_id); + ReturnCode := (var_retval); + RETURN + /* 0 means success */; +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_update_jobstep ( + par_job_id integer = NULL::integer, + par_job_name varchar = NULL::character varying, + par_step_id integer = NULL::integer, + par_step_name varchar = NULL::character varying, + par_subsystem varchar = NULL::character varying, + par_command text = NULL::text, + par_additional_parameters text = NULL::text, + par_cmdexec_success_code integer = NULL::integer, + par_on_success_action smallint = NULL::smallint, + par_on_success_step_id integer = NULL::integer, + par_on_fail_action smallint = NULL::smallint, + par_on_fail_step_id integer = NULL::integer, + par_server varchar = NULL::character varying, + par_database_name varchar = NULL::character varying, + par_database_user_name varchar = NULL::character varying, + par_retry_attempts integer = NULL::integer, + par_retry_interval integer = NULL::integer, + par_os_run_priority integer = NULL::integer, + par_output_file_name varchar = NULL::character varying, + par_flags integer = NULL::integer, + par_proxy_id integer = NULL::integer, + par_proxy_name varchar = NULL::character varying, + out returncode integer +) +RETURNS integer AS +$body$ +DECLARE + var_retval INT; + var_os_run_priority_code INT; + var_step_id_as_char VARCHAR(10); + var_new_step_name VARCHAR(128); + var_x_step_name VARCHAR(128); + var_x_subsystem VARCHAR(40); + var_x_command TEXT; + var_x_flags INT; + var_x_cmdexec_success_code INT; + var_x_on_success_action SMALLINT; + var_x_on_success_step_id INT; + var_x_on_fail_action SMALLINT; + var_x_on_fail_step_id INT; + var_x_server VARCHAR(128); + var_x_database_name VARCHAR(128); + var_x_database_user_name VARCHAR(128); + var_x_retry_attempts INT; + var_x_retry_interval INT; + var_x_os_run_priority INT; + var_x_output_file_name VARCHAR(200); + var_x_proxy_id INT; + var_x_last_run_outcome SMALLINT; + var_x_last_run_duration INT; + var_x_last_run_retries INT; + var_x_last_run_date INT; + var_x_last_run_time INT; + var_new_proxy_id INT; + var_subsystem_id INT; + var_auto_proxy_name VARCHAR(128); + var_job_owner_sid CHAR(85); + var_step_uid CHAR(85); +BEGIN + SELECT NULL INTO var_new_proxy_id; + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_step_name)) INTO par_step_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_subsystem)) INTO par_subsystem; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_command)) INTO par_command; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_server)) INTO par_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_database_name)) INTO par_database_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_database_user_name)) INTO par_database_user_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_output_file_name)) INTO par_output_file_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_proxy_name)) INTO par_proxy_name; + /* Make sure Dts is translated into new subsystem's name SSIS */ + /* IF (@subsystem IS NOT NULL AND UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'DTS') */ + /* BEGIN */ + /* SET @subsystem = N'SSIS' */ + /* END */ + SELECT + t.par_job_name, t.par_job_id, t.par_owner_sid, t.ReturnCode + FROM sys.babelfish_sp_verify_job_identifiers('@job_name' + /* @name_of_name_parameter */, '@job_id' + /* @name_of_id_parameter */, par_job_name + /* @job_name */, par_job_id + /* @job_id */, 'TEST' + /* @sqlagent_starting_test */, var_job_owner_sid) + INTO par_job_name, par_job_id, var_job_owner_sid, var_retval + /* @owner_sid */; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF; + /* Failure */ + /* Check that the step exists */ + + IF (NOT EXISTS (SELECT + * + FROM sys.sysjobsteps + WHERE (job_id = par_job_id) AND (step_id = par_step_id))) THEN + SELECT + CAST (par_step_id AS VARCHAR(10)) + INTO var_step_id_as_char; + RAISE 'Error %, severity %, state % was raised. Message: %. Argument: %. Argument: %', '50000', 0, 0, 'The specified %s ("%s") does not exist.', '@step_id', var_step_id_as_char USING ERRCODE := '50000'; + ReturnCode := (1); + RETURN; + /* Failure */ + END IF; + /* Set the x_ (existing) variables */ + SELECT + step_name, subsystem, command, flags, cmdexec_success_code, on_success_action, on_success_step_id, on_fail_action, on_fail_step_id, server, database_name, database_user_name, retry_attempts, retry_interval, os_run_priority, output_file_name, proxy_id, last_run_outcome, last_run_duration, last_run_retries, last_run_date, last_run_time + INTO var_x_step_name, var_x_subsystem, var_x_command, var_x_flags, var_x_cmdexec_success_code, var_x_on_success_action, var_x_on_success_step_id, var_x_on_fail_action, var_x_on_fail_step_id, var_x_server, var_x_database_name, var_x_database_user_name, var_x_retry_attempts, var_x_retry_interval, var_x_os_run_priority, var_x_output_file_name, var_x_proxy_id, var_x_last_run_outcome, var_x_last_run_duration, var_x_last_run_retries, var_x_last_run_date, var_x_last_run_time + FROM sys.sysjobsteps + WHERE (job_id = par_job_id) AND (step_id = par_step_id); + + IF ((par_step_name IS NOT NULL) AND (par_step_name <> var_x_step_name)) THEN + SELECT + par_step_name + INTO var_new_step_name; + END IF; + /* Fill out the values for all non-supplied parameters from the existing values */ + + IF (par_step_name IS NULL) THEN + SELECT var_x_step_name INTO par_step_name; + END IF; + + IF (par_subsystem IS NULL) THEN + SELECT var_x_subsystem INTO par_subsystem; + END IF; + + IF (par_command IS NULL) THEN + SELECT var_x_command INTO par_command; + END IF; + + IF (par_flags IS NULL) THEN + SELECT var_x_flags INTO par_flags; + END IF; + + IF (par_cmdexec_success_code IS NULL) THEN + SELECT var_x_cmdexec_success_code INTO par_cmdexec_success_code; + END IF; + + IF (par_on_success_action IS NULL) THEN + SELECT var_x_on_success_action INTO par_on_success_action; + END IF; + + IF (par_on_success_step_id IS NULL) THEN + SELECT var_x_on_success_step_id INTO par_on_success_step_id; + END IF; + + IF (par_on_fail_action IS NULL) THEN + SELECT var_x_on_fail_action INTO par_on_fail_action; + END IF; + + IF (par_on_fail_step_id IS NULL) THEN + SELECT var_x_on_fail_step_id INTO par_on_fail_step_id; + END IF; + + IF (par_server IS NULL) THEN + SELECT var_x_server INTO par_server; + END IF; + + IF (par_database_name IS NULL) THEN + SELECT var_x_database_name INTO par_database_name; + END IF; + + IF (par_database_user_name IS NULL) THEN + SELECT var_x_database_user_name INTO par_database_user_name; + END IF; + + IF (par_retry_attempts IS NULL) THEN + SELECT var_x_retry_attempts INTO par_retry_attempts; + END IF; + + IF (par_retry_interval IS NULL) THEN + SELECT var_x_retry_interval INTO par_retry_interval; + END IF; + + IF (par_os_run_priority IS NULL) THEN + SELECT var_x_os_run_priority INTO par_os_run_priority; + END IF; + + IF (par_output_file_name IS NULL) THEN + SELECT var_x_output_file_name INTO par_output_file_name; + END IF; + + IF (par_proxy_id IS NULL) THEN + SELECT var_x_proxy_id INTO var_new_proxy_id; + END IF; + /* if an empty proxy_name is supplied the proxy is removed */ + + IF par_proxy_name = '' THEN + SELECT NULL INTO var_new_proxy_id; + END IF; + /* Turn [nullable] empty string parameters into NULLs */ + + IF (LOWER(par_command) = LOWER('')) THEN + SELECT NULL INTO par_command; + END IF; + + IF (par_server = '') THEN + SELECT NULL INTO par_server; + END IF; + + IF (par_database_name = '') THEN + SELECT NULL INTO par_database_name; + END IF; + + IF (par_database_user_name = '') THEN + SELECT NULL INTO par_database_user_name; + END IF; + + IF (LOWER(par_output_file_name) = LOWER('')) THEN + SELECT NULL INTO par_output_file_name; + END IF + /* Check new values */; + SELECT + t.par_database_name, t.par_database_user_name, t.ReturnCode + FROM sys.babelfish_sp_verify_jobstep(par_job_id, par_step_id, var_new_step_name, par_subsystem, par_command, par_server, par_on_success_action, par_on_success_step_id, par_on_fail_action, par_on_fail_step_id, par_os_run_priority, par_database_name, par_database_user_name, par_flags, par_output_file_name, var_new_proxy_id) t + INTO par_database_name, par_database_user_name, var_retval; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF + /* Failure */ + /* Update the job's version/last-modified information */; + UPDATE sys.sysjobs + SET version_number = version_number + 1 + /* date_modified = GETDATE() */ + WHERE (job_id = par_job_id) + /* Update the step */; + UPDATE sys.sysjobsteps + SET step_name = par_step_name, subsystem = par_subsystem, command = par_command, flags = par_flags, additional_parameters = par_additional_parameters, cmdexec_success_code = par_cmdexec_success_code, on_success_action = par_on_success_action, on_success_step_id = par_on_success_step_id, on_fail_action = par_on_fail_action, on_fail_step_id = par_on_fail_step_id, server = par_server, database_name = par_database_name, database_user_name = par_database_user_name, retry_attempts = par_retry_attempts, retry_interval = par_retry_interval, os_run_priority = par_os_run_priority, output_file_name = par_output_file_name, last_run_outcome = var_x_last_run_outcome, last_run_duration = var_x_last_run_duration, last_run_retries = var_x_last_run_retries, last_run_date = var_x_last_run_date, last_run_time = var_x_last_run_time, proxy_id = var_new_proxy_id + WHERE (job_id = par_job_id) AND (step_id = par_step_id); + + SELECT step_uid + FROM sys.sysjobsteps + WHERE job_id = par_job_id AND step_id = par_step_id + INTO var_step_uid; + + -- PERFORM sys.sp_jobstep_create_proc (var_step_uid); + + ReturnCode := (0); + RETURN + /* Success */; +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_update_schedule ( + par_schedule_id integer = NULL::integer, + par_name varchar = NULL::character varying, + par_new_name varchar = NULL::character varying, + par_enabled smallint = NULL::smallint, + par_freq_type integer = NULL::integer, + par_freq_interval integer = NULL::integer, + par_freq_subday_type integer = NULL::integer, + par_freq_subday_interval integer = NULL::integer, + par_freq_relative_interval integer = NULL::integer, + par_freq_recurrence_factor integer = NULL::integer, + par_active_start_date integer = NULL::integer, + par_active_end_date integer = NULL::integer, + par_active_start_time integer = NULL::integer, + par_active_end_time integer = NULL::integer, + par_owner_login_name varchar = NULL::character varying, + par_automatic_post smallint = 1, + out returncode integer +) +RETURNS integer AS +$body$ +DECLARE + var_retval INT; + var_owner_sid CHAR(85); + var_cur_owner_sid CHAR(85); + var_x_name VARCHAR(128); + var_enable_only_used INT; + var_x_enabled SMALLINT; + var_x_freq_type INT; + var_x_freq_interval INT; + var_x_freq_subday_type INT; + var_x_freq_subday_interval INT; + var_x_freq_relative_interval INT; + var_x_freq_recurrence_factor INT; + var_x_active_start_date INT; + var_x_active_end_date INT; + var_x_active_start_time INT; + var_x_active_end_time INT; + var_schedule_uid CHAR(38); +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) + INTO par_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_new_name)) + INTO par_new_name; + SELECT + PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_owner_login_name)) + INTO par_owner_login_name + /* Turn [nullable] empty string parameters into NULLs */; + + IF (par_new_name = '') THEN + SELECT + NULL + INTO par_new_name; + END IF + /* Check that we can uniquely identify the schedule. This only returns a schedule that is visible to this user */; + SELECT + t.par_schedule_name, t.par_schedule_id, t.par_owner_sid, t.par_orig_server_id, t.ReturnCode + FROM sys.babelfish_sp_verify_schedule_identifiers('@name' + /* @name_of_name_parameter */, '@schedule_id' + /* @name_of_id_parameter */, par_name + /* @schedule_name */, par_schedule_id + /* @schedule_id */, var_cur_owner_sid + /* @owner_sid */, NULL + /* @orig_server_id */, NULL) t + INTO par_name, par_schedule_id, var_cur_owner_sid, var_retval + /* @job_id_filter */; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF + /* Failure */ + /* Is @enable the only parameter used beside jobname and jobid? */; + + IF ((par_enabled IS NOT NULL) AND (par_new_name IS NULL) AND (par_freq_type IS NULL) AND (par_freq_interval IS NULL) AND (par_freq_subday_type IS NULL) AND (par_freq_subday_interval IS NULL) AND (par_freq_relative_interval IS NULL) AND (par_freq_recurrence_factor IS NULL) AND (par_active_start_date IS NULL) AND (par_active_end_date IS NULL) AND (par_active_start_time IS NULL) AND (par_active_end_time IS NULL) AND (par_owner_login_name IS NULL)) THEN + SELECT + 1 + INTO var_enable_only_used; + ELSE + SELECT + 0 + INTO var_enable_only_used; + END IF + /* If the param @owner_login_name is null or doesn't get resolved by SUSER_SID() set it to the current owner of the schedule */; + + IF (var_owner_sid IS NULL) THEN + SELECT + var_cur_owner_sid + INTO var_owner_sid; + END IF + /* Set the x_ (existing) variables */; + SELECT + name, enabled, freq_type, freq_interval, freq_subday_type, freq_subday_interval, freq_relative_interval, freq_recurrence_factor, active_start_date, active_end_date, active_start_time, active_end_time + INTO var_x_name, var_x_enabled, var_x_freq_type, var_x_freq_interval, var_x_freq_subday_type, var_x_freq_subday_interval, var_x_freq_relative_interval, var_x_freq_recurrence_factor, var_x_active_start_date, var_x_active_end_date, var_x_active_start_time, var_x_active_end_time + FROM sys.sysschedules + WHERE (schedule_id = par_schedule_id) + /* Fill out the values for all non-supplied parameters from the existing values */; + + IF (par_new_name IS NULL) THEN + SELECT + var_x_name + INTO par_new_name; + END IF; + + IF (par_enabled IS NULL) THEN + SELECT + var_x_enabled + INTO par_enabled; + END IF; + + IF (par_freq_type IS NULL) THEN + SELECT + var_x_freq_type + INTO par_freq_type; + END IF; + + IF (par_freq_interval IS NULL) THEN + SELECT + var_x_freq_interval + INTO par_freq_interval; + END IF; + + IF (par_freq_subday_type IS NULL) THEN + SELECT + var_x_freq_subday_type + INTO par_freq_subday_type; + END IF; + + IF (par_freq_subday_interval IS NULL) THEN + SELECT + var_x_freq_subday_interval + INTO par_freq_subday_interval; + END IF; + + IF (par_freq_relative_interval IS NULL) THEN + SELECT + var_x_freq_relative_interval + INTO par_freq_relative_interval; + END IF; + + IF (par_freq_recurrence_factor IS NULL) THEN + SELECT + var_x_freq_recurrence_factor + INTO par_freq_recurrence_factor; + END IF; + + IF (par_active_start_date IS NULL) THEN + SELECT + var_x_active_start_date + INTO par_active_start_date; + END IF; + + IF (par_active_end_date IS NULL) THEN + SELECT + var_x_active_end_date + INTO par_active_end_date; + END IF; + + IF (par_active_start_time IS NULL) THEN + SELECT + var_x_active_start_time + INTO par_active_start_time; + END IF; + + IF (par_active_end_time IS NULL) THEN + SELECT + var_x_active_end_time + INTO par_active_end_time; + END IF + /* Check schedule (frequency and owner) parameters */; + SELECT + t.par_freq_interval, t.par_freq_subday_type, t.par_freq_subday_interval, t.par_freq_relative_interval, t.par_freq_recurrence_factor, t.par_active_start_date, + t.par_active_start_time, t.par_active_end_date, t.par_active_end_time, t.ReturnCode + FROM sys.babelfish_sp_verify_schedule(par_schedule_id + /* @schedule_id */, par_new_name + /* @name */, par_enabled + /* @enabled */, par_freq_type + /* @freq_type */, par_freq_interval + /* @freq_interval */, par_freq_subday_type + /* @freq_subday_type */, par_freq_subday_interval + /* @freq_subday_interval */, par_freq_relative_interval + /* @freq_relative_interval */, par_freq_recurrence_factor + /* @freq_recurrence_factor */, par_active_start_date + /* @active_start_date */, par_active_start_time + /* @active_start_time */, par_active_end_date + /* @active_end_date */, par_active_end_time + /* @active_end_time */, var_owner_sid) t + INTO par_freq_interval, par_freq_subday_type, par_freq_subday_interval, par_freq_relative_interval, par_freq_recurrence_factor, par_active_start_date, par_active_start_time, par_active_end_date, par_active_end_time, var_retval /* @owner_sid */; + + IF (var_retval <> 0) THEN + ReturnCode := (1); + RETURN; + END IF + /* Failure */ + /* Update the sysschedules table */; + UPDATE sys.sysschedules + SET name = par_new_name, owner_sid = var_owner_sid, enabled = par_enabled, freq_type = par_freq_type, freq_interval = par_freq_interval, freq_subday_type = par_freq_subday_type, freq_subday_interval = par_freq_subday_interval, freq_relative_interval = par_freq_relative_interval, freq_recurrence_factor = par_freq_recurrence_factor, active_start_date = par_active_start_date, active_end_date = par_active_end_date, active_start_time = par_active_start_time, active_end_time = par_active_end_time + /* date_modified = GETDATE(), */, version_number = version_number + 1 + WHERE (schedule_id = par_schedule_id); + SELECT + 0 + INTO var_retval; + + ReturnCode := (var_retval); + RETURN + /* 0 means success */; +END; +$body$ +LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_job ( + par_job_id integer, + par_name varchar, + par_enabled smallint, + par_start_step_id integer, + par_category_name varchar, + inout par_owner_sid char, + par_notify_level_eventlog integer, + inout par_notify_level_email integer, + inout par_notify_level_netsend integer, + inout par_notify_level_page integer, + par_notify_email_operator_name varchar, + par_notify_netsend_operator_name varchar, + par_notify_page_operator_name varchar, + par_delete_level integer, + inout par_category_id integer, + inout par_notify_email_operator_id integer, + inout par_notify_netsend_operator_id integer, + inout par_notify_page_operator_id integer, + inout par_originating_server varchar, + out returncode integer +) +RETURNS record AS +$body$ +DECLARE + var_job_type INT; + var_retval INT; + var_current_date INT; + var_res_valid_range VARCHAR(200); + var_max_step_id INT; + var_valid_range VARCHAR(50); +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_category_name)) INTO par_category_name; + SELECT UPPER(PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_originating_server))) INTO par_originating_server; + + IF ( + EXISTS ( + SELECT * + FROM sys.sysjobs AS job + WHERE (name = par_name) + /* AND (job_id <> ISNULL(@job_id, 0x911)))) -- When adding a new job @job_id is NULL */ + ) + ) + THEN /* Failure */ + RAISE 'The specified % ("%") already exists.', 'par_name', par_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check enabled state */ + IF (par_enabled <> 0) AND (par_enabled <> 1) THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'par_enabled', '0, 1' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check start step */ + + IF (par_job_id IS NULL) THEN /* New job */ + IF (par_start_step_id <> 1) THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'par_start_step_id', '1' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + ELSE /* Existing job */ + /* Get current maximum step id */ + SELECT COALESCE(MAX(step_id), 0) + INTO var_max_step_id + FROM sys.sysjobsteps + WHERE (job_id = par_job_id); + + IF (par_start_step_id < 1) OR (par_start_step_id > var_max_step_id + 1) THEN /* Failure */ + SELECT '1..' || CAST (var_max_step_id + 1 AS VARCHAR(1)) + INTO var_valid_range; + RAISE 'The specified "%" is invalid (valid values are: %).', 'par_start_step_id', var_valid_range USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + /* Get the category_id, handling any special-cases as appropriate */ + SELECT NULL INTO par_category_id; + + IF (par_category_name = '[DEFAULT]') /* User wants to revert to the default job category */ + THEN + SELECT + CASE COALESCE(var_job_type, 1) + WHEN 1 THEN 0 /* [Uncategorized (Local)] */ + WHEN 2 THEN 2 /* [Uncategorized (Multi-Server)] */ + END + INTO par_category_id; + ELSE + SELECT 0 INTO par_category_id; + END IF; + + returncode := (0); /* Success */ + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_job_date ( + par_date integer, + par_date_name varchar = 'date'::character varying, + out returncode integer +) +RETURNS integer AS +$body$ +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_date_name)) INTO par_date_name; + + /* Success */ + returncode := 0; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_job_identifiers ( + par_name_of_name_parameter varchar, + par_name_of_id_parameter varchar, + inout par_job_name varchar, + inout par_job_id integer, + par_sqlagent_starting_test varchar = 'TEST'::character varying, + inout par_owner_sid char = NULL::bpchar, + out returncode integer +) +RETURNS record AS +$body$ +DECLARE + var_retval INT; + var_job_id_as_char VARCHAR(36); +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_name_parameter)) INTO par_name_of_name_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_id_parameter)) INTO par_name_of_id_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_job_name)) INTO par_job_name; + + IF (par_job_name = '') + THEN + SELECT NULL INTO par_job_name; + END IF; + + IF ((par_job_name IS NULL) AND (par_job_id IS NULL)) OR ((par_job_name IS NOT NULL) AND (par_job_id IS NOT NULL)) + THEN /* Failure */ + RAISE 'Supply either % or % to identify the job.', par_name_of_id_parameter, par_name_of_name_parameter USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check job id */ + IF (par_job_id IS NOT NULL) + THEN + SELECT name + , owner_sid + INTO par_job_name + , par_owner_sid + FROM sys.sysjobs + WHERE (job_id = par_job_id); + + /* the view would take care of all the permissions issues. */ + IF (par_job_name IS NULL) + THEN /* Failure */ + SELECT CAST (par_job_id AS VARCHAR(36)) + INTO var_job_id_as_char; + + RAISE 'The specified % ("%") does not exist.', 'job_id', var_job_id_as_char USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + ELSE + /* Check job name */ + IF (par_job_name IS NOT NULL) + THEN + /* Check if the job name is ambiguous */ + IF (SELECT COUNT(*) FROM sys.sysjobs WHERE name = par_job_name) > 1 + THEN /* Failure */ + RAISE 'There are two or more jobs named "%". Specify % instead of % to uniquely identify the job.', par_job_name, par_name_of_id_parameter, par_name_of_name_parameter USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* The name is not ambiguous, so get the corresponding job_id (if the job exists) */ + SELECT job_id + , owner_sid + INTO par_job_id + , par_owner_sid + FROM sys.sysjobs + WHERE (name = par_job_name); + + /* the view would take care of all the permissions issues. */ + IF (par_job_id IS NULL) + THEN /* Failure */ + RAISE 'The specified % ("%") does not exist.', 'job_name', par_job_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + END IF; + + /* Success */ + returncode := 0; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_job_time ( + par_time integer, + par_time_name varchar = 'time'::character varying, + out returncode integer +) +RETURNS integer AS +$body$ +DECLARE + var_hour INT; + var_minute INT; + var_second INT; +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_time_name)) INTO par_time_name; + + IF ((par_time < 0) OR (par_time > 235959)) + THEN + RAISE 'The specified "%" is invalid (valid values are: %).', par_time_name, '000000..235959' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + SELECT (par_time / 10000) INTO var_hour; + SELECT (par_time % 10000) / 100 INTO var_minute; + SELECT (par_time % 100) INTO var_second; + + /* Check hour range */ + IF (var_hour > 23) THEN + RAISE 'The "%" supplied has an invalid %.', par_time_name, 'hour' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check minute range */ + IF (var_minute > 59) THEN + RAISE 'The "%" supplied has an invalid %.', par_time_name, 'minute' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check second range */ + IF (var_second > 59) THEN + RAISE 'The "%" supplied has an invalid %.', par_time_name, 'second' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + returncode := 0; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_jobstep ( + par_job_id integer, + par_step_id integer, + par_step_name varchar, + par_subsystem varchar, + par_command text, + par_server varchar, + par_on_success_action smallint, + par_on_success_step_id integer, + par_on_fail_action smallint, + par_on_fail_step_id integer, + par_os_run_priority integer, + par_flags integer, + par_output_file_name varchar, + par_proxy_id integer, + out returncode integer +) +AS +$body$ +DECLARE + var_max_step_id INT; + var_retval INT; + var_valid_values VARCHAR(50); + var_database_name_temp VARCHAR(258); + var_database_user_name_temp VARCHAR(256); + var_temp_command TEXT; + var_iPos INT; + var_create_count INT; + var_destroy_count INT; + var_is_olap_subsystem SMALLINT; + var_owner_sid CHAR(85); + var_owner_name VARCHAR(128); +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_subsystem)) INTO par_subsystem; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_server)) INTO par_server; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_output_file_name)) INTO par_output_file_name; + + /* Get current maximum step id */ + SELECT COALESCE(MAX(step_id), 0) + INTO var_max_step_id + FROM sys.sysjobsteps + WHERE (job_id = par_job_id); + + /* Check step id */ + IF (par_step_id < 1) OR (par_step_id > var_max_step_id + 1) /* Failure */ + THEN + SELECT '1..' || CAST (var_max_step_id + 1 AS VARCHAR(1)) INTO var_valid_values; + RAISE 'The specified "%" is invalid (valid values are: %).', '@step_id', var_valid_values USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check step name */ + IF ( + EXISTS ( + SELECT * + FROM sys.sysjobsteps + WHERE (job_id = par_job_id) AND (step_name = par_step_name) + ) + ) + THEN /* Failure */ + RAISE 'The specified % ("%") already exists.', 'step_name', par_step_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check on-success action/step */ + IF (par_on_success_action <> 1) /* Quit Qith Success */ + AND (par_on_success_action <> 2) /* Quit Qith Failure */ + AND (par_on_success_action <> 3) /* Goto Next Step */ + AND (par_on_success_action <> 4) /* Goto Step */ + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'on_success_action', '1, 2, 3, 4' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF (par_on_success_action = 4) AND ((par_on_success_step_id < 1) OR (par_on_success_step_id = par_step_id)) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are greater than 0 but excluding %ld).', 'on_success_step', par_step_id USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check on-fail action/step */ + IF (par_on_fail_action <> 1) /* Quit With Success */ + AND (par_on_fail_action <> 2) /* Quit With Failure */ + AND (par_on_fail_action <> 3) /* Goto Next Step */ + AND (par_on_fail_action <> 4) /* Goto Step */ + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'on_failure_action', '1, 2, 3, 4' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF (par_on_fail_action = 4) AND ((par_on_fail_step_id < 1) OR (par_on_fail_step_id = par_step_id)) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are greater than 0 but excluding %).', 'on_failure_step', par_step_id USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Warn the user about forward references */ + IF ((par_on_success_action = 4) AND (par_on_success_step_id > var_max_step_id)) + THEN + RAISE 'Warning: Non-existent step referenced by %.', 'on_success_step_id' USING ERRCODE := '50000'; + END IF; + + IF ((par_on_fail_action = 4) AND (par_on_fail_step_id > var_max_step_id)) + THEN + RAISE 'Warning: Non-existent step referenced by %.', '@on_fail_step_id' USING ERRCODE := '50000'; + END IF; + + /* Check run priority: must be a valid value to pass to SetThreadPriority: */ + /* [-15 = IDLE, -1 = BELOW_NORMAL, 0 = NORMAL, 1 = ABOVE_NORMAL, 15 = TIME_CRITICAL] */ + IF (par_os_run_priority NOT IN (- 15, - 1, 0, 1, 15)) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', '@os_run_priority', '-15, -1, 0, 1, 15' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check flags */ + IF ((par_flags < 0) OR (par_flags > 114)) THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', '@flags', '0..114' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF (LOWER(UPPER(par_subsystem)) <> LOWER('TSQL')) THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', '@subsystem', 'TSQL' USING ERRCODE := '50000'; + returncode := (1); + RETURN; + END IF; + + /* Success */ + returncode := 0; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_schedule ( + par_schedule_id integer, + par_name varchar, + par_enabled smallint, + par_freq_type integer, + inout par_freq_interval integer, + inout par_freq_subday_type integer, + inout par_freq_subday_interval integer, + inout par_freq_relative_interval integer, + inout par_freq_recurrence_factor integer, + inout par_active_start_date integer, + inout par_active_start_time integer, + inout par_active_end_date integer, + inout par_active_end_time integer, + par_owner_sid char, + out returncode integer +) +RETURNS record AS +$body$ +DECLARE + var_return_code INT; + var_isAdmin INT; +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name)) INTO par_name; + + /* Make sure that NULL input/output parameters - if NULL - are initialized to 0 */ + SELECT COALESCE(par_freq_interval, 0) INTO par_freq_interval; + SELECT COALESCE(par_freq_subday_type, 0) INTO par_freq_subday_type; + SELECT COALESCE(par_freq_subday_interval, 0) INTO par_freq_subday_interval; + SELECT COALESCE(par_freq_relative_interval, 0) INTO par_freq_relative_interval; + SELECT COALESCE(par_freq_recurrence_factor, 0) INTO par_freq_recurrence_factor; + SELECT COALESCE(par_active_start_date, 0) INTO par_active_start_date; + SELECT COALESCE(par_active_start_time, 0) INTO par_active_start_time; + SELECT COALESCE(par_active_end_date, 0) INTO par_active_end_date; + SELECT COALESCE(par_active_end_time, 0) INTO par_active_end_time; + + /* Verify name (we disallow schedules called 'ALL' since this has special meaning in sp_delete_jobschedules) */ + SELECT 0 INTO var_isAdmin; + + IF ( + EXISTS ( + SELECT * + FROM sys.sysschedules + WHERE (name = par_name) + ) + ) + THEN /* Failure */ + RAISE 'The specified % ("%") already exists.', 'par_name', par_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF (UPPER(par_name) = 'ALL') + THEN /* Failure */ + RAISE 'The specified "%" is invalid.', 'name' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Verify enabled state */ + IF (par_enabled <> 0) AND (par_enabled <> 1) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', '@enabled', '0, 1' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Verify frequency type */ + IF (par_freq_type = 2) /* OnDemand is no longer supported */ + THEN /* Failure */ + RAISE 'Frequency Type 0x2 (OnDemand) is no longer supported.' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF (par_freq_type NOT IN (1, 4, 8, 16, 32, 64, 128)) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'freq_type', '1, 4, 8, 16, 32, 64, 128' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Verify frequency sub-day type */ + IF (par_freq_subday_type <> 0) AND (par_freq_subday_type NOT IN (1, 2, 4, 8)) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'freq_subday_type', '1, 2, 4, 8' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Default active start/end date/times (if not supplied, or supplied as NULLs or 0) */ + IF (par_active_start_date = 0) + THEN + SELECT date_part('year', NOW()::TIMESTAMP) * 10000 + date_part('month', NOW()::TIMESTAMP) * 100 + date_part('day', NOW()::TIMESTAMP) + INTO par_active_start_date; + END IF; + + /* This is an ISO format: "yyyymmdd" */ + IF (par_active_end_date = 0) + THEN + /* December 31st 9999 */ + SELECT 99991231 INTO par_active_end_date; + END IF; + + IF (par_active_start_time = 0) + THEN + /* 12:00:00 am */ + SELECT 000000 INTO par_active_start_time; + END IF; + + IF (par_active_end_time = 0) + THEN + /* 11:59:59 pm */ + SELECT 235959 INTO par_active_end_time; + END IF; + + /* Verify active start/end dates */ + IF (par_active_end_date = 0) + THEN + SELECT 99991231 INTO par_active_end_date; + END IF; + + SELECT t.returncode + FROM sys.babelfish_sp_verify_job_date(par_active_end_date, 'active_end_date') t + INTO var_return_code; + + IF (var_return_code <> 0) + THEN /* Failure */ + returncode := 1; + RETURN; + END IF; + + SELECT t.returncode + FROM sys.babelfish_sp_verify_job_date(par_active_start_date, '@active_start_date') t + INTO var_return_code; + + IF (var_return_code <> 0) + THEN /* Failure */ + returncode := 1; + RETURN; + END IF; + + IF (par_active_end_date < par_active_start_date) + THEN /* Failure */ + RAISE '% cannot be before %.', 'active_end_date', 'active_start_date' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + SELECT t.returncode + FROM sys.babelfish_sp_verify_job_time(par_active_end_time, '@active_end_time') t + INTO var_return_code; + + IF (var_return_code <> 0) + THEN /* Failure */ + returncode := 1; + RETURN; + END IF; + + SELECT t.returncode + FROM sys.babelfish_sp_verify_job_time(par_active_start_time, '@active_start_time') t + INTO var_return_code; + + IF (var_return_code <> 0) + THEN /* Failure */ + returncode := 1; + RETURN; + END IF; + + IF (par_active_start_time = par_active_end_time AND (par_freq_subday_type IN (2, 4, 8))) + THEN /* Failure */ + RAISE 'The specified "%" is invalid (valid values are: %).', 'active_end_time', 'before or after active_start_time' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF ((par_freq_type = 1) /* FREQTYPE_ONETIME */ + OR (par_freq_type = 64) /* FREQTYPE_AUTOSTART */ + OR (par_freq_type = 128)) /* FREQTYPE_ONIDLE */ + THEN /* Set standard defaults for non-required parameters */ + SELECT 0 INTO par_freq_interval; + SELECT 0 INTO par_freq_subday_type; + SELECT 0 INTO par_freq_subday_interval; + SELECT 0 INTO par_freq_relative_interval; + SELECT 0 INTO par_freq_recurrence_factor; + /* Success */ + returncode := 0; + RETURN; + END IF; + + IF (par_freq_subday_type = 0) /* FREQSUBTYPE_ONCE */ + THEN + SELECT 1 INTO par_freq_subday_type; + END IF; + + IF ((par_freq_subday_type <> 1) /* FREQSUBTYPE_ONCE */ + AND (par_freq_subday_type <> 2) /* FREQSUBTYPE_SECOND */ + AND (par_freq_subday_type <> 4) /* FREQSUBTYPE_MINUTE */ + AND (par_freq_subday_type <> 8)) /* FREQSUBTYPE_HOUR */ + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: The specified @freq_subday_type is invalid (valid values are: 0x1, 0x2, 0x4, 0x8).).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF ((par_freq_subday_type <> 1) AND (par_freq_subday_interval < 1)) /* FREQSUBTYPE_ONCE and less than 1 interval */ + OR ((par_freq_subday_type = 2) AND (par_freq_subday_interval < 10)) /* FREQSUBTYPE_SECOND and less than 10 seconds (see MIN_SCHEDULE_GRANULARITY in SqlAgent source code) */ + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: The specified @freq_subday_interval is invalid).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + IF (par_freq_type = 4) /* FREQTYPE_DAILY */ + THEN + SELECT 0 INTO par_freq_recurrence_factor; + + IF (par_freq_interval < 1) THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: @freq_interval must be at least 1 for a daily job.).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + IF (par_freq_type = 8) /* FREQTYPE_WEEKLY */ + THEN + IF (par_freq_interval < 1) OR (par_freq_interval > 127) /* (2^7)-1 [freq_interval is a bitmap (Sun=1..Sat=64)] */ + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: @freq_interval must be a valid day of the week bitmask [Sunday = 1 .. Saturday = 64] for a weekly job.).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + IF (par_freq_type = 16) /* FREQTYPE_MONTHLY */ + THEN + IF (par_freq_interval < 1) OR (par_freq_interval > 31) + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: @freq_interval must be between 1 and 31 for a monthly job.).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + IF (par_freq_type = 32) /* FREQTYPE_MONTHLYRELATIVE */ + THEN + IF (par_freq_relative_interval <> 1) /* RELINT_1ST */ + AND (par_freq_relative_interval <> 2) /* RELINT_2ND */ + AND (par_freq_relative_interval <> 4) /* RELINT_3RD */ + AND (par_freq_relative_interval <> 8) /* RELINT_4TH */ + AND (par_freq_relative_interval <> 16) /* RELINT_LAST */ + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: @freq_relative_interval must be one of 1st (0x1), 2nd (0x2), 3rd [0x4], 4th (0x8) or Last (0x10).).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + IF (par_freq_type = 32) /* FREQTYPE_MONTHLYRELATIVE */ + THEN + IF (par_freq_interval <> 1) /* RELATIVE_SUN */ + AND (par_freq_interval <> 2) /* RELATIVE_MON */ + AND (par_freq_interval <> 3) /* RELATIVE_TUE */ + AND (par_freq_interval <> 4) /* RELATIVE_WED */ + AND (par_freq_interval <> 5) /* RELATIVE_THU */ + AND (par_freq_interval <> 6) /* RELATIVE_FRI */ + AND (par_freq_interval <> 7) /* RELATIVE_SAT */ + AND (par_freq_interval <> 8) /* RELATIVE_DAY */ + AND (par_freq_interval <> 9) /* RELATIVE_WEEKDAY */ + AND (par_freq_interval <> 10) /* RELATIVE_WEEKENDDAY */ + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: @freq_interval must be between 1 and 10 (1 = Sunday .. 7 = Saturday, 8 = Day, 9 = Weekday, 10 = Weekend-day) for a monthly-relative job.).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + + IF ((par_freq_type = 8) /* FREQTYPE_WEEKLY */ + OR (par_freq_type = 16) /* FREQTYPE_MONTHLY */ + OR (par_freq_type = 32)) /* FREQTYPE_MONTHLYRELATIVE */ + AND (par_freq_recurrence_factor < 1) + THEN /* Failure */ + RAISE 'The schedule for this job is invalid (reason: @freq_recurrence_factor must be at least 1.).' USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + /* Success */ + returncode := 0; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION sys.babelfish_sp_verify_schedule_identifiers ( + par_name_of_name_parameter varchar, + par_name_of_id_parameter varchar, + inout par_schedule_name varchar, + inout par_schedule_id integer, + inout par_owner_sid char, + inout par_orig_server_id integer, + par_job_id_filter integer = NULL::integer, + out returncode integer +) +AS +$body$ +DECLARE + var_retval INT; + var_schedule_id_as_char VARCHAR(36); + var_sch_name_count INT; +BEGIN + /* Remove any leading/trailing spaces from parameters */ + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_name_parameter)) INTO par_name_of_name_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_name_of_id_parameter)) INTO par_name_of_id_parameter; + SELECT PG_CATALOG.LTRIM(PG_CATALOG.RTRIM(par_schedule_name)) INTO par_schedule_name; + SELECT 0 INTO var_sch_name_count; + + IF (par_schedule_name = '') + THEN + SELECT NULL INTO par_schedule_name; + END IF; + + IF ((par_schedule_name IS NULL) AND (par_schedule_id IS NULL)) OR ((par_schedule_name IS NOT NULL) AND (par_schedule_id IS NOT NULL)) + THEN /* Failure */ + RAISE 'Supply either % or % to identify the schedule.', par_name_of_id_parameter, par_name_of_name_parameter USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* Check schedule id */ + IF (par_schedule_id IS NOT NULL) + THEN + /* Look at all schedules */ + SELECT name + , owner_sid + , originating_server_id + INTO par_schedule_name + , par_owner_sid + , par_orig_server_id + FROM sys.sysschedules + WHERE (schedule_id = par_schedule_id); + + IF (par_schedule_name IS NULL) + THEN /* Failure */ + SELECT CAST (par_schedule_id AS VARCHAR(36)) + INTO var_schedule_id_as_char; + + RAISE 'The specified % ("%") does not exist.', 'schedule_id', var_schedule_id_as_char USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + ELSE + IF (par_schedule_name IS NOT NULL) + THEN + /* Check if the schedule name is ambiguous */ + IF (SELECT COUNT(*) FROM sys.sysschedules WHERE name = par_schedule_name) > 1 + THEN /* Failure */ + RAISE 'There are two or more sysschedules named "%". Specify % instead of % to uniquely identify the sysschedules.', par_job_name, par_name_of_id_parameter, par_name_of_name_parameter USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + + /* The name is not ambiguous, so get the corresponding job_id (if the job exists) */ + SELECT schedule_id + , owner_sid + INTO par_schedule_id, par_owner_sid + FROM sys.sysschedules + WHERE (name = par_schedule_name); + + /* the view would take care of all the permissions issues. */ + IF (par_schedule_id IS NULL) + THEN /* Failure */ + RAISE 'The specified % ("%") does not exist.', 'par_schedule_name', par_schedule_name USING ERRCODE := '50000'; + returncode := 1; + RETURN; + END IF; + END IF; + END IF; + + /* Success */ + returncode := 0; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' +STABLE; + +CREATE OR REPLACE FUNCTION babelfish_get_name_delimiter_pos(name TEXT) +RETURNS INTEGER +AS $$ +DECLARE + pos int; +BEGIN + IF (length(name) <= 2 AND (position('"' IN name) != 0 OR position(']' IN name) != 0 OR position('[' IN name) != 0)) + -- invalid name + THEN RETURN 0; + ELSIF PG_CATALOG.left(name, 1) = '[' THEN + pos = position('].' IN name); + IF pos = 0 THEN + -- invalid name + RETURN 0; + ELSE + RETURN pos + 1; + END IF; + ELSIF PG_CATALOG.left(name, 1) = '"' THEN + -- search from position 1 in case name starts with a double quote. + pos = position('".' IN PG_CATALOG.right(name, length(name) - 1)); + IF pos = 0 THEN + -- invalid name + RETURN 0; + ELSE + RETURN pos + 2; + END IF; + ELSE + RETURN position('.' IN name); + END IF; +END; +$$ +LANGUAGE plpgsql +STABLE; + +-- valid names are db_name.schema_name.object_name or schema_name.object_name or object_name +CREATE OR REPLACE FUNCTION sys.babelfish_split_object_name( + name TEXT, + OUT db_name TEXT, + OUT schema_name TEXT, + OUT object_name TEXT) +AS $$ +DECLARE + lower_object_name text; + names text[2]; + counter int; + cur_pos int; +BEGIN + lower_object_name = lower(PG_CATALOG.rtrim(name)); + + counter = 1; + cur_pos = babelfish_get_name_delimiter_pos(lower_object_name); + + -- Parse user input into names split by '.' + WHILE cur_pos > 0 LOOP + IF counter > 3 THEN + -- Too many names provided + RETURN; + END IF; + + names[counter] = babelfish_remove_delimiter_pair(PG_CATALOG.rtrim(PG_CATALOG.left(lower_object_name, cur_pos - 1))); + + -- invalid name + IF names[counter] IS NULL THEN + RETURN; + END IF; + + lower_object_name = substring(lower_object_name from cur_pos + 1); + counter = counter + 1; + cur_pos = babelfish_get_name_delimiter_pos(lower_object_name); + END LOOP; + + CASE counter + WHEN 1 THEN + db_name = NULL; + schema_name = NULL; + WHEN 2 THEN + db_name = NULL; + schema_name = sys.babelfish_truncate_identifier(names[1]); + WHEN 3 THEN + db_name = sys.babelfish_truncate_identifier(names[1]); + schema_name = sys.babelfish_truncate_identifier(names[2]); + ELSE + RETURN; + END CASE; + + -- Assign each name accordingly + object_name = sys.babelfish_truncate_identifier(babelfish_remove_delimiter_pair(PG_CATALOG.rtrim(lower_object_name))); +END; +$$ +LANGUAGE plpgsql +STABLE; + +CREATE OR REPLACE FUNCTION sys.timezone(IN tzzone PG_CATALOG.TEXT , IN input_expr anyelement) +RETURNS sys.datetimeoffset +AS +$BODY$ +DECLARE + tz_offset PG_CATALOG.TEXT; + tz_name PG_CATALOG.TEXT; + lower_tzn PG_CATALOG.TEXT; + prev_res PG_CATALOG.TEXT; + result PG_CATALOG.TEXT; + is_dstt bool; + tz_diff PG_CATALOG.TEXT; + input_expr_tx PG_CATALOG.TEXT; + input_expr_tmz TIMESTAMPTZ; +BEGIN + IF input_expr IS NULL OR tzzone IS NULL THEN + RETURN NULL; + END IF; + + lower_tzn := lower(tzzone); + IF lower_tzn <> 'utc' THEN + tz_name := sys.babelfish_timezone_mapping(lower_tzn); + ELSE + tz_name := 'utc'; + END IF; + + IF tz_name = 'NULL' THEN + RAISE USING MESSAGE := format('Argument data type or the parameter %s provided to AT TIME ZONE clause is invalid.', tzzone); + END IF; + + IF pg_typeof(input_expr) IN ('sys.smalldatetime'::regtype, 'sys.datetime'::regtype, 'sys.datetime2'::regtype) THEN + input_expr_tx := input_expr::TEXT; + input_expr_tmz := input_expr_tx :: TIMESTAMPTZ; + + result := (SELECT input_expr_tmz AT TIME ZONE tz_name)::TEXT; + tz_diff := (SELECT result::TIMESTAMPTZ - input_expr_tmz)::TEXT; + if PG_CATALOG.LEFT(tz_diff,1) <> '-' THEN + tz_diff := concat('+',tz_diff); + END IF; + tz_offset := PG_CATALOG.left(tz_diff,6); + input_expr_tx := concat(input_expr_tx,tz_offset); + return cast(input_expr_tx as sys.datetimeoffset); + ELSIF pg_typeof(input_expr) = 'sys.DATETIMEOFFSET'::regtype THEN + input_expr_tx := input_expr::TEXT; + input_expr_tmz := input_expr_tx :: TIMESTAMPTZ; + result := (SELECT input_expr_tmz AT TIME ZONE tz_name)::TEXT; + tz_diff := (SELECT result::TIMESTAMPTZ - input_expr_tmz)::TEXT; + if PG_CATALOG.LEFT(tz_diff,1) <> '-' THEN + tz_diff := concat('+',tz_diff); + END IF; + tz_offset := PG_CATALOG.left(tz_diff,6); + result := concat(result,tz_offset); + return cast(result as sys.datetimeoffset); + ELSE + RAISE USING MESSAGE := 'Argument data type varchar is invalid for argument 1 of AT TIME ZONE function.'; + END IF; + +END; +$BODY$ +LANGUAGE 'plpgsql' STABLE; + +create or replace function sys.PATINDEX(in pattern varchar, in expression varchar) returns bigint as +$body$ +declare + v_find_result VARCHAR; + v_pos bigint; + v_regexp_pattern VARCHAR; +begin + if pattern is null or expression is null then + return null; + end if; + if PG_CATALOG.left(pattern, 1) = '%' collate sys.database_default then + v_regexp_pattern := regexp_replace(pattern, '^%', '%#"', 'i'); + else + v_regexp_pattern := '#"' || pattern; + end if; + + if PG_CATALOG.right(pattern, 1) = '%' collate sys.database_default then + v_regexp_pattern := regexp_replace(v_regexp_pattern, '%$', '#"%', 'i'); + else + v_regexp_pattern := v_regexp_pattern || '#"'; + end if; + v_find_result := substring(expression, v_regexp_pattern, '#'); + if v_find_result <> '' collate sys.database_default then + v_pos := strpos(expression, v_find_result); + else + v_pos := 0; + end if; + return v_pos; +end; +$body$ +language plpgsql immutable returns null on null input; + +CREATE OR REPLACE FUNCTION sys.has_perms_by_name( + securable SYS.SYSNAME, + securable_class SYS.NVARCHAR(60), + permission SYS.SYSNAME, + sub_securable SYS.SYSNAME DEFAULT NULL, + sub_securable_class SYS.NVARCHAR(60) DEFAULT NULL +) +RETURNS integer +LANGUAGE plpgsql +STABLE +AS $$ +DECLARE + db_name text COLLATE sys.database_default; + bbf_schema_name text; + pg_schema text COLLATE sys.database_default; + implied_dbo_permissions boolean; + fully_supported boolean; + is_cross_db boolean := false; + object_name text COLLATE sys.database_default; + database_id smallint; + namespace_id oid; + userid oid; + object_type text; + function_signature text; + qualified_name text; + return_value integer; + cs_as_securable text COLLATE "C" := securable; + cs_as_securable_class text COLLATE "C" := securable_class; + cs_as_permission text COLLATE "C" := permission; + cs_as_sub_securable text COLLATE "C" := sub_securable; + cs_as_sub_securable_class text COLLATE "C" := sub_securable_class; +BEGIN + return_value := NULL; + + -- Lower-case to avoid case issues, remove trailing whitespace to match SQL SERVER behavior + -- Objects created in Babelfish are stored in lower-case in pg_class/pg_proc + cs_as_securable = lower(PG_CATALOG.rtrim(cs_as_securable)); + cs_as_securable_class = lower(PG_CATALOG.rtrim(cs_as_securable_class)); + cs_as_permission = lower(PG_CATALOG.rtrim(cs_as_permission)); + cs_as_sub_securable = lower(PG_CATALOG.rtrim(cs_as_sub_securable)); + cs_as_sub_securable_class = lower(PG_CATALOG.rtrim(cs_as_sub_securable_class)); + + -- Assert that sub_securable and sub_securable_class are either both NULL or both defined + IF cs_as_sub_securable IS NOT NULL AND cs_as_sub_securable_class IS NULL THEN + RETURN NULL; + ELSIF cs_as_sub_securable IS NULL AND cs_as_sub_securable_class IS NOT NULL THEN + RETURN NULL; + -- If they are both defined, user must be evaluating column privileges. + -- Check that inputs are valid for column privileges: sub_securable_class must + -- be column, securable_class must be object, and permission cannot be any. + ELSIF cs_as_sub_securable_class IS NOT NULL + AND (cs_as_sub_securable_class != 'column' + OR cs_as_securable_class IS NULL + OR cs_as_securable_class != 'object' + OR cs_as_permission = 'any') THEN + RETURN NULL; + + -- If securable is null, securable_class must be null + ELSIF cs_as_securable IS NULL AND cs_as_securable_class IS NOT NULL THEN + RETURN NULL; + -- If securable_class is null, securable must be null + ELSIF cs_as_securable IS NOT NULL AND cs_as_securable_class IS NULL THEN + RETURN NULL; + END IF; + + IF cs_as_securable_class = 'server' THEN + -- SQL Server does not permit a securable_class value of 'server'. + -- securable_class should be NULL to evaluate server permissions. + RETURN NULL; + ELSIF cs_as_securable_class IS NULL THEN + -- NULL indicates a server permission. Set this variable so that we can + -- search for the matching entry in babelfish_has_perms_by_name_permissions + cs_as_securable_class = 'server'; + END IF; + + IF cs_as_sub_securable IS NOT NULL THEN + cs_as_sub_securable := babelfish_remove_delimiter_pair(cs_as_sub_securable); + IF cs_as_sub_securable IS NULL THEN + RETURN NULL; + END IF; + END IF; + + SELECT p.implied_dbo_permissions,p.fully_supported + INTO implied_dbo_permissions,fully_supported + FROM babelfish_has_perms_by_name_permissions p + WHERE p.securable_type = cs_as_securable_class AND p.permission_name = cs_as_permission; + + IF implied_dbo_permissions IS NULL OR fully_supported IS NULL THEN + -- Securable class or permission is not valid, or permission is not valid for given securable + RETURN NULL; + END IF; + + IF cs_as_securable_class = 'database' AND cs_as_securable IS NOT NULL THEN + db_name = babelfish_remove_delimiter_pair(cs_as_securable); + IF db_name IS NULL THEN + RETURN NULL; + ELSIF (SELECT COUNT(name) FROM sys.databases WHERE name = db_name) != 1 THEN + RETURN 0; + END IF; + ELSIF cs_as_securable_class = 'schema' THEN + bbf_schema_name = babelfish_remove_delimiter_pair(cs_as_securable); + IF bbf_schema_name IS NULL THEN + RETURN NULL; + ELSIF (SELECT COUNT(nspname) FROM sys.babelfish_namespace_ext ext + WHERE ext.orig_name = bbf_schema_name + AND ext.dbid = sys.db_id()) != 1 THEN + RETURN 0; + END IF; + END IF; + + IF fully_supported = 'f' AND + (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) = 'dbo' THEN + RETURN CAST(implied_dbo_permissions AS integer); + ELSIF fully_supported = 'f' THEN + RETURN 0; + END IF; + + -- The only permissions that are fully supported belong to the OBJECT securable class. + -- The block above has dealt with all permissions that are not fully supported, so + -- if we reach this point we know the securable class is OBJECT. + SELECT s.db_name, s.schema_name, s.object_name INTO db_name, bbf_schema_name, object_name + FROM babelfish_split_object_name(cs_as_securable) s; + + -- Invalid securable name + IF object_name IS NULL OR object_name = '' THEN + RETURN NULL; + END IF; + + -- If schema was not specified, use the default + IF bbf_schema_name IS NULL OR bbf_schema_name = '' THEN + bbf_schema_name := sys.schema_name(); + END IF; + + database_id := ( + SELECT CASE + WHEN db_name IS NULL OR db_name = '' THEN (sys.db_id()) + ELSE (sys.db_id(db_name)) + END); + + IF database_id <> sys.db_id() THEN + is_cross_db = true; + END IF; + + userid := ( + SELECT CASE + WHEN is_cross_db THEN sys.suser_id() + ELSE sys.user_id() + END); + + -- Translate schema name from bbf to postgres, e.g. dbo -> master_dbo + pg_schema := (SELECT nspname + FROM sys.babelfish_namespace_ext ext + WHERE ext.orig_name = bbf_schema_name + AND CAST(ext.dbid AS oid) = CAST(database_id AS oid)); + + IF pg_schema IS NULL THEN + -- Shared schemas like sys and pg_catalog do not exist in the table above. + -- These schemas do not need to be translated from Babelfish to Postgres + pg_schema := bbf_schema_name; + END IF; + + -- Surround with double-quotes to handle names that contain periods/spaces + qualified_name := concat('"', pg_schema, '"."', object_name, '"'); + + SELECT oid INTO namespace_id FROM pg_catalog.pg_namespace WHERE nspname = pg_schema COLLATE sys.database_default; + + object_type := ( + SELECT CASE + WHEN cs_as_sub_securable_class = 'column' + THEN CASE + WHEN (SELECT count(a.attname) + FROM pg_attribute a + INNER JOIN pg_class c ON c.oid = a.attrelid + INNER JOIN pg_namespace s ON s.oid = c.relnamespace + WHERE + a.attname = cs_as_sub_securable COLLATE sys.database_default + AND c.relname = object_name COLLATE sys.database_default + AND s.nspname = pg_schema COLLATE sys.database_default + AND NOT a.attisdropped + AND (s.nspname IN (SELECT nspname FROM sys.babelfish_namespace_ext) OR s.nspname = 'sys') + -- r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table + AND c.relkind IN ('r', 'v', 'm', 'f', 'p') + AND a.attnum > 0) = 1 + THEN 'column' + ELSE NULL + END + + WHEN (SELECT count(relname) + FROM pg_catalog.pg_class + WHERE relname = object_name COLLATE sys.database_default + AND relnamespace = namespace_id) = 1 + THEN 'table' + + WHEN (SELECT count(proname) + FROM pg_catalog.pg_proc + WHERE proname = object_name COLLATE sys.database_default + AND pronamespace = namespace_id + AND prokind = 'f') = 1 + THEN 'function' + + WHEN (SELECT count(proname) + FROM pg_catalog.pg_proc + WHERE proname = object_name COLLATE sys.database_default + AND pronamespace = namespace_id + AND prokind = 'p') = 1 + THEN 'procedure' + ELSE NULL + END + ); + + -- Object was not found + IF object_type IS NULL THEN + RETURN 0; + END IF; + + -- Get signature for function-like objects + IF object_type IN('function', 'procedure') THEN + SELECT CAST(oid AS regprocedure) + INTO function_signature + FROM pg_catalog.pg_proc + WHERE proname = object_name COLLATE sys.database_default + AND pronamespace = namespace_id; + END IF; + + return_value := ( + SELECT CASE + WHEN cs_as_permission = 'any' THEN babelfish_has_any_privilege(userid, object_type, pg_schema, object_name) + + WHEN object_type = 'column' + THEN CASE + WHEN cs_as_permission IN('insert', 'delete', 'execute') THEN NULL + ELSE CAST(has_column_privilege(userid, qualified_name, cs_as_sub_securable, cs_as_permission) AS integer) + END + + WHEN object_type = 'table' + THEN CASE + WHEN cs_as_permission = 'execute' THEN 0 + ELSE CAST(has_table_privilege(userid, qualified_name, cs_as_permission) AS integer) + END + + WHEN object_type = 'function' + THEN CASE + WHEN cs_as_permission IN('select', 'execute') + THEN CAST(has_function_privilege(userid, function_signature, 'execute') AS integer) + WHEN cs_as_permission IN('update', 'insert', 'delete', 'references') + THEN 0 + ELSE NULL + END + + WHEN object_type = 'procedure' + THEN CASE + WHEN cs_as_permission = 'execute' + THEN CAST(has_function_privilege(userid, function_signature, 'execute') AS integer) + WHEN cs_as_permission IN('select', 'update', 'insert', 'delete', 'references') + THEN 0 + ELSE NULL + END + + ELSE NULL + END + ); + + RETURN return_value; + EXCEPTION WHEN OTHERS THEN RETURN NULL; +END; +$$; + +CREATE OR REPLACE FUNCTION OBJECTPROPERTYEX( + id INT, + property SYS.VARCHAR +) +RETURNS SYS.SQL_VARIANT +AS $$ +BEGIN + property := PG_CATALOG.RTRIM(LOWER(COALESCE(property, ''))); + + IF NOT EXISTS(SELECT ao.object_id FROM sys.all_objects ao WHERE object_id = id) + THEN + RETURN NULL; + END IF; + + IF property = 'basetype' -- BaseType + THEN + RETURN (SELECT CAST(ao.type AS SYS.SQL_VARIANT) + FROM sys.all_objects ao + WHERE ao.object_id = id + LIMIT 1 + ); + END IF; + + RETURN CAST(OBJECTPROPERTY(id, property) AS SYS.SQL_VARIANT); +END +$$ +LANGUAGE plpgsql STABLE; + +CREATE OR REPLACE FUNCTION sys.date_bucket(IN datepart PG_CATALOG.TEXT, IN number INTEGER, IN date ANYELEMENT, IN origin ANYELEMENT default NULL) RETURNS ANYELEMENT +AS +$body$ +DECLARE + required_bucket INT; + years_diff INT; + quarters_diff INT; + months_diff INT; + hours_diff INT; + minutes_diff INT; + seconds_diff INT; + milliseconds_diff INT; + timezone INT; + result_time time; + result_date timestamp; + offset_string PG_CATALOG.text; + date_difference_interval INTERVAL; + millisec_trunc_diff_interval INTERVAL; + date_arg_datatype regtype; + is_valid boolean; +BEGIN + BEGIN + date_arg_datatype := pg_typeof(date); + is_valid := sys.date_bucket_internal_helper(datepart, number, true, true, date); + + -- If optional argument origin's value is not provided by user then set it's default value of valid datatype. + IF origin IS NULL THEN + IF date_arg_datatype = 'sys.datetime'::regtype THEN + origin := CAST('1900-01-01 00:00:00.000' AS sys.datetime); + ELSIF date_arg_datatype = 'sys.datetime2'::regtype THEN + origin := CAST('1900-01-01 00:00:00.000' AS sys.datetime2); + ELSIF date_arg_datatype = 'sys.datetimeoffset'::regtype THEN + origin := CAST('1900-01-01 00:00:00.000' AS sys.datetimeoffset); + ELSIF date_arg_datatype = 'sys.smalldatetime'::regtype THEN + origin := CAST('1900-01-01 00:00:00.000' AS sys.smalldatetime); + ELSIF date_arg_datatype = 'date'::regtype THEN + origin := CAST('1900-01-01 00:00:00.000' AS pg_catalog.date); + ELSIF date_arg_datatype = 'time'::regtype THEN + origin := CAST('00:00:00.000' AS pg_catalog.time); + END IF; + END IF; + END; + + /* support of date_bucket() for different kinds of date datatype starts here */ + -- support of date_bucket() when date is of 'time' datatype + IF date_arg_datatype = 'time'::regtype THEN + -- Find interval between date and origin and extract hour, minute, second, millisecond from the interval + date_difference_interval := date_trunc('millisecond', date) - date_trunc('millisecond', origin); + hours_diff := EXTRACT('hour' from date_difference_interval)::INT; + minutes_diff := EXTRACT('minute' from date_difference_interval)::INT; + seconds_diff := FLOOR(EXTRACT('second' from date_difference_interval))::INT; + milliseconds_diff := FLOOR(EXTRACT('millisecond' from date_difference_interval))::INT; + CASE datepart + WHEN 'hour' THEN + -- Here we are finding how many buckets we have to add in the origin so that we can reach to a bucket in which date belongs. + -- For cases where origin > date, we might end up in a bucket which exceeds date by 1 bucket. + -- For Ex. 'date_bucket(hour, 2, '01:00:00', '08:00:00')' hence check if the result_time is greater then date + -- For comparision we are trunceting the result_time to milliseconds + required_bucket := hours_diff/number; + result_time := origin + make_interval(hours => required_bucket * number); + IF date_trunc('millisecond', result_time) > date THEN + RETURN result_time - make_interval(hours => number); + END IF; + RETURN result_time; + + WHEN 'minute' THEN + required_bucket := (hours_diff * 60 + minutes_diff)/number; + result_time := origin + make_interval(mins => required_bucket * number); + IF date_trunc('millisecond', result_time) > date THEN + RETURN result_time - make_interval(mins => number); + END IF; + RETURN result_time; + + WHEN 'second' THEN + required_bucket := ((hours_diff * 60 + minutes_diff) * 60 + seconds_diff)/number; + result_time := origin + make_interval(secs => required_bucket * number); + IF date_trunc('millisecond', result_time) > date THEN + RETURN result_time - make_interval(secs => number); + END IF; + RETURN result_time; + + WHEN 'millisecond' THEN + required_bucket := (((hours_diff * 60 + minutes_diff) * 60) * 1000 + milliseconds_diff)/number; + result_time := origin + make_interval(secs => ((required_bucket * number)::numeric) * 0.001); + IF date_trunc('millisecond', result_time) > date THEN + RETURN result_time - make_interval(secs => (number::numeric) * 0.001); + END IF; + RETURN result_time; + END CASE; + + -- support of date_bucket() when date is of {'datetime2', 'datetimeoffset'} datatype + -- handling separately because both the datatypes have precision in milliseconds + ELSIF date_arg_datatype IN ('sys.datetime2'::regtype, 'sys.datetimeoffset'::regtype) THEN + -- when datepart is {year, quarter, month} make use of AGE() function to find number of buckets + IF datepart IN ('year', 'quarter', 'month') THEN + date_difference_interval := AGE(date_trunc('day', date::timestamp), date_trunc('day', origin::timestamp)); + years_diff := EXTRACT('Year' from date_difference_interval)::INT; + months_diff := EXTRACT('Month' from date_difference_interval)::INT; + CASE datepart + WHEN 'year' THEN + -- Here we are finding how many buckets we have to add in the origin so that we can reach to a bucket in which date belongs. + -- For cases where origin > date, we might end up in a bucket which exceeds date by 1 bucket. + -- For Ex. date_bucket(year, 2, '2010-01-01', '2019-01-01')) hence check if the result_time is greater then date. + -- For comparision we are trunceting the result_time to milliseconds + required_bucket := years_diff/number; + result_date := origin::timestamp + make_interval(years => required_bucket * number); + IF result_date > date::timestamp THEN + result_date = result_date - make_interval(years => number); + END IF; + + WHEN 'month' THEN + required_bucket := (12 * years_diff + months_diff)/number; + result_date := origin::timestamp + make_interval(months => required_bucket * number); + IF result_date > date::timestamp THEN + result_date = result_date - make_interval(months => number); + END IF; + + WHEN 'quarter' THEN + quarters_diff := (12 * years_diff + months_diff)/3; + required_bucket := quarters_diff/number; + result_date := origin::timestamp + make_interval(months => required_bucket * number * 3); + IF result_date > date::timestamp THEN + result_date = result_date - make_interval(months => number*3); + END IF; + END CASE; + + -- when datepart is {week, day, hour, minute, second, millisecond} make use of built-in date_bin() postgresql function. + ELSE + -- trunceting origin to millisecond before passing it to date_bin() function. + -- store the difference between origin and trunceted origin to add it in the result of date_bin() function + date_difference_interval := concat(number, ' ', datepart)::INTERVAL; + millisec_trunc_diff_interval := (origin::timestamp - date_trunc('millisecond', origin::timestamp))::interval; + result_date = date_bin(date_difference_interval, date::timestamp, date_trunc('millisecond', origin::timestamp)) + millisec_trunc_diff_interval; + + -- Filetering cases where the required bucket ends at date then date_bin() gives start point of this bucket as result. + IF result_date + date_difference_interval <= date::timestamp THEN + result_date = result_date + date_difference_interval; + END IF; + END IF; + + -- All the above operations are performed by converting every date datatype into TIMESTAMPS. + -- datetimeoffset is typecasted into TIMESTAMPS that changes the value. + -- Ex. '2023-02-23 09:19:21.23 +10:12'::sys.datetimeoffset::timestamp => '2023-02-22 23:07:21.23' + -- The output of date_bucket() for datetimeoffset datatype will always be in the same time-zone as of provided date argument. + -- Here, converting TIMESTAMP into datetimeoffset datatype with the same timezone as of date argument. + IF date_arg_datatype = 'sys.datetimeoffset'::regtype THEN + timezone = sys.babelfish_get_datetimeoffset_tzoffset(date)::INTEGER; + offset_string = PG_CATALOG.right(date::PG_CATALOG.TEXT, 6); + result_date = result_date + make_interval(mins => timezone); + RETURN concat(result_date, ' ', offset_string)::sys.datetimeoffset; + ELSE + RETURN result_date; + END IF; + + -- support of date_bucket() when date is of {'date', 'datetime', 'smalldatetime'} datatype + ELSE + -- Round datetime to fixed bins (e.g. .000, .003, .007) + IF date_arg_datatype = 'sys.datetime'::regtype THEN + date := sys.babelfish_conv_string_to_datetime('DATETIME', date::TEXT)::sys.datetime; + origin := sys.babelfish_conv_string_to_datetime('DATETIME', origin::TEXT)::sys.datetime; + END IF; + -- when datepart is {year, quarter, month} make use of AGE() function to find number of buckets + IF datepart IN ('year', 'quarter', 'month') THEN + date_difference_interval := AGE(date_trunc('day', date::timestamp), date_trunc('day', origin::timestamp)); + years_diff := EXTRACT('Year' from date_difference_interval)::INT; + months_diff := EXTRACT('Month' from date_difference_interval)::INT; + CASE datepart + WHEN 'year' THEN + -- Here we are finding how many buckets we have to add in the origin so that we can reach to a bucket in which date belongs. + -- For cases where origin > date, we might end up in a bucket which exceeds date by 1 bucket. + -- For Example. date_bucket(year, 2, '2010-01-01', '2019-01-01') hence check if the result_time is greater then date. + -- For comparision we are trunceting the result_time to milliseconds + required_bucket := years_diff/number; + result_date := origin::timestamp + make_interval(years => required_bucket * number); + IF result_date > date::timestamp THEN + result_date = result_date - make_interval(years => number); + END IF; + + WHEN 'month' THEN + required_bucket := (12 * years_diff + months_diff)/number; + result_date := origin::timestamp + make_interval(months => required_bucket * number); + IF result_date > date::timestamp THEN + result_date = result_date - make_interval(months => number); + END IF; + + WHEN 'quarter' THEN + quarters_diff := (12 * years_diff + months_diff)/3; + required_bucket := quarters_diff/number; + result_date := origin::timestamp + make_interval(months => required_bucket * number * 3); + IF result_date > date::timestamp THEN + result_date = result_date - make_interval(months => number * 3); + END IF; + END CASE; + RETURN result_date; + + -- when datepart is {week, day, hour, minute, second, millisecond} make use of built-in date_bin() postgresql function. + ELSE + -- trunceting origin to millisecond before passing it to date_bin() function. + -- store the difference between origin and trunceted origin to add it in the result of date_bin() function + date_difference_interval := concat(number, ' ', datepart)::INTERVAL; + result_date = date_bin(date_difference_interval, date::TIMESTAMP, origin::TIMESTAMP); + -- Filetering cases where the required bucket ends at date then date_bin() gives start point of this bucket as result. + IF result_date + date_difference_interval <= date::TIMESTAMP THEN + result_date = result_date + date_difference_interval; + END IF; + RETURN result_date; + END IF; + END IF; +END; +$body$ +LANGUAGE plpgsql IMMUTABLE; + +CREATE OR REPLACE FUNCTION sys.DATETRUNC(IN datepart PG_CATALOG.TEXT, IN date ANYELEMENT) RETURNS ANYELEMENT AS +$body$ +DECLARE + days_offset INT; + v_day INT; + result_date timestamp; + input_expr_timestamp timestamp; + date_arg_datatype regtype; + offset_string PG_CATALOG.TEXT; + datefirst_value INT; +BEGIN + BEGIN + /* perform input validation */ + date_arg_datatype := pg_typeof(date); + IF datepart NOT IN ('year', 'quarter', 'month', 'week', 'tsql_week', 'hour', 'minute', 'second', 'millisecond', 'microsecond', + 'doy', 'day', 'nanosecond', 'tzoffset') THEN + RAISE EXCEPTION '''%'' is not a recognized datetrunc option.', datepart; + ELSIF date_arg_datatype NOT IN ('date'::regtype, 'time'::regtype, 'sys.datetime'::regtype, 'sys.datetime2'::regtype, + 'sys.datetimeoffset'::regtype, 'sys.smalldatetime'::regtype) THEN + RAISE EXCEPTION 'Argument data type ''%'' is invalid for argument 2 of datetrunc function.', date_arg_datatype; + ELSIF datepart IN ('nanosecond', 'tzoffset') THEN + RAISE EXCEPTION 'The datepart ''%'' is not supported by date function datetrunc for data type ''%''.',datepart, date_arg_datatype; + ELSIF datepart IN ('dow') THEN + RAISE EXCEPTION 'The datepart ''weekday'' is not supported by date function datetrunc for data type ''%''.', date_arg_datatype; + ELSIF date_arg_datatype = 'date'::regtype AND datepart IN ('hour', 'minute', 'second', 'millisecond', 'microsecond') THEN + RAISE EXCEPTION 'The datepart ''%'' is not supported by date function datetrunc for data type ''date''.', datepart; + ELSIF date_arg_datatype = 'datetime'::regtype AND datepart IN ('microsecond') THEN + RAISE EXCEPTION 'The datepart ''%'' is not supported by date function datetrunc for data type ''datetime''.', datepart; + ELSIF date_arg_datatype = 'smalldatetime'::regtype AND datepart IN ('millisecond', 'microsecond') THEN + RAISE EXCEPTION 'The datepart ''%'' is not supported by date function datetrunc for data type ''smalldatetime''.', datepart; + ELSIF date_arg_datatype = 'time'::regtype THEN + IF datepart IN ('year', 'quarter', 'month', 'doy', 'day', 'week', 'tsql_week') THEN + RAISE EXCEPTION 'The datepart ''%'' is not supported by date function datetrunc for data type ''time''.', datepart; + END IF; + -- Limitation in determining if the specified fractional scale (if provided any) for time datatype is + -- insufficient to support provided datepart (millisecond, microsecond) value + ELSIF date_arg_datatype IN ('datetime2'::regtype, 'datetimeoffset'::regtype) THEN + -- Limitation in determining if the specified fractional scale (if provided any) for the above datatype is + -- insufficient to support for provided datepart (millisecond, microsecond) value + END IF; + + /* input validation is complete, proceed with result calculation. */ + IF date_arg_datatype = 'time'::regtype THEN + RETURN date_trunc(datepart, date); + ELSE + input_expr_timestamp = date::timestamp; + -- preserving offset_string value in the case of datetimeoffset datatype before converting it to timestamps + IF date_arg_datatype = 'sys.datetimeoffset'::regtype THEN + offset_string = PG_CATALOG.RIGHT(date::PG_CATALOG.TEXT, 6); + input_expr_timestamp := PG_CATALOG.LEFT(date::PG_CATALOG.TEXT, -6)::timestamp; + END IF; + CASE + WHEN datepart IN ('year', 'quarter', 'month', 'week', 'hour', 'minute', 'second', 'millisecond', 'microsecond') THEN + result_date := date_trunc(datepart, input_expr_timestamp); + WHEN datepart IN ('doy', 'day') THEN + result_date := date_trunc('day', input_expr_timestamp); + WHEN datepart IN ('tsql_week') THEN + -- sql server datepart 'iso_week' is similar to postgres 'week' datepart + -- handle sql server datepart 'week' here based on the value of set variable 'DATEFIRST' + v_day := EXTRACT(dow from input_expr_timestamp)::INT; + datefirst_value := current_setting('babelfishpg_tsql.datefirst')::INT; + IF v_day = 0 THEN + v_day := 7; + END IF; + result_date := date_trunc('day', input_expr_timestamp); + days_offset := (7 + v_day - datefirst_value)%7; + result_date := result_date - make_interval(days => days_offset); + END CASE; + -- concat offset_string to result_date in case of datetimeoffset before converting it to datetimeoffset datatype. + IF date_arg_datatype = 'sys.datetimeoffset'::regtype THEN + RETURN concat(result_date, ' ', offset_string)::sys.datetimeoffset; + ELSE + RETURN result_date; + END IF; + END IF; + END; +END; +$body$ +LANGUAGE plpgsql STABLE; + +CREATE OR REPLACE FUNCTION sys.bbf_get_immediate_base_type_of_UDT(OID) +RETURNS OID +AS 'babelfishpg_tsql', 'get_immediate_base_type_of_UDT' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar); diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 0d05adecf87..4843a586627 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -148,7 +148,7 @@ static void fill_missing_values_in_copyfrom(Relation rel, Datum *values, bool *n /***************************************** * Utility Hooks *****************************************/ -static void pltsql_report_proc_not_found_error(List *names, List *argnames, int nargs, ParseState *pstate, int location, bool proc_call); +static void pltsql_report_proc_not_found_error(List *names, List *argnames, Oid *input_typeids, int nargs, ParseState *pstate, int location, bool proc_call); extern PLtsql_execstate *get_outermost_tsql_estate(int *nestlevel); extern PLtsql_execstate *get_current_tsql_estate(); static void pltsql_store_view_definition(const char *queryString, ObjectAddress address); @@ -184,6 +184,7 @@ static bool bbf_check_rowcount_hook(int es_processed); static char *get_local_schema_for_bbf_functions(Oid proc_nsp_oid); extern bool called_from_tsql_insert_exec(); +extern bool called_for_tsql_itvf_func(); extern Datum pltsql_exec_tsql_cast_value(Datum value, bool *isnull, Oid valtype, int32 valtypmod, Oid reqtype, int32 reqtypmod); @@ -261,6 +262,7 @@ static get_bbf_admin_oid_hook_type prev_get_bbf_admin_oid_hook = NULL; static transform_pivot_clause_hook_type pre_transform_pivot_clause_hook = NULL; static pass_pivot_data_to_fcinfo_hook_type pre_pass_pivot_data_to_fcinfo_hook = NULL; static called_from_tsql_insert_exec_hook_type pre_called_from_tsql_insert_exec_hook = NULL; +static called_for_tsql_itvf_func_hook_type prev_called_for_tsql_itvf_func_hook = NULL; static exec_tsql_cast_value_hook_type pre_exec_tsql_cast_value_hook = NULL; static pltsql_pgstat_end_function_usage_hook_type prev_pltsql_pgstat_end_function_usage_hook = NULL; static pltsql_unique_constraint_nulls_ordering_hook_type prev_pltsql_unique_constraint_nulls_ordering_hook = NULL; @@ -444,6 +446,9 @@ InstallExtendedHooks(void) pre_called_from_tsql_insert_exec_hook = called_from_tsql_insert_exec_hook; called_from_tsql_insert_exec_hook = called_from_tsql_insert_exec; + prev_called_for_tsql_itvf_func_hook = called_for_tsql_itvf_func_hook; + called_for_tsql_itvf_func_hook = called_for_tsql_itvf_func; + pre_exec_tsql_cast_value_hook = exec_tsql_cast_value_hook; exec_tsql_cast_value_hook = pltsql_exec_tsql_cast_value; @@ -516,6 +521,7 @@ UninstallExtendedHooks(void) transform_pivot_clause_hook = pre_transform_pivot_clause_hook; optimize_explicit_cast_hook = prev_optimize_explicit_cast_hook; called_from_tsql_insert_exec_hook = pre_called_from_tsql_insert_exec_hook; + called_for_tsql_itvf_func_hook = prev_called_for_tsql_itvf_func_hook; pltsql_pgstat_end_function_usage_hook = prev_pltsql_pgstat_end_function_usage_hook; pltsql_unique_constraint_nulls_ordering_hook = prev_pltsql_unique_constraint_nulls_ordering_hook; @@ -2432,7 +2438,7 @@ get_trigger_object_address(List *object, Relation *relp, bool missing_ok, bool o /* Generate similar error message with SQL Server when function/procedure is not found if possible. */ void -pltsql_report_proc_not_found_error(List *names, List *given_argnames, int nargs, ParseState *pstate, int location, bool proc_call) +pltsql_report_proc_not_found_error(List *names, List *given_argnames, Oid *input_typeids, int nargs, ParseState *pstate, int location, bool proc_call) { FuncCandidateList candidates = NULL, current_candidate = NULL; @@ -2440,6 +2446,8 @@ pltsql_report_proc_not_found_error(List *names, List *given_argnames, int nargs, int min_nargs = INT_MAX; int ncandidates = 0; bool found = false; + char *schemaname; + char *funcname; const char *obj_type = proc_call ? "procedure" : "function"; candidates = FuncnameGetCandidates(names, -1, NIL, false, false, false, true); /* search all possible @@ -2479,6 +2487,18 @@ pltsql_report_proc_not_found_error(List *names, List *given_argnames, int nargs, */ if (found) { + if (!proc_call) + { + /* deconstruct the names list */ + DeconstructQualifiedName(names, &schemaname, &funcname); + + /* + * Check whether function is an special function or not, and + * report appropriate error if applicable + */ + validate_special_function(schemaname, funcname, nargs, input_typeids); + } + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("The %s %s is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.", obj_type, NameListToString(names))), diff --git a/contrib/babelfishpg_tsql/src/pl_exec.c b/contrib/babelfishpg_tsql/src/pl_exec.c index 168f98bb288..d7ac9f5b138 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec.c +++ b/contrib/babelfishpg_tsql/src/pl_exec.c @@ -491,6 +491,18 @@ extern int static void pltsql_exec_function_cleanup(PLtsql_execstate *estate, PLtsql_function *func, ErrorContextCallback *plerrcontext); +static bool called_for_tsql_itvf_function = false; +bool called_for_tsql_itvf_func(void); + + +bool +called_for_tsql_itvf_func() +{ + if (sql_dialect != SQL_DIALECT_TSQL) + return false; + return called_for_tsql_itvf_function; +} + /* ---------- * pltsql_exec_function Called by the call handler for * function execution. @@ -668,7 +680,13 @@ pltsql_exec_function(PLtsql_function *func, FunctionCallInfo fcinfo, if (pltsql_trace_exec_time) config.trace_mode |= TRACE_EXEC_TIME; + /* + * Following variable will be used inside exec_stmt_iterative function to + * identify whether the function is ITVF function or not + */ + called_for_tsql_itvf_function = func->is_itvf; rc = exec_stmt_iterative(&estate, func->exec_codes, &config); + called_for_tsql_itvf_function = false; if (rc != PLTSQL_RC_RETURN) { diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 4957012e65c..0ae4d136dc1 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -4443,6 +4443,7 @@ _PG_init(void) init_tsql_coerce_hash_tab(fcinfo); init_tsql_datatype_precedence_hash_tab(fcinfo); + init_special_function_list(); init_tsql_cursor_hash_tab(fcinfo); RegisterXactCallback(pltsql_xact_cb, NULL); RegisterSubXactCallback(pltsql_subxact_cb, NULL); diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 6e792fd8df5..72e76c6c97b 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -2267,4 +2267,10 @@ void GetOpenqueryTupdescFromMetadata(char *linked_server, char *query, TupleDes extern void exec_utility_cmd_helper(char *query_str); extern void exec_alter_role_cmd(char *query_str, RoleSpec *role); +/* + * Functions in pltsql_coerce.c + */ +extern bool validate_special_function(char *proc_nsname, char *proc_name, int nargs, Oid *input_typeids); +extern void init_special_function_list(void); + #endif /* PLTSQL_H */ diff --git a/contrib/babelfishpg_tsql/src/pltsql_coerce.c b/contrib/babelfishpg_tsql/src/pltsql_coerce.c index d0fb25115e1..1f7693b9726 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_coerce.c +++ b/contrib/babelfishpg_tsql/src/pltsql_coerce.c @@ -10,6 +10,8 @@ #include "varatt.h" #include "access/htup_details.h" +#include "access/genam.h" +#include "access/table.h" #include "access/parallel.h" /* InitializingParallelWorker */ #include "miscadmin.h" #include "catalog/pg_authid.h" @@ -29,6 +31,7 @@ #include "utils/builtins.h" #include "utils/float.h" #include "utils/guc.h" +#include "utils/fmgroids.h" #include "common/int.h" #include "utils/numeric.h" #include "utils/memutils.h" @@ -54,6 +57,7 @@ extern bool babelfish_dump_restore; PG_FUNCTION_INFO_V1(init_tsql_coerce_hash_tab); PG_FUNCTION_INFO_V1(init_tsql_datatype_precedence_hash_tab); +PG_FUNCTION_INFO_V1(get_immediate_base_type_of_UDT); static Oid select_common_type_setop(ParseState *pstate, List *exprs, Node **which_expr); static Oid select_common_type_for_isnull(ParseState *pstate, List *exprs); @@ -375,6 +379,37 @@ tsql_precedence_info_t tsql_precedence_infos[] = #define TOTAL_TSQL_PRECEDENCE_COUNT (sizeof(tsql_precedence_infos)/sizeof(tsql_precedence_infos[0])) +/* Following constants value are defined based on the special function list */ +#define SFUNC_MAX_ARGS 2 /* maximum number of args special function in special function list can have */ +#define SFUNC_MAX_VALID_TYPES 6 /* maximum number of valid types supported argument of function in special function list can have */ + +/* struct to store details of valid types supported for a argument */ +typedef struct tsql_valid_arg_type +{ + int len; /* length of list of valid types for the argument */ + char *valid_types[SFUNC_MAX_VALID_TYPES]; /* list of valid type name supported for the argument */ + Oid valid_types_oid[SFUNC_MAX_VALID_TYPES]; /* list of valid type oid supported for the argument */ +} tsql_valid_arg_type_t; + +/* struct to store details of special function */ +typedef struct tsql_special_function +{ + const char *nsp; /* namespace of special function */ + const char *funcname; /* name of special function */ + const char *formatted_funcname; /* formatted name of special function */ + int nargs; /* number of arguments of special function */ + tsql_valid_arg_type_t valid_arg_types[SFUNC_MAX_ARGS]; /* list for storing details of all the valid types supported for each arguments */ +} tsql_special_function_t; + +tsql_special_function_t tsql_special_function_list[] = +{ + {"sys", "trim", "Trim", 2, {{6, {"char","varchar","nchar","nvarchar","text","ntext"}, {InvalidOid, InvalidOid, InvalidOid, InvalidOid, InvalidOid, InvalidOid}}, {6, {"char","varchar","nchar","nvarchar","text","ntext"}, {InvalidOid, InvalidOid, InvalidOid, InvalidOid, InvalidOid, InvalidOid}}}} +}; + +static bool inited_tsql_special_function_list = false; + +#define TOTAL_TSQL_SPECIAL_FUNCTION_COUNT (sizeof(tsql_special_function_list)/sizeof(tsql_special_function_list[0])) + /* T-SQL Cast */ typedef struct tsql_cast_info_key { @@ -889,11 +924,282 @@ run_tsql_best_match_heuristics(int nargs, Oid *input_typeids, FuncCandidateList return new_candidates; } +/* + * get_immediate_base_type_of_UDT_internal() + * This function returns the Immediate base type for UDT. + * Returns InvalidOid if given type is not an UDT + */ +static Oid +get_immediate_base_type_of_UDT_internal(Oid typeid) +{ + HeapTuple tuple; + bool isnull; + Datum datum; + Datum tsql_typename; + Oid base_type; + LOCAL_FCINFO(fcinfo, 1); + + if (!OidIsValid(typeid)) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("typeid is invalid!"))); + + /* if common_utility_plugin_ptr is not initialised */ + if (common_utility_plugin_ptr == NULL) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Failed to find common utility plugin."))); + + /* if tsql_typename is NULL it implies that inputTypId corresponds to UDT */ + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); + fcinfo->args[0].value = ObjectIdGetDatum(typeid); + fcinfo->args[0].isnull = false; + tsql_typename = (*common_utility_plugin_ptr->translate_pg_type_to_tsql) (fcinfo); + + /* if given type is not an UDT then return InvalidOid */ + if (tsql_typename) + return InvalidOid; + + /* Get immediate base type id of given type id */ + tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeid)); + if (!HeapTupleIsValid(tuple)) + return InvalidOid; + + datum = SysCacheGetAttr(TYPEOID, tuple, Anum_pg_type_typbasetype, &isnull); + if (isnull) + return InvalidOid; + + base_type = DatumGetObjectId(datum); + ReleaseSysCache(tuple); + + return base_type; +} + +Datum +get_immediate_base_type_of_UDT(PG_FUNCTION_ARGS) +{ + Oid base_type; + + base_type = get_immediate_base_type_of_UDT_internal(PG_GETARG_OID(0)); + if (!OidIsValid(base_type)) + PG_RETURN_NULL(); + + PG_RETURN_OID(base_type); +} + +void +init_special_function_list() +{ + Oid type_id; + + /* if common_utility_plugin_ptr is not initialised */ + if (common_utility_plugin_ptr == NULL) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Failed to find common utility plugin."))); + + /* mark the special function list initialised */ + inited_tsql_special_function_list = true; + + for (int special_func_idx = 0; special_func_idx < TOTAL_TSQL_SPECIAL_FUNCTION_COUNT; special_func_idx++) + { + for (int arg_idx = 0; arg_idx < tsql_special_function_list[special_func_idx].nargs; arg_idx++) + { + for (int valid_type_idx = 0; valid_type_idx < tsql_special_function_list[special_func_idx].valid_arg_types[arg_idx].len; valid_type_idx++) + { + if (!OidIsValid(tsql_special_function_list[special_func_idx].valid_arg_types[arg_idx].valid_types_oid[valid_type_idx])) + { + type_id = (*common_utility_plugin_ptr->get_tsql_datatype_oid)(tsql_special_function_list[special_func_idx].valid_arg_types[arg_idx].valid_types[valid_type_idx]); + + if (OidIsValid(type_id)) + { + tsql_special_function_list[special_func_idx].valid_arg_types[arg_idx].valid_types_oid[valid_type_idx] = type_id; + } + else + { + /* type id is not loaded. wait for next scan */ + inited_tsql_special_function_list = false; + } + } + } + } + } +} + +/* + * For a given function details, validate whether it is in special function list + * and also validate the input argument data types. + */ +bool +validate_special_function(char *func_nsname, char *func_name, int nargs, Oid *input_typeids) +{ + tsql_special_function_t *special_func; + bool type_match; + Oid input_type_id, valid_type_id, base_type_id; + Oid sys_varcharoid; + + /* Sanity checks */ + if (func_name == NULL || (nargs != 0 && input_typeids == NULL)) + return false; + + /* + * Special function handling is only for some specific system functions. + * If func_nsname is NULL, consider it to be a "sys". + */ + if (func_nsname != NULL && + (strlen(func_nsname) != 3 || strncmp(func_nsname, "sys", 3) != 0)) + return false; + + /* Initialise T-SQL special function argument type id list if not already done */ + if (!inited_tsql_special_function_list) + { + init_special_function_list(); + } + + /* Get Special function details */ + special_func = NULL; + for (int i = 0; i < TOTAL_TSQL_SPECIAL_FUNCTION_COUNT; i++) + { + if (strcmp(func_name, tsql_special_function_list[i].funcname) == 0 + && nargs == tsql_special_function_list[i].nargs) + { + special_func = &tsql_special_function_list[i]; + break; + } + } + + /* If function is not a special function no additional handling required */ + if (special_func == NULL) + return false; + + sys_varcharoid = get_sys_varcharoid(); + + /* Report error in case of invalid argument datatype */ + for (int i = 0; i < special_func->nargs; i++) + { + /* for unknown literals consider its type as sys.VARCHAR */ + input_type_id = (input_typeids[i] == UNKNOWNOID) ? sys_varcharoid : input_typeids[i]; + + /* for UDT use its base type for input argument datatype validation */ + base_type_id = get_immediate_base_type_of_UDT_internal(input_type_id); + if (OidIsValid(base_type_id)) + input_type_id = base_type_id; + + type_match = false; + for (int j = 0; j < special_func->valid_arg_types[i].len; j++) + { + valid_type_id = special_func->valid_arg_types[i].valid_types_oid[j]; + + if (input_type_id == valid_type_id) + { + type_match = true; + break; + } + } + if (!type_match) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("Argument data type %s is invalid for argument %d of %s function.", + format_type_be(input_type_id), i+1, special_func->formatted_funcname))); + } + } + + return true; +} + +/* + * tsql_func_select_candidate_for_special_func() + * + * For functions present in special function list, and try to find best candidate + * based on matching return type. Also throw error in case of invalid argument data type. + */ +static FuncCandidateList +tsql_func_select_candidate_for_special_func(List *names, int nargs, Oid *input_typeids, FuncCandidateList candidates) +{ + FuncCandidateList current_candidate, best_candidate; + Oid expr_result_type; + char *proc_nsname; + char *proc_name; + bool is_func_validated; + int ncandidates; + Oid rettype; + + DeconstructQualifiedName(names, &proc_nsname, &proc_name); + + is_func_validated = validate_special_function(proc_nsname, proc_name, nargs, input_typeids); + + /* Return NULL if function is not a special function */ + if (!is_func_validated) + return NULL; + + /* if common_utility_plugin_ptr is not initialised */ + if (common_utility_plugin_ptr == NULL) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Failed to find common utility plugin."))); + + /* function based logic to decide return type */ + expr_result_type = InvalidOid; + if (strlen(proc_name) == 4 && strncmp(proc_name,"trim", 4) == 0) + { + if ((*common_utility_plugin_ptr->is_tsql_nvarchar_datatype)(input_typeids[1]) + || (*common_utility_plugin_ptr->is_tsql_nchar_datatype)(input_typeids[1])) + { + expr_result_type = (*common_utility_plugin_ptr->lookup_tsql_datatype_oid) ("nvarchar"); + } + else if ((*common_utility_plugin_ptr->is_tsql_varchar_datatype)(input_typeids[1]) + || (*common_utility_plugin_ptr->is_tsql_bpchar_datatype)(input_typeids[1]) + || input_typeids[1] == UNKNOWNOID) + { + expr_result_type = get_sys_varcharoid(); + } + } + + if (!OidIsValid(expr_result_type)) + return NULL; + + /* Get the candidate with matching return type */ + ncandidates = 0; + best_candidate = NULL; + for (current_candidate = candidates; + current_candidate != NULL; + current_candidate = current_candidate->next) + { + rettype = get_func_rettype(current_candidate->oid); + if (expr_result_type == rettype) + { + best_candidate = current_candidate; + ncandidates++; + } + } + + /* Only one definition should exists per return type for special function */ + if (ncandidates == 0) + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("function %s.%s with return type %s does not exists.", proc_nsname, proc_name, format_type_be(expr_result_type)))); + } + else if (ncandidates > 1) + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("multiple definitions of function %s.%s with return type %s found.", proc_nsname, proc_name, format_type_be(expr_result_type)))); + } + + if (best_candidate != NULL) + best_candidate->next = NULL; + return best_candidate; +} + static FuncCandidateList -tsql_func_select_candidate(int nargs, +tsql_func_select_candidate(List *names, + int nargs, Oid *input_typeids, FuncCandidateList candidates, - bool unknowns_resolved) + bool unknowns_resolved, + bool is_special) { FuncCandidateList new_candidates; FuncCandidateList current_candidate; @@ -901,6 +1207,9 @@ tsql_func_select_candidate(int nargs, int i; bool candidates_are_opers = false; + if (is_special) + return tsql_func_select_candidate_for_special_func(names, nargs, input_typeids, candidates); + if (unknowns_resolved) { Oid *new_input_typeids = palloc(nargs * sizeof(Oid)); diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index 582ce935d3f..f3805c32824 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -214,6 +214,7 @@ static void handleModuloOperator(TSqlParser::Mult_div_percent_exprContext *ctx); static void handleAtAtVarInPredicate(TSqlParser::PredicateContext *ctx); static void handleOrderByOffsetFetch(TSqlParser::Order_by_clauseContext *ctx); static bool setSysSchema = false; +static void rewrite_function_trim_to_sys_trim(TSqlParser::TRIMContext *ctx); /* * Structure / Utility function for general purpose of query string modification @@ -954,6 +955,26 @@ class tsqlCommonMutator : public TSqlParserBaseListener void exitFunction_call(TSqlParser::Function_callContext *ctx) override { handleGeospatialFunctionsInFunctionCall(ctx); + + if (ctx->func_proc_name_server_database_schema()) + { + auto fpnsds = ctx->func_proc_name_server_database_schema(); + + if (fpnsds->DOT().empty() && fpnsds->id().back()->keyword()) /* built-in functions */ + { + auto id = fpnsds->id().back(); + + if (id->keyword()->TRIM()) + { + rewritten_query_fragment.emplace(std::make_pair(id->keyword()->TRIM()->getSymbol()->getStartIndex(), std::make_pair(::getFullText(id->keyword()->TRIM()), "sys.trim"))); + } + } + } + } + + void exitTRIM(TSqlParser::TRIMContext *ctx) override + { + rewrite_function_trim_to_sys_trim(ctx); } /* We are adding handling for CLR_UDT Types in: @@ -2347,6 +2368,11 @@ class tsqlBuilder : public tsqlCommonMutator handleOrderByOffsetFetch(ctx); } + void exitTRIM(TSqlParser::TRIMContext *ctx) override + { + rewrite_function_trim_to_sys_trim(ctx); + } + // NB: the following are copied in tsqlMutator void exitColumn_def_table_constraints(TSqlParser::Column_def_table_constraintsContext *ctx) { @@ -2560,7 +2586,11 @@ class tsqlBuilder : public tsqlCommonMutator } } } - + + if (id->keyword()->TRIM()) + { + rewritten_query_fragment.emplace(std::make_pair(id->keyword()->TRIM()->getSymbol()->getStartIndex(), std::make_pair(::getFullText(id->keyword()->TRIM()), "sys.trim"))); + } } if (ctx->func_proc_name_server_database_schema()->procedure) @@ -8244,6 +8274,20 @@ rewrite_column_name_with_omitted_schema_name(T ctx, GetCtxFunc getSchema, Get return ""; } +/* + * In this function we Rewrite the Query for Trim function as follows + * TRIM '(' expression from expression ')' -> sys.TRIM '(' expression , expression ')' + */ +static void +rewrite_function_trim_to_sys_trim(TSqlParser::TRIMContext *ctx) +{ + if (ctx->trim_from()) + { + rewritten_query_fragment.emplace(std::make_pair(ctx->trim_from()->start->getStartIndex(), std::make_pair(::getFullText(ctx->trim_from()), " , "))); + } + rewritten_query_fragment.emplace(std::make_pair(ctx->TRIM()->getSymbol()->getStartIndex(), std::make_pair(::getFullText(ctx->TRIM()), "sys.trim"))); +} + /////////////////////////////////////////////////////////////////////////////// // Spatial Query Helper //////////////////////////////////////////////////////////////////////////////// diff --git a/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out b/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out index 245f7077a98..dd9391646a7 100644 --- a/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out +++ b/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out @@ -160,7 +160,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#text +int#!#text#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ @@ -176,7 +176,7 @@ select ; go ~~START~~ -text#!#text#!#int#!#int#!#int#!#int#!#int +text#!#varchar#!#int#!#int#!#int#!#int#!#int a #!#a #!#0#!#97#!#5#!#5#!#3 ~~END~~ diff --git a/test/JDBC/expected/BABEL-1994-CHAR.out b/test/JDBC/expected/BABEL-1994-CHAR.out index f5339bda4b2..d3a4ed2a963 100644 --- a/test/JDBC/expected/BABEL-1994-CHAR.out +++ b/test/JDBC/expected/BABEL-1994-CHAR.out @@ -191,7 +191,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#text +int#!#text#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ @@ -207,7 +207,7 @@ select ; go ~~START~~ -text#!#text#!#int#!#int#!#int#!#int#!#int +text#!#varchar#!#int#!#int#!#int#!#int#!#int a #!#a #!#0#!#97#!#5#!#5#!#3 ~~END~~ diff --git a/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out b/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out index 6aa88ddadc1..f1861abcbec 100644 --- a/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out +++ b/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out @@ -165,7 +165,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#text +int#!#text#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ @@ -181,7 +181,7 @@ select ; go ~~START~~ -text#!#text#!#int#!#int#!#int#!#int#!#int +text#!#varchar#!#int#!#int#!#int#!#int#!#int a #!#a #!#1#!#97#!#4#!#4#!#3 ~~END~~ diff --git a/test/JDBC/expected/BABEL-1994-VARCHAR.out b/test/JDBC/expected/BABEL-1994-VARCHAR.out index f53a9a4392d..4c3597c7a2f 100644 --- a/test/JDBC/expected/BABEL-1994-VARCHAR.out +++ b/test/JDBC/expected/BABEL-1994-VARCHAR.out @@ -189,7 +189,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#text +int#!#text#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ @@ -205,7 +205,7 @@ select ; go ~~START~~ -text#!#text#!#int#!#int#!#int#!#int#!#int +text#!#varchar#!#int#!#int#!#int#!#int#!#int a #!#a #!#1#!#97#!#4#!#4#!#3 ~~END~~ diff --git a/test/JDBC/expected/TestProcedureWithTransactions.out b/test/JDBC/expected/TestProcedureWithTransactions.out index ecd765871ec..1c7123a2324 100644 --- a/test/JDBC/expected/TestProcedureWithTransactions.out +++ b/test/JDBC/expected/TestProcedureWithTransactions.out @@ -760,7 +760,7 @@ datetime ~~END~~ ~~START~~ -text#!#text#!#int#!#int#!#int#!#int#!#int +text#!#varchar#!#int#!#int#!#int#!#int#!#int a #!#a #!#0#!#97#!#5#!#5#!#3 ~~END~~ @@ -804,7 +804,7 @@ datetime ~~END~~ ~~START~~ -text#!#text#!#int#!#int#!#int#!#int#!#int +text#!#varchar#!#int#!#int#!#int#!#int#!#int a #!#a #!#0#!#97#!#5#!#5#!#3 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_6__sys-host_name-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_6__sys-host_name-vu-verify.out index 2ea0477de3f..6eb09724dba 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_6__sys-host_name-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_6__sys-host_name-vu-verify.out @@ -77,7 +77,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_7__sys-host_name-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_7__sys-host_name-vu-verify.out index 2ea0477de3f..6eb09724dba 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_7__sys-host_name-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_7__sys-host_name-vu-verify.out @@ -77,7 +77,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_8__sys-host_name-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_8__sys-host_name-vu-verify.out index 2ea0477de3f..6eb09724dba 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_8__sys-host_name-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_8__sys-host_name-vu-verify.out @@ -77,7 +77,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_9__sys-host_name-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_9__sys-host_name-vu-verify.out index 2ea0477de3f..6eb09724dba 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_9__sys-host_name-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_9__sys-host_name-vu-verify.out @@ -77,7 +77,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__14_3__sys-host_name-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__14_3__sys-host_name-vu-verify.out index 2ea0477de3f..6eb09724dba 100644 --- a/test/JDBC/expected/latest__verification_cleanup__14_3__sys-host_name-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__14_3__sys-host_name-vu-verify.out @@ -77,7 +77,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__14_5__ISC-Check-Constraints-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__14_5__ISC-Check-Constraints-vu-verify.out index a7c3f6cbbd9..98fa313bc63 100644 --- a/test/JDBC/expected/latest__verification_cleanup__14_5__ISC-Check-Constraints-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__14_5__ISC-Check-Constraints-vu-verify.out @@ -31,8 +31,8 @@ isc_check_constraints_db1#!#dbo#!#test_datetime_c_datetimeoffset_check#!#(((c_da isc_check_constraints_db1#!#dbo#!#test_datetime_c_smalldatetime_check#!#((c_smalldatetime < '2007-05-08 12:35:00')) isc_check_constraints_db1#!#dbo#!#test_datetime_c_time_check#!#(((c_time < '09:00:00') AND (c_time < CAST('09:00:00' AS time(6))))) isc_check_constraints_db1#!#dbo#!#test_functioncall_col1_check#!#((isjson(col1) > 0)) -isc_check_constraints_db1#!#dbo#!#test_functioncall_col1_check1#!#(("right"(col1, 1) <> ',')) -isc_check_constraints_db1#!#dbo#!#test_functioncall_col1_check2#!#((ltrim(col1) <> '')) +isc_check_constraints_db1#!#dbo#!#test_functioncall_col1_check1#!#((pg_catalog."right"(col1, 1) <> ',')) +isc_check_constraints_db1#!#dbo#!#test_functioncall_col1_check2#!#((pg_catalog.ltrim(col1) <> '')) isc_check_constraints_db1#!#dbo#!#test_functioncall_col1_check3#!#((CAST((getutcdate() AT TIME ZONE col1) AS nvarchar(128)) <> '')) isc_check_constraints_db1#!#dbo#!#test_null_a_check#!#((a IS NOT NULL)) isc_check_constraints_db1#!#dbo#!#test_null1_a_check#!#((a <> CAST(NULL AS int))) diff --git a/test/JDBC/expected/left-before-15_8-or-16_4-vu-cleanup.out b/test/JDBC/expected/left-before-15_8-or-16_4-vu-cleanup.out new file mode 100644 index 00000000000..c172e1720e0 --- /dev/null +++ b/test/JDBC/expected/left-before-15_8-or-16_4-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_left_itvf_func +GO + +DROP FUNCTION babel_4489_left_dep_func +GO + +DROP PROCEDURE babel_4489_left_dep_proc +GO + +DROP VIEW babel_4489_left_dep_view +GO + +DROP TABLE babel_4489_left_UDT +GO + +DROP VIEW babel_4489_left_dep_view_1 +GO + +DROP VIEW babel_4489_left_dep_view_2 +GO + +DROP VIEW babel_4489_left_dep_view_3 +GO + +DROP VIEW babel_4489_left_dep_view_4 +GO + +DROP VIEW babel_4489_left_dep_view_5 +GO + +DROP VIEW babel_4489_left_dep_view_6 +GO + +DROP VIEW babel_4489_left_dep_view_7 +GO + +DROP TYPE dbo.babel_4489_left_varUDT +GO + +DROP TYPE dbo.babel_4489_left_imageUDT +GO + +DROP TABLE babel_4489_left_text +GO + +DROP TABLE babel_4489_left_image +GO + +DROP TABLE babel_4489_left_arabic_ci_ai +GO + +DROP TABLE babel_4489_left_arabic_cs_as +GO + +DROP TABLE babel_4489_left_arabic_ci_as +GO + +DROP TABLE babel_4489_left_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_left_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_left_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_left_t5 +GO + +DROP TABLE babel_4489_left_t4 +GO + +DROP TABLE babel_4489_left_t3 +GO + +DROP TABLE babel_4489_left_t2 +GO + +DROP TABLE babel_4489_left_t1 +GO diff --git a/test/JDBC/expected/left-before-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/left-before-15_8-or-16_4-vu-prepare.out new file mode 100644 index 00000000000..8e203bb67d1 --- /dev/null +++ b/test/JDBC/expected/left-before-15_8-or-16_4-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4489_left_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_left_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4489_left_t1 VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_left_t2 VALUES(N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_left_t3 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_left_t4 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_left_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_left_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_left_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_left_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_left_arabic_ci_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_left_arabic_cs_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_left_arabic_ci_ai VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_image(a IMAGE) +GO +INSERT INTO babel_4489_left_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_left_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_left_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4489_left_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_left_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_left_UDT(a dbo.babel_4489_left_imageUDT, b dbo.babel_4489_left_varUDT) +GO +INSERT INTO babel_4489_left_UDT VALUES(CAST('abcdef' as dbo.babel_4489_left_imageUDT), CAST('abcdef' as dbo.babel_4489_left_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4489_left_dep_view AS + SELECT LEFT(a, 5) as result from babel_4489_left_t2 +GO + +CREATE PROCEDURE babel_4489_left_dep_proc AS + SELECT LEFT(a, 5) as result from babel_4489_left_t2 +GO + +CREATE FUNCTION babel_4489_left_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 LEFT(a, 5) from babel_4489_left_t2) +END +GO + +CREATE VIEW babel_4489_left_dep_view_1 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t1 +GO + +CREATE VIEW babel_4489_left_dep_view_2 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t2 +GO + +CREATE VIEW babel_4489_left_dep_view_3 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t3 +GO + +CREATE VIEW babel_4489_left_dep_view_4 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t4 +GO + +CREATE VIEW babel_4489_left_dep_view_5 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t5 +GO + +CREATE VIEW babel_4489_left_dep_view_6 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_text +GO + +CREATE VIEW babel_4489_left_dep_view_7 AS + SELECT LEFT(b, 5) as result FROM babel_4489_left_text +GO + +CREATE FUNCTION babel_4489_left_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT LEFT(a, 5) as result from babel_4489_left_t2) +GO diff --git a/test/JDBC/expected/left-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/left-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..d8b4baed87a --- /dev/null +++ b/test/JDBC/expected/left-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,745 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT LEFT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT LEFT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT LEFT('AbdefGhi', 2) +GO +~~START~~ +varchar +Ab +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +procedureName +~~END~~ + + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +varchar +|abc?d| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +varchar +|??·?| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·?| +~~END~~ + + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +varchar +abc?d +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +??·? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +nvarchar +|abc?d| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +nvarchar +|??·?| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO +~~START~~ +nvarchar +|abc🙂d| +|比尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +nvarchar +比尔·拉 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO +~~START~~ +text +abc?d +~~END~~ + + +EXEC babel_4489_left_dep_proc +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_itvf_func() +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_1 +GO +~~START~~ +text +abc?d +??·?? +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_2 +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_3 +GO +~~START~~ +text + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_4 +GO +~~START~~ +text + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_5 +GO +~~START~~ +text +0x202 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_6 +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_7 +GO +~~START~~ +text +abc?d +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +abc +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +195 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +12: +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO +~~START~~ +varchar +abc?d +~~END~~ + + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT LEFT('AbdefGhi', 2) +GO +~~START~~ +varchar +Ab +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +procedureName +~~END~~ + + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +varchar +|abc?d| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +varchar +|??·?| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·?| +~~END~~ + + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +varchar +abc?d +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +??·? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +nvarchar +|abc?d| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +nvarchar +|??·?| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO +~~START~~ +nvarchar +|abc🙂d| +|比尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +nvarchar +比尔·拉 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +EXEC babel_4489_left_dep_proc +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_itvf_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_1 +GO +~~START~~ +nvarchar +abc🙂d +比尔·拉莫 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_2 +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_3 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_4 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_5 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_6 +GO +~~START~~ +varchar +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_7 +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +abc +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +195 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +12: +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO +~~START~~ +varchar +abc?d +~~END~~ + + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·??? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·??? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·??? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|??·??? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +EXEC babel_4489_ltrim_dep_proc +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO +~~START~~ +varchar +|abc?defghi?? | +|??·??? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO +~~START~~ +varchar +|0x2020616263642020| +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/ltrim-vu-cleanup.out b/test/JDBC/expected/ltrim-vu-cleanup.out new file mode 100644 index 00000000000..7cbd333dee1 --- /dev/null +++ b/test/JDBC/expected/ltrim-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_ltrim_itvf_func +GO + +DROP FUNCTION babel_4489_ltrim_dep_func +GO + +DROP PROCEDURE babel_4489_ltrim_dep_proc +GO + +DROP VIEW babel_4489_ltrim_dep_view +GO + +DROP VIEW babel_4489_ltrim_dep_view_1 +GO + +DROP VIEW babel_4489_ltrim_dep_view_2 +GO + +DROP VIEW babel_4489_ltrim_dep_view_3 +GO + +DROP VIEW babel_4489_ltrim_dep_view_4 +GO + +DROP VIEW babel_4489_ltrim_dep_view_5 +GO + +DROP VIEW babel_4489_ltrim_dep_view_6 +GO + +DROP VIEW babel_4489_ltrim_dep_view_7 +GO + +DROP TABLE babel_4489_ltrim_UDT +GO + +DROP TYPE dbo.babel_4489_ltrim_varUDT +GO + +DROP TYPE dbo.babel_4489_ltrim_imageUDT +GO + +DROP TABLE babel_4489_ltrim_text +GO + +DROP TABLE babel_4489_ltrim_image +GO + +DROP TABLE babel_4489_ltrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_ltrim_arabic_cs_as +GO + +DROP TABLE babel_4489_ltrim_arabic_ci_as +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_ltrim_t5 +GO + +DROP TABLE babel_4489_ltrim_t4 +GO + +DROP TABLE babel_4489_ltrim_t3 +GO + +DROP TABLE babel_4489_ltrim_t2 +GO + +DROP TABLE babel_4489_ltrim_t1 +GO diff --git a/test/JDBC/expected/ltrim-vu-prepare.out b/test/JDBC/expected/ltrim-vu-prepare.out new file mode 100644 index 00000000000..5c88f4e03ed --- /dev/null +++ b/test/JDBC/expected/ltrim-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4489_ltrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_ltrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t3 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t4 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_ltrim_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_ltrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_ltrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_ltrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_image(a IMAGE) +GO +INSERT INTO babel_4489_ltrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_ltrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_ltrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4489_ltrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_ltrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_ltrim_UDT(a dbo.babel_4489_ltrim_imageUDT, b dbo.babel_4489_ltrim_varUDT) +GO +INSERT INTO babel_4489_ltrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_ltrim_imageUDT), CAST('abcdef' as dbo.babel_4489_ltrim_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4489_ltrim_dep_view AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE PROCEDURE babel_4489_ltrim_dep_proc AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE FUNCTION babel_4489_ltrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + LTRIM(a) + '|') FROM babel_4489_ltrim_t2) +END +GO + +CREATE VIEW babel_4489_ltrim_dep_view_1 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t1 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_2 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_3 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t3 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_4 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t4 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_5 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t5 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_6 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_text +GO + +CREATE VIEW babel_4489_ltrim_dep_view_7 AS + SELECT ('|' + LTRIM(b) + '|') as result FROM babel_4489_ltrim_text +GO + +CREATE FUNCTION babel_4489_ltrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2) +GO diff --git a/test/JDBC/expected/ltrim-vu-verify.out b/test/JDBC/expected/ltrim-vu-verify.out new file mode 100644 index 00000000000..de546af507f --- /dev/null +++ b/test/JDBC/expected/ltrim-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT LTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·??? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·??? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·??? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|??·??? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +EXEC babel_4489_ltrim_dep_proc +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO +~~START~~ +varchar +|abcd | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/left-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/left-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..028fff54cfb --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/left-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,745 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT LEFT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT LEFT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT LEFT('AbdefGhi', 2) +GO +~~START~~ +varchar +Ab +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +procedureName +~~END~~ + + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +varchar +|abc?d| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +varchar +|比尔·拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +varchar +abc?d +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +nvarchar +|abc?d| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +nvarchar +|比尔·拉| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO +~~START~~ +nvarchar +|abc🙂d| +|比尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +nvarchar +比尔·拉 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO +~~START~~ +text +abc?d +~~END~~ + + +EXEC babel_4489_left_dep_proc +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_itvf_func() +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_1 +GO +~~START~~ +text +abc?d +比尔·拉莫 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_2 +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_3 +GO +~~START~~ +text + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_4 +GO +~~START~~ +text + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_5 +GO +~~START~~ +text +0x202 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_6 +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_7 +GO +~~START~~ +text +abc?d +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +abc +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +195 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +12: +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO +~~START~~ +varchar +abc?d +~~END~~ + + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT LEFT('AbdefGhi', 2) +GO +~~START~~ +varchar +Ab +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +procedureName +~~END~~ + + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +varchar +|abc?d| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +varchar +|比尔·拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +varchar +abc?d +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +nvarchar +|abc?d| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +nvarchar +|比尔·拉| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO +~~START~~ +nvarchar +|abc🙂d| +|比尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +nvarchar +比尔·拉 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +EXEC babel_4489_left_dep_proc +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_itvf_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_1 +GO +~~START~~ +nvarchar +abc🙂d +比尔·拉莫 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_2 +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_3 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_4 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_5 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_6 +GO +~~START~~ +varchar +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_7 +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +abc +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +195 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +12: +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO +~~START~~ +varchar +abc?d +~~END~~ + + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +EXEC babel_4489_ltrim_dep_proc +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO +~~START~~ +varchar +|abc?defghi?? | +|比尔·拉莫斯 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO +~~START~~ +varchar +|0x2020616263642020| +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/ltrim-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/ltrim-vu-verify.out new file mode 100644 index 00000000000..88ad03f724c --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/ltrim-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT LTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +EXEC babel_4489_ltrim_dep_proc +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO +~~START~~ +varchar +|abcd | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..8d2dd65532f --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,716 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RIGHT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT RIGHT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2) +GO +~~START~~ +varchar +hi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +varchar +|ghi?? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +nvarchar +|ghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂 | +|·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +nvarchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO +~~START~~ +text +ghi?? +~~END~~ + + +EXEC babel_4489_right_dep_proc +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_itvf_func() +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_1 +GO +~~START~~ +text +?? + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_2 +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_3 +GO +~~START~~ +text + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_4 +GO +~~START~~ +text +i +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_5 +GO +~~START~~ +text +42020 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_6 +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_7 +GO +~~START~~ +text +ghi?? +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +def +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +dy> +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-vu-verify.out new file mode 100644 index 00000000000..d5da9980729 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/right-vu-verify.out @@ -0,0 +1,716 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RIGHT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT RIGHT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2) +GO +~~START~~ +varchar +hi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +varchar +|ghi?? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +nvarchar +|ghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂 | +|·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +nvarchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +EXEC babel_4489_right_dep_proc +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_itvf_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_1 +GO +~~START~~ +nvarchar +🙂🙂 + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_2 +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_3 +GO +~~START~~ +varchar + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_4 +GO +~~START~~ +varchar +i +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_5 +GO +~~START~~ +varchar +bcd +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_6 +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_7 +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +def +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +dy> +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..49fdb73cc23 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +EXEC babel_4489_rtrim_dep_proc +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO +~~START~~ +varchar +| abc?defghi??| +| 比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO +~~START~~ +varchar +|0x2020616263642020| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO +~~START~~ +varchar + abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO +~~START~~ +nvarchar + abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-vu-verify.out new file mode 100644 index 00000000000..f45246480d1 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/rtrim-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +EXEC babel_4489_rtrim_dep_proc +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO +~~START~~ +varchar +| abcd| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO +~~START~~ +varchar + abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO +~~START~~ +nvarchar + abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/trim-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/trim-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..15998b983aa --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/trim-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,1364 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT TRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM('' FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM '') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|?c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO +~~START~~ +nvarchar +|c🙂defghi| +|尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +EXEC babel_4489_trim_dep_proc +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_itvf_func() +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_1 +GO +~~START~~ +varchar +|abc?defghi??| +|比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_2 +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_5 +GO +~~START~~ +varchar +|0x61626364| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_6 +GO +~~START~~ +varchar +|cdefgh| +~~END~~ + + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "binary" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +cdef +~~END~~ + + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 1 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "decimal" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type numeric is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type double precision is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type real is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type bigint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type integer is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type tinyint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type money is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallmoney is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "bit" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +9619FF-8B86-D011-B42D-00C04FC964 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +body> +~~END~~ + + +SELECT TRIM(NULL FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM('' FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM '') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|?c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO +~~START~~ +nvarchar +|c🙂defghi| +|尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +EXEC babel_4489_trim_dep_proc +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_itvf_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +|比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_2 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_5 +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +SELECT * FROM babel_4489_trim_dep_view_6 +GO +~~START~~ +varchar +|cdefgh| +~~END~~ + + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "binary" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +cdef +~~END~~ + + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 1 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "decimal" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type numeric is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type double precision is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type real is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type bigint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type integer is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type tinyint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type money is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallmoney is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "bit" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +9619FF-8B86-D011-B42D-00C04FC964 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +body> +~~END~~ + + +SELECT LEFT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT LEFT('AbdefGhi', 2) +GO +~~START~~ +varchar +Ab +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +procedureName +~~END~~ + + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +varchar +|abc?d| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +varchar +|比??拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +varchar +abc?d +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +比??拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +nvarchar +|abc?d| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +nvarchar +|比??拉| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO +~~START~~ +nvarchar +|abc🙂d| +|比尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +nvarchar +比尔·拉 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO +~~START~~ +text +abc?d +~~END~~ + + +EXEC babel_4489_left_dep_proc +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_itvf_func() +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_1 +GO +~~START~~ +text +abc?d +比??拉莫 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_2 +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_3 +GO +~~START~~ +text + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_4 +GO +~~START~~ +text + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_5 +GO +~~START~~ +text +0x202 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_6 +GO +~~START~~ +text +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_7 +GO +~~START~~ +text +abc?d +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +abc +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +195 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +12: +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO +~~START~~ +varchar +abc?d +~~END~~ + + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT LEFT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the left function.)~~ + + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT LEFT('AbdefGhi', 2) +GO +~~START~~ +varchar +Ab +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT LEFT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +procedureName +~~END~~ + + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO +~~START~~ +nvarchar +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +varchar +|abc?d| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +varchar +|比??拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉| +~~END~~ + + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +varchar +abc?d +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +比??拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO +~~START~~ +varchar +比尔·拉 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO +~~START~~ +varchar +الله +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO +~~START~~ +varchar +الله +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO +~~START~~ +nvarchar +|abc?d| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO +~~START~~ +nvarchar +|比??拉| +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO +~~START~~ +nvarchar +|abc🙂d| +|比尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO +~~START~~ +nvarchar +比尔·拉 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO +~~START~~ +varchar +abcd +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +EXEC babel_4489_left_dep_proc +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_itvf_func() +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_1 +GO +~~START~~ +nvarchar +abc🙂d +比尔·拉莫 +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_2 +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_3 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_4 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_5 +GO +~~START~~ +varchar + abc +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_6 +GO +~~START~~ +varchar +abc?d +~~END~~ + + +SELECT * FROM babel_4489_left_dep_view_7 +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO +~~START~~ +varchar +abc +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +201 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +195 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +12: +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +196 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +123 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of left function.)~~ + + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO +~~START~~ +varchar +abc?d +~~END~~ + + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO +~~START~~ +nvarchar +abc🙂d +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of left function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +6F9 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比??拉莫斯 | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +EXEC babel_4489_ltrim_dep_proc +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO +~~START~~ +varchar +|abc?defghi?? | +|比??拉莫斯 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO +~~START~~ +varchar +|0x2020616263642020| +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/ltrim-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/ltrim-vu-verify.out new file mode 100644 index 00000000000..9d48cccb442 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/ltrim-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT LTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|比尔·拉莫斯 | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتقين | +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比??拉莫斯 | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯 | +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +EXEC babel_4489_ltrim_dep_proc +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +|比尔·拉莫斯 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO +~~START~~ +varchar +|abcd | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂 | +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of ltrim function.)~~ + + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of ltrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..94d955c4bc5 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,716 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RIGHT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT RIGHT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2) +GO +~~START~~ +varchar +hi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +varchar +|ghi?? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +?拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +nvarchar +|ghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +nvarchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂 | +|·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +nvarchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO +~~START~~ +text +ghi?? +~~END~~ + + +EXEC babel_4489_right_dep_proc +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_itvf_func() +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_1 +GO +~~START~~ +text +?? + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_2 +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_3 +GO +~~START~~ +text + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_4 +GO +~~START~~ +text +i +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_5 +GO +~~START~~ +text +42020 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_6 +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_7 +GO +~~START~~ +text +ghi?? +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +def +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +dy> +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-vu-verify.out new file mode 100644 index 00000000000..0d822e07f01 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/right-vu-verify.out @@ -0,0 +1,716 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RIGHT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT RIGHT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2) +GO +~~START~~ +varchar +hi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +varchar +|ghi?? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +?拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +nvarchar +|ghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +nvarchar +|比??拉莫斯 | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂 | +|·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +nvarchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +EXEC babel_4489_right_dep_proc +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_itvf_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_1 +GO +~~START~~ +nvarchar +🙂🙂 + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_2 +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_3 +GO +~~START~~ +varchar + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_4 +GO +~~START~~ +varchar +i +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_5 +GO +~~START~~ +varchar +bcd +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_6 +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_7 +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +def +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +dy> +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..8a7bf0af644 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比??拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比??拉莫斯| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比??拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比??拉莫斯| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +EXEC babel_4489_rtrim_dep_proc +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO +~~START~~ +varchar +| abc?defghi??| +| 比??拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO +~~START~~ +varchar +|0x2020616263642020| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO +~~START~~ +varchar + abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO +~~START~~ +nvarchar + abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-vu-verify.out new file mode 100644 index 00000000000..ca5eeff5d96 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/rtrim-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比??拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比??拉莫斯| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| 比??拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比??拉莫斯| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +EXEC babel_4489_rtrim_dep_proc +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO +~~START~~ +varchar +| abcd| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO +~~START~~ +varchar + abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO +~~START~~ +nvarchar + abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/trim-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/trim-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..0731b7cc2c3 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/trim-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,1364 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT TRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM('' FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM '') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|?c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO +~~START~~ +nvarchar +|c🙂defghi| +|尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +EXEC babel_4489_trim_dep_proc +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_itvf_func() +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_1 +GO +~~START~~ +varchar +|abc?defghi??| +|比??拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_2 +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_5 +GO +~~START~~ +varchar +|0x61626364| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_6 +GO +~~START~~ +varchar +|cdefgh| +~~END~~ + + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "binary" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +cdef +~~END~~ + + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 1 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "decimal" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type numeric is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type double precision is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type real is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type bigint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type integer is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type tinyint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type money is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallmoney is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "bit" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +9619FF-8B86-D011-B42D-00C04FC964 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +body> +~~END~~ + + +SELECT TRIM(NULL FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM('' FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM '') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比??拉莫斯| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|?c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO +~~START~~ +nvarchar +|c🙂defghi| +|尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +EXEC babel_4489_trim_dep_proc +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_itvf_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +|比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_2 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_5 +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +SELECT * FROM babel_4489_trim_dep_view_6 +GO +~~START~~ +varchar +|cdefgh| +~~END~~ + + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "binary" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +cdef +~~END~~ + + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 1 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "decimal" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type numeric is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type double precision is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type real is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type bigint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type integer is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type tinyint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type money is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallmoney is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "bit" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +9619FF-8B86-D011-B42D-00C04FC964 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +body> +~~END~~ + + +SELECT RIGHT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2) +GO +~~START~~ +varchar +hi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +varchar +|ghi?? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +varchar +|·??? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|·??? | +~~END~~ + + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +·??? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +nvarchar +|ghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +nvarchar +|·??? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂 | +|·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +nvarchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO +~~START~~ +text +ghi?? +~~END~~ + + +EXEC babel_4489_right_dep_proc +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_itvf_func() +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_1 +GO +~~START~~ +text +?? + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_2 +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_3 +GO +~~START~~ +text + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_4 +GO +~~START~~ +text +i +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_5 +GO +~~START~~ +text +42020 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_6 +GO +~~START~~ +text +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_7 +GO +~~START~~ +text +ghi?? +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +def +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +dy> +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + 2) +~~END~~ + diff --git a/test/JDBC/expected/right-vu-cleanup.out b/test/JDBC/expected/right-vu-cleanup.out new file mode 100644 index 00000000000..f3aad52c027 --- /dev/null +++ b/test/JDBC/expected/right-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_right_itvf_func +GO + +DROP FUNCTION babel_4489_right_dep_func +GO + +DROP PROCEDURE babel_4489_right_dep_proc +GO + +DROP VIEW babel_4489_right_dep_view +GO + +DROP TABLE babel_4489_right_UDT +GO + +DROP VIEW babel_4489_right_dep_view_1 +GO + +DROP VIEW babel_4489_right_dep_view_2 +GO + +DROP VIEW babel_4489_right_dep_view_3 +GO + +DROP VIEW babel_4489_right_dep_view_4 +GO + +DROP VIEW babel_4489_right_dep_view_5 +GO + +DROP VIEW babel_4489_right_dep_view_6 +GO + +DROP VIEW babel_4489_right_dep_view_7 +GO + +DROP TYPE dbo.babel_4489_right_varUDT +GO + +DROP TYPE dbo.babel_4489_right_imageUDT +GO + +DROP TABLE babel_4489_right_text +GO + +DROP TABLE babel_4489_right_image +GO + +DROP TABLE babel_4489_right_arabic_ci_ai +GO + +DROP TABLE babel_4489_right_arabic_cs_as +GO + +DROP TABLE babel_4489_right_arabic_ci_as +GO + +DROP TABLE babel_4489_right_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_right_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_right_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_right_t5 +GO + +DROP TABLE babel_4489_right_t4 +GO + +DROP TABLE babel_4489_right_t3 +GO + +DROP TABLE babel_4489_right_t2 +GO + +DROP TABLE babel_4489_right_t1 +GO diff --git a/test/JDBC/expected/right-vu-prepare.out b/test/JDBC/expected/right-vu-prepare.out new file mode 100644 index 00000000000..b352b44be5a --- /dev/null +++ b/test/JDBC/expected/right-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4489_right_t1(a NCHAR(15)) +GO +INSERT INTO babel_4489_right_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4489_right_t1 VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_right_t2 VALUES(N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_right_t3 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_right_t4 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_right_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_right_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_right_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_right_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_right_arabic_ci_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_right_arabic_cs_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_right_arabic_ci_ai VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_image(a IMAGE) +GO +INSERT INTO babel_4489_right_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_right_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_right_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4489_right_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_right_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_right_UDT(a dbo.babel_4489_right_imageUDT, b dbo.babel_4489_right_varUDT) +GO +INSERT INTO babel_4489_right_UDT VALUES(CAST('abcdef' as dbo.babel_4489_right_imageUDT), CAST('abcdef' as dbo.babel_4489_right_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4489_right_dep_view AS + SELECT RIGHT(a, 5) as result from babel_4489_right_t2 +GO + +CREATE PROCEDURE babel_4489_right_dep_proc AS + SELECT RIGHT(a, 5) as result from babel_4489_right_t2 +GO + +CREATE FUNCTION babel_4489_right_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 RIGHT(a, 5) from babel_4489_right_t2) +END +GO + +CREATE VIEW babel_4489_right_dep_view_1 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t1 +GO + +CREATE VIEW babel_4489_right_dep_view_2 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t2 +GO + +CREATE VIEW babel_4489_right_dep_view_3 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t3 +GO + +CREATE VIEW babel_4489_right_dep_view_4 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t4 +GO + +CREATE VIEW babel_4489_right_dep_view_5 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t5 +GO + +CREATE VIEW babel_4489_right_dep_view_6 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_text +GO + +CREATE VIEW babel_4489_right_dep_view_7 AS + SELECT RIGHT(b, 5) as result FROM babel_4489_right_text +GO + +CREATE FUNCTION babel_4489_right_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT RIGHT(a, 5) as result from babel_4489_right_t2) +GO diff --git a/test/JDBC/expected/right-vu-verify.out b/test/JDBC/expected/right-vu-verify.out new file mode 100644 index 00000000000..8f10999211a --- /dev/null +++ b/test/JDBC/expected/right-vu-verify.out @@ -0,0 +1,716 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RIGHT(NULL, -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT RIGHT(NULL, 0) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, 2) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT('abc', NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT RIGHT(NULL, NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid length parameter passed to the right function.)~~ + + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO +~~START~~ +varchar +|| +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2) +GO +~~START~~ +varchar +hi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483646) +GO +~~START~~ +varchar +AbdefGhi +~~END~~ + + +SELECT RIGHT('AbdefGhi', 2147483650) +GO +~~ERROR (Code: 8115)~~ + +~~ERROR (Message: integer out of range)~~ + + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +varchar +|ghi?? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +varchar +|·??? | +~~END~~ + + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|·??? | +~~END~~ + + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +varchar +|abc?defghi?? | +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +·??? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +varchar +abc?defghi?? +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO +~~START~~ +varchar +·拉莫斯 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO +~~START~~ +varchar +تقين +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO +~~START~~ +nvarchar +|ghi?? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO +~~START~~ +nvarchar +|·??? | +~~END~~ + + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO +~~START~~ +nvarchar +|abc?defghi?? | +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂 | +|·拉莫斯 | +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +nvarchar +·拉莫斯 +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO +~~START~~ +nvarchar +abc🙂defghi🙂🙂 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO +~~START~~ +varchar +efgh +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +EXEC babel_4489_right_dep_proc +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_itvf_func() +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_1 +GO +~~START~~ +nvarchar +🙂🙂 + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_2 +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_3 +GO +~~START~~ +varchar + +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_4 +GO +~~START~~ +varchar +i +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_5 +GO +~~START~~ +varchar +bcd +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_6 +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +SELECT * FROM babel_4489_right_dep_view_7 +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO +~~START~~ +varchar +def +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +5.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of right function.)~~ + + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO +~~START~~ +varchar +ghi?? +~~END~~ + + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO +~~START~~ +nvarchar +ghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of right function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +4FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar +dy> +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO +~~START~~ +varchar + 2) +~~END~~ + diff --git a/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-cleanup.out b/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-cleanup.out new file mode 100644 index 00000000000..e9c3c566bdb --- /dev/null +++ b/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_rtrim_itvf_func +GO + +DROP FUNCTION babel_4489_rtrim_dep_func +GO + +DROP PROCEDURE babel_4489_rtrim_dep_proc +GO + +DROP VIEW babel_4489_rtrim_dep_view +GO + +DROP VIEW babel_4489_rtrim_dep_view_1 +GO + +DROP VIEW babel_4489_rtrim_dep_view_2 +GO + +DROP VIEW babel_4489_rtrim_dep_view_3 +GO + +DROP VIEW babel_4489_rtrim_dep_view_4 +GO + +DROP VIEW babel_4489_rtrim_dep_view_5 +GO + +DROP VIEW babel_4489_rtrim_dep_view_6 +GO + +DROP VIEW babel_4489_rtrim_dep_view_7 +GO + +DROP TABLE babel_4489_rtrim_UDT +GO + +DROP TYPE dbo.babel_4489_rtrim_varUDT +GO + +DROP TYPE dbo.babel_4489_rtrim_imageUDT +GO + +DROP TABLE babel_4489_rtrim_text +GO + +DROP TABLE babel_4489_rtrim_image +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_rtrim_arabic_cs_as +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_rtrim_t5 +GO + +DROP TABLE babel_4489_rtrim_t4 +GO + +DROP TABLE babel_4489_rtrim_t3 +GO + +DROP TABLE babel_4489_rtrim_t2 +GO + +DROP TABLE babel_4489_rtrim_t1 +GO diff --git a/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-prepare.out new file mode 100644 index 00000000000..87af3cec2e7 --- /dev/null +++ b/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4489_rtrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_rtrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t3 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t4 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_rtrim_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_image(a IMAGE) +GO +INSERT INTO babel_4489_rtrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_rtrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4489_rtrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_rtrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_rtrim_UDT(a dbo.babel_4489_rtrim_imageUDT, b dbo.babel_4489_rtrim_varUDT) +GO +INSERT INTO babel_4489_rtrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_rtrim_imageUDT), CAST('abcdef' as dbo.babel_4489_rtrim_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4489_rtrim_dep_view AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE PROCEDURE babel_4489_rtrim_dep_proc AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE FUNCTION babel_4489_rtrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + RTRIM(a) + '|') FROM babel_4489_rtrim_t2) +END +GO + +CREATE VIEW babel_4489_rtrim_dep_view_1 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t1 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_2 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_3 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t3 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_4 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t4 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_5 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t5 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_6 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE VIEW babel_4489_rtrim_dep_view_7 AS + SELECT ('|' + RTRIM(b) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE FUNCTION babel_4489_rtrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2) +GO diff --git a/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..7c340544854 --- /dev/null +++ b/test/JDBC/expected/rtrim-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| ??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| ??·???| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| ??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| ??·???| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +EXEC babel_4489_rtrim_dep_proc +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO +~~START~~ +varchar +| abc?defghi??| +| ??·???| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO +~~START~~ +varchar +|0x2020616263642020| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO +~~START~~ +varchar + abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO +~~START~~ +nvarchar + abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/rtrim-vu-cleanup.out b/test/JDBC/expected/rtrim-vu-cleanup.out new file mode 100644 index 00000000000..e9c3c566bdb --- /dev/null +++ b/test/JDBC/expected/rtrim-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_rtrim_itvf_func +GO + +DROP FUNCTION babel_4489_rtrim_dep_func +GO + +DROP PROCEDURE babel_4489_rtrim_dep_proc +GO + +DROP VIEW babel_4489_rtrim_dep_view +GO + +DROP VIEW babel_4489_rtrim_dep_view_1 +GO + +DROP VIEW babel_4489_rtrim_dep_view_2 +GO + +DROP VIEW babel_4489_rtrim_dep_view_3 +GO + +DROP VIEW babel_4489_rtrim_dep_view_4 +GO + +DROP VIEW babel_4489_rtrim_dep_view_5 +GO + +DROP VIEW babel_4489_rtrim_dep_view_6 +GO + +DROP VIEW babel_4489_rtrim_dep_view_7 +GO + +DROP TABLE babel_4489_rtrim_UDT +GO + +DROP TYPE dbo.babel_4489_rtrim_varUDT +GO + +DROP TYPE dbo.babel_4489_rtrim_imageUDT +GO + +DROP TABLE babel_4489_rtrim_text +GO + +DROP TABLE babel_4489_rtrim_image +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_rtrim_arabic_cs_as +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_rtrim_t5 +GO + +DROP TABLE babel_4489_rtrim_t4 +GO + +DROP TABLE babel_4489_rtrim_t3 +GO + +DROP TABLE babel_4489_rtrim_t2 +GO + +DROP TABLE babel_4489_rtrim_t1 +GO diff --git a/test/JDBC/expected/rtrim-vu-prepare.out b/test/JDBC/expected/rtrim-vu-prepare.out new file mode 100644 index 00000000000..87af3cec2e7 --- /dev/null +++ b/test/JDBC/expected/rtrim-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4489_rtrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_rtrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t3 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t4 VALUES(' abcdefghi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_rtrim_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_image(a IMAGE) +GO +INSERT INTO babel_4489_rtrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_rtrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_rtrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4489_rtrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_rtrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_rtrim_UDT(a dbo.babel_4489_rtrim_imageUDT, b dbo.babel_4489_rtrim_varUDT) +GO +INSERT INTO babel_4489_rtrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_rtrim_imageUDT), CAST('abcdef' as dbo.babel_4489_rtrim_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4489_rtrim_dep_view AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE PROCEDURE babel_4489_rtrim_dep_proc AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE FUNCTION babel_4489_rtrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + RTRIM(a) + '|') FROM babel_4489_rtrim_t2) +END +GO + +CREATE VIEW babel_4489_rtrim_dep_view_1 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t1 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_2 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_3 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t3 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_4 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t4 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_5 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t5 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_6 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE VIEW babel_4489_rtrim_dep_view_7 AS + SELECT ('|' + RTRIM(b) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE FUNCTION babel_4489_rtrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2) +GO diff --git a/test/JDBC/expected/rtrim-vu-verify.out b/test/JDBC/expected/rtrim-vu-verify.out new file mode 100644 index 00000000000..0a1d5f82034 --- /dev/null +++ b/test/JDBC/expected/rtrim-vu-verify.out @@ -0,0 +1,610 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT RTRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| ??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| ??·???| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| ??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO +~~START~~ +varchar +| 比尔·拉莫斯| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO +~~START~~ +varchar +| الله مع المتقين| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| ??·???| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +| 比尔·拉莫斯| +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO +~~START~~ +varchar +| abcdefgh| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +EXEC babel_4489_rtrim_dep_proc +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +| 比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO +~~START~~ +varchar +| abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO +~~START~~ +varchar +| abcd| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO +~~START~~ +varchar +| abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO +~~START~~ +nvarchar +| abc🙂defghi🙂🙂| +~~END~~ + + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +2016-12-21 00:00:00 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1955-12-13 12:43:00 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12:10:05.1237 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1234 +10:00 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1968-10-23 12:45:37.1237 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +123456 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345.1 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12345678 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +235 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +12356.0000 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of rtrim function.)~~ + + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO +~~START~~ +varchar + abc?defghi?? +~~END~~ + + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO +~~START~~ +nvarchar + abc🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of rtrim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +6F9619FF-8B86-D011-B42D-00C04FC964FF +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar + +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +POINT(1 2) +~~END~~ + diff --git a/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-cleanup.out b/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-cleanup.out new file mode 100644 index 00000000000..eb18e931d5e --- /dev/null +++ b/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-cleanup.out @@ -0,0 +1,26 @@ +DROP VIEW sys_host_name_vu_prepare__host_name_view +GO + +DROP FUNCTION sys_host_name_vu_prepare__host_name_func +GO + +DROP PROCEDURE sys_host_name_vu_prepare__host_name_proc +GO + +DROP VIEW sys_host_name_vu_prepare__dm_exec_connections_view +GO + +DROP FUNCTION sys_host_name_vu_prepare__dm_exec_connections_func +GO + +DROP PROCEDURE sys_host_name_vu_prepare__dm_exec_connections_proc +GO + +DROP VIEW sys_host_name_vu_prepare__dm_exec_sessions_view +GO + +DROP FUNCTION sys_host_name_vu_prepare__dm_exec_sessions_func +GO + +DROP PROCEDURE sys_host_name_vu_prepare__dm_exec_sessions_proc +GO diff --git a/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-prepare.out new file mode 100644 index 00000000000..c4153e6ca81 --- /dev/null +++ b/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-prepare.out @@ -0,0 +1,42 @@ +CREATE VIEW sys_host_name_vu_prepare__host_name_view AS SELECT DISTINCT hostname FROM sys.sysprocesses WHERE spid = @@SPID +GO + +CREATE FUNCTION sys_host_name_vu_prepare__host_name_func(@pid int) +RETURNS TABLE +AS +RETURN (SELECT DISTINCT CAST(hostname as nvarchar(128)) FROM sys.sysprocesses WHERE spid = @pid); +GO + +CREATE PROCEDURE sys_host_name_vu_prepare__host_name_proc +AS +SELECT DISTINCT hostname FROM sys.sysprocesses WHERE spid = @@SPID +GO + +-- Create objects that relied on dependent functions that were modified +CREATE VIEW sys_host_name_vu_prepare__dm_exec_connections_view AS select net_transport, protocol_type, protocol_version, endpoint_id, encrypt_option from sys.dm_exec_connections where session_id = @@SPID +GO + +CREATE FUNCTION sys_host_name_vu_prepare__dm_exec_connections_func(@pid int) +RETURNS TABLE +AS +RETURN (select net_transport, protocol_type, protocol_version, endpoint_id, encrypt_option from sys.dm_exec_connections where session_id = @pid); +GO + +CREATE PROCEDURE sys_host_name_vu_prepare__dm_exec_connections_proc +AS +select net_transport, protocol_type, protocol_version, endpoint_id, encrypt_option from sys.dm_exec_connections where session_id = @@SPID +GO + +CREATE VIEW sys_host_name_vu_prepare__dm_exec_sessions_view AS select language, host_name, client_version, TRIM('0123456789.' FROM client_interface_name), program_name, date_format, date_first from sys.dm_exec_sessions where session_id = @@SPID +GO + +CREATE FUNCTION sys_host_name_vu_prepare__dm_exec_sessions_func(@pid int) +RETURNS TABLE +AS +RETURN (select language, host_name, client_version, TRIM('0123456789.' FROM client_interface_name), program_name, date_format, date_first from sys.dm_exec_sessions where session_id = @pid); +GO + +CREATE PROCEDURE sys_host_name_vu_prepare__dm_exec_sessions_proc +AS +select language, host_name, client_version, TRIM('0123456789.' FROM client_interface_name), program_name, date_format, date_first from sys.dm_exec_sessions where session_id = @@SPID +GO diff --git a/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..36baa707a80 --- /dev/null +++ b/test/JDBC/expected/sys-host_name-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,83 @@ + +-- tsql password=12345678;workstationID=a_nice_workstation_name +-- explicitly specify a workstation name to check the HOST_NAME +-- T-SQL function and hostname entry in sys.sysprocesses view +SELECT HOST_NAME() +GO +~~START~~ +nvarchar +a_nice_workstation_name +~~END~~ + + +SELECT * from sys_host_name_vu_prepare__host_name_func(@@SPID) +GO +~~START~~ +nvarchar +a_nice_workstation_name +~~END~~ + + +SELECT * FROM sys_host_name_vu_prepare__host_name_view +GO +~~START~~ +nchar +a_nice_workstation_name +~~END~~ + + +EXECUTE sys_host_name_vu_prepare__host_name_proc +GO +~~START~~ +nchar +a_nice_workstation_name +~~END~~ + + +SELECT * from sys_host_name_vu_prepare__dm_exec_connections_func(@@SPID) +GO +~~START~~ +nvarchar#!#nvarchar#!#int#!#int#!#nvarchar +TCP#!#TSQL#!#1946157060#!#4#!#FALSE +~~END~~ + + +SELECT * FROM sys_host_name_vu_prepare__dm_exec_connections_view +GO +~~START~~ +nvarchar#!#nvarchar#!#int#!#int#!#nvarchar +TCP#!#TSQL#!#1946157060#!#4#!#FALSE +~~END~~ + + +EXECUTE sys_host_name_vu_prepare__dm_exec_connections_proc +GO +~~START~~ +nvarchar#!#nvarchar#!#int#!#int#!#nvarchar +TCP#!#TSQL#!#1946157060#!#4#!#FALSE +~~END~~ + + +SELECT * from sys_host_name_vu_prepare__dm_exec_sessions_func(@@SPID) +GO +~~START~~ +nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 +~~END~~ + + +SELECT * FROM sys_host_name_vu_prepare__dm_exec_sessions_view +GO +~~START~~ +nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 +~~END~~ + + +EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc +GO +~~START~~ +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint +us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 +~~END~~ + diff --git a/test/JDBC/expected/sys-host_name-vu-verify.out b/test/JDBC/expected/sys-host_name-vu-verify.out index ebffa467f79..13ef097ccf2 100644 --- a/test/JDBC/expected/sys-host_name-vu-verify.out +++ b/test/JDBC/expected/sys-host_name-vu-verify.out @@ -61,7 +61,7 @@ TCP#!#TSQL#!#1946157060#!#4#!#FALSE SELECT * from sys_host_name_vu_prepare__dm_exec_sessions_func(@@SPID) GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ @@ -69,7 +69,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso SELECT * FROM sys_host_name_vu_prepare__dm_exec_sessions_view GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ @@ -77,7 +77,7 @@ us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microso EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc GO ~~START~~ -nvarchar#!#nvarchar#!#int#!#text#!#nvarchar#!#nvarchar#!#smallint +nvarchar#!#nvarchar#!#int#!#nvarchar#!#nvarchar#!#nvarchar#!#smallint us_english#!#a_nice_workstation_name#!#131592#!#Microsoft JDBC Driver #!#Microsoft JDBC Driver for SQL Server#!#ymd#!#7 ~~END~~ diff --git a/test/JDBC/expected/trim-before-15_8-or-16_4-vu-cleanup.out b/test/JDBC/expected/trim-before-15_8-or-16_4-vu-cleanup.out new file mode 100644 index 00000000000..a5ab529c011 --- /dev/null +++ b/test/JDBC/expected/trim-before-15_8-or-16_4-vu-cleanup.out @@ -0,0 +1,77 @@ +DROP FUNCTION babel_4489_trim_itvf_func +GO + +DROP FUNCTION babel_4489_trim_dep_func +GO + +DROP PROCEDURE babel_4489_trim_dep_proc +GO + +DROP VIEW babel_4489_trim_dep_view +GO + +DROP VIEW babel_4489_trim_dep_view_1 +GO + +DROP VIEW babel_4489_trim_dep_view_2 +GO + +DROP VIEW babel_4489_trim_dep_view_3 +GO + +DROP VIEW babel_4489_trim_dep_view_4 +GO + +DROP VIEW babel_4489_trim_dep_view_5 +GO + +DROP VIEW babel_4489_trim_dep_view_6 +GO + +DROP TABLE babel_4489_trim_UDT +GO + +DROP TYPE dbo.babel_4489_trim_varUDT +GO + +DROP TYPE dbo.babel_4489_trim_imageUDT +GO + +DROP TABLE babel_4489_trim_text +GO + +DROP TABLE babel_4489_trim_image +GO + +DROP TABLE babel_4489_trim_arabic_ci_ai +GO + +DROP TABLE babel_4489_trim_arabic_cs_as +GO + +DROP TABLE babel_4489_trim_arabic_ci_as +GO + +DROP TABLE babel_4489_trim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_trim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_trim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_trim_t5 +GO + +DROP TABLE babel_4489_trim_t4 +GO + +DROP TABLE babel_4489_trim_t3 +GO + +DROP TABLE babel_4489_trim_t2 +GO + +DROP TABLE babel_4489_trim_t1 +GO diff --git a/test/JDBC/expected/trim-before-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/trim-before-15_8-or-16_4-vu-prepare.out new file mode 100644 index 00000000000..468efff53c9 --- /dev/null +++ b/test/JDBC/expected/trim-before-15_8-or-16_4-vu-prepare.out @@ -0,0 +1,152 @@ +CREATE TABLE babel_4489_trim_t1(a NCHAR(50), b NCHAR(20)) +GO +INSERT INTO babel_4489_trim_t1 VALUES(N' abc🙂defghi🙂🙂 ', N'ab🙂 ') +INSERT INTO babel_4489_trim_t1 VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_t2(a NVARCHAR(50), b NVARCHAR(20)) +GO +INSERT INTO babel_4489_trim_t2 VALUES(N' abc🙂defghi🙂🙂 ', N'ab🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_t3(a CHAR(50), b CHAR(20)) +GO +INSERT INTO babel_4489_trim_t3 VALUES(' abcdefghi ', 'abi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_t4(a VARCHAR(50), b VARCHAR(20)) +GO +INSERT INTO babel_4489_trim_t4 VALUES(' abcdefghi ', 'abi ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_t5(a VARBINARY(50), b VARBINARY(50)) +GO +INSERT INTO babel_4489_trim_t5 VALUES(0x61626364, 0x6164) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS, b VARCHAR(20) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_trim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS, b VARCHAR(20) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_trim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI, b VARCHAR(20) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_trim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS, b VARCHAR(20) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_trim_arabic_ci_as VALUES(N' الله مع المتقين ', N'ين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS, b VARCHAR(20) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_trim_arabic_cs_as VALUES(N' الله مع المتقين ', N'ين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI, b VARCHAR(20) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_trim_arabic_ci_ai VALUES(N' الله مع المتقين ', N'ين ') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_image(a IMAGE) +GO +INSERT INTO babel_4489_trim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4489_trim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_trim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4489_trim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_trim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_trim_UDT(a dbo.babel_4489_trim_imageUDT, b dbo.babel_4489_trim_varUDT) +GO +INSERT INTO babel_4489_trim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_trim_imageUDT), CAST('abcdef' as dbo.babel_4489_trim_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4489_trim_dep_view AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE PROCEDURE babel_4489_trim_dep_proc AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE FUNCTION babel_4489_trim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + TRIM(b FROM a) + '|') FROM babel_4489_trim_t2) +END +GO + +CREATE VIEW babel_4489_trim_dep_view_1 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t1 +GO + +CREATE VIEW babel_4489_trim_dep_view_2 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE VIEW babel_4489_trim_dep_view_3 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t3 +GO + +CREATE VIEW babel_4489_trim_dep_view_4 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t4 +GO + +CREATE VIEW babel_4489_trim_dep_view_5 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t5 +GO + +CREATE VIEW babel_4489_trim_dep_view_6 AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t4 +GO + +CREATE FUNCTION babel_4489_trim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2) +GO diff --git a/test/JDBC/expected/trim-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/trim-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..0e905e48eac --- /dev/null +++ b/test/JDBC/expected/trim-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,1364 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉莫斯#!#比尔·拉#!#·拉莫斯#!#尔·拉莫 +~~END~~ + + +-- NULL +SELECT TRIM(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM('' FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM '') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|·| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|·| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|?c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|·| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO +~~START~~ +nvarchar +|c🙂defghi| +|尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +EXEC babel_4489_trim_dep_proc +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_itvf_func() +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_1 +GO +~~START~~ +varchar +|abc?defghi??| +|??·???| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_2 +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_5 +GO +~~START~~ +varchar +|0x61626364| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_6 +GO +~~START~~ +varchar +|cdefgh| +~~END~~ + + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|·| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|·| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "binary" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +cdef +~~END~~ + + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 1 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "decimal" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type numeric is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type double precision is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type real is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type bigint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type integer is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type tinyint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type money is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallmoney is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "bit" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +9619FF-8B86-D011-B42D-00C04FC964 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +body> +~~END~~ + + +SELECT TRIM(NULL FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM('' FROM NULL) +GO +~~START~~ +varchar + +~~END~~ + + +SELECT TRIM(NULL FROM '') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|·| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|·| +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO +~~START~~ +varchar +|尔·拉莫| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO +~~START~~ +varchar +|الله مع المتق| +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|?c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|·| +~~END~~ + + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO +~~START~~ +nvarchar +|c🙂defghi| +|尔·拉莫| +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +EXEC babel_4489_trim_dep_proc +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_itvf_func() +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_1 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +|比尔·拉莫斯| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_2 +GO +~~START~~ +nvarchar +|abc🙂defghi🙂🙂| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_3 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_4 +GO +~~START~~ +varchar +|abcdefghi| +~~END~~ + + +SELECT * FROM babel_4489_trim_dep_view_5 +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +SELECT * FROM babel_4489_trim_dep_view_6 +GO +~~START~~ +varchar +|cdefgh| +~~END~~ + + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|·| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|??·???| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +varchar +|?·??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|·| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c?defghi??| +~~END~~ + + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|??·???| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|尔·拉莫| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|c🙂defghi🙂🙂| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~START~~ +nvarchar +|比尔·拉莫斯| +~~END~~ + + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "binary" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type varbinary is invalid for argument 1 of Trim function.)~~ + + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +abcdef +~~END~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO +~~START~~ +varchar +cdef +~~END~~ + + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type date is invalid for argument 1 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smalldatetime is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type time without time zone is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetimeoffset is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 2 of Trim function.)~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type datetime2 is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "decimal" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type numeric is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type double precision is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type real is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type bigint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type integer is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type tinyint is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type money is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type smallmoney is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type "bit" is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type uniqueidentifier is invalid for argument 1 of Trim function.)~~ + + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of Trim function.)~~ + + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 2 of Trim function.)~~ + + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar + +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO +~~START~~ +nvarchar +c🙂defghi🙂🙂 +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 2 of Trim function.)~~ + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of Trim function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +9619FF-8B86-D011-B42D-00C04FC964 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +body>' AS xml) +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO diff --git a/test/JDBC/input/functions/string_functions/left-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/left-vu-cleanup.sql new file mode 100644 index 00000000000..cabd616f301 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/left-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_left_itvf_func +GO + +DROP FUNCTION babel_4489_left_dep_func +GO + +DROP PROCEDURE babel_4489_left_dep_proc +GO + +DROP VIEW babel_4489_left_dep_view +GO + +DROP TABLE babel_4489_left_UDT +GO + +DROP VIEW babel_4489_left_dep_view_1 +GO + +DROP VIEW babel_4489_left_dep_view_2 +GO + +DROP VIEW babel_4489_left_dep_view_3 +GO + +DROP VIEW babel_4489_left_dep_view_4 +GO + +DROP VIEW babel_4489_left_dep_view_5 +GO + +DROP VIEW babel_4489_left_dep_view_6 +GO + +DROP VIEW babel_4489_left_dep_view_7 +GO + +DROP TYPE dbo.babel_4489_left_varUDT +GO + +DROP TYPE dbo.babel_4489_left_imageUDT +GO + +DROP TABLE babel_4489_left_text +GO + +DROP TABLE babel_4489_left_image +GO + +DROP TABLE babel_4489_left_arabic_ci_ai +GO + +DROP TABLE babel_4489_left_arabic_cs_as +GO + +DROP TABLE babel_4489_left_arabic_ci_as +GO + +DROP TABLE babel_4489_left_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_left_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_left_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_left_t5 +GO + +DROP TABLE babel_4489_left_t4 +GO + +DROP TABLE babel_4489_left_t3 +GO + +DROP TABLE babel_4489_left_t2 +GO + +DROP TABLE babel_4489_left_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/left-vu-prepare.sql b/test/JDBC/input/functions/string_functions/left-vu-prepare.sql new file mode 100644 index 00000000000..65ae5999db3 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/left-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_left_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_left_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4489_left_t1 VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_left_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_left_t2 VALUES(N'abc🙂defghi🙂🙂') +GO + +CREATE TABLE babel_4489_left_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_left_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_left_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_left_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_left_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_left_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_left_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_left_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_left_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_left_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_left_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_left_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_left_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_left_arabic_ci_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_left_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_left_arabic_cs_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_left_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_left_arabic_ci_ai VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_left_image(a IMAGE) +GO +INSERT INTO babel_4489_left_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_left_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_left_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO + +CREATE TYPE dbo.babel_4489_left_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_left_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_left_UDT(a dbo.babel_4489_left_imageUDT, b dbo.babel_4489_left_varUDT) +GO +INSERT INTO babel_4489_left_UDT VALUES(CAST('abcdef' as dbo.babel_4489_left_imageUDT), CAST('abcdef' as dbo.babel_4489_left_varUDT)) +GO + +CREATE VIEW babel_4489_left_dep_view AS + SELECT LEFT(a, 5) as result from babel_4489_left_t2 +GO + +CREATE PROCEDURE babel_4489_left_dep_proc AS + SELECT LEFT(a, 5) as result from babel_4489_left_t2 +GO + +CREATE FUNCTION babel_4489_left_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 LEFT(a, 5) from babel_4489_left_t2) +END +GO + +CREATE VIEW babel_4489_left_dep_view_1 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t1 +GO + +CREATE VIEW babel_4489_left_dep_view_2 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t2 +GO + +CREATE VIEW babel_4489_left_dep_view_3 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t3 +GO + +CREATE VIEW babel_4489_left_dep_view_4 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t4 +GO + +CREATE VIEW babel_4489_left_dep_view_5 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_t5 +GO + +CREATE VIEW babel_4489_left_dep_view_6 AS + SELECT LEFT(a, 5) as result FROM babel_4489_left_text +GO + +CREATE VIEW babel_4489_left_dep_view_7 AS + SELECT LEFT(b, 5) as result FROM babel_4489_left_text +GO + +CREATE FUNCTION babel_4489_left_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT LEFT(a, 5) as result from babel_4489_left_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/left-vu-verify.sql b/test/JDBC/input/functions/string_functions/left-vu-verify.sql new file mode 100644 index 00000000000..79b7b7d32d2 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/left-vu-verify.sql @@ -0,0 +1,328 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT LEFT(NULL, -2) +GO + +SELECT LEFT(NULL, 0) +GO + +SELECT LEFT(NULL, 2) +GO + +SELECT LEFT('abc', NULL) +GO + +SELECT LEFT(NULL, NULL) +GO + +-- edge case values for second parameter +SELECT LEFT('AbdefGhi', -2) +GO + +SELECT '|' + LEFT('AbdefGhi', 0) + '|' +GO + +SELECT LEFT('AbdefGhi', 2) +GO + +SELECT LEFT('AbdefGhi', 2147483646) +GO + +SELECT LEFT('AbdefGhi', 2147483650) +GO + +-- misc tests +DECLARE @procedure_name NVARCHAR(134) = ';1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO + +DECLARE @procedure_name NVARCHAR(134) = 'procedureName;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO + +-- procedure name with length equal to 134 +DECLARE @procedure_name NVARCHAR(134) = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;1' +SELECT LEFT(@procedure_name, LEN(@procedure_name)-2) +GO + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT LEFT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_as +GO + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_left_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_cs_as +GO + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_left_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_chinese_prc_ci_ai +GO + +SELECT LEFT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_left_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_as +GO + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_left_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_cs_as +GO + +SELECT LEFT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_left_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT LEFT(a, 4) FROM babel_4489_left_arabic_ci_ai +GO + +SELECT LEFT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_left_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 5) + '|' +GO + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT '|' + LEFT(@inputString, 4) + '|' +GO + +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT '|' + LEFT(@inputString, 50) + '|' +GO + +-- with table column of type nchar +SELECT '|' + LEFT(a, 5) + '|' FROM babel_4489_left_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 5) +GO + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT LEFT(@inputString, 4) +GO + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT LEFT(@inputString, 50) +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT LEFT(@inputString, 4) +GO + +-- dependent objects +SELECT * FROM babel_4489_left_dep_view +GO + +EXEC babel_4489_left_dep_proc +GO + +SELECT * FROM babel_4489_left_dep_func() +GO + +SELECT * FROM babel_4489_left_itvf_func() +GO + +SELECT * FROM babel_4489_left_dep_view_1 +GO + +SELECT * FROM babel_4489_left_dep_view_2 +GO + +SELECT * FROM babel_4489_left_dep_view_3 +GO + +SELECT * FROM babel_4489_left_dep_view_4 +GO + +SELECT * FROM babel_4489_left_dep_view_5 +GO + +SELECT * FROM babel_4489_left_dep_view_6 +GO + +SELECT * FROM babel_4489_left_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_left_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LEFT(a, 3) FROM babel_4489_left_UDT +GO + +SELECT LEFT(b, 3) FROM babel_4489_left_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString decimal = 123456; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString float = 12345.1; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString real = 12345.1; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString bigint = 12345678; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString int = 12345678; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString smallint = 12356; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString tinyint = 235; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString money = 12356; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString bit = 1; +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LEFT(@inputString, 3) +GO + +SELECT LEFT(a, 5) from babel_4489_left_image; +GO + +-- input datatype text +SELECT LEFT(a, 5) FROM babel_4489_left_text +GO + +-- input datatype ntext +SELECT LEFT(b, 5) FROM babel_4489_left_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LEFT(@inputString, 3) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LEFT(CAST(@inputString AS VARCHAR(50)), 3) +GO diff --git a/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 00000000000..6b8328690ae --- /dev/null +++ b/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_ltrim_itvf_func +GO + +DROP FUNCTION babel_4489_ltrim_dep_func +GO + +DROP PROCEDURE babel_4489_ltrim_dep_proc +GO + +DROP VIEW babel_4489_ltrim_dep_view +GO + +DROP VIEW babel_4489_ltrim_dep_view_1 +GO + +DROP VIEW babel_4489_ltrim_dep_view_2 +GO + +DROP VIEW babel_4489_ltrim_dep_view_3 +GO + +DROP VIEW babel_4489_ltrim_dep_view_4 +GO + +DROP VIEW babel_4489_ltrim_dep_view_5 +GO + +DROP VIEW babel_4489_ltrim_dep_view_6 +GO + +DROP VIEW babel_4489_ltrim_dep_view_7 +GO + +DROP TABLE babel_4489_ltrim_UDT +GO + +DROP TYPE dbo.babel_4489_ltrim_varUDT +GO + +DROP TYPE dbo.babel_4489_ltrim_imageUDT +GO + +DROP TABLE babel_4489_ltrim_text +GO + +DROP TABLE babel_4489_ltrim_image +GO + +DROP TABLE babel_4489_ltrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_ltrim_arabic_cs_as +GO + +DROP TABLE babel_4489_ltrim_arabic_ci_as +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_ltrim_t5 +GO + +DROP TABLE babel_4489_ltrim_t4 +GO + +DROP TABLE babel_4489_ltrim_t3 +GO + +DROP TABLE babel_4489_ltrim_t2 +GO + +DROP TABLE babel_4489_ltrim_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 00000000000..55cec8a828b --- /dev/null +++ b/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_ltrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_ltrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO + +CREATE TABLE babel_4489_ltrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_ltrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_ltrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_ltrim_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_ltrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_ltrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_ltrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_ltrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_ltrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_ltrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_ltrim_image(a IMAGE) +GO +INSERT INTO babel_4489_ltrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_ltrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_ltrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO + +CREATE TYPE dbo.babel_4489_ltrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_ltrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_ltrim_UDT(a dbo.babel_4489_ltrim_imageUDT, b dbo.babel_4489_ltrim_varUDT) +GO +INSERT INTO babel_4489_ltrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_ltrim_imageUDT), CAST('abcdef' as dbo.babel_4489_ltrim_varUDT)) +GO + +CREATE VIEW babel_4489_ltrim_dep_view AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE PROCEDURE babel_4489_ltrim_dep_proc AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE FUNCTION babel_4489_ltrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + LTRIM(a) + '|') FROM babel_4489_ltrim_t2) +END +GO + +CREATE VIEW babel_4489_ltrim_dep_view_1 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t1 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_2 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_3 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t3 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_4 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t4 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_5 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t5 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_6 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_text +GO + +CREATE VIEW babel_4489_ltrim_dep_view_7 AS + SELECT ('|' + LTRIM(b) + '|') as result FROM babel_4489_ltrim_text +GO + +CREATE FUNCTION babel_4489_ltrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-verify.sql new file mode 100644 index 00000000000..0913db43758 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/ltrim-before-15_8-or-16_4-vu-verify.sql @@ -0,0 +1,270 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT LTRIM(NULL) +GO + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO + +EXEC babel_4489_ltrim_dep_proc +GO + +SELECT * FROM babel_4489_ltrim_dep_func() +GO + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/string_functions/ltrim-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/ltrim-vu-cleanup.sql new file mode 100644 index 00000000000..6b8328690ae --- /dev/null +++ b/test/JDBC/input/functions/string_functions/ltrim-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_ltrim_itvf_func +GO + +DROP FUNCTION babel_4489_ltrim_dep_func +GO + +DROP PROCEDURE babel_4489_ltrim_dep_proc +GO + +DROP VIEW babel_4489_ltrim_dep_view +GO + +DROP VIEW babel_4489_ltrim_dep_view_1 +GO + +DROP VIEW babel_4489_ltrim_dep_view_2 +GO + +DROP VIEW babel_4489_ltrim_dep_view_3 +GO + +DROP VIEW babel_4489_ltrim_dep_view_4 +GO + +DROP VIEW babel_4489_ltrim_dep_view_5 +GO + +DROP VIEW babel_4489_ltrim_dep_view_6 +GO + +DROP VIEW babel_4489_ltrim_dep_view_7 +GO + +DROP TABLE babel_4489_ltrim_UDT +GO + +DROP TYPE dbo.babel_4489_ltrim_varUDT +GO + +DROP TYPE dbo.babel_4489_ltrim_imageUDT +GO + +DROP TABLE babel_4489_ltrim_text +GO + +DROP TABLE babel_4489_ltrim_image +GO + +DROP TABLE babel_4489_ltrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_ltrim_arabic_cs_as +GO + +DROP TABLE babel_4489_ltrim_arabic_ci_as +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_ltrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_ltrim_t5 +GO + +DROP TABLE babel_4489_ltrim_t4 +GO + +DROP TABLE babel_4489_ltrim_t3 +GO + +DROP TABLE babel_4489_ltrim_t2 +GO + +DROP TABLE babel_4489_ltrim_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/ltrim-vu-prepare.sql b/test/JDBC/input/functions/string_functions/ltrim-vu-prepare.sql new file mode 100644 index 00000000000..55cec8a828b --- /dev/null +++ b/test/JDBC/input/functions/string_functions/ltrim-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_ltrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_ltrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO + +CREATE TABLE babel_4489_ltrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_ltrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_ltrim_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_ltrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_ltrim_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_ltrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_ltrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_ltrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_ltrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_ltrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_ltrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_ltrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_ltrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_ltrim_image(a IMAGE) +GO +INSERT INTO babel_4489_ltrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_ltrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_ltrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO + +CREATE TYPE dbo.babel_4489_ltrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_ltrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_ltrim_UDT(a dbo.babel_4489_ltrim_imageUDT, b dbo.babel_4489_ltrim_varUDT) +GO +INSERT INTO babel_4489_ltrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_ltrim_imageUDT), CAST('abcdef' as dbo.babel_4489_ltrim_varUDT)) +GO + +CREATE VIEW babel_4489_ltrim_dep_view AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE PROCEDURE babel_4489_ltrim_dep_proc AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE FUNCTION babel_4489_ltrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + LTRIM(a) + '|') FROM babel_4489_ltrim_t2) +END +GO + +CREATE VIEW babel_4489_ltrim_dep_view_1 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t1 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_2 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_3 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t3 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_4 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t4 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_5 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t5 +GO + +CREATE VIEW babel_4489_ltrim_dep_view_6 AS + SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_text +GO + +CREATE VIEW babel_4489_ltrim_dep_view_7 AS + SELECT ('|' + LTRIM(b) + '|') as result FROM babel_4489_ltrim_text +GO + +CREATE FUNCTION babel_4489_ltrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + LTRIM(a) + '|') as result FROM babel_4489_ltrim_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/ltrim-vu-verify.sql b/test/JDBC/input/functions/string_functions/ltrim-vu-verify.sql new file mode 100644 index 00000000000..0913db43758 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/ltrim-vu-verify.sql @@ -0,0 +1,270 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT LTRIM(NULL) +GO + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_ltrim_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_ltrim_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO + +SELECT '|' + LTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_ltrim_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_as +GO + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_ltrim_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_cs_as +GO + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_ltrim_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO + +SELECT '|' + LTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_ltrim_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- with table column of type nchar +SELECT '|' + LTRIM(a) + '|' FROM babel_4489_ltrim_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + LTRIM(@inputString) + '|' +GO + +-- dependent objects +SELECT * FROM babel_4489_ltrim_dep_view +GO + +EXEC babel_4489_ltrim_dep_proc +GO + +SELECT * FROM babel_4489_ltrim_dep_func() +GO + +SELECT * FROM babel_4489_ltrim_itvf_func() +GO + +SELECT * FROM babel_4489_ltrim_dep_view_1 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_2 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_3 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_4 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_5 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_6 +GO + +SELECT * FROM babel_4489_ltrim_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_ltrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT LTRIM(a) FROM babel_4489_ltrim_UDT +GO + +SELECT LTRIM(b) FROM babel_4489_ltrim_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT LTRIM(@inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString decimal = 123456; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString float = 12345.1; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString real = 12345.1; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString bigint = 12345678; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString int = 12345678; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString smallint = 12356; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString tinyint = 235; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString money = 12356; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString bit = 1; +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT LTRIM(@inputString) +GO + +SELECT LTRIM(a) from babel_4489_ltrim_image; +GO + +-- input datatype text +SELECT LTRIM(a) FROM babel_4489_ltrim_text +GO + +-- input datatype ntext +SELECT LTRIM(b) FROM babel_4489_ltrim_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT LTRIM(@inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT LTRIM(CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 00000000000..5b804d8f235 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_right_itvf_func +GO + +DROP FUNCTION babel_4489_right_dep_func +GO + +DROP PROCEDURE babel_4489_right_dep_proc +GO + +DROP VIEW babel_4489_right_dep_view +GO + +DROP TABLE babel_4489_right_UDT +GO + +DROP VIEW babel_4489_right_dep_view_1 +GO + +DROP VIEW babel_4489_right_dep_view_2 +GO + +DROP VIEW babel_4489_right_dep_view_3 +GO + +DROP VIEW babel_4489_right_dep_view_4 +GO + +DROP VIEW babel_4489_right_dep_view_5 +GO + +DROP VIEW babel_4489_right_dep_view_6 +GO + +DROP VIEW babel_4489_right_dep_view_7 +GO + +DROP TYPE dbo.babel_4489_right_varUDT +GO + +DROP TYPE dbo.babel_4489_right_imageUDT +GO + +DROP TABLE babel_4489_right_text +GO + +DROP TABLE babel_4489_right_image +GO + +DROP TABLE babel_4489_right_arabic_ci_ai +GO + +DROP TABLE babel_4489_right_arabic_cs_as +GO + +DROP TABLE babel_4489_right_arabic_ci_as +GO + +DROP TABLE babel_4489_right_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_right_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_right_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_right_t5 +GO + +DROP TABLE babel_4489_right_t4 +GO + +DROP TABLE babel_4489_right_t3 +GO + +DROP TABLE babel_4489_right_t2 +GO + +DROP TABLE babel_4489_right_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 00000000000..a7637d2356e --- /dev/null +++ b/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_right_t1(a NCHAR(15)) +GO +INSERT INTO babel_4489_right_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4489_right_t1 VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_right_t2 VALUES(N'abc🙂defghi🙂🙂') +GO + +CREATE TABLE babel_4489_right_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_right_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_right_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_right_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_right_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_right_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_right_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_right_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_right_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_right_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_right_arabic_ci_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_right_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_right_arabic_cs_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_right_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_right_arabic_ci_ai VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_right_image(a IMAGE) +GO +INSERT INTO babel_4489_right_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_right_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_right_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO + +CREATE TYPE dbo.babel_4489_right_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_right_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_right_UDT(a dbo.babel_4489_right_imageUDT, b dbo.babel_4489_right_varUDT) +GO +INSERT INTO babel_4489_right_UDT VALUES(CAST('abcdef' as dbo.babel_4489_right_imageUDT), CAST('abcdef' as dbo.babel_4489_right_varUDT)) +GO + +CREATE VIEW babel_4489_right_dep_view AS + SELECT RIGHT(a, 5) as result from babel_4489_right_t2 +GO + +CREATE PROCEDURE babel_4489_right_dep_proc AS + SELECT RIGHT(a, 5) as result from babel_4489_right_t2 +GO + +CREATE FUNCTION babel_4489_right_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 RIGHT(a, 5) from babel_4489_right_t2) +END +GO + +CREATE VIEW babel_4489_right_dep_view_1 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t1 +GO + +CREATE VIEW babel_4489_right_dep_view_2 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t2 +GO + +CREATE VIEW babel_4489_right_dep_view_3 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t3 +GO + +CREATE VIEW babel_4489_right_dep_view_4 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t4 +GO + +CREATE VIEW babel_4489_right_dep_view_5 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t5 +GO + +CREATE VIEW babel_4489_right_dep_view_6 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_text +GO + +CREATE VIEW babel_4489_right_dep_view_7 AS + SELECT RIGHT(b, 5) as result FROM babel_4489_right_text +GO + +CREATE FUNCTION babel_4489_right_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT RIGHT(a, 5) as result from babel_4489_right_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-verify.sql new file mode 100644 index 00000000000..ae50e1acba0 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/right-before-15_8-or-16_4-vu-verify.sql @@ -0,0 +1,314 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT RIGHT(NULL, -2) +GO + +SELECT RIGHT(NULL, 0) +GO + +SELECT RIGHT(NULL, 2) +GO + +SELECT RIGHT('abc', NULL) +GO + +SELECT RIGHT(NULL, NULL) +GO + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO + +SELECT RIGHT('AbdefGhi', 2) +GO + +SELECT RIGHT('AbdefGhi', 2147483646) +GO + +SELECT RIGHT('AbdefGhi', 2147483650) +GO + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO + +EXEC babel_4489_right_dep_proc +GO + +SELECT * FROM babel_4489_right_dep_func() +GO + +SELECT * FROM babel_4489_right_itvf_func() +GO + +SELECT * FROM babel_4489_right_dep_view_1 +GO + +SELECT * FROM babel_4489_right_dep_view_2 +GO + +SELECT * FROM babel_4489_right_dep_view_3 +GO + +SELECT * FROM babel_4489_right_dep_view_4 +GO + +SELECT * FROM babel_4489_right_dep_view_5 +GO + +SELECT * FROM babel_4489_right_dep_view_6 +GO + +SELECT * FROM babel_4489_right_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO diff --git a/test/JDBC/input/functions/string_functions/right-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/right-vu-cleanup.sql new file mode 100644 index 00000000000..5b804d8f235 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/right-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_right_itvf_func +GO + +DROP FUNCTION babel_4489_right_dep_func +GO + +DROP PROCEDURE babel_4489_right_dep_proc +GO + +DROP VIEW babel_4489_right_dep_view +GO + +DROP TABLE babel_4489_right_UDT +GO + +DROP VIEW babel_4489_right_dep_view_1 +GO + +DROP VIEW babel_4489_right_dep_view_2 +GO + +DROP VIEW babel_4489_right_dep_view_3 +GO + +DROP VIEW babel_4489_right_dep_view_4 +GO + +DROP VIEW babel_4489_right_dep_view_5 +GO + +DROP VIEW babel_4489_right_dep_view_6 +GO + +DROP VIEW babel_4489_right_dep_view_7 +GO + +DROP TYPE dbo.babel_4489_right_varUDT +GO + +DROP TYPE dbo.babel_4489_right_imageUDT +GO + +DROP TABLE babel_4489_right_text +GO + +DROP TABLE babel_4489_right_image +GO + +DROP TABLE babel_4489_right_arabic_ci_ai +GO + +DROP TABLE babel_4489_right_arabic_cs_as +GO + +DROP TABLE babel_4489_right_arabic_ci_as +GO + +DROP TABLE babel_4489_right_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_right_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_right_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_right_t5 +GO + +DROP TABLE babel_4489_right_t4 +GO + +DROP TABLE babel_4489_right_t3 +GO + +DROP TABLE babel_4489_right_t2 +GO + +DROP TABLE babel_4489_right_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/right-vu-prepare.sql b/test/JDBC/input/functions/string_functions/right-vu-prepare.sql new file mode 100644 index 00000000000..a7637d2356e --- /dev/null +++ b/test/JDBC/input/functions/string_functions/right-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_right_t1(a NCHAR(15)) +GO +INSERT INTO babel_4489_right_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4489_right_t1 VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_right_t2 VALUES(N'abc🙂defghi🙂🙂') +GO + +CREATE TABLE babel_4489_right_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_right_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_right_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_right_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_right_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_right_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_right_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_right_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_right_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_right_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4489_right_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_right_arabic_ci_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_right_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_right_arabic_cs_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_right_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_right_arabic_ci_ai VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4489_right_image(a IMAGE) +GO +INSERT INTO babel_4489_right_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_right_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_right_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO + +CREATE TYPE dbo.babel_4489_right_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_right_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_right_UDT(a dbo.babel_4489_right_imageUDT, b dbo.babel_4489_right_varUDT) +GO +INSERT INTO babel_4489_right_UDT VALUES(CAST('abcdef' as dbo.babel_4489_right_imageUDT), CAST('abcdef' as dbo.babel_4489_right_varUDT)) +GO + +CREATE VIEW babel_4489_right_dep_view AS + SELECT RIGHT(a, 5) as result from babel_4489_right_t2 +GO + +CREATE PROCEDURE babel_4489_right_dep_proc AS + SELECT RIGHT(a, 5) as result from babel_4489_right_t2 +GO + +CREATE FUNCTION babel_4489_right_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 RIGHT(a, 5) from babel_4489_right_t2) +END +GO + +CREATE VIEW babel_4489_right_dep_view_1 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t1 +GO + +CREATE VIEW babel_4489_right_dep_view_2 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t2 +GO + +CREATE VIEW babel_4489_right_dep_view_3 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t3 +GO + +CREATE VIEW babel_4489_right_dep_view_4 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t4 +GO + +CREATE VIEW babel_4489_right_dep_view_5 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_t5 +GO + +CREATE VIEW babel_4489_right_dep_view_6 AS + SELECT RIGHT(a, 5) as result FROM babel_4489_right_text +GO + +CREATE VIEW babel_4489_right_dep_view_7 AS + SELECT RIGHT(b, 5) as result FROM babel_4489_right_text +GO + +CREATE FUNCTION babel_4489_right_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT RIGHT(a, 5) as result from babel_4489_right_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/right-vu-verify.sql b/test/JDBC/input/functions/string_functions/right-vu-verify.sql new file mode 100644 index 00000000000..ae50e1acba0 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/right-vu-verify.sql @@ -0,0 +1,314 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(25) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT RIGHT(NULL, -2) +GO + +SELECT RIGHT(NULL, 0) +GO + +SELECT RIGHT(NULL, 2) +GO + +SELECT RIGHT('abc', NULL) +GO + +SELECT RIGHT(NULL, NULL) +GO + +-- edge case values for second parameter +SELECT RIGHT('AbdefGhi', -2) +GO + +SELECT '|' + RIGHT('AbdefGhi', 0) + '|' +GO + +SELECT RIGHT('AbdefGhi', 2) +GO + +SELECT RIGHT('AbdefGhi', 2147483646) +GO + +SELECT RIGHT('AbdefGhi', 2147483650) +GO + +-- input type char +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO + +DECLARE @inputString CHAR(15) = '比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(15) = 'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) COLLATE CHINESE_PRC_CI_AS +GO + +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_as +GO + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AS FROM babel_4489_right_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_cs_as +GO + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CS_AS FROM babel_4489_right_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_chinese_prc_ci_ai +GO + +SELECT RIGHT(a, 4) COLLATE CHINESE_PRC_CI_AI FROM babel_4489_right_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_as +GO + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AS FROM babel_4489_right_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_cs_as +GO + +SELECT RIGHT(a, 4) COLLATE ARABIC_CS_AS FROM babel_4489_right_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT RIGHT(a, 4) FROM babel_4489_right_arabic_ci_ai +GO + +SELECT RIGHT(a, 4) COLLATE ARABIC_CI_AI FROM babel_4489_right_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 8) + '|' +GO + +DECLARE @inputString NCHAR(15) = N'比尔·拉莫斯' +SELECT '|' + RIGHT(@inputString, 13) + '|' +GO + +DECLARE @inputString NCHAR(15) = N'abc🙂defghi🙂🙂' +SELECT '|' + RIGHT(@inputString, 50) + '|' +GO + +-- with table column of type nchar +SELECT '|' + RIGHT(a, 13) + '|' FROM babel_4489_right_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 5) +GO + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT RIGHT(@inputString, 4) +GO + +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT RIGHT(@inputString, 50) +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT RIGHT(@inputString, 4) +GO + +-- dependent objects +SELECT * FROM babel_4489_right_dep_view +GO + +EXEC babel_4489_right_dep_proc +GO + +SELECT * FROM babel_4489_right_dep_func() +GO + +SELECT * FROM babel_4489_right_itvf_func() +GO + +SELECT * FROM babel_4489_right_dep_view_1 +GO + +SELECT * FROM babel_4489_right_dep_view_2 +GO + +SELECT * FROM babel_4489_right_dep_view_3 +GO + +SELECT * FROM babel_4489_right_dep_view_4 +GO + +SELECT * FROM babel_4489_right_dep_view_5 +GO + +SELECT * FROM babel_4489_right_dep_view_6 +GO + +SELECT * FROM babel_4489_right_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_right_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RIGHT(a, 3) FROM babel_4489_right_UDT +GO + +SELECT RIGHT(b, 3) FROM babel_4489_right_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString decimal = 123456; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString float = 12345.1; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString real = 12345.1; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString bigint = 12345678; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString int = 12345678; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString smallint = 12356; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString tinyint = 235; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString money = 12356; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString bit = 1; +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RIGHT(@inputString, 3) +GO + +SELECT RIGHT(a, 5) from babel_4489_right_image; +GO + +-- input datatype text +SELECT RIGHT(a, 5) FROM babel_4489_right_text +GO + +-- input datatype ntext +SELECT RIGHT(b, 5) FROM babel_4489_right_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RIGHT(@inputString, 3) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RIGHT(CAST(@inputString AS VARCHAR(50)), 3) +GO diff --git a/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 00000000000..f249ba024ba --- /dev/null +++ b/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_rtrim_itvf_func +GO + +DROP FUNCTION babel_4489_rtrim_dep_func +GO + +DROP PROCEDURE babel_4489_rtrim_dep_proc +GO + +DROP VIEW babel_4489_rtrim_dep_view +GO + +DROP VIEW babel_4489_rtrim_dep_view_1 +GO + +DROP VIEW babel_4489_rtrim_dep_view_2 +GO + +DROP VIEW babel_4489_rtrim_dep_view_3 +GO + +DROP VIEW babel_4489_rtrim_dep_view_4 +GO + +DROP VIEW babel_4489_rtrim_dep_view_5 +GO + +DROP VIEW babel_4489_rtrim_dep_view_6 +GO + +DROP VIEW babel_4489_rtrim_dep_view_7 +GO + +DROP TABLE babel_4489_rtrim_UDT +GO + +DROP TYPE dbo.babel_4489_rtrim_varUDT +GO + +DROP TYPE dbo.babel_4489_rtrim_imageUDT +GO + +DROP TABLE babel_4489_rtrim_text +GO + +DROP TABLE babel_4489_rtrim_image +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_rtrim_arabic_cs_as +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_rtrim_t5 +GO + +DROP TABLE babel_4489_rtrim_t4 +GO + +DROP TABLE babel_4489_rtrim_t3 +GO + +DROP TABLE babel_4489_rtrim_t2 +GO + +DROP TABLE babel_4489_rtrim_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 00000000000..417234024f6 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_rtrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_rtrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO + +CREATE TABLE babel_4489_rtrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_rtrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_rtrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_rtrim_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_rtrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_rtrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_rtrim_image(a IMAGE) +GO +INSERT INTO babel_4489_rtrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_rtrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_rtrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO + +CREATE TYPE dbo.babel_4489_rtrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_rtrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_rtrim_UDT(a dbo.babel_4489_rtrim_imageUDT, b dbo.babel_4489_rtrim_varUDT) +GO +INSERT INTO babel_4489_rtrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_rtrim_imageUDT), CAST('abcdef' as dbo.babel_4489_rtrim_varUDT)) +GO + +CREATE VIEW babel_4489_rtrim_dep_view AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE PROCEDURE babel_4489_rtrim_dep_proc AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE FUNCTION babel_4489_rtrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + RTRIM(a) + '|') FROM babel_4489_rtrim_t2) +END +GO + +CREATE VIEW babel_4489_rtrim_dep_view_1 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t1 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_2 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_3 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t3 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_4 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t4 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_5 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t5 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_6 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE VIEW babel_4489_rtrim_dep_view_7 AS + SELECT ('|' + RTRIM(b) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE FUNCTION babel_4489_rtrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-verify.sql new file mode 100644 index 00000000000..32e6f0925cf --- /dev/null +++ b/test/JDBC/input/functions/string_functions/rtrim-before-15_8-or-16_4-vu-verify.sql @@ -0,0 +1,270 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT RTRIM(NULL) +GO + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO + +EXEC babel_4489_rtrim_dep_proc +GO + +SELECT * FROM babel_4489_rtrim_dep_func() +GO + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/string_functions/rtrim-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/rtrim-vu-cleanup.sql new file mode 100644 index 00000000000..f249ba024ba --- /dev/null +++ b/test/JDBC/input/functions/string_functions/rtrim-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4489_rtrim_itvf_func +GO + +DROP FUNCTION babel_4489_rtrim_dep_func +GO + +DROP PROCEDURE babel_4489_rtrim_dep_proc +GO + +DROP VIEW babel_4489_rtrim_dep_view +GO + +DROP VIEW babel_4489_rtrim_dep_view_1 +GO + +DROP VIEW babel_4489_rtrim_dep_view_2 +GO + +DROP VIEW babel_4489_rtrim_dep_view_3 +GO + +DROP VIEW babel_4489_rtrim_dep_view_4 +GO + +DROP VIEW babel_4489_rtrim_dep_view_5 +GO + +DROP VIEW babel_4489_rtrim_dep_view_6 +GO + +DROP VIEW babel_4489_rtrim_dep_view_7 +GO + +DROP TABLE babel_4489_rtrim_UDT +GO + +DROP TYPE dbo.babel_4489_rtrim_varUDT +GO + +DROP TYPE dbo.babel_4489_rtrim_imageUDT +GO + +DROP TABLE babel_4489_rtrim_text +GO + +DROP TABLE babel_4489_rtrim_image +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_ai +GO + +DROP TABLE babel_4489_rtrim_arabic_cs_as +GO + +DROP TABLE babel_4489_rtrim_arabic_ci_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_rtrim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_rtrim_t5 +GO + +DROP TABLE babel_4489_rtrim_t4 +GO + +DROP TABLE babel_4489_rtrim_t3 +GO + +DROP TABLE babel_4489_rtrim_t2 +GO + +DROP TABLE babel_4489_rtrim_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/rtrim-vu-prepare.sql b/test/JDBC/input/functions/string_functions/rtrim-vu-prepare.sql new file mode 100644 index 00000000000..417234024f6 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/rtrim-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4489_rtrim_t1(a NCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t1 VALUES(N' abc🙂defghi🙂🙂 ') +INSERT INTO babel_4489_rtrim_t1 VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t2 VALUES(N' abc🙂defghi🙂🙂 ') +GO + +CREATE TABLE babel_4489_rtrim_t3(a CHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t3 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_rtrim_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4489_rtrim_t4 VALUES(' abcdefghi ') +GO + +CREATE TABLE babel_4489_rtrim_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4489_rtrim_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ') +GO + +CREATE TABLE babel_4489_rtrim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_rtrim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_rtrim_arabic_cs_as VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_rtrim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_rtrim_arabic_ci_ai VALUES(N' الله مع المتقين ') +GO + +CREATE TABLE babel_4489_rtrim_image(a IMAGE) +GO +INSERT INTO babel_4489_rtrim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_rtrim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_rtrim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO + +CREATE TYPE dbo.babel_4489_rtrim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_rtrim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_rtrim_UDT(a dbo.babel_4489_rtrim_imageUDT, b dbo.babel_4489_rtrim_varUDT) +GO +INSERT INTO babel_4489_rtrim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_rtrim_imageUDT), CAST('abcdef' as dbo.babel_4489_rtrim_varUDT)) +GO + +CREATE VIEW babel_4489_rtrim_dep_view AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE PROCEDURE babel_4489_rtrim_dep_proc AS + SELECT ('|' + RTRIM(a) + '|') as result from babel_4489_rtrim_t2 +GO + +CREATE FUNCTION babel_4489_rtrim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + RTRIM(a) + '|') FROM babel_4489_rtrim_t2) +END +GO + +CREATE VIEW babel_4489_rtrim_dep_view_1 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t1 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_2 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_3 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t3 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_4 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t4 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_5 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t5 +GO + +CREATE VIEW babel_4489_rtrim_dep_view_6 AS + SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE VIEW babel_4489_rtrim_dep_view_7 AS + SELECT ('|' + RTRIM(b) + '|') as result FROM babel_4489_rtrim_text +GO + +CREATE FUNCTION babel_4489_rtrim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + RTRIM(a) + '|') as result FROM babel_4489_rtrim_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/rtrim-vu-verify.sql b/test/JDBC/input/functions/string_functions/rtrim-vu-verify.sql new file mode 100644 index 00000000000..32e6f0925cf --- /dev/null +++ b/test/JDBC/input/functions/string_functions/rtrim-vu-verify.sql @@ -0,0 +1,270 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT RTRIM(NULL) +GO + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_rtrim_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_rtrim_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO + +SELECT '|' + RTRIM(a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_rtrim_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_as +GO + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_rtrim_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_cs_as +GO + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_rtrim_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO + +SELECT '|' + RTRIM(a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_rtrim_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- with table column of type nchar +SELECT '|' + RTRIM(a) + '|' FROM babel_4489_rtrim_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x202061626364656667682020 +SELECT '|' + RTRIM(@inputString) + '|' +GO + +-- dependent objects +SELECT * FROM babel_4489_rtrim_dep_view +GO + +EXEC babel_4489_rtrim_dep_proc +GO + +SELECT * FROM babel_4489_rtrim_dep_func() +GO + +SELECT * FROM babel_4489_rtrim_itvf_func() +GO + +SELECT * FROM babel_4489_rtrim_dep_view_1 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_2 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_3 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_4 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_5 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_6 +GO + +SELECT * FROM babel_4489_rtrim_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4489_rtrim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT RTRIM(a) FROM babel_4489_rtrim_UDT +GO + +SELECT RTRIM(b) FROM babel_4489_rtrim_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT RTRIM(@inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString decimal = 123456; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString float = 12345.1; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString real = 12345.1; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString bigint = 12345678; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString int = 12345678; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString smallint = 12356; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString tinyint = 235; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString money = 12356; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString bit = 1; +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT RTRIM(@inputString) +GO + +SELECT RTRIM(a) from babel_4489_rtrim_image; +GO + +-- input datatype text +SELECT RTRIM(a) FROM babel_4489_rtrim_text +GO + +-- input datatype ntext +SELECT RTRIM(b) FROM babel_4489_rtrim_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT RTRIM(@inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT RTRIM(CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 00000000000..fef5323495e --- /dev/null +++ b/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,77 @@ +DROP FUNCTION babel_4489_trim_itvf_func +GO + +DROP FUNCTION babel_4489_trim_dep_func +GO + +DROP PROCEDURE babel_4489_trim_dep_proc +GO + +DROP VIEW babel_4489_trim_dep_view +GO + +DROP VIEW babel_4489_trim_dep_view_1 +GO + +DROP VIEW babel_4489_trim_dep_view_2 +GO + +DROP VIEW babel_4489_trim_dep_view_3 +GO + +DROP VIEW babel_4489_trim_dep_view_4 +GO + +DROP VIEW babel_4489_trim_dep_view_5 +GO + +DROP VIEW babel_4489_trim_dep_view_6 +GO + +DROP TABLE babel_4489_trim_UDT +GO + +DROP TYPE dbo.babel_4489_trim_varUDT +GO + +DROP TYPE dbo.babel_4489_trim_imageUDT +GO + +DROP TABLE babel_4489_trim_text +GO + +DROP TABLE babel_4489_trim_image +GO + +DROP TABLE babel_4489_trim_arabic_ci_ai +GO + +DROP TABLE babel_4489_trim_arabic_cs_as +GO + +DROP TABLE babel_4489_trim_arabic_ci_as +GO + +DROP TABLE babel_4489_trim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_trim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_trim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_trim_t5 +GO + +DROP TABLE babel_4489_trim_t4 +GO + +DROP TABLE babel_4489_trim_t3 +GO + +DROP TABLE babel_4489_trim_t2 +GO + +DROP TABLE babel_4489_trim_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 00000000000..a771d12b4b0 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,122 @@ +CREATE TABLE babel_4489_trim_t1(a NCHAR(50), b NCHAR(20)) +GO +INSERT INTO babel_4489_trim_t1 VALUES(N' abc🙂defghi🙂🙂 ', N'ab🙂 ') +INSERT INTO babel_4489_trim_t1 VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_t2(a NVARCHAR(50), b NVARCHAR(20)) +GO +INSERT INTO babel_4489_trim_t2 VALUES(N' abc🙂defghi🙂🙂 ', N'ab🙂 ') +GO + +CREATE TABLE babel_4489_trim_t3(a CHAR(50), b CHAR(20)) +GO +INSERT INTO babel_4489_trim_t3 VALUES(' abcdefghi ', 'abi ') +GO + +CREATE TABLE babel_4489_trim_t4(a VARCHAR(50), b VARCHAR(20)) +GO +INSERT INTO babel_4489_trim_t4 VALUES(' abcdefghi ', 'abi ') +GO + +CREATE TABLE babel_4489_trim_t5(a VARBINARY(50), b VARBINARY(50)) +GO +INSERT INTO babel_4489_trim_t5 VALUES(0x61626364, 0x6164) +GO + +CREATE TABLE babel_4489_trim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS, b VARCHAR(20) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_trim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS, b VARCHAR(20) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_trim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI, b VARCHAR(20) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_trim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS, b VARCHAR(20) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_trim_arabic_ci_as VALUES(N' الله مع المتقين ', N'ين ') +GO + +CREATE TABLE babel_4489_trim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS, b VARCHAR(20) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_trim_arabic_cs_as VALUES(N' الله مع المتقين ', N'ين ') +GO + +CREATE TABLE babel_4489_trim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI, b VARCHAR(20) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_trim_arabic_ci_ai VALUES(N' الله مع المتقين ', N'ين ') +GO + +CREATE TABLE babel_4489_trim_image(a IMAGE) +GO +INSERT INTO babel_4489_trim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_trim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_trim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO + +CREATE TYPE dbo.babel_4489_trim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_trim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_trim_UDT(a dbo.babel_4489_trim_imageUDT, b dbo.babel_4489_trim_varUDT) +GO +INSERT INTO babel_4489_trim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_trim_imageUDT), CAST('abcdef' as dbo.babel_4489_trim_varUDT)) +GO + +CREATE VIEW babel_4489_trim_dep_view AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE PROCEDURE babel_4489_trim_dep_proc AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE FUNCTION babel_4489_trim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + TRIM(b FROM a) + '|') FROM babel_4489_trim_t2) +END +GO + +CREATE VIEW babel_4489_trim_dep_view_1 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t1 +GO + +CREATE VIEW babel_4489_trim_dep_view_2 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE VIEW babel_4489_trim_dep_view_3 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t3 +GO + +CREATE VIEW babel_4489_trim_dep_view_4 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t4 +GO + +CREATE VIEW babel_4489_trim_dep_view_5 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t5 +GO + +CREATE VIEW babel_4489_trim_dep_view_6 AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t4 +GO + +CREATE FUNCTION babel_4489_trim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-verify.sql new file mode 100644 index 00000000000..00892e69363 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/trim-before-15_8-or-16_4-vu-verify.sql @@ -0,0 +1,619 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT TRIM(NULL) +GO + +SELECT TRIM(NULL FROM NULL) +GO + +SELECT TRIM('' FROM NULL) +GO + +SELECT TRIM(NULL FROM '') +GO + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO + +EXEC babel_4489_trim_dep_proc +GO + +SELECT * FROM babel_4489_trim_dep_func() +GO + +SELECT * FROM babel_4489_trim_itvf_func() +GO + +SELECT * FROM babel_4489_trim_dep_view_1 +GO + +SELECT * FROM babel_4489_trim_dep_view_2 +GO + +SELECT * FROM babel_4489_trim_dep_view_3 +GO + +SELECT * FROM babel_4489_trim_dep_view_4 +GO + +SELECT * FROM babel_4489_trim_dep_view_5 +GO + +SELECT * FROM babel_4489_trim_dep_view_6 +GO + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/string_functions/trim-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/trim-vu-cleanup.sql new file mode 100644 index 00000000000..fef5323495e --- /dev/null +++ b/test/JDBC/input/functions/string_functions/trim-vu-cleanup.sql @@ -0,0 +1,77 @@ +DROP FUNCTION babel_4489_trim_itvf_func +GO + +DROP FUNCTION babel_4489_trim_dep_func +GO + +DROP PROCEDURE babel_4489_trim_dep_proc +GO + +DROP VIEW babel_4489_trim_dep_view +GO + +DROP VIEW babel_4489_trim_dep_view_1 +GO + +DROP VIEW babel_4489_trim_dep_view_2 +GO + +DROP VIEW babel_4489_trim_dep_view_3 +GO + +DROP VIEW babel_4489_trim_dep_view_4 +GO + +DROP VIEW babel_4489_trim_dep_view_5 +GO + +DROP VIEW babel_4489_trim_dep_view_6 +GO + +DROP TABLE babel_4489_trim_UDT +GO + +DROP TYPE dbo.babel_4489_trim_varUDT +GO + +DROP TYPE dbo.babel_4489_trim_imageUDT +GO + +DROP TABLE babel_4489_trim_text +GO + +DROP TABLE babel_4489_trim_image +GO + +DROP TABLE babel_4489_trim_arabic_ci_ai +GO + +DROP TABLE babel_4489_trim_arabic_cs_as +GO + +DROP TABLE babel_4489_trim_arabic_ci_as +GO + +DROP TABLE babel_4489_trim_chinese_prc_ci_ai +GO + +DROP TABLE babel_4489_trim_chinese_prc_cs_as +GO + +DROP TABLE babel_4489_trim_chinese_prc_ci_as +GO + +DROP TABLE babel_4489_trim_t5 +GO + +DROP TABLE babel_4489_trim_t4 +GO + +DROP TABLE babel_4489_trim_t3 +GO + +DROP TABLE babel_4489_trim_t2 +GO + +DROP TABLE babel_4489_trim_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/trim-vu-prepare.sql b/test/JDBC/input/functions/string_functions/trim-vu-prepare.sql new file mode 100644 index 00000000000..a771d12b4b0 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/trim-vu-prepare.sql @@ -0,0 +1,122 @@ +CREATE TABLE babel_4489_trim_t1(a NCHAR(50), b NCHAR(20)) +GO +INSERT INTO babel_4489_trim_t1 VALUES(N' abc🙂defghi🙂🙂 ', N'ab🙂 ') +INSERT INTO babel_4489_trim_t1 VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_t2(a NVARCHAR(50), b NVARCHAR(20)) +GO +INSERT INTO babel_4489_trim_t2 VALUES(N' abc🙂defghi🙂🙂 ', N'ab🙂 ') +GO + +CREATE TABLE babel_4489_trim_t3(a CHAR(50), b CHAR(20)) +GO +INSERT INTO babel_4489_trim_t3 VALUES(' abcdefghi ', 'abi ') +GO + +CREATE TABLE babel_4489_trim_t4(a VARCHAR(50), b VARCHAR(20)) +GO +INSERT INTO babel_4489_trim_t4 VALUES(' abcdefghi ', 'abi ') +GO + +CREATE TABLE babel_4489_trim_t5(a VARBINARY(50), b VARBINARY(50)) +GO +INSERT INTO babel_4489_trim_t5 VALUES(0x61626364, 0x6164) +GO + +CREATE TABLE babel_4489_trim_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS, b VARCHAR(20) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4489_trim_chinese_prc_ci_as VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS, b VARCHAR(20) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4489_trim_chinese_prc_cs_as VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI, b VARCHAR(20) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4489_trim_chinese_prc_ci_ai VALUES(N' 比尔·拉莫斯 ', N'比拉斯 ') +GO + +CREATE TABLE babel_4489_trim_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS, b VARCHAR(20) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4489_trim_arabic_ci_as VALUES(N' الله مع المتقين ', N'ين ') +GO + +CREATE TABLE babel_4489_trim_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS, b VARCHAR(20) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4489_trim_arabic_cs_as VALUES(N' الله مع المتقين ', N'ين ') +GO + +CREATE TABLE babel_4489_trim_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI, b VARCHAR(20) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4489_trim_arabic_ci_ai VALUES(N' الله مع المتقين ', N'ين ') +GO + +CREATE TABLE babel_4489_trim_image(a IMAGE) +GO +INSERT INTO babel_4489_trim_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4489_trim_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4489_trim_text VALUES (N' abc🙂defghi🙂🙂 ', N' abc🙂defghi🙂🙂 ') +GO + +CREATE TYPE dbo.babel_4489_trim_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4489_trim_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4489_trim_UDT(a dbo.babel_4489_trim_imageUDT, b dbo.babel_4489_trim_varUDT) +GO +INSERT INTO babel_4489_trim_UDT VALUES(CAST('abcdef' as dbo.babel_4489_trim_imageUDT), CAST('abcdef' as dbo.babel_4489_trim_varUDT)) +GO + +CREATE VIEW babel_4489_trim_dep_view AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE PROCEDURE babel_4489_trim_dep_proc AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE FUNCTION babel_4489_trim_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 ('|' + TRIM(b FROM a) + '|') FROM babel_4489_trim_t2) +END +GO + +CREATE VIEW babel_4489_trim_dep_view_1 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t1 +GO + +CREATE VIEW babel_4489_trim_dep_view_2 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t2 +GO + +CREATE VIEW babel_4489_trim_dep_view_3 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t3 +GO + +CREATE VIEW babel_4489_trim_dep_view_4 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t4 +GO + +CREATE VIEW babel_4489_trim_dep_view_5 AS + SELECT ('|' + TRIM(a) + '|') as result FROM babel_4489_trim_t5 +GO + +CREATE VIEW babel_4489_trim_dep_view_6 AS + SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t4 +GO + +CREATE FUNCTION babel_4489_trim_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT ('|' + TRIM(b FROM a) + '|') as result FROM babel_4489_trim_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/trim-vu-verify.sql b/test/JDBC/input/functions/string_functions/trim-vu-verify.sql new file mode 100644 index 00000000000..00892e69363 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/trim-vu-verify.sql @@ -0,0 +1,619 @@ +-- customer case, mentioned in the jira description +DECLARE @custname NVARCHAR(50) = N'比尔·拉莫斯' +SELECT @custname, + TRIM(@custname) as [TRIM] + , LTRIM(@custname) as [LTRIM] + , RTRIM(@custname) as [RTRIM] + , LEFT(@custname, 4) as [LEFT4] + , RIGHT(@custname, 4) as [RIGHT4] + , SUBSTRING(@custname, 2, 4) as [SUBSTRING_2_4] +; +GO + +-- NULL +SELECT TRIM(NULL) +GO + +SELECT TRIM(NULL FROM NULL) +GO + +SELECT TRIM('' FROM NULL) +GO + +SELECT TRIM(NULL FROM '') +GO + +-- input type char +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- input type varchar +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab? ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(10) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(MAX) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) COLLATE CHINESE_PRC_CI_AS + '|' +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AS + '|' FROM babel_4489_trim_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CS_AS + '|' FROM babel_4489_trim_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO + +SELECT '|' + TRIM(b FROM a) COLLATE CHINESE_PRC_CI_AI + '|' FROM babel_4489_trim_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AS + '|' FROM babel_4489_trim_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_cs_as +GO + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CS_AS + '|' FROM babel_4489_trim_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_arabic_ci_ai +GO + +SELECT '|' + TRIM(b FROM a) COLLATE ARABIC_CI_AI + '|' FROM babel_4489_trim_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +-- with table column of type nchar +SELECT '|' + TRIM(b FROM a) + '|' FROM babel_4489_trim_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM(@inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' ab😎c🙂defghi🙂🙂 ' +SELECT '|' + TRIM('ab🙂😎 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ' +SELECT '|' + TRIM('比拉斯 ' FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(MAX) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +-- dependent objects +SELECT * FROM babel_4489_trim_dep_view +GO + +EXEC babel_4489_trim_dep_proc +GO + +SELECT * FROM babel_4489_trim_dep_func() +GO + +SELECT * FROM babel_4489_trim_itvf_func() +GO + +SELECT * FROM babel_4489_trim_dep_view_1 +GO + +SELECT * FROM babel_4489_trim_dep_view_2 +GO + +SELECT * FROM babel_4489_trim_dep_view_3 +GO + +SELECT * FROM babel_4489_trim_dep_view_4 +GO + +SELECT * FROM babel_4489_trim_dep_view_5 +GO + +SELECT * FROM babel_4489_trim_dep_view_6 +GO + +-- different datatypes of inputString and charSet +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString CHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARCHAR(50) = ' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NVARCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NCHAR(50) = N' 比尔·拉莫斯 ', @charSet NVARCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet CHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet CHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab? ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet VARCHAR(20) = 'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet VARCHAR(20) = '比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab🙂 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' abc🙂defghi🙂🙂 ', @charSet NCHAR(20) = N'ab😎 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' 比尔·拉莫斯 ', @charSet NCHAR(20) = N'比拉斯 ' +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString NVARCHAR(50) = N' ABCDEF ', @charSet BINARY(4) = 0x414243 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +DECLARE @inputString VARBINARY(50) = 0x41424344, @charSet VARBINARY(2) = 0x4144 +SELECT '|' + TRIM(@charSet FROM @inputString) + '|' +GO + +-- input type UDT +-- -- in table babel_4489_trim_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT TRIM(a) FROM babel_4489_trim_UDT +GO + +SELECT TRIM(b) FROM babel_4489_trim_UDT +GO + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_UDT +GO + +DECLARE @charSet VARCHAR(10) = 'ab' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_UDT +GO + +-- other different datatypes, all of these should be blocked +DECLARE @inputString date = '2016-12-21' +SELECT TRIM('12' FROM @inputString) +GO + +DECLARE @inputString date = '2016-12-21', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString date = '2016-12-21' +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date, @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10', @charSet VARCHAR(10) = '12'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237', @charSet VARCHAR(10) = '10'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237', @charSet VARCHAR(10) = '23'; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString decimal = 123456, @charSet decimal = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString numeric = 12345.12, @charSet numeric = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString float = 12345.1, @charSet float = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString real = 12345.1, @charSet real = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString bigint = 12345678, @charSet bigint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString int = 12345678, @charSet int = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString smallint = 12356, @charSet smallint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString tinyint = 235, @charSet tinyint = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString money = 12356, @charSet money = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString smallmoney = 12356, @charSet smallmoney = 12; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString bit = 1, @charSet bit = 1; +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString UNIQUEIDENTIFIER = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS UNIQUEIDENTIFIER) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO + +SELECT TRIM(a FROM a) FROM babel_4489_trim_image; +GO + +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM a) from babel_4489_trim_image; +GO + +SELECT TRIM(a FROM b) FROM babel_4489_trim_text +GO +SELECT TRIM(b FROM a) FROM babel_4489_trim_text +GO + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM a) FROM babel_4489_trim_text +GO + +DECLARE @charSet VARCHAR(20) = 'ab? ' +SELECT TRIM(@charSet FROM b) FROM babel_4489_trim_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(@charSet FROM @inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@charSet FROM @inputString) +GO +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326), @charSet VARCHAR(10) = '2'; +SELECT TRIM(@inputString FROM @inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +DECLARE @charSet VARCHAR(10) = '6F'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +DECLARE @charSet xml = CAST ('' AS xml); +SELECT TRIM(CAST(@charSet AS VARCHAR) FROM CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0), @charSet VARCHAR(10) = '(1 2)'; +SELECT TRIM(@charSet FROM CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 00000000000..f26a20c06b2 --- /dev/null +++ b/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,26 @@ +DROP VIEW sys_host_name_vu_prepare__host_name_view +GO + +DROP FUNCTION sys_host_name_vu_prepare__host_name_func +GO + +DROP PROCEDURE sys_host_name_vu_prepare__host_name_proc +GO + +DROP VIEW sys_host_name_vu_prepare__dm_exec_connections_view +GO + +DROP FUNCTION sys_host_name_vu_prepare__dm_exec_connections_func +GO + +DROP PROCEDURE sys_host_name_vu_prepare__dm_exec_connections_proc +GO + +DROP VIEW sys_host_name_vu_prepare__dm_exec_sessions_view +GO + +DROP FUNCTION sys_host_name_vu_prepare__dm_exec_sessions_func +GO + +DROP PROCEDURE sys_host_name_vu_prepare__dm_exec_sessions_proc +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 00000000000..c4153e6ca81 --- /dev/null +++ b/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,42 @@ +CREATE VIEW sys_host_name_vu_prepare__host_name_view AS SELECT DISTINCT hostname FROM sys.sysprocesses WHERE spid = @@SPID +GO + +CREATE FUNCTION sys_host_name_vu_prepare__host_name_func(@pid int) +RETURNS TABLE +AS +RETURN (SELECT DISTINCT CAST(hostname as nvarchar(128)) FROM sys.sysprocesses WHERE spid = @pid); +GO + +CREATE PROCEDURE sys_host_name_vu_prepare__host_name_proc +AS +SELECT DISTINCT hostname FROM sys.sysprocesses WHERE spid = @@SPID +GO + +-- Create objects that relied on dependent functions that were modified +CREATE VIEW sys_host_name_vu_prepare__dm_exec_connections_view AS select net_transport, protocol_type, protocol_version, endpoint_id, encrypt_option from sys.dm_exec_connections where session_id = @@SPID +GO + +CREATE FUNCTION sys_host_name_vu_prepare__dm_exec_connections_func(@pid int) +RETURNS TABLE +AS +RETURN (select net_transport, protocol_type, protocol_version, endpoint_id, encrypt_option from sys.dm_exec_connections where session_id = @pid); +GO + +CREATE PROCEDURE sys_host_name_vu_prepare__dm_exec_connections_proc +AS +select net_transport, protocol_type, protocol_version, endpoint_id, encrypt_option from sys.dm_exec_connections where session_id = @@SPID +GO + +CREATE VIEW sys_host_name_vu_prepare__dm_exec_sessions_view AS select language, host_name, client_version, TRIM('0123456789.' FROM client_interface_name), program_name, date_format, date_first from sys.dm_exec_sessions where session_id = @@SPID +GO + +CREATE FUNCTION sys_host_name_vu_prepare__dm_exec_sessions_func(@pid int) +RETURNS TABLE +AS +RETURN (select language, host_name, client_version, TRIM('0123456789.' FROM client_interface_name), program_name, date_format, date_first from sys.dm_exec_sessions where session_id = @pid); +GO + +CREATE PROCEDURE sys_host_name_vu_prepare__dm_exec_sessions_proc +AS +select language, host_name, client_version, TRIM('0123456789.' FROM client_interface_name), program_name, date_format, date_first from sys.dm_exec_sessions where session_id = @@SPID +GO diff --git a/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-verify.mix b/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-verify.mix new file mode 100644 index 00000000000..6cab155c011 --- /dev/null +++ b/test/JDBC/input/functions/sys-host_name-before-15_8-or-16_4-vu-verify.mix @@ -0,0 +1,33 @@ +-- explicitly specify a workstation name to check the HOST_NAME +-- T-SQL function and hostname entry in sys.sysprocesses view + +-- tsql password=12345678;workstationID=a_nice_workstation_name +SELECT HOST_NAME() +GO + +SELECT * from sys_host_name_vu_prepare__host_name_func(@@SPID) +GO + +SELECT * FROM sys_host_name_vu_prepare__host_name_view +GO + +EXECUTE sys_host_name_vu_prepare__host_name_proc +GO + +SELECT * from sys_host_name_vu_prepare__dm_exec_connections_func(@@SPID) +GO + +SELECT * FROM sys_host_name_vu_prepare__dm_exec_connections_view +GO + +EXECUTE sys_host_name_vu_prepare__dm_exec_connections_proc +GO + +SELECT * from sys_host_name_vu_prepare__dm_exec_sessions_func(@@SPID) +GO + +SELECT * FROM sys_host_name_vu_prepare__dm_exec_sessions_view +GO + +EXECUTE sys_host_name_vu_prepare__dm_exec_sessions_proc +GO diff --git a/test/JDBC/jdbc_schedule b/test/JDBC/jdbc_schedule index 9178d3bb051..7e23eb108f5 100644 --- a/test/JDBC/jdbc_schedule +++ b/test/JDBC/jdbc_schedule @@ -214,8 +214,6 @@ ignore#!#BABEL-730-before-15_6-or-16_1-vu-prepare ignore#!#BABEL-730-before-15_6-or-16_1-vu-verify ignore#!#BABEL-730-before-15_6-or-16_1-vu-cleanup -# These tests are meant for upgrade scenario prior to (potential) 15_7 or 16_3 release - ignore#!#BABEL-404-before-15_7-or-16_3-vu-prepare ignore#!#BABEL-404-before-15_7-or-16_3-vu-verify ignore#!#BABEL-404-before-15_7-or-16_3-vu-cleanup @@ -262,6 +260,26 @@ ignore#!#BABEL-621-after-14_12-before-15-vu-prepare ignore#!#BABEL-621-after-14_12-before-15-vu-verify ignore#!#BABEL-621-after-14_12-before-15-vu-cleanup +# These tests are meant for upgrade scenario prior to 15_8 or 16_4 release +ignore#!#sys-host_name-before-15_8-or-16_4-vu-prepare +ignore#!#sys-host_name-before-15_8-or-16_4-vu-verify +ignore#!#sys-host_name-before-15_8-or-16_4-vu-cleanup +ignore#!#left-before-15_8-or-16_4-vu-prepare +ignore#!#left-before-15_8-or-16_4-vu-verify +ignore#!#left-before-15_8-or-16_4-vu-cleanup +ignore#!#right-before-15_8-or-16_4-vu-prepare +ignore#!#right-before-15_8-or-16_4-vu-verify +ignore#!#right-before-15_8-or-16_4-vu-cleanup +ignore#!#ltrim-before-15_8-or-16_4-vu-prepare +ignore#!#ltrim-before-15_8-or-16_4-vu-verify +ignore#!#ltrim-before-15_8-or-16_4-vu-cleanup +ignore#!#rtrim-before-15_8-or-16_4-vu-prepare +ignore#!#rtrim-before-15_8-or-16_4-vu-verify +ignore#!#rtrim-before-15_8-or-16_4-vu-cleanup +ignore#!#trim-before-15_8-or-16_4-vu-prepare +ignore#!#trim-before-15_8-or-16_4-vu-verify +ignore#!#trim-before-15_8-or-16_4-vu-cleanup + # These tests are running in multidb mode in upgrade and singledb mode in JDBC ignore#!#BABEL-4279-vu-prepare ignore#!#BABEL-4279-vu-verify diff --git a/test/JDBC/upgrade/13_4/schedule b/test/JDBC/upgrade/13_4/schedule index c03f4408ebb..6bca6f66c75 100644 --- a/test/JDBC/upgrade/13_4/schedule +++ b/test/JDBC/upgrade/13_4/schedule @@ -233,5 +233,10 @@ permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 diff --git a/test/JDBC/upgrade/13_5/schedule b/test/JDBC/upgrade/13_5/schedule index be23c26e591..a8fe82a0554 100644 --- a/test/JDBC/upgrade/13_5/schedule +++ b/test/JDBC/upgrade/13_5/schedule @@ -286,5 +286,10 @@ permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 diff --git a/test/JDBC/upgrade/13_6/schedule b/test/JDBC/upgrade/13_6/schedule index ddf5bfae305..5871c317d48 100644 --- a/test/JDBC/upgrade/13_6/schedule +++ b/test/JDBC/upgrade/13_6/schedule @@ -341,6 +341,11 @@ BABEL-730-before-15_6-or-16_1 GRANT_SCHEMA-before-15_7-16_3 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/13_7/schedule b/test/JDBC/upgrade/13_7/schedule index 4424e1b95fb..1c4ddaf153e 100644 --- a/test/JDBC/upgrade/13_7/schedule +++ b/test/JDBC/upgrade/13_7/schedule @@ -335,5 +335,10 @@ permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 diff --git a/test/JDBC/upgrade/13_8/schedule b/test/JDBC/upgrade/13_8/schedule index 0b65bb893b9..422e444d0d4 100644 --- a/test/JDBC/upgrade/13_8/schedule +++ b/test/JDBC/upgrade/13_8/schedule @@ -335,5 +335,10 @@ permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index c99e5b9b5f9..a4e2812e781 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -339,6 +339,11 @@ BABEL-730-before-15_6-or-16_1 babel-4517 GRANT_SCHEMA-before-15_7-16_3 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index 03f4adcb888..6dfa08bb94f 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -60,7 +60,7 @@ column_domain_usage constraint_column_usage select-strip-parens-before-15_5 sp_describe_first_result_set -sys-host_name +sys-host_name-before-15_8-or-16_4 SYSTEM_USER indexproperty sys-all_parameters @@ -438,6 +438,11 @@ BABEL-4815 BABEL_3571-before-15-5 BABEL_4817 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 6fd8e9e14b5..3af98943697 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -60,7 +60,7 @@ column_domain_usage constraint_column_usage select-strip-parens-before-15_5 sp_describe_first_result_set -sys-host_name +sys-host_name-before-15_8-or-16_4 SYSTEM_USER indexproperty sys-all_parameters @@ -437,6 +437,11 @@ BABEL-4815 BABEL_3571-before-15-5 BABEL_4817 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 babel_4328_datetime-before-16_3 diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index bad7b3f4f2a..deb8b1f5906 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -60,7 +60,7 @@ column_domain_usage constraint_column_usage select-strip-parens-before-15_5 sp_describe_first_result_set -sys-host_name +sys-host_name-before-15_8-or-16_4 SYSTEM_USER indexproperty sys-all_parameters @@ -432,6 +432,11 @@ BABEL-492-before-15_6 babel-4517 babel-3254 BABEL-4641 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863 babel_test_int4_numeric_oper_before_16_3 babel_test_int8_numeric_oper_before_16_3 diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index 9da3682ed58..882322de179 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -60,7 +60,7 @@ column_domain_usage constraint_column_usage select-strip-parens-before-15_5 sp_describe_first_result_set -sys-host_name +sys-host_name-before-15_8-or-16_4 SYSTEM_USER indexproperty sys-all_parameters @@ -432,6 +432,11 @@ BABEL-492-before-15_6 babel-4517 babel-3254 BABEL-4641 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863 babel_test_int4_numeric_oper_before_16_3 babel_test_int8_numeric_oper_before_16_3 diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index f024fa904ec..6a28ac8060a 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -356,6 +356,11 @@ BABEL-730-before-15_6-or-16_1 GRANT_SCHEMA-before-15_7-16_3 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 babel_test_int4_numeric_oper_before_16_3 diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index c41157dad33..8e2c880f955 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -237,7 +237,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -371,6 +371,11 @@ BABEL-730-before-15_6-or-16_1 GRANT_SCHEMA-before-15_7-16_3 babel-4517 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index daaf2288105..bfdd647c650 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -270,7 +270,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -408,6 +408,11 @@ GRANT_SCHEMA-before-15_7-16_3 babel-4517 BABEL_3571-before-15-5 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index 696973674a1..e39dfeb7422 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -287,7 +287,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -429,6 +429,11 @@ babel-4517 BABEL-4815 BABEL_3571-before-15-5 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 5078b78093e..1b56fb23c42 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -285,7 +285,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -431,6 +431,11 @@ BABEL-4815 BABEL_3571-before-15-5 BABEL_4817 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 606da86407a..de665b221e8 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -59,7 +59,7 @@ routines_definition column_domain_usage constraint_column_usage sp_describe_first_result_set -sys-host_name +sys-host_name-before-15_8-or-16_4 SYSTEM_USER indexproperty sys-all_parameters @@ -434,6 +434,11 @@ BABEL-4815 BABEL_3571-before-15-5 BABEL_4817 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index e7c7d60e1d2..73a53866db8 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -267,7 +267,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -408,6 +408,11 @@ babel-4517 BABEL-4815 BABEL_3571-before-15-5 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 babel_4328_datetime-before-16_3 diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 979ef5dfe25..3d98fad0c55 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -292,7 +292,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -440,6 +440,11 @@ babel-4475 babel-4517 BABEL_3571-before-15-5 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_test_int4_numeric_oper_before_16_3 babel_test_int8_numeric_oper_before_16_3 diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index f13c4ee20b5..498207cbc23 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -306,7 +306,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -462,6 +462,11 @@ babel-4517 BABEL-4815 BABEL_3571-before-15-5 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 babel_4328_datetime-before-16_3 diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index 9f99685837a..1c889afba57 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -312,7 +312,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -474,6 +474,11 @@ GRANT_SCHEMA-before-15_7-16_3 babel-4517 BABEL_3571-before-15-5 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 babel_4328_datetime-before-16_3 diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 853228c17dd..cbf9c3dedeb 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -320,7 +320,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -505,6 +505,11 @@ GRANT_SCHEMA-before-15_7-16_3 BABEL-4815 BABEL_3571-15_5-or-15_6-or-16_1-or-16_2 BABEL-4641-before-16_3-or-15_7-or-14_12 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 babel_4328_datetime-before-16_3 diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 1931228e8e6..919e1e84204 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -326,7 +326,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -512,6 +512,11 @@ BABEL-730 babel-4475 babel-4517 GRANT_SCHEMA-before-15_7-16_3 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4815 BABEL_3571-15_5-or-15_6-or-16_1-or-16_2 BABEL-4641-before-16_3-or-15_7-or-14_12 diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 514511e13ab..787237264a3 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -327,7 +327,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -517,6 +517,11 @@ babel_table_type 1_GRANT_SCHEMA BABEL-4707 BABEL_4817 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 BABEL-4641 BABEL-4863 babel_test_int4_numeric_oper diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 1d31eddd56b..21da5b04e9e 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -523,3 +523,8 @@ babel_4328_datetime2 babel_4328_datetimeoffset BABEL-3401 babel_726 +trim +ltrim +rtrim +left +right diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index 4e6c19061cf..16869e5de2a 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -325,7 +325,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -519,3 +519,8 @@ babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 babel_726-before-14_12-or-15_7-or-16_3 BABEL-5071 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index 69326b652f6..0f149508df5 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -328,7 +328,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -534,3 +534,8 @@ babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 BABEL-5071 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 65854906a15..6066507dcb3 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -328,7 +328,7 @@ sys-fulltext_stoplists sys-hash_indexes sys-has_perms_by_name sys-has_perms_by_name-dep -sys-host_name +sys-host_name-before-15_8-or-16_4 sys-identity_columns sys-identity_columns-dep sys-index_columns @@ -535,4 +535,9 @@ babel_4328_datetime babel_4328_datetime2 babel_4328_datetimeoffset babel_726 -BABEL-3401 \ No newline at end of file +BABEL-3401 +trim-before-15_8-or-16_4 +ltrim-before-15_8-or-16_4 +rtrim-before-15_8-or-16_4 +left-before-15_8-or-16_4 +right-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index a7c3fb366eb..efa230e4fc7 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -529,6 +529,11 @@ alter-procedure BABEL-4707 BABEL_4817 BABEL-4641 +trim +ltrim +rtrim +left +right BABEL-4863 babel_test_int4_numeric_oper babel_test_int8_numeric_oper diff --git a/test/odbc/psqlodbc/test/text.cpp b/test/odbc/psqlodbc/test/text.cpp index df02bfb55b4..51815a58443 100644 --- a/test/odbc/psqlodbc/test/text.cpp +++ b/test/odbc/psqlodbc/test/text.cpp @@ -369,6 +369,11 @@ TEST_F(PSQL_DataTypes_Text, Comparison_Operators) { } TEST_F(PSQL_DataTypes_Text, String_Functions) { + const vector> TABLE_COLUMNS = { + {COL1_NAME, " int PRIMARY KEY"}, + {COL2_NAME, " sys.VARCHAR(50)"} + }; + const vector INSERTED_DATA = { "aBcDeFg", " test", diff --git a/test/python/expected/sql_validation_framework/expected_drop.out b/test/python/expected/sql_validation_framework/expected_drop.out index 9f2b0bd6c39..6c8a9e636b3 100644 --- a/test/python/expected/sql_validation_framework/expected_drop.out +++ b/test/python/expected/sql_validation_framework/expected_drop.out @@ -76,3 +76,4 @@ Unexpected drop found for procedure sys.babelfish_update_user_catalog_for_guest Unexpected drop found for procedure sys.babelfish_update_user_catalog_for_guest_schema in file babelfishpg_tsql--3.3.0--3.4.0.sql Unexpected drop found for procedure sys.create_xp_qv_in_master_dbo in file babelfishpg_tsql--1.1.0--1.2.0.sql Unexpected drop found for procedure sys.sp_babelfish_grant_usage_to_all in file babelfishpg_tsql--1.1.0--1.2.0.sql +Unexpected drop found for table "#temp_schedules_to_delete" in file babelfishpg_tsql--4.2.0--4.3.0.sql diff --git a/test/python/expected/upgrade_validation/expected_dependency.out b/test/python/expected/upgrade_validation/expected_dependency.out index dd1059bd7de..005bb22080b 100644 --- a/test/python/expected/upgrade_validation/expected_dependency.out +++ b/test/python/expected/upgrade_validation/expected_dependency.out @@ -1,5 +1,4 @@ Could not find dependencies on -Collation sys.arabic_cs_as Collation sys.bbf_unicode_cp1250_ci_ai Collation sys.bbf_unicode_cp1250_cs_ai Collation sys.bbf_unicode_cp1251_ci_ai @@ -37,8 +36,6 @@ Collation sys.bbf_unicode_pref_cp1257_cs_as Collation sys.bbf_unicode_pref_cp1258_cs_as Collation sys.bbf_unicode_pref_cp1_cs_as Collation sys.bbf_unicode_pref_cp874_cs_as -Collation sys.chinese_prc_ci_as -Collation sys.chinese_prc_cs_as Collation sys.cyrillic_general_ci_ai Collation sys.cyrillic_general_ci_as Collation sys.estonian_ci_as @@ -223,6 +220,7 @@ Function sys.bbf_binary_cmp(sys.bbf_binary,sys.bbf_binary) Function sys.bbf_binary_varbinary_cmp(sys.bbf_binary,sys.bbf_varbinary) Function sys.bbf_get_context_info() Function sys.bbf_get_current_physical_schema_name(text) +Function sys.bbf_get_immediate_base_type_of_udt(oid) Function sys.bbf_is_shared_schema(text) Function sys.bbf_pivot() Function sys.bbf_varbinary(sys.geography) @@ -815,7 +813,6 @@ Operator sys.+(sys.fixeddecimal,integer) Operator sys.+(sys.fixeddecimal,smallint) Operator sys.+(sys.fixeddecimal,sys.fixeddecimal) Operator sys.+(sys.nvarchar,sys."varchar") -Operator sys.+(sys.nvarchar,sys.nvarchar) Operator sys.+(sys.smallmoney,bigint) Operator sys.+(sys.smallmoney,integer) Operator sys.+(sys.smallmoney,smallint) From f03c712ae415dcc4ae273cc257a063d13f060c69 Mon Sep 17 00:00:00 2001 From: Sumit Jaiswal <54075285+sumitj824@users.noreply.github.com> Date: Thu, 25 Jul 2024 20:49:17 +0530 Subject: [PATCH 11/15] Support Table and Index Partitioning in Babelfish (#2702) This commit introduces Support for Table and Index Partitioning in Babelfish, enabling users to partition large tables and indexes using partition schemes. Key Changes: 1. Partitioned Table Support: - Added syntax support for creating partitioned tables using the `CREATE TABLE ... on PARTITION_SCHEME (column)` statement. - Implemented support for partitioned table using partition scheme, where child partitions are implicitly created by looking up the metadata of the partition function and partitioning column values. - Restricted InsertBulk operations for partitioned tables as they are not supported yet. - Restricted users from modifying Babelfish partitioned tables to attach, detach, or modify partitions of these tables to maintain data consistency in the Babelfish catalog. Existing users who have created partitioned tables from the PostgreSQL endpoint can continue to modify, attach, and detach partitions as usual. - Introduced sys.babelfish_partition_depend catalog to track the dependency between partitioned tables and the partition schemes used to create them. The catalog maintains consistent table name even after RENAME or DROP TABLE operations. 2. Partitioned Index Support: - Added syntax support for creating partitioned indexes using the `CREATE INDEX ... ON PARTITION_SCHEME (column)` statement. - Implemented support for creating aligned partitioned indexes, where the index partitioning scheme aligns with the underlying table partitioning scheme. - Restricted the ability to create non-aligned partitioned indexes with custom partition schemes. 3. System Catalog Views: - Modified system catalog views to exclude listing child partitions for partitioned tables and indexes. - Modified system catalog views to list the partitioned table along with regular tables. - These changes ensures that only the parent partitioned object is listed in the relevant system views Signed-off-by: Sumit Jaiswal [sumiji@amazon.com](mailto:sumiji@amazon.com) Engine PR: https://github.com/babelfish-for-postgresql/postgresql_modified_for_babelfish/pull/399 Issues Resolved Task: BABEL-4968, BABEL-4969 --- contrib/babelfishpg_tsql/Makefile | 1 + .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 3 +- .../sql/information_schema_tsql.sql | 8 +- contrib/babelfishpg_tsql/sql/sys_views.sql | 15 +- .../babelfishpg_tsql--4.2.0--4.3.0.sql | 1166 ++++++ .../src/backend_parser/gram-tsql-decl.y | 6 +- .../src/backend_parser/gram-tsql-rule.y | 93 +- contrib/babelfishpg_tsql/src/catalog.c | 268 +- contrib/babelfishpg_tsql/src/catalog.h | 7 +- contrib/babelfishpg_tsql/src/hooks.c | 39 +- contrib/babelfishpg_tsql/src/hooks.h | 4 +- contrib/babelfishpg_tsql/src/pl_exec-2.c | 36 +- contrib/babelfishpg_tsql/src/pl_handler.c | 68 + contrib/babelfishpg_tsql/src/pltsql.h | 5 +- .../babelfishpg_tsql/src/pltsql_bulkcopy.c | 7 +- .../babelfishpg_tsql/src/pltsql_partition.c | 841 +++++ .../babelfishpg_tsql/src/pltsql_partition.h | 30 + contrib/babelfishpg_tsql/src/schemacmds.c | 1 + contrib/babelfishpg_tsql/src/tsqlIface.cpp | 14 +- .../src/tsqlUnsupportedFeatureHandler.cpp | 9 +- test/JDBC/expected/BABEL-2515.out | 36 - test/JDBC/expected/BABEL-UNSUPPORTED.out | 12 - test/JDBC/expected/PARTITION-vu-cleanup.out | 242 +- test/JDBC/expected/PARTITION-vu-prepare.out | 771 +++- test/JDBC/expected/PARTITION-vu-verify.out | 1952 +++++++++- .../chinese_prc_ci_as/BABEL-UNSUPPORTED.out | 12 - .../chinese_prc_ci_as/PARTITION-vu-verify.out | 1952 +++++++++- .../parallel_query/PARTITION-vu-verify.out | 3154 +++++++++++++++++ test/JDBC/input/BABEL-2515.sql | 32 - test/JDBC/input/BABEL-UNSUPPORTED.sql | 8 - test/JDBC/input/PARTITION-vu-cleanup.mix | 229 +- test/JDBC/input/PARTITION-vu-prepare.mix | 595 +++- test/JDBC/input/PARTITION-vu-verify.mix | 849 ++++- test/dotnet/ExpectedOutput/insertBulk.out | 15 + test/dotnet/input/InsertBulk/insertBulk.txt | 16 +- .../expected_create.out | 4 - 36 files changed, 12270 insertions(+), 230 deletions(-) create mode 100644 contrib/babelfishpg_tsql/src/pltsql_partition.c create mode 100644 contrib/babelfishpg_tsql/src/pltsql_partition.h delete mode 100644 test/JDBC/expected/BABEL-2515.out create mode 100644 test/JDBC/expected/parallel_query/PARTITION-vu-verify.out delete mode 100644 test/JDBC/input/BABEL-2515.sql diff --git a/contrib/babelfishpg_tsql/Makefile b/contrib/babelfishpg_tsql/Makefile index 84b5ab253fd..64b16953263 100644 --- a/contrib/babelfishpg_tsql/Makefile +++ b/contrib/babelfishpg_tsql/Makefile @@ -76,6 +76,7 @@ OBJS += src/table_variable_mvcc.o OBJS += src/extendedproperty.o OBJS += src/fts.o OBJS += src/fts_parser.o +OBJS += src/pltsql_partition.o export ANTLR4_JAVA_BIN=java export ANTLR4_RUNTIME_LIB=-lantlr4-runtime diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index 26428f147f4..740eecf2602 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -977,7 +977,8 @@ END AS TABLE_TYPE, CAST(NULL AS varchar(254)) AS remarks FROM pg_catalog.pg_class AS t1, sys.pg_namespace_ext AS t2, sys.schemas AS t3 -WHERE t1.relnamespace = t3.schema_id AND t1.relnamespace = t2.oid AND t1.relkind IN ('r','v','m') +WHERE t1.relnamespace = t3.schema_id AND t1.relnamespace = t2.oid AND t1.relkind IN ('r','p','v','m') +AND t1.relispartition = false AND has_schema_privilege(t1.relnamespace, 'USAGE') AND has_table_privilege(t1.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER'); GRANT SELECT ON sys.sp_tables_view TO PUBLIC; diff --git a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql index 2f37a85d600..0f200a79370 100644 --- a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql @@ -333,6 +333,7 @@ CREATE OR REPLACE VIEW information_schema_tsql.columns_internal AS WHERE (NOT pg_is_other_temp_schema(nc.oid)) AND a.attnum > 0 AND NOT a.attisdropped AND c.relkind IN ('r', 'v', 'p') + AND c.relispartition = false AND (pg_has_role(c.relowner, 'USAGE') OR has_column_privilege(c.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES')) @@ -463,6 +464,7 @@ CREATE VIEW information_schema_tsql.tables AS LEFT JOIN sys.table_types_internal tt on c.oid = tt.typrelid WHERE c.relkind IN ('r', 'v', 'p') + AND c.relispartition = false AND (NOT pg_is_other_temp_schema(nc.oid)) AND tt.typrelid IS NULL AND (pg_has_role(c.relowner, 'USAGE') @@ -502,6 +504,7 @@ CREATE VIEW information_schema_tsql.table_constraints AS AND c.conrelid = r.oid AND c.contype NOT IN ('t', 'x') AND r.relkind IN ('r', 'p') + AND relispartition = false AND (NOT pg_is_other_temp_schema(nr.oid)) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') @@ -565,6 +568,7 @@ CREATE VIEW information_schema_tsql.check_constraints AS AND c.conrelid = r.oid AND c.contype = 'c' AND r.relkind IN ('r', 'p') + AND r.relispartition = false AND (NOT pg_is_other_temp_schema(nc.oid)) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') @@ -605,6 +609,7 @@ FROM ( AND c.connamespace = nc.oid AND c.contype = 'c' AND r.relkind IN ('r', 'p') + AND r.relispartition = false AND NOT a.attisdropped AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') @@ -627,6 +632,7 @@ FROM ( AND NOT a.attisdropped AND c.contype IN ('p', 'u', 'f') AND r.relkind IN ('r', 'p') + AND r.relispartition = false AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') OR has_any_column_privilege(r.oid, 'SELECT, INSERT, UPDATE, REFERENCES')) @@ -809,7 +815,7 @@ CREATE OR REPLACE VIEW information_schema_tsql.key_column_usage AS CAST(ord AS int) AS "ORDINAL_POSITION" FROM pg_constraint c - JOIN pg_class r ON r.oid = c.conrelid AND c.contype in ('p','u','f') AND r.relkind in ('r','p') + JOIN pg_class r ON r.oid = c.conrelid AND c.contype in ('p','u','f') AND r.relkind in ('r','p') AND r.relispartition = false JOIN sys.pg_namespace_ext nc ON nc.oid = c.connamespace AND r.relnamespace = nc.oid JOIN sys.babelfish_namespace_ext ext ON ext.nspname = nc.nspname AND ext.dbid = sys.db_id() CROSS JOIN unnest(c.conkey) WITH ORDINALITY AS ak(j,ord) diff --git a/contrib/babelfishpg_tsql/sql/sys_views.sql b/contrib/babelfishpg_tsql/sql/sys_views.sql index 8b01e8894b8..a21ef921b7f 100644 --- a/contrib/babelfishpg_tsql/sql/sys_views.sql +++ b/contrib/babelfishpg_tsql/sql/sys_views.sql @@ -70,7 +70,8 @@ from pg_class t inner join sys.schemas sch on sch.schema_id = t.relnamespace left join tt_internal tt on t.oid = tt.typrelid where tt.typrelid is null -and t.relkind = 'r' +and (t.relkind = 'r' or t.relkind = 'p') +and t.relispartition = false and has_schema_privilege(t.relnamespace, 'USAGE') and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER'); GRANT SELECT ON sys.tables TO PUBLIC; @@ -450,6 +451,7 @@ where not a.attisdropped and (s.nspname = 'sys' or ext.nspname is not null) -- r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table and c.relkind in ('r', 'v', 'm', 'f', 'p') +and c.relispartition = false and has_schema_privilege(s.oid, 'USAGE') and has_column_privilege(quote_ident(s.nspname) ||'.'||quote_ident(c.relname), a.attname, 'SELECT,INSERT,UPDATE,REFERENCES') and a.attnum > 0; @@ -574,6 +576,7 @@ BEGIN AND a.attnum > 0 -- r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table AND c.relkind IN ('r', 'v', 'm', 'f', 'p') + AND c.relispartition = false AND has_schema_privilege(sch.schema_id, 'USAGE') AND has_column_privilege(a.attrelid, a.attname, 'SELECT,INSERT,UPDATE,REFERENCES') union all @@ -854,7 +857,7 @@ select , cast(imap.index_id as int) as index_id from pg_index X inner join index_id_map imap on imap.indexrelid = X.indexrelid -inner join pg_class I on I.oid = X.indexrelid and I.relkind = 'i' +inner join pg_class I on I.oid = X.indexrelid and (I.relkind = 'i' or I.relkind = 'I') and I.relispartition = false inner join pg_namespace nsp on nsp.oid = I.relnamespace left join sys.babelfish_namespace_ext ext on (nsp.nspname = ext.nspname and ext.dbid = sys.db_id()) -- check if index is a unique constraint @@ -890,7 +893,8 @@ select from pg_class t inner join pg_namespace nsp on nsp.oid = t.relnamespace left join sys.babelfish_namespace_ext ext on (nsp.nspname = ext.nspname and ext.dbid = sys.db_id()) -where t.relkind = 'r' +where (t.relkind = 'r' or t.relkind = 'p') +and t.relispartition = false -- filter to get all the objects that belong to sys or babelfish schemas and (nsp.nspname = 'sys' or ext.nspname is not null) and has_schema_privilege(t.relnamespace, 'USAGE') @@ -1339,7 +1343,8 @@ left join sys.table_types_internal tt on t.oid = tt.typrelid left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) left join sys.shipped_objects_not_in_sys nis on nis.name = t.relname and nis.schemaid = s.oid and nis.type = 'U' where t.relpersistence in ('p', 'u', 't') -and t.relkind = 'r' +and (t.relkind = 'r' or t.relkind = 'p') +and t.relispartition = false and s.nspname <> 'sys' and nis.name is null and ext.nspname is not null and tt.typrelid is null @@ -2161,7 +2166,7 @@ SELECT FROM pg_index i INNER JOIN index_id_map imap ON imap.indexrelid = i.indexrelid - INNER JOIN pg_class c ON i.indrelid = c.oid + INNER JOIN pg_class c ON i.indrelid = c.oid and c.relispartition = false INNER JOIN pg_namespace nsp ON nsp.oid = c.relnamespace LEFT JOIN sys.babelfish_namespace_ext ext ON (nsp.nspname = ext.nspname AND ext.dbid = sys.db_id()) LEFT JOIN unnest(i.indkey) WITH ORDINALITY AS a(attnum, index_column_id) ON true diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 77dafa5aa22..79fc47bbb7f 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -5298,6 +5298,1172 @@ RETURNS OID AS 'babelfishpg_tsql', 'get_immediate_base_type_of_UDT' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +create or replace view sys.tables as +with tt_internal as MATERIALIZED +( + select * from sys.table_types_internal +) +select + CAST(t.relname as sys._ci_sysname) as name + , CAST(t.oid as int) as object_id + , CAST(NULL as int) as principal_id + , CAST(t.relnamespace as int) as schema_id + , 0 as parent_object_id + , CAST('U' as sys.bpchar(2)) as type + , CAST('USER_TABLE' as sys.nvarchar(60)) as type_desc + , CAST((select string_agg( + case + when option like 'bbf_rel_create_date=%%' then substring(option, 21) + else NULL + end, ',') + from unnest(t.reloptions) as option) + as sys.datetime) as create_date + , CAST((select string_agg( + case + when option like 'bbf_rel_create_date=%%' then substring(option, 21) + else NULL + end, ',') + from unnest(t.reloptions) as option) + as sys.datetime) as modify_date + , CAST(0 as sys.bit) as is_ms_shipped + , CAST(0 as sys.bit) as is_published + , CAST(0 as sys.bit) as is_schema_published + , case reltoastrelid when 0 then 0 else 1 end as lob_data_space_id + , CAST(NULL as int) as filestream_data_space_id + , CAST(relnatts as int) as max_column_id_used + , CAST(0 as sys.bit) as lock_on_bulk_load + , CAST(1 as sys.bit) as uses_ansi_nulls + , CAST(0 as sys.bit) as is_replicated + , CAST(0 as sys.bit) as has_replication_filter + , CAST(0 as sys.bit) as is_merge_published + , CAST(0 as sys.bit) as is_sync_tran_subscribed + , CAST(0 as sys.bit) as has_unchecked_assembly_data + , 0 as text_in_row_limit + , CAST(0 as sys.bit) as large_value_types_out_of_row + , CAST(0 as sys.bit) as is_tracked_by_cdc + , CAST(0 as sys.tinyint) as lock_escalation + , CAST('TABLE' as sys.nvarchar(60)) as lock_escalation_desc + , CAST(0 as sys.bit) as is_filetable + , CAST(0 as sys.tinyint) as durability + , CAST('SCHEMA_AND_DATA' as sys.nvarchar(60)) as durability_desc + , CAST(0 as sys.bit) is_memory_optimized + , case relpersistence when 't' then CAST(2 as sys.tinyint) else CAST(0 as sys.tinyint) end as temporal_type + , case relpersistence when 't' then CAST('SYSTEM_VERSIONED_TEMPORAL_TABLE' as sys.nvarchar(60)) else CAST('NON_TEMPORAL_TABLE' as sys.nvarchar(60)) end as temporal_type_desc + , CAST(null as integer) as history_table_id + , CAST(0 as sys.bit) as is_remote_data_archive_enabled + , CAST(0 as sys.bit) as is_external +from pg_class t +inner join sys.schemas sch on sch.schema_id = t.relnamespace +left join tt_internal tt on t.oid = tt.typrelid +where tt.typrelid is null +and (t.relkind = 'r' or t.relkind = 'p') +and t.relispartition = false +and has_schema_privilege(t.relnamespace, 'USAGE') +and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER'); +GRANT SELECT ON sys.tables TO PUBLIC; + +create or replace view sys.all_columns as +select CAST(c.oid as int) as object_id + , CAST(a.attname as sys.sysname) as name + , CAST(a.attnum as int) as column_id + , CAST(t.oid as int) as system_type_id + , CAST(t.oid as int) as user_type_id + , CAST(sys.tsql_type_max_length_helper(coalesce(tsql_type_name, tsql_base_type_name), a.attlen, a.atttypmod) as smallint) as max_length + , CAST(case + when a.atttypmod != -1 then + sys.tsql_type_precision_helper(coalesce(tsql_type_name, tsql_base_type_name), a.atttypmod) + else + sys.tsql_type_precision_helper(coalesce(tsql_type_name, tsql_base_type_name), t.typtypmod) + end as sys.tinyint) as precision + , CAST(case + when a.atttypmod != -1 THEN + sys.tsql_type_scale_helper(coalesce(tsql_type_name, tsql_base_type_name), a.atttypmod, false) + else + sys.tsql_type_scale_helper(coalesce(tsql_type_name, tsql_base_type_name), t.typtypmod, false) + end as sys.tinyint) as scale + , CAST(coll.collname as sys.sysname) as collation_name + , case when a.attnotnull then CAST(0 as sys.bit) else CAST(1 as sys.bit) end as is_nullable + , CAST(0 as sys.bit) as is_ansi_padded + , CAST(0 as sys.bit) as is_rowguidcol + , CAST(case when a.attidentity <> ''::"char" then 1 else 0 end AS sys.bit) as is_identity + , CAST(case when a.attgenerated <> ''::"char" then 1 else 0 end AS sys.bit) as is_computed + , CAST(0 as sys.bit) as is_filestream + , CAST(0 as sys.bit) as is_replicated + , CAST(0 as sys.bit) as is_non_sql_subscribed + , CAST(0 as sys.bit) as is_merge_published + , CAST(0 as sys.bit) as is_dts_replicated + , CAST(0 as sys.bit) as is_xml_document + , CAST(0 as int) as xml_collection_id + , CAST(coalesce(d.oid, 0) as int) as default_object_id + , CAST(coalesce((select oid from pg_constraint where conrelid = t.oid and contype = 'c' and a.attnum = any(conkey) limit 1), 0) as int) as rule_object_id + , CAST(0 as sys.bit) as is_sparse + , CAST(0 as sys.bit) as is_column_set + , CAST(0 as sys.tinyint) as generated_always_type + , CAST('NOT_APPLICABLE' as sys.nvarchar(60)) as generated_always_type_desc +from pg_attribute a +inner join pg_class c on c.oid = a.attrelid +inner join pg_type t on t.oid = a.atttypid +inner join pg_namespace s on s.oid = c.relnamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join pg_attrdef d on c.oid = d.adrelid and a.attnum = d.adnum +left join pg_collation coll on coll.oid = a.attcollation +, sys.translate_pg_type_to_tsql(a.atttypid) AS tsql_type_name +, sys.translate_pg_type_to_tsql(t.typbasetype) AS tsql_base_type_name +where not a.attisdropped +and (s.nspname = 'sys' or ext.nspname is not null) +-- r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table +and c.relkind in ('r', 'v', 'm', 'f', 'p') +and c.relispartition = false +and has_schema_privilege(s.oid, 'USAGE') +and has_column_privilege(quote_ident(s.nspname) ||'.'||quote_ident(c.relname), a.attname, 'SELECT,INSERT,UPDATE,REFERENCES') +and a.attnum > 0; +GRANT SELECT ON sys.all_columns TO PUBLIC; + + +-- internal function in order to workaround BABEL-1597 +CREATE OR REPLACE FUNCTION sys.columns_internal() +RETURNS TABLE ( + out_object_id int, + out_name sys.sysname, + out_column_id int, + out_system_type_id int, + out_user_type_id int, + out_max_length smallint, + out_precision sys.tinyint, + out_scale sys.tinyint, + out_collation_name sys.sysname, + out_collation_id int, + out_offset smallint, + out_is_nullable sys.bit, + out_is_ansi_padded sys.bit, + out_is_rowguidcol sys.bit, + out_is_identity sys.bit, + out_is_computed sys.bit, + out_is_filestream sys.bit, + out_is_replicated sys.bit, + out_is_non_sql_subscribed sys.bit, + out_is_merge_published sys.bit, + out_is_dts_replicated sys.bit, + out_is_xml_document sys.bit, + out_xml_collection_id int, + out_default_object_id int, + out_rule_object_id int, + out_is_sparse sys.bit, + out_is_column_set sys.bit, + out_generated_always_type sys.tinyint, + out_generated_always_type_desc sys.nvarchar(60), + out_encryption_type int, + out_encryption_type_desc sys.nvarchar(64), + out_encryption_algorithm_name sys.sysname, + out_column_encryption_key_id int, + out_column_encryption_key_database_name sys.sysname, + out_is_hidden sys.bit, + out_is_masked sys.bit, + out_graph_type int, + out_graph_type_desc sys.nvarchar(60) +) +AS +$$ +BEGIN + RETURN QUERY + SELECT CAST(c.oid AS int), + CAST(a.attname AS sys.sysname), + CAST(a.attnum AS int), + CASE + WHEN tsql_type_name IS NOT NULL OR t.typbasetype = 0 THEN + -- either tsql or PG base type + CAST(a.atttypid AS int) + ELSE + CAST(t.typbasetype AS int) + END, + CAST(a.atttypid AS int), + CASE + WHEN a.atttypmod != -1 THEN + sys.tsql_type_max_length_helper(coalesce(tsql_type_name, tsql_base_type_name), a.attlen, a.atttypmod) + ELSE + sys.tsql_type_max_length_helper(coalesce(tsql_type_name, tsql_base_type_name), a.attlen, t.typtypmod) + END, + CASE + WHEN a.atttypmod != -1 THEN + sys.tsql_type_precision_helper(coalesce(tsql_type_name, tsql_base_type_name), a.atttypmod) + ELSE + sys.tsql_type_precision_helper(coalesce(tsql_type_name, tsql_base_type_name), t.typtypmod) + END, + CASE + WHEN a.atttypmod != -1 THEN + sys.tsql_type_scale_helper(coalesce(tsql_type_name, tsql_base_type_name), a.atttypmod, false) + ELSE + sys.tsql_type_scale_helper(coalesce(tsql_type_name, tsql_base_type_name), t.typtypmod, false) + END, + CAST(coll.collname AS sys.sysname), + CAST(a.attcollation AS int), + CAST(a.attnum AS smallint), + CAST(case when a.attnotnull then 0 else 1 end AS sys.bit), + CAST(case when t.typname in ('bpchar', 'nchar', 'binary') then 1 else 0 end AS sys.bit), + CAST(0 AS sys.bit), + CAST(case when a.attidentity <> ''::"char" then 1 else 0 end AS sys.bit), + CAST(case when a.attgenerated <> ''::"char" then 1 else 0 end AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS int), + CAST(coalesce(d.oid, 0) AS int), + CAST(coalesce((select oid from pg_constraint where conrelid = t.oid + and contype = 'c' and a.attnum = any(conkey) limit 1), 0) AS int), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.tinyint), + CAST('NOT_APPLICABLE' AS sys.nvarchar(60)), + CAST(null AS int), + CAST(null AS sys.nvarchar(64)), + CAST(null AS sys.sysname), + CAST(null AS int), + CAST(null AS sys.sysname), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(null AS int), + CAST(null AS sys.nvarchar(60)) + FROM pg_attribute a + INNER JOIN pg_class c ON c.oid = a.attrelid + INNER JOIN pg_type t ON t.oid = a.atttypid + INNER JOIN sys.schemas sch on c.relnamespace = sch.schema_id + INNER JOIN sys.pg_namespace_ext ext on sch.schema_id = ext.oid + LEFT JOIN pg_attrdef d ON c.oid = d.adrelid AND a.attnum = d.adnum + LEFT JOIN pg_collation coll ON coll.oid = a.attcollation + , sys.translate_pg_type_to_tsql(a.atttypid) AS tsql_type_name + , sys.translate_pg_type_to_tsql(t.typbasetype) AS tsql_base_type_name + WHERE NOT a.attisdropped + AND a.attnum > 0 + -- r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table + AND c.relkind IN ('r', 'v', 'm', 'f', 'p') + AND c.relispartition = false + AND has_schema_privilege(sch.schema_id, 'USAGE') + AND has_column_privilege(a.attrelid, a.attname, 'SELECT,INSERT,UPDATE,REFERENCES') + union all + -- system tables information + SELECT CAST(c.oid AS int), + CAST(a.attname AS sys.sysname), + CAST(a.attnum AS int), + CASE + WHEN tsql_type_name IS NOT NULL OR t.typbasetype = 0 THEN + -- either tsql or PG base type + CAST(a.atttypid AS int) + ELSE + CAST(t.typbasetype AS int) + END, + CAST(a.atttypid AS int), + CASE + WHEN a.atttypmod != -1 THEN + sys.tsql_type_max_length_helper(coalesce(tsql_type_name, tsql_base_type_name), a.attlen, a.atttypmod) + ELSE + sys.tsql_type_max_length_helper(coalesce(tsql_type_name, tsql_base_type_name), a.attlen, t.typtypmod) + END, + CASE + WHEN a.atttypmod != -1 THEN + sys.tsql_type_precision_helper(coalesce(tsql_type_name, tsql_base_type_name), a.atttypmod) + ELSE + sys.tsql_type_precision_helper(coalesce(tsql_type_name, tsql_base_type_name), t.typtypmod) + END, + CASE + WHEN a.atttypmod != -1 THEN + sys.tsql_type_scale_helper(coalesce(tsql_type_name, tsql_base_type_name), a.atttypmod, false) + ELSE + sys.tsql_type_scale_helper(coalesce(tsql_type_name, tsql_base_type_name), t.typtypmod, false) + END, + CAST(coll.collname AS sys.sysname), + CAST(a.attcollation AS int), + CAST(a.attnum AS smallint), + CAST(case when a.attnotnull then 0 else 1 end AS sys.bit), + CAST(case when t.typname in ('bpchar', 'nchar', 'binary') then 1 else 0 end AS sys.bit), + CAST(0 AS sys.bit), + CAST(case when a.attidentity <> ''::"char" then 1 else 0 end AS sys.bit), + CAST(case when a.attgenerated <> ''::"char" then 1 else 0 end AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS int), + CAST(coalesce(d.oid, 0) AS int), + CAST(coalesce((select oid from pg_constraint where conrelid = t.oid + and contype = 'c' and a.attnum = any(conkey) limit 1), 0) AS int), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(0 AS sys.tinyint), + CAST('NOT_APPLICABLE' AS sys.nvarchar(60)), + CAST(null AS int), + CAST(null AS sys.nvarchar(64)), + CAST(null AS sys.sysname), + CAST(null AS int), + CAST(null AS sys.sysname), + CAST(0 AS sys.bit), + CAST(0 AS sys.bit), + CAST(null AS int), + CAST(null AS sys.nvarchar(60)) + FROM pg_attribute a + INNER JOIN pg_class c ON c.oid = a.attrelid + INNER JOIN pg_type t ON t.oid = a.atttypid + INNER JOIN pg_namespace nsp ON (nsp.oid = c.relnamespace and nsp.nspname = 'sys') + LEFT JOIN pg_attrdef d ON c.oid = d.adrelid AND a.attnum = d.adnum + LEFT JOIN pg_collation coll ON coll.oid = a.attcollation + , sys.translate_pg_type_to_tsql(a.atttypid) AS tsql_type_name + , sys.translate_pg_type_to_tsql(t.typbasetype) AS tsql_base_type_name + WHERE NOT a.attisdropped + AND a.attnum > 0 + AND c.relkind = 'r' + AND has_schema_privilege(nsp.oid, 'USAGE') + AND has_column_privilege(a.attrelid, a.attname, 'SELECT,INSERT,UPDATE,REFERENCES'); +END; +$$ +language plpgsql STABLE; + +create or replace view sys.indexes as +-- Get all indexes from all system and user tables +with index_id_map as MATERIALIZED( + select + indexrelid, + case + when indisclustered then 1 + else 1+row_number() over(partition by indrelid order by indexrelid) + end as index_id + from pg_index +) +select + cast(X.indrelid as int) as object_id + , cast(I.relname as sys.sysname) as name + , cast(case when X.indisclustered then 1 else 2 end as sys.tinyint) as type + , cast(case when X.indisclustered then 'CLUSTERED' else 'NONCLUSTERED' end as sys.nvarchar(60)) as type_desc + , cast(case when X.indisunique then 1 else 0 end as sys.bit) as is_unique + , cast(I.reltablespace as int) as data_space_id + , cast(0 as sys.bit) as ignore_dup_key + , cast(case when X.indisprimary then 1 else 0 end as sys.bit) as is_primary_key + , cast(case when const.oid is null then 0 else 1 end as sys.bit) as is_unique_constraint + , cast(0 as sys.tinyint) as fill_factor + , cast(case when X.indpred is null then 0 else 1 end as sys.bit) as is_padded + , cast(case when X.indisready then 0 else 1 end as sys.bit) as is_disabled + , cast(0 as sys.bit) as is_hypothetical + , cast(1 as sys.bit) as allow_row_locks + , cast(1 as sys.bit) as allow_page_locks + , cast(0 as sys.bit) as has_filter + , cast(null as sys.nvarchar) as filter_definition + , cast(0 as sys.bit) as auto_created + , cast(imap.index_id as int) as index_id +from pg_index X +inner join index_id_map imap on imap.indexrelid = X.indexrelid +inner join pg_class I on I.oid = X.indexrelid and (I.relkind = 'i' or I.relkind = 'I') and I.relispartition = false +inner join pg_namespace nsp on nsp.oid = I.relnamespace +left join sys.babelfish_namespace_ext ext on (nsp.nspname = ext.nspname and ext.dbid = sys.db_id()) +-- check if index is a unique constraint +left join pg_constraint const on const.conindid = I.oid and const.contype = 'u' +where has_schema_privilege(I.relnamespace, 'USAGE') +-- index is active +and X.indislive +-- filter to get all the objects that belong to sys or babelfish schemas +and (nsp.nspname = 'sys' or ext.nspname is not null) + +union all +-- Create HEAP entries for each system and user table +select + cast(t.oid as int) as object_id + , cast(null as sys.sysname) as name + , cast(0 as sys.tinyint) as type + , cast('HEAP' as sys.nvarchar(60)) as type_desc + , cast(0 as sys.bit) as is_unique + , cast(1 as int) as data_space_id + , cast(0 as sys.bit) as ignore_dup_key + , cast(0 as sys.bit) as is_primary_key + , cast(0 as sys.bit) as is_unique_constraint + , cast(0 as sys.tinyint) as fill_factor + , cast(0 as sys.bit) as is_padded + , cast(0 as sys.bit) as is_disabled + , cast(0 as sys.bit) as is_hypothetical + , cast(1 as sys.bit) as allow_row_locks + , cast(1 as sys.bit) as allow_page_locks + , cast(0 as sys.bit) as has_filter + , cast(null as sys.nvarchar) as filter_definition + , cast(0 as sys.bit) as auto_created + , cast(0 as int) as index_id +from pg_class t +inner join pg_namespace nsp on nsp.oid = t.relnamespace +left join sys.babelfish_namespace_ext ext on (nsp.nspname = ext.nspname and ext.dbid = sys.db_id()) +where (t.relkind = 'r' or t.relkind = 'p') +and t.relispartition = false +-- filter to get all the objects that belong to sys or babelfish schemas +and (nsp.nspname = 'sys' or ext.nspname is not null) +and has_schema_privilege(t.relnamespace, 'USAGE') +and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER') +order by object_id, type_desc; +GRANT SELECT ON sys.indexes TO PUBLIC; + +create or replace view sys.all_objects as +select + name collate sys.database_default + , cast (object_id as integer) + , cast ( principal_id as integer) + , cast (schema_id as integer) + , cast (parent_object_id as integer) + , type collate sys.database_default + , cast (type_desc as sys.nvarchar(60)) + , cast (create_date as sys.datetime) + , cast (modify_date as sys.datetime) + , is_ms_shipped + , cast (is_published as sys.bit) + , cast (is_schema_published as sys.bit) +from +( +-- Currently for pg_class, pg_proc UNIONs, we separated user defined objects and system objects because the +-- optimiser will be able to make a better estimation of number of rows(in case the query contains a filter on +-- is_ms_shipped column) and in turn chooses a better query plan. + +-- details of system tables +select + t.relname::sys.sysname as name + , t.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , 0 as parent_object_id + , 'U'::char(2) as type + , 'USER_TABLE' as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , 1::sys.bit as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_class t inner join pg_namespace s on s.oid = t.relnamespace +left join sys.table_types_internal tt on t.oid = tt.typrelid +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = t.relname and nis.schemaid = s.oid and nis.type = 'U' +where t.relpersistence in ('p', 'u', 't') +and t.relkind = 'r' +and (s.nspname = 'sys' or (nis.name is not null and ext.nspname is not null)) +and tt.typrelid is null +and has_schema_privilege(s.oid, 'USAGE') +and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER') + +union all +-- details of user defined tables +select + t.relname::sys.sysname as name + , t.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , 0 as parent_object_id + , 'U'::char(2) as type + , 'USER_TABLE' as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , 0::sys.bit as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_class t inner join pg_namespace s on s.oid = t.relnamespace +left join sys.table_types_internal tt on t.oid = tt.typrelid +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = t.relname and nis.schemaid = s.oid and nis.type = 'U' +where t.relpersistence in ('p', 'u', 't') +and (t.relkind = 'r' or t.relkind = 'p') +and t.relispartition = false +and s.nspname <> 'sys' and nis.name is null +and ext.nspname is not null +and tt.typrelid is null +and has_schema_privilege(s.oid, 'USAGE') +and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER') + +union all +-- details of system views +select + t.relname::sys.sysname as name + , t.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , 0 as parent_object_id + , 'V'::char(2) as type + , 'VIEW'::varchar(60) as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , 1::sys.bit as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_class t inner join pg_namespace s on s.oid = t.relnamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = t.relname and nis.schemaid = s.oid and nis.type = 'V' +where t.relkind = 'v' +and (s.nspname = 'sys' or (nis.name is not null and ext.nspname is not null)) +and has_schema_privilege(s.oid, 'USAGE') +and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER') +union all +-- Details of user defined views +select + t.relname::sys.sysname as name + , t.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , 0 as parent_object_id + , 'V'::char(2) as type + , 'VIEW'::varchar(60) as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , 0::sys.bit as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_class t inner join pg_namespace s on s.oid = t.relnamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = t.relname and nis.schemaid = s.oid and nis.type = 'V' +where t.relkind = 'v' +and s.nspname <> 'sys' and nis.name is null +and ext.nspname is not null +and has_schema_privilege(s.oid, 'USAGE') +and has_table_privilege(t.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER') +union all +-- details of user defined and system foreign key constraints +select + c.conname::sys.sysname as name + , c.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , c.conrelid as parent_object_id + , 'F'::char(2) as type + , 'FOREIGN_KEY_CONSTRAINT' + , null::timestamp as create_date + , null::timestamp as modify_date + , CAST (case when (s.nspname = 'sys' or nis.name is not null) then 1 + else 0 end as sys.bit ) as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_constraint c +inner join pg_namespace s on s.oid = c.connamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = c.conname and nis.schemaid = s.oid and nis.type = 'F' +where has_schema_privilege(s.oid, 'USAGE') +and c.contype = 'f' +and (s.nspname = 'sys' or ext.nspname is not null) +union all +-- details of user defined and system primary key constraints +select + c.conname::sys.sysname as name + , c.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , c.conrelid as parent_object_id + , 'PK'::char(2) as type + , 'PRIMARY_KEY_CONSTRAINT' as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , CAST (case when (s.nspname = 'sys' or nis.name is not null) then 1 + else 0 end as sys.bit ) as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_constraint c +inner join pg_namespace s on s.oid = c.connamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = c.conname and nis.schemaid = s.oid and nis.type = 'PK' +where has_schema_privilege(s.oid, 'USAGE') +and c.contype = 'p' +and (s.nspname = 'sys' or ext.nspname is not null) +union all +-- details of system defined procedures +select + p.proname::sys.sysname as name + , p.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , cast (case when tr.tgrelid is not null + then tr.tgrelid + else 0 end as int) + as parent_object_id + , case p.prokind + when 'p' then 'P'::char(2) + when 'a' then 'AF'::char(2) + else + case + when t.typname = 'trigger' + then 'TR'::char(2) + when p.proretset then + case + when t.typtype = 'c' + then 'TF'::char(2) + else 'IF'::char(2) + end + else 'FN'::char(2) + end + end as type + , case p.prokind + when 'p' then 'SQL_STORED_PROCEDURE'::varchar(60) + when 'a' then 'AGGREGATE_FUNCTION'::varchar(60) + else + case + when t.typname = 'trigger' + then 'SQL_TRIGGER'::varchar(60) + when p.proretset then + case + when t.typtype = 'c' + then 'SQL_TABLE_VALUED_FUNCTION'::varchar(60) + else 'SQL_INLINE_TABLE_VALUED_FUNCTION'::varchar(60) + end + else 'SQL_SCALAR_FUNCTION'::varchar(60) + end + end as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , 1::sys.bit as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_proc p +inner join pg_namespace s on s.oid = p.pronamespace +inner join pg_catalog.pg_type t on t.oid = p.prorettype +left join pg_trigger tr on tr.tgfoid = p.oid +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = p.proname and nis.schemaid = s.oid +and nis.type = (case p.prokind + when 'p' then 'P'::char(2) + when 'a' then 'AF'::char(2) + else + case + when t.typname = 'trigger' + then 'TR'::char(2) + when p.proretset then + case + when t.typtype = 'c' + then 'TF'::char(2) + else 'IF'::char(2) + end + else 'FN'::char(2) + end + end) +where (s.nspname = 'sys' or (nis.name is not null and ext.nspname is not null)) +and has_schema_privilege(s.oid, 'USAGE') +and has_function_privilege(p.oid, 'EXECUTE') +and p.proname != 'pltsql_call_handler' + +union all +-- details of user defined procedures +select + p.proname::sys.sysname as name + , p.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , cast (case when tr.tgrelid is not null + then tr.tgrelid + else 0 end as int) + as parent_object_id + , case p.prokind + when 'p' then 'P'::char(2) + when 'a' then 'AF'::char(2) + else + case + when t.typname = 'trigger' + then 'TR'::char(2) + when p.proretset then + case + when t.typtype = 'c' + then 'TF'::char(2) + else 'IF'::char(2) + end + else 'FN'::char(2) + end + end as type + , case p.prokind + when 'p' then 'SQL_STORED_PROCEDURE'::varchar(60) + when 'a' then 'AGGREGATE_FUNCTION'::varchar(60) + else + case + when t.typname = 'trigger' + then 'SQL_TRIGGER'::varchar(60) + when p.proretset then + case + when t.typtype = 'c' + then 'SQL_TABLE_VALUED_FUNCTION'::varchar(60) + else 'SQL_INLINE_TABLE_VALUED_FUNCTION'::varchar(60) + end + else 'SQL_SCALAR_FUNCTION'::varchar(60) + end + end as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , 0::sys.bit as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_proc p +inner join pg_namespace s on s.oid = p.pronamespace +inner join pg_catalog.pg_type t on t.oid = p.prorettype +left join pg_trigger tr on tr.tgfoid = p.oid +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = p.proname and nis.schemaid = s.oid +and nis.type = (case p.prokind + when 'p' then 'P'::char(2) + when 'a' then 'AF'::char(2) + else + case + when t.typname = 'trigger' + then 'TR'::char(2) + when p.proretset then + case + when t.typtype = 'c' + then 'TF'::char(2) + else 'IF'::char(2) + end + else 'FN'::char(2) + end + end) +where s.nspname <> 'sys' and nis.name is null +and ext.nspname is not null +and has_schema_privilege(s.oid, 'USAGE') +and has_function_privilege(p.oid, 'EXECUTE') + +union all +-- details of all default constraints +select + ('DF_' || o.relname || '_' || d.oid)::sys.sysname as name + , d.oid as object_id + , null::int as principal_id + , o.relnamespace as schema_id + , d.adrelid as parent_object_id + , 'D'::char(2) as type + , 'DEFAULT_CONSTRAINT'::sys.nvarchar(60) AS type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , CAST (case when (s.nspname = 'sys' or nis.name is not null) then 1 + else 0 end as sys.bit ) as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_catalog.pg_attrdef d +inner join pg_attribute a on a.attrelid = d.adrelid and d.adnum = a.attnum +inner join pg_class o on d.adrelid = o.oid +inner join pg_namespace s on s.oid = o.relnamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = ('DF_' || o.relname || '_' || d.oid) and nis.schemaid = s.oid and nis.type = 'D' +where a.atthasdef = 't' and a.attgenerated = '' +and (s.nspname = 'sys' or ext.nspname is not null) +and has_schema_privilege(s.oid, 'USAGE') +and has_column_privilege(a.attrelid, a.attname, 'SELECT,INSERT,UPDATE,REFERENCES') +union all +-- details of all check constraints +select + c.conname::sys.sysname + , c.oid::integer as object_id + , NULL::integer as principal_id + , s.oid as schema_id + , c.conrelid::integer as parent_object_id + , 'C'::char(2) as type + , 'CHECK_CONSTRAINT'::sys.nvarchar(60) as type_desc + , null::sys.datetime as create_date + , null::sys.datetime as modify_date + , CAST (case when (s.nspname = 'sys' or nis.name is not null) then 1 + else 0 end as sys.bit ) as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_catalog.pg_constraint as c +inner join pg_namespace s on s.oid = c.connamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = c.conname and nis.schemaid = s.oid and nis.type = 'C' +where has_schema_privilege(s.oid, 'USAGE') +and c.contype = 'c' and c.conrelid != 0 +and (s.nspname = 'sys' or ext.nspname is not null) +union all +-- details of user defined and system defined sequence objects +select + p.relname::sys.sysname as name + , p.oid as object_id + , null::integer as principal_id + , s.oid as schema_id + , 0 as parent_object_id + , 'SO'::char(2) as type + , 'SEQUENCE_OBJECT'::varchar(60) as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , CAST (case when (s.nspname = 'sys' or nis.name is not null) then 1 + else 0 end as sys.bit ) as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from pg_class p +inner join pg_namespace s on s.oid = p.relnamespace +left join sys.babelfish_namespace_ext ext on (s.nspname = ext.nspname and ext.dbid = sys.db_id()) +left join sys.shipped_objects_not_in_sys nis on nis.name = p.relname and nis.schemaid = s.oid and nis.type = 'SO' +where p.relkind = 'S' +and (s.nspname = 'sys' or ext.nspname is not null) +and has_schema_privilege(s.oid, 'USAGE') +union all +-- details of user defined table types +select + ('TT_' || tt.name || '_' || tt.type_table_object_id)::sys.sysname as name + , tt.type_table_object_id as object_id + , tt.principal_id as principal_id + , tt.schema_id as schema_id + , 0 as parent_object_id + , 'TT'::char(2) as type + , 'TABLE_TYPE'::varchar(60) as type_desc + , null::timestamp as create_date + , null::timestamp as modify_date + , CAST (case when (tt.schema_id::regnamespace::text = 'sys' or nis.name is not null) then 1 + else 0 end as sys.bit ) as is_ms_shipped + , 0 as is_published + , 0 as is_schema_published +from sys.table_types tt +left join sys.shipped_objects_not_in_sys nis on nis.name = ('TT_' || tt.name || '_' || tt.type_table_object_id)::name and nis.schemaid = tt.schema_id and nis.type = 'TT' +) ot; +GRANT SELECT ON sys.all_objects TO PUBLIC; + +CREATE OR REPLACE VIEW sys.index_columns +AS +WITH index_id_map AS MATERIALIZED ( + SELECT + indexrelid, + CASE + WHEN indisclustered THEN 1 + ELSE 1+row_number() OVER(PARTITION BY indrelid ORDER BY indexrelid) + END AS index_id + FROM pg_index +) +SELECT + CAST(i.indrelid AS INT) AS object_id, + -- should match index_id of sys.indexes + CAST(imap.index_id AS INT) AS index_id, + CAST(a.index_column_id AS INT) AS index_column_id, + CAST(a.attnum AS INT) AS column_id, + CAST(CASE + WHEN a.index_column_id <= i.indnkeyatts THEN a.index_column_id + ELSE 0 + END AS SYS.TINYINT) AS key_ordinal, + CAST(0 AS SYS.TINYINT) AS partition_ordinal, + CAST(CASE + WHEN i.indoption[a.index_column_id-1] & 1 = 1 THEN 1 + ELSE 0 + END AS SYS.BIT) AS is_descending_key, + CAST(CASE + WHEN a.index_column_id > i.indnkeyatts THEN 1 + ELSE 0 + END AS SYS.BIT) AS is_included_column +FROM + pg_index i + INNER JOIN index_id_map imap ON imap.indexrelid = i.indexrelid + INNER JOIN pg_class c ON i.indrelid = c.oid and c.relispartition = false + INNER JOIN pg_namespace nsp ON nsp.oid = c.relnamespace + LEFT JOIN sys.babelfish_namespace_ext ext ON (nsp.nspname = ext.nspname AND ext.dbid = sys.db_id()) + LEFT JOIN unnest(i.indkey) WITH ORDINALITY AS a(attnum, index_column_id) ON true +WHERE + has_schema_privilege(c.relnamespace, 'USAGE') AND + has_table_privilege(c.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER') AND + (nsp.nspname = 'sys' OR ext.nspname is not null) AND + i.indislive; +GRANT SELECT ON sys.index_columns TO PUBLIC; + +/* + * COLUMNS view internal + */ + +CREATE OR REPLACE VIEW information_schema_tsql.columns_internal AS + SELECT c.oid AS "TABLE_OID", + CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", + CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", + CAST(CASE + WHEN c.reloptions[1] LIKE 'bbf_original_rel_name=%' THEN substring(c.reloptions[1], 23) + ELSE c.relname + END AS sys.nvarchar(128)) AS "TABLE_NAME", + + CAST(CASE + WHEN a.attoptions[1] LIKE 'bbf_original_name=%' THEN substring(a.attoptions[1], 19) + ELSE a.attname + END AS sys.nvarchar(128)) AS "COLUMN_NAME", + + CAST(a.attnum AS int) AS "ORDINAL_POSITION", + CAST(CASE WHEN a.attgenerated = '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS sys.nvarchar(4000)) AS "COLUMN_DEFAULT", + CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END + AS varchar(3)) + AS "IS_NULLABLE", + + CAST( + CASE WHEN tsql_type_name = 'sysname' THEN sys.translate_pg_type_to_tsql(t.typbasetype) + WHEN tsql_type_name.tsql_type_name IS NULL THEN format_type(t.oid, NULL::integer) + ELSE tsql_type_name END + AS sys.nvarchar(128)) + AS "DATA_TYPE", + + CAST( + information_schema_tsql._pgtsql_char_max_length(tsql_type_name, true_typmod) + AS int) + AS "CHARACTER_MAXIMUM_LENGTH", + + CAST( + information_schema_tsql._pgtsql_char_octet_length(tsql_type_name, true_typmod) + AS int) + AS "CHARACTER_OCTET_LENGTH", + + CAST( + /* Handle Tinyint separately */ + information_schema_tsql._pgtsql_numeric_precision(tsql_type_name, true_typid, true_typmod) + AS sys.tinyint) + AS "NUMERIC_PRECISION", + + CAST( + information_schema_tsql._pgtsql_numeric_precision_radix(tsql_type_name, true_typid, true_typmod) + AS smallint) + AS "NUMERIC_PRECISION_RADIX", + + CAST( + information_schema_tsql._pgtsql_numeric_scale(tsql_type_name, true_typid, true_typmod) + AS int) + AS "NUMERIC_SCALE", + + CAST( + information_schema_tsql._pgtsql_datetime_precision(tsql_type_name, true_typmod) + AS smallint) + AS "DATETIME_PRECISION", + + CAST(null AS sys.nvarchar(128)) AS "CHARACTER_SET_CATALOG", + CAST(null AS sys.nvarchar(128)) AS "CHARACTER_SET_SCHEMA", + /* + * TODO: We need to first create mapping of collation name to char-set name; + * Until then return null. + */ + CAST(null AS sys.nvarchar(128)) AS "CHARACTER_SET_NAME", + + CAST(NULL as sys.nvarchar(128)) AS "COLLATION_CATALOG", + CAST(NULL as sys.nvarchar(128)) AS "COLLATION_SCHEMA", + + /* Returns Babelfish specific collation name. */ + CAST(co.collname AS sys.nvarchar(128)) AS "COLLATION_NAME", + + CAST(CASE WHEN t.typtype = 'd' AND nt.nspname <> 'pg_catalog' AND nt.nspname <> 'sys' + THEN nc.dbname ELSE null END + AS sys.nvarchar(128)) AS "DOMAIN_CATALOG", + CAST(CASE WHEN t.typtype = 'd' AND nt.nspname <> 'pg_catalog' AND nt.nspname <> 'sys' + THEN ext.orig_name ELSE null END + AS sys.nvarchar(128)) AS "DOMAIN_SCHEMA", + CAST(CASE WHEN t.typtype = 'd' AND nt.nspname <> 'pg_catalog' AND nt.nspname <> 'sys' + THEN t.typname ELSE null END + AS sys.nvarchar(128)) AS "DOMAIN_NAME" + + FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum) + JOIN (pg_class c JOIN sys.pg_namespace_ext nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid + JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid + LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid)) + ON (t.typtype = 'd' AND t.typbasetype = bt.oid) + LEFT JOIN pg_collation co on co.oid = a.attcollation + LEFT OUTER JOIN sys.babelfish_namespace_ext ext on nc.nspname = ext.nspname, + information_schema_tsql._pgtsql_truetypid(nt, a, t) AS true_typid, + information_schema_tsql._pgtsql_truetypmod(nt, a, t) AS true_typmod, + sys.translate_pg_type_to_tsql(true_typid) AS tsql_type_name + + WHERE (NOT pg_is_other_temp_schema(nc.oid)) + AND a.attnum > 0 AND NOT a.attisdropped + AND c.relkind IN ('r', 'v', 'p') + AND c.relispartition = false + AND (pg_has_role(c.relowner, 'USAGE') + OR has_column_privilege(c.oid, a.attnum, + 'SELECT, INSERT, UPDATE, REFERENCES')) + AND ext.dbid =sys.db_id(); + +/* + * TABLES view + */ + +CREATE OR REPLACE VIEW information_schema_tsql.tables AS + SELECT CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", + CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", + CAST( + CASE WHEN c.reloptions[1] LIKE 'bbf_original_rel_name%' THEN substring(c.reloptions[1], 23) + ELSE c.relname END + AS sys._ci_sysname) AS "TABLE_NAME", + + CAST( + CASE WHEN c.relkind IN ('r', 'p') THEN 'BASE TABLE' + WHEN c.relkind = 'v' THEN 'VIEW' + ELSE null END + AS sys.varchar(10)) COLLATE sys.database_default AS "TABLE_TYPE" + + FROM sys.pg_namespace_ext nc JOIN pg_class c ON (nc.oid = c.relnamespace) + LEFT OUTER JOIN sys.babelfish_namespace_ext ext on nc.nspname = ext.nspname + LEFT JOIN sys.table_types_internal tt on c.oid = tt.typrelid + + WHERE c.relkind IN ('r', 'v', 'p') + AND c.relispartition = false + AND (NOT pg_is_other_temp_schema(nc.oid)) + AND tt.typrelid IS NULL + AND (pg_has_role(c.relowner, 'USAGE') + OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') ) + AND ext.dbid = sys.db_id() + AND (NOT c.relname = 'sysdatabases'); + +GRANT SELECT ON information_schema_tsql.tables TO PUBLIC; + +/* + * TABLE_CONSTRAINTS view + */ + +CREATE OR REPLACE VIEW information_schema_tsql.table_constraints AS + SELECT CAST(nc.dbname AS sys.nvarchar(128)) AS "CONSTRAINT_CATALOG", + CAST(extc.orig_name AS sys.nvarchar(128)) AS "CONSTRAINT_SCHEMA", + CAST(c.conname AS sys.sysname) AS "CONSTRAINT_NAME", + CAST(nr.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", + CAST(extr.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", + CAST(r.relname AS sys.sysname) AS "TABLE_NAME", + CAST( + CASE c.contype WHEN 'c' THEN 'CHECK' + WHEN 'f' THEN 'FOREIGN KEY' + WHEN 'p' THEN 'PRIMARY KEY' + WHEN 'u' THEN 'UNIQUE' END + AS sys.varchar(11)) COLLATE sys.database_default AS "CONSTRAINT_TYPE", + CAST('NO' AS sys.varchar(2)) AS "IS_DEFERRABLE", + CAST('NO' AS sys.varchar(2)) AS "INITIALLY_DEFERRED" + + FROM sys.pg_namespace_ext nc LEFT OUTER JOIN sys.babelfish_namespace_ext extc ON nc.nspname = extc.nspname, + sys.pg_namespace_ext nr LEFT OUTER JOIN sys.babelfish_namespace_ext extr ON nr.nspname = extr.nspname, + pg_constraint c, + pg_class r + + WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace + AND c.conrelid = r.oid + AND c.contype NOT IN ('t', 'x') + AND r.relkind IN ('r', 'p') + AND relispartition = false + AND (NOT pg_is_other_temp_schema(nr.oid)) + AND (pg_has_role(r.relowner, 'USAGE') + OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(r.oid, 'SELECT, INSERT, UPDATE, REFERENCES') ) + AND extc.dbid = sys.db_id(); + +GRANT SELECT ON information_schema_tsql.table_constraints TO PUBLIC; + +/* + * CHECK_CONSTRAINTS view + */ + +CREATE OR REPLACE VIEW information_schema_tsql.check_constraints AS + SELECT CAST(nc.dbname AS sys.nvarchar(128)) AS "CONSTRAINT_CATALOG", + CAST(extc.orig_name AS sys.nvarchar(128)) AS "CONSTRAINT_SCHEMA", + CAST(c.conname AS sys.sysname) AS "CONSTRAINT_NAME", + CAST(sys.tsql_get_constraintdef(c.oid) AS sys.nvarchar(4000)) AS "CHECK_CLAUSE" + + FROM sys.pg_namespace_ext nc LEFT OUTER JOIN sys.babelfish_namespace_ext extc ON nc.nspname = extc.nspname, + pg_constraint c, + pg_class r + + WHERE nc.oid = c.connamespace AND nc.oid = r.relnamespace + AND c.conrelid = r.oid + AND c.contype = 'c' + AND r.relkind IN ('r', 'p') + AND r.relispartition = false + AND (NOT pg_is_other_temp_schema(nc.oid)) + AND (pg_has_role(r.relowner, 'USAGE') + OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(r.oid, 'SELECT, INSERT, UPDATE, REFERENCES')) + AND extc.dbid = sys.db_id(); + +GRANT SELECT ON information_schema_tsql.check_constraints TO PUBLIC; + +/* + * CONSTARINT_COLUMN_USAGE + */ + +CREATE OR REPLACE VIEW information_schema_tsql.CONSTRAINT_COLUMN_USAGE AS +SELECT CAST(tblcat AS sys.nvarchar(128)) AS "TABLE_CATALOG", + CAST(tblschema AS sys.nvarchar(128)) AS "TABLE_SCHEMA", + CAST(tblname AS sys.nvarchar(128)) AS "TABLE_NAME" , + CAST(colname AS sys.nvarchar(128)) AS "COLUMN_NAME", + CAST(cstrcat AS sys.nvarchar(128)) AS "CONSTRAINT_CATALOG", + CAST(cstrschema AS sys.nvarchar(128)) AS "CONSTRAINT_SCHEMA", + CAST(cstrname AS sys.nvarchar(128)) AS "CONSTRAINT_NAME" + +FROM ( + /* check constraints */ + SELECT DISTINCT extr.orig_name, r.relname, r.relowner, a.attname, extc.orig_name, c.conname, nr.dbname, nc.dbname + FROM sys.pg_namespace_ext nc LEFT OUTER JOIN sys.babelfish_namespace_ext extc ON nc.nspname = extc.nspname, + sys.pg_namespace_ext nr LEFT OUTER JOIN sys.babelfish_namespace_ext extr ON nr.nspname = extr.nspname, + pg_attribute a, + pg_constraint c, + pg_class r, pg_depend d + + WHERE nr.oid = r.relnamespace + AND r.oid = a.attrelid + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND d.refobjid = r.oid + AND d.refobjsubid = a.attnum + AND d.classid = 'pg_catalog.pg_constraint'::regclass + AND d.objid = c.oid + AND c.connamespace = nc.oid + AND c.contype = 'c' + AND r.relkind IN ('r', 'p') + AND r.relispartition = false + AND NOT a.attisdropped + AND (pg_has_role(r.relowner, 'USAGE') + OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(r.oid, 'SELECT, INSERT, UPDATE, REFERENCES')) + + UNION ALL + + /* unique/primary key/foreign key constraints */ + SELECT extr.orig_name, r.relname, r.relowner, a.attname, extc.orig_name, c.conname, nr.dbname, nc.dbname + FROM sys.pg_namespace_ext nc LEFT OUTER JOIN sys.babelfish_namespace_ext extc ON nc.nspname = extc.nspname, + sys.pg_namespace_ext nr LEFT OUTER JOIN sys.babelfish_namespace_ext extr ON nr.nspname = extr.nspname, + pg_attribute a, + pg_constraint c, + pg_class r + WHERE nr.oid = r.relnamespace + AND r.oid = a.attrelid + AND nc.oid = c.connamespace + AND r.oid = c.conrelid + AND a.attnum = ANY (c.conkey) + AND NOT a.attisdropped + AND c.contype IN ('p', 'u', 'f') + AND r.relkind IN ('r', 'p') + AND r.relispartition = false + AND (pg_has_role(r.relowner, 'USAGE') + OR has_table_privilege(r.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(r.oid, 'SELECT, INSERT, UPDATE, REFERENCES')) + + ) AS x (tblschema, tblname, tblowner, colname, cstrschema, cstrname, tblcat, cstrcat); + +GRANT SELECT ON information_schema_tsql.CONSTRAINT_COLUMN_USAGE TO PUBLIC; + +CREATE OR REPLACE VIEW information_schema_tsql.key_column_usage AS + SELECT + CAST(nc.dbname AS sys.nvarchar(128)) AS "CONSTRAINT_CATALOG", + CAST(ext.orig_name AS sys.nvarchar(128)) AS "CONSTRAINT_SCHEMA", + CAST(c.conname AS sys.nvarchar(128)) AS "CONSTRAINT_NAME", + CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", + CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", + CAST(r.relname AS sys.nvarchar(128)) AS "TABLE_NAME", + CAST(a.attname AS sys.nvarchar(128)) AS "COLUMN_NAME", + CAST(ord AS int) AS "ORDINAL_POSITION" + FROM + pg_constraint c + JOIN pg_class r ON r.oid = c.conrelid AND c.contype in ('p','u','f') AND r.relkind in ('r','p') AND r.relispartition = false + JOIN sys.pg_namespace_ext nc ON nc.oid = c.connamespace AND r.relnamespace = nc.oid + JOIN sys.babelfish_namespace_ext ext ON ext.nspname = nc.nspname AND ext.dbid = sys.db_id() + CROSS JOIN unnest(c.conkey) WITH ORDINALITY AS ak(j,ord) + LEFT JOIN pg_attribute a ON a.attrelid = r.oid AND a.attnum = ak.j + WHERE + pg_has_role(r.relowner, 'USAGE'::text) + OR has_column_privilege(r.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'::text) + AND NOT pg_is_other_temp_schema(nc.oid) + ; +GRANT SELECT ON information_schema_tsql.key_column_usage TO PUBLIC; + +CREATE OR REPLACE VIEW sys.sp_tables_view AS +SELECT +t2.dbname AS TABLE_QUALIFIER, +CAST(t3.name AS name) AS TABLE_OWNER, +t1.relname AS TABLE_NAME, + +CASE +WHEN t1.relkind = 'v' + THEN 'VIEW' +ELSE 'TABLE' +END AS TABLE_TYPE, + +CAST(NULL AS varchar(254)) AS remarks +FROM pg_catalog.pg_class AS t1, sys.pg_namespace_ext AS t2, sys.schemas AS t3 +WHERE t1.relnamespace = t3.schema_id AND t1.relnamespace = t2.oid AND t1.relkind IN ('r','p','v','m') +AND t1.relispartition = false +AND has_schema_privilege(t1.relnamespace, 'USAGE') +AND has_table_privilege(t1.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER'); +GRANT SELECT ON sys.sp_tables_view TO PUBLIC; + -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar); diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-decl.y b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-decl.y index 3192df37de8..0ba8f48be4b 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-decl.y +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-decl.y @@ -14,8 +14,9 @@ %type tsql_stmt -%type tsql_AlterFunctionStmt +%type tsql_AlterFunctionStmt tsql_CreatePartitionStmt %type tsql_CreateFunctionStmt tsql_VariableSetStmt tsql_CreateTrigStmt tsql_TransactionStmt tsql_UpdateStmt tsql_DeleteStmt tsql_IndexStmt +%type tsql_PartitionSpec %type tsql_DropIndexStmt tsql_InsertStmt %type tsql_DropIndexStmtSchema %type tsql_CreateLoginStmt tsql_AlterLoginStmt tsql_DropLoginStmt @@ -47,6 +48,7 @@ %type tsql_ExecStmt tsql_output_ExecStmt %type tsql_actual_args +%type tsql_opt_partition_scheme_or_filegroup %type tsql_actual_arg %type tsql_opt_output tsql_opt_readonly @@ -71,7 +73,7 @@ %type TSQL_Typename TSQL_SimpleTypename TSQL_GenericType -%type datepart_arg datediff_arg dateadd_arg +%type datepart_arg datediff_arg dateadd_arg tsql_untruncated_IDENT %type tsql_type_function_name %type tsql_createproc_args tsql_createfunc_args %type tsql_triggername tsql_trigger_list diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y index 6a6fc64bf4e..8544c5f3e89 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y @@ -2505,6 +2505,7 @@ tsql_stmt : | CreatePLangStmt | CreateSchemaStmt | CreateSeqStmt + | tsql_CreatePartitionStmt | CreateStmt | CreateSubscriptionStmt | CreateStatsStmt @@ -2574,6 +2575,75 @@ tsql_stmt : { $$ = NULL; } ; +/* + * The Opt clauses are included in the tsql_CreatePartitionStmt rule + * to resolve a shift-reduce conflict with the CreateStmt rule. + * Although semantically it is not required for TSQL partitioned table creation, + * its inclusion ensures that the parser can unambiguously distinguish + * between regular table creation and TSQL partitioned table creation statements. + */ +tsql_CreatePartitionStmt: + CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' + OptInherit OptPartitionSpec table_access_method_clause OptWith + tsql_PartitionSpec + { + CreateStmt *n = makeNode(CreateStmt); + n->relation = $4; + n->tableElts = $6; + n->inhRelations = NIL; + n->partspec = $12; + n->ofTypename = NULL; + n->constraints = NIL; + n->accessMethod = NULL; + n->options = NIL; + n->oncommit = ONCOMMIT_NOOP; + n->tablespacename = NULL; + n->if_not_exists = false; + $$ = (Node *) n; + } + ; + +tsql_PartitionSpec: + ON tsql_untruncated_IDENT '(' part_params ')' + { + PartitionSpec *n = makeNode(PartitionSpec); + n->tsql_partition_scheme = $2; + n->strategy = PARTITION_STRATEGY_RANGE; + n->partParams = $4; + n->location = @1; + $$ = n; + } + ; + + + /* + * TSQL untruncated identfiers: + * This rule handles the parsing of untruncated identifiers in TSQL. + * Unlike PostgreSQL, which truncates identifier when they exceeds the + * maximum allowed length (NAMEDATALEN), while in TSQL, for certain cases we + * want to parse identifiers with lengths exceeding such limit. + * + * This rule extract the entire identifier string from the input buffer, + * regardless of its length. + */ +tsql_untruncated_IDENT: + IDENT + { + /* + * Retrieve the "extra" information attached to the scanner + * to access the input string (the string being parsed). + */ + base_yy_extra_type *yyextra = pg_yyget_extra(yyscanner); + + /* + * Extract the original, untruncated identifier from the input buffer. + * Here, @1 represents the start location of the identifier token. + */ + $$ = extract_identifier(yyextra->core_yy_extra.scanbuf + @1); + + } + ; + tsql_opt_INTO: INTO | /* empty */ @@ -3245,7 +3315,7 @@ tsql_IndexStmt: INDEX opt_concurrently opt_single_name ON relation_expr access_method_clause '(' index_params ')' opt_include where_clause opt_reloptions - tsql_opt_on_filegroup + tsql_opt_partition_scheme_or_filegroup { IndexStmt *n = makeNode(IndexStmt); n->unique = $2; @@ -3258,7 +3328,7 @@ tsql_IndexStmt: n->nulls_not_distinct = $2; n->whereClause = $15; n->options = $16; - n->excludeOpNames = NIL; + n->excludeOpNames = $17; n->idxcomment = NULL; n->indexOid = InvalidOid; n->oldNumber = InvalidOid; @@ -3313,6 +3383,25 @@ tsql_opt_on_filegroup: | /*EMPTY*/ {} ; +/* + * TSQL support for partition scheme and filegroup + */ + +tsql_opt_partition_scheme_or_filegroup: + ON tsql_untruncated_IDENT '(' ColId ')' + { + $$ = list_make2(makeString($2), makeString($4)); + } + | tsql_on_filegroup + { + $$ = NIL; + } + | /*EMPTY*/ + { + $$ = NIL; + } + ; + /* * TSQL support for DATA_COMPRESSION in and : * DATA_COMPRESSION = {NONE | ROW | PAGE} [ON PARTITIONS ( [,...n])] diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 1fde3d7a687..41231f1f760 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -3195,8 +3195,6 @@ rename_object_update_bbf_schema_permission_catalog(RenameStmt *stmt, int rename_ pfree(physical_schema_name); if (logical_schema_name != NULL) pfree(logical_schema_name); - if (object_name != NULL) - pfree(object_name); systable_endscan(scan); table_close(bbf_schema_rel, RowExclusiveLock); @@ -5336,11 +5334,11 @@ partition_scheme_exists(int16 dbid, const char *partition_scheme_name) } /* - * get_partition_function - * Returns the partition function name for the given partition scheme name. + * get_partition_function_name + * Returns the partition function name for the given partition scheme name. */ char* -get_partition_function(int16 dbid, const char *partition_scheme_name) +get_partition_function_name(int16 dbid, const char *partition_scheme_name) { Relation rel; HeapTuple tuple; @@ -5375,6 +5373,266 @@ get_partition_function(int16 dbid, const char *partition_scheme_name) table_close(rel, AccessShareLock); return partition_function_name; } +/* + * add_entry_to_bbf_partition_depend + * Inserts a new entry into the sys.babelfish_partition_depend catalog + * to track the dependecy between partition scheme and partitioned tables + * created using that. + */ +void +add_entry_to_bbf_partition_depend(int16 dbid, char* partition_scheme_name, char *schema_name, char *table_name) +{ + Relation rel; + TupleDesc dsc; + HeapTuple tuple; + Datum new_record[BBF_PARTITION_DEPEND_NUM_COLS]; + bool new_record_nulls[BBF_PARTITION_DEPEND_NUM_COLS]; + + MemSet(new_record, 0, sizeof(new_record)); + MemSet(new_record_nulls, false, sizeof(new_record_nulls)); + + rel = table_open(get_bbf_partition_depend_oid(), RowExclusiveLock); + dsc = RelationGetDescr(rel); + + /* Build a tuple to insert. */ + new_record[Anum_bbf_partition_depend_dbid - 1] = Int16GetDatum(dbid); + new_record[Anum_bbf_partition_depend_scheme_name - 1] = CStringGetTextDatum(partition_scheme_name); + new_record[Anum_bbf_partition_depend_table_schema_name - 1] = CStringGetTextDatum(schema_name); + new_record[Anum_bbf_partition_depend_table_name - 1] = CStringGetTextDatum(table_name); + + tuple = heap_form_tuple(dsc, new_record, new_record_nulls); + + /* Insert new record in the table. */ + CatalogTupleInsert(rel, tuple); + + heap_freetuple(tuple); + table_close(rel, RowExclusiveLock); +} + +/* + * remove_entry_from_bbf_partition_depend + * Removes an entry from the sys.babelfish_partition_depend catalog. + */ +void +remove_entry_from_bbf_partition_depend(int16 dbid, char *schema_name, char *table_name) +{ + Relation rel; + HeapTuple tuple; + ScanKeyData scanKey[3]; + SysScanDesc scan; + + rel = table_open(get_bbf_partition_depend_oid(), RowExclusiveLock); + + ScanKeyInit(&scanKey[0], + Anum_bbf_partition_depend_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_partition_depend_table_schema_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(schema_name)); + + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_partition_depend_table_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(table_name)); + + scan = systable_beginscan(rel, get_bbf_partition_depend_idx_oid(), + false, NULL, 3, scanKey); + + tuple = systable_getnext(scan); + if (HeapTupleIsValid(tuple)) + { + CatalogTupleDelete(rel, &tuple->t_self); + } + + systable_endscan(scan); + table_close(rel, RowExclusiveLock); +} + +/* + * rename_table_update_bbf_partition_depend_catalog + * Updates table_name in sys.babelfish_partition_depend catalog for + * RENAME TABLE command to have consistency with the new names. + */ +void +rename_table_update_bbf_partition_depend_catalog(RenameStmt *stmt) +{ + Relation rel; + HeapTuple tuple, new_tuple; + TupleDesc dsc; + ScanKeyData scanKey[3]; + SysScanDesc scan; + Datum new_record[BBF_PARTITION_DEPEND_NUM_COLS]; + bool new_record_nulls[BBF_PARTITION_DEPEND_NUM_COLS]; + bool new_record_replace[BBF_PARTITION_DEPEND_NUM_COLS]; + char *logical_schema_name; + char *table_name = stmt->relation->relname; + int16 dbid; + + /* Find the logical schema name from physical schema name. */ + logical_schema_name = (char *) get_logical_schema_name(stmt->relation->schemaname, true); + + if (!logical_schema_name) /* not a TSQL schema */ + return; + + /* Find the dbid from physical schema name. */ + dbid = get_dbid_from_physical_schema_name(stmt->relation->schemaname, false); + + /* Open the catalog table. */ + rel = table_open(get_bbf_partition_depend_oid(), RowExclusiveLock); + + /* Search for the row which needs to be updated. */ + ScanKeyInit(&scanKey[0], + Anum_bbf_partition_depend_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_partition_depend_table_schema_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(logical_schema_name)); + + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_partition_depend_table_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(table_name)); + + scan = systable_beginscan(rel, get_bbf_partition_depend_idx_oid(), + false, NULL, 3, scanKey); + + tuple = systable_getnext(scan); + + /* Update the table name of the found row. */ + if (HeapTupleIsValid(tuple)) + { + /* Get the descriptor of the table. */ + dsc = RelationGetDescr(rel); + + /* Build a tuple to insert. */ + MemSet(new_record, 0, sizeof(new_record)); + MemSet(new_record_nulls, false, sizeof(new_record_nulls)); + MemSet(new_record_replace, false, sizeof(new_record_replace)); + + new_record[Anum_bbf_partition_depend_table_name - 1] = CStringGetTextDatum(stmt->newname); + new_record_replace[Anum_bbf_partition_depend_table_name - 1] = true; + new_tuple = heap_modify_tuple(tuple, dsc, new_record, new_record_nulls, new_record_replace); + + /* Perform the actual catalog update. */ + CatalogTupleUpdate(rel, &new_tuple->t_self, new_tuple); + + /* Free the allocated tuple. */ + heap_freetuple(new_tuple); + } + + systable_endscan(scan); + /* Close the catalog table. */ + table_close(rel, RowExclusiveLock); + + /* Free the allocated memory. */ + pfree(logical_schema_name); +} + +/* + * is_bbf_partitioned_table + * Returns true if provided table is babelfish partitioned table, false otherwise. + * + * This function checks if provided table is babelfish partitioned table + * by looking up in sys.babelfish_partition_depend catalog. + */ +bool +is_bbf_partitioned_table(int16 dbid, char *schema_name, char *table_name) +{ + Relation rel; + HeapTuple tuple; + ScanKeyData scanKey[3]; + SysScanDesc scan; + bool sucess = false; + + rel = table_open(get_bbf_partition_depend_oid(), AccessShareLock); + + ScanKeyInit(&scanKey[0], + Anum_bbf_partition_depend_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_partition_depend_table_schema_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(schema_name)); + + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_partition_depend_table_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(table_name)); + + scan = systable_beginscan(rel, get_bbf_partition_depend_idx_oid(), + false, NULL, 3, scanKey); + + tuple = systable_getnext(scan); + if (HeapTupleIsValid(tuple)) + sucess = true; + + systable_endscan(scan); + table_close(rel, AccessShareLock); + + return sucess; +} + +/* + * get_partition_scheme_for_partitioned_table + * Returns the name of partition scheme used to create the partitioned table. + */ +char* +get_partition_scheme_for_partitioned_table(int16 dbid, char *schema_name, char *table_name) +{ + Relation rel; + HeapTuple tuple; + ScanKeyData scanKey[3]; + SysScanDesc scan; + char *partition_scheme_name = NULL; + + rel = table_open(get_bbf_partition_depend_oid(), AccessShareLock); + + ScanKeyInit(&scanKey[0], + Anum_bbf_partition_depend_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_partition_depend_table_schema_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(schema_name)); + + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_partition_depend_table_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(table_name)); + + scan = systable_beginscan(rel, get_bbf_partition_depend_idx_oid(), + false, NULL, 3, scanKey); + + tuple = systable_getnext(scan); + if (HeapTupleIsValid(tuple)) + { + bool isnull; + partition_scheme_name = TextDatumGetCString(heap_getattr(tuple, Anum_bbf_partition_depend_scheme_name, RelationGetDescr(rel), &isnull)); + } + + systable_endscan(scan); + table_close(rel, AccessShareLock); + + return partition_scheme_name; +} /* * clean_up_bbf_partition_metadata diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 9bb937b6402..4a30c9b4442 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -450,7 +450,7 @@ extern int32 get_available_partition_scheme_id(void); extern void add_entry_to_bbf_partition_scheme(int16 dbid, const char *partition_scheme_name, const char *partition_function_name, bool next_used); extern void remove_entry_from_bbf_partition_scheme(int16 dbid, const char *partition_scheme_name); extern bool partition_scheme_exists(int16 dbid, const char *partition_scheme_name); -extern char *get_partition_function(int16 dbid, const char *partition_scheme_name); +extern char *get_partition_function_name(int16 dbid, const char *partition_scheme_name); /***************************************** * PARTITION_DEPEND @@ -469,6 +469,11 @@ extern Oid bbf_partition_depend_idx_oid; extern Oid get_bbf_partition_depend_oid(void); extern Oid get_bbf_partition_depend_idx_oid(void); +extern void add_entry_to_bbf_partition_depend(int16 dbid, char* partition_scheme_name, char *schema_name, char *table_name); +extern void remove_entry_from_bbf_partition_depend(int16 dbid, char *schema_name, char *table_name); +extern bool is_bbf_partitioned_table(int16 dbid, char *schema_name, char *table_name); +extern char *get_partition_scheme_for_partitioned_table(int16 dbid, char *schema_name, char *table_name); +extern void rename_table_update_bbf_partition_depend_catalog(RenameStmt *stmt); typedef struct FormData_bbf_extended_properties diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 4843a586627..af82ac40f80 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -11,6 +11,7 @@ #include "utils/pg_locale.h" #include "access/xact.h" #include "access/relation.h" +#include "access/reloptions.h" #include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_aggregate.h" @@ -185,9 +186,6 @@ static bool bbf_check_rowcount_hook(int es_processed); static char *get_local_schema_for_bbf_functions(Oid proc_nsp_oid); extern bool called_from_tsql_insert_exec(); extern bool called_for_tsql_itvf_func(); -extern Datum pltsql_exec_tsql_cast_value(Datum value, bool *isnull, - Oid valtype, int32 valtypmod, - Oid reqtype, int32 reqtypmod); static void is_function_pg_stat_valid(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu, char prokind, bool finalize); @@ -204,6 +202,7 @@ static void logicalrep_modify_slot(Relation rel, EState *estate, TupleTableSlot static object_access_hook_type prev_object_access_hook = NULL; static void bbf_object_access_hook(ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg); static void revoke_func_permission_from_public(Oid objectId); +static bool is_partitioned_table_reloptions_allowed(Datum reloptions); /***************************************** * Planner Hook @@ -266,6 +265,7 @@ static called_for_tsql_itvf_func_hook_type prev_called_for_tsql_itvf_func_hook = static exec_tsql_cast_value_hook_type pre_exec_tsql_cast_value_hook = NULL; static pltsql_pgstat_end_function_usage_hook_type prev_pltsql_pgstat_end_function_usage_hook = NULL; static pltsql_unique_constraint_nulls_ordering_hook_type prev_pltsql_unique_constraint_nulls_ordering_hook = NULL; +static pltsql_is_partitioned_table_reloptions_allowed_hook_type prev_pltsql_is_partitioned_table_reloptions_allowed_hook = NULL; /***************************************** * Install / Uninstall @@ -460,6 +460,9 @@ InstallExtendedHooks(void) prev_pltsql_unique_constraint_nulls_ordering_hook = pltsql_unique_constraint_nulls_ordering_hook; pltsql_unique_constraint_nulls_ordering_hook = unique_constraint_nulls_ordering; + + prev_pltsql_is_partitioned_table_reloptions_allowed_hook = pltsql_is_partitioned_table_reloptions_allowed_hook; + pltsql_is_partitioned_table_reloptions_allowed_hook = is_partitioned_table_reloptions_allowed; } void @@ -524,6 +527,7 @@ UninstallExtendedHooks(void) called_for_tsql_itvf_func_hook = prev_called_for_tsql_itvf_func_hook; pltsql_pgstat_end_function_usage_hook = prev_pltsql_pgstat_end_function_usage_hook; pltsql_unique_constraint_nulls_ordering_hook = prev_pltsql_unique_constraint_nulls_ordering_hook; + pltsql_is_partitioned_table_reloptions_allowed_hook = prev_pltsql_is_partitioned_table_reloptions_allowed_hook; bbf_InitializeParallelDSM_hook = NULL; bbf_ParallelWorkerMain_hook = NULL; @@ -5223,3 +5227,32 @@ unique_constraint_nulls_ordering(ConstrType constraint_type, SortByDir ordering) return SORTBY_NULLS_DEFAULT; } + +/* + * is_partitioned_table_reloptions_allowed + * This function checks if the given reloptions are allowed or not for partitioned tables. + * Returns true if allowed, false otherwise. + * + * Only bbf_rel_create_date and bbf_original_rel_name reloptions + * are allowed in TSQL dialect and while restoring babelfish database. + */ +static bool +is_partitioned_table_reloptions_allowed(Datum reloptions) +{ + if (sql_dialect == SQL_DIALECT_TSQL || babelfish_dump_restore) + { + List *options = untransformRelOptions(reloptions); + ListCell *cell; + + foreach(cell, options) + { + DefElem *defel = (DefElem *) lfirst(cell); + + if (pg_strcasecmp(defel->defname, ATTOPTION_BBF_TABLE_CREATE_DATE) != 0 && + pg_strcasecmp(defel->defname, ATTOPTION_BBF_ORIGINAL_TABLE_NAME) != 0) + return false; + + } + } + return true; +} diff --git a/contrib/babelfishpg_tsql/src/hooks.h b/contrib/babelfishpg_tsql/src/hooks.h index 19fe9a2c1fa..3f606f83d42 100644 --- a/contrib/babelfishpg_tsql/src/hooks.h +++ b/contrib/babelfishpg_tsql/src/hooks.h @@ -17,7 +17,6 @@ void pre_wrapper_pgstat_init_function_usage(const char *); pg_locale_t *collation_cache_entry_hook_function(Oid ,pg_locale_t *); extern bool output_update_transformation; extern bool output_into_insert_transformation; -extern char *extract_identifier(const char *start); extern char *gen_func_arg_list(Oid objectId); extern char * gen_func_arg_list_from_params(List* parameters); extern void pltsql_store_func_default_positions(ObjectAddress address, @@ -32,6 +31,9 @@ extern void alter_bbf_schema_permissions_catalog(ObjectWithArgs *owa, extern Oid get_tsql_trigger_oid(List *object, const char *tsql_trigger_name, bool object_from_input); +extern Datum pltsql_exec_tsql_cast_value(Datum value, bool *isnull, + Oid valtype, int32 valtypmod, + Oid reqtype, int32 reqtypmod); extern void pltsql_bbfSelectIntoUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, QueryEnvironment *queryEnv, ParamListInfo params, QueryCompletion *qc); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index 25dab2f9c52..d7e9cf4904a 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -17,6 +17,7 @@ #include "storage/lmgr.h" #include "storage/procarray.h" #include "pltsql_bulkcopy.h" +#include "pltsql_partition.h" #include "table_variable_mvcc.h" #include "catalog.h" @@ -4146,6 +4147,8 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun Oid opfamily_oid; Oid cmpfunction_oid; int nargs; + HeapTuple tuple; + Form_pg_type typform; int16 dbid = get_cur_db_id(); tsql_compare_context cxt; LOCAL_FCINFO(fcinfo, 1); @@ -4182,17 +4185,38 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun errmsg("There is already an object named '%s' in the database.", partition_function_name))); } - /* get the tsql typename from the input type */ + /* + * Try to find the TSQL type name for the input type and if it fails + * and input type is DOMAIN type created in sys schema then + * find the TSQL type name using the base type of DOMAIN. + */ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); fcinfo->args[0].value = ObjectIdGetDatum(typ->typoid); fcinfo->args[0].isnull = false; tsql_type_datum = (*common_utility_plugin_ptr->translate_pg_type_to_tsql) (fcinfo); - if (tsql_type_datum) { tsql_typename = text_to_cstring(DatumGetTextPP(tsql_type_datum)); } - + else + { + tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typ->typoid)); + typform = (Form_pg_type) GETSTRUCT(tuple); + if (OidIsValid(typform->typbasetype) && typform->typnamespace == get_namespace_oid("sys", false)) + { + /* Input type is DOMAIN type created in sys schema. */ + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); + fcinfo->args[0].value = ObjectIdGetDatum(typform->typbasetype); + fcinfo->args[0].isnull = false; + tsql_type_datum = (*common_utility_plugin_ptr->translate_pg_type_to_tsql) (fcinfo); + if (tsql_type_datum) + { + tsql_typename = text_to_cstring(DatumGetTextPP(tsql_type_datum)); + } + } + ReleaseSysCache(tuple); + } + /* * Check if datatype is supported or not, if tsql_typename is NULL * then it implies that type is User Defined Type. @@ -4236,6 +4260,12 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun /* evaluate the value from the expr */ val = exec_eval_expr(estate, list_nth(arg, i), &isnull, &valtype, &valtypmod); + /* raise error for null value */ + if (isnull) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("NULL values are not allowed in partition function boundary values list."))); + /* * implicitly convert range values to specified parameter type * and raise error with ordinal position if conversion fails diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 0ae4d136dc1..3f915f3406a 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -87,6 +87,7 @@ #include "schemacmds.h" #include "session.h" #include "pltsql.h" +#include "pltsql_partition.h" #include "pl_explain.h" #include "table_variable_mvcc.h" @@ -2527,6 +2528,15 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } } } + + /* + * Babelfish partitioned tables have specific security requirements to maintain data integrity. + * Non-superusers should not be permitted to attach, detach, or modify partitions of these tables. + */ + if (!babelfish_dump_restore && atstmt->objtype == OBJECT_TABLE && !superuser()) + { + bbf_alter_handle_partitioned_table(atstmt); + } break; } case T_TruncateStmt: @@ -3500,6 +3510,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { DropStmt *drop_stmt = (DropStmt *) parsetree; + if (drop_stmt->removeType == OBJECT_TABLE) + bbf_drop_handle_partitioned_table(drop_stmt); + if (drop_stmt->removeType != OBJECT_SCHEMA) { if (sql_dialect == SQL_DIALECT_TSQL) @@ -3647,6 +3660,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + + if (stmt->renameType == OBJECT_TABLE) + { + rename_table_update_bbf_partitions_name(stmt); + rename_table_update_bbf_partition_depend_catalog(stmt); + } if (sql_dialect == SQL_DIALECT_TSQL) { rename_update_bbf_catalog(stmt); @@ -3730,6 +3749,15 @@ bbf_ProcessUtility(PlannedStmt *pstmt, standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + /* + * Create partitions of babelfish partitioned table + * using the partition scheme and partitioning column. + */ + if (create_stmt->partspec && create_stmt->partspec->tsql_partition_scheme) + { + bbf_create_partition_tables(create_stmt); + } + if (create_stmt->tsql_tabletype || isTableVariable) { List *name; @@ -3747,6 +3775,46 @@ bbf_ProcessUtility(PlannedStmt *pstmt, return; } + case T_IndexStmt: + { + if (sql_dialect == SQL_DIALECT_TSQL) + { + IndexStmt *stmt = (IndexStmt *) parsetree; + + /* + * Create partitioned index if partition scheme is specified. + * Allow only aligned-index. + */ + if (stmt->excludeOpNames != NIL) + { + List *partition_schemes = stmt->excludeOpNames; + stmt->excludeOpNames = NIL; + + /* + * Create the index first so that columns and table name + * checks get done before index alignment check. + */ + if (prev_ProcessUtility) + prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, + queryEnv, dest, qc); + else + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, + queryEnv, dest, qc); + + stmt->excludeOpNames = partition_schemes; + + /* Validate that index is aligned-index. */ + if (!bbf_validate_partitioned_index_alignment(stmt)) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Un-aligned Index is not supported in Babelfish."))); + } + return; + } + } + break; + } case T_CreateDomainStmt: { CreateDomainStmt *create_domain = (CreateDomainStmt *) parsetree; diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 72e76c6c97b..6cf1f772eb2 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -64,8 +64,6 @@ #define TRIGGER_MAX_NEST_LEVEL 32 /* Maximum allowed trigger nesting level*/ - /* Max number of partitions allowed for babelfish partitioned tables. */ -#define MAX_PARTITIONS_LIMIT 15000 /* * Compiler's namespace item types @@ -2108,6 +2106,9 @@ extern void pltsql_scanner_finish(void); */ extern int pltsql_yyparse(void); +/* functions in hooks.c */ +extern char *extract_identifier(const char *start); + /* functions in pltsql_utils.c */ extern char *gen_createfulltextindex_cmds(const char *table_name, const char *schema_name, const List *column_name, const char *index_name); extern char *gen_dropfulltextindex_cmds(const char *index_name, const char *schema_name); diff --git a/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c b/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c index 967807f215e..fb2d209e485 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c +++ b/contrib/babelfishpg_tsql/src/pltsql_bulkcopy.c @@ -587,12 +587,11 @@ ExecuteBulkCopy(BulkCopyState cstate, int rowCount, int colCount, Assert(list_length(cstate->range_table) == 1); /* - * The target must be a plain, foreign, or partitioned relation, or have + * The target must be a plain, or foreign relation, or have * an INSTEAD OF INSERT row trigger. */ if (cstate->rel->rd_rel->relkind != RELKIND_RELATION && cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE && - cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && !(cstate->rel->trigdesc && cstate->rel->trigdesc->trig_insert_instead_row)) { @@ -611,6 +610,10 @@ ExecuteBulkCopy(BulkCopyState cstate, int rowCount, int colCount, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot bulk copy to sequence \"%s\"", RelationGetRelationName(cstate->rel)))); + else if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Bulk Copy to partitioned-table is not yet supported in Babelfish."))); else ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), diff --git a/contrib/babelfishpg_tsql/src/pltsql_partition.c b/contrib/babelfishpg_tsql/src/pltsql_partition.c new file mode 100644 index 00000000000..c14baea72e3 --- /dev/null +++ b/contrib/babelfishpg_tsql/src/pltsql_partition.c @@ -0,0 +1,841 @@ +/*------------------------------------------------------------------------- + * + * pltsql_partition.c + * This file contains definitions of functions used + * for PL/tsql Partition. + * + * Portions Copyright (c) 2024, AWS + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * contrib/babelfishpg_tsql/src/pltsql_partition.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" +#include "access/genam.h" +#include "access/relation.h" +#include "access/table.h" +#include "catalog/partition.h" +#include "catalog/pg_inherits.h" +#include "catalog/pg_type.h" +#include "common/md5.h" +#include "miscadmin.h" +#include "nodes/nodes.h" +#include "nodes/pg_list.h" +#include "nodes/plannodes.h" +#include "parser/parse_coerce.h" +#include "parser/parse_type.h" +#include "utils/builtins.h" +#include "utils/elog.h" +#include "utils/fmgroids.h" +#include "utils/partcache.h" +#include "utils/lsyscache.h" +#include "utils/syscache.h" + +#include "catalog.h" +#include "hooks.h" +#include "pltsql.h" +#include "pltsql_partition.h" +#include "session.h" + +#define MD5_HASH_LEN 32 + +static char *construct_unique_hash(char *relation_name); +static void set_partition_range_bounds(PartitionBoundSpec *partbound, Datum *range_values, int idx, + int total_partitions, bool is_binary_datatype); +static void set_node_value_from_datum(A_Const *node, Datum val, bool is_binary_datatype); +static CreateStmt *create_partition_stmt(char *physical_schema_name, char *relname); + + +/* + * bbf_create_partition_tables + * This function creates partitions of babelfish partitioned table + * using the partition scheme and partitioning column. + */ +void +bbf_create_partition_tables(CreateStmt *stmt) +{ + Relation rel; + HeapTuple tuple; + SysScanDesc scan; + ScanKeyData scanKey[2]; + char *input_parameter_type; + char *partition_function_name; + Datum *range_values; + Datum *datum_values; + bool *nulls; + int nelems; + Oid sql_variant_type_oid; + Oid input_type_oid; + ListCell *elements; + Oid partition_column_typoid = InvalidOid; + Oid partition_column_basetypoid = InvalidOid; + char *partition_column_typname = NULL; + bool is_binary_datatype = false; + int16 dbid = get_cur_db_id(); + char *partition_scheme_name = stmt->partspec->tsql_partition_scheme; + char *relname = stmt->relation->relname; + char *partition_colname = linitial_node(PartitionElem, stmt->partspec->partParams)->name; + CreateStmt *partition_stmt; + PlannedStmt *wrapper; + char *unique_hash; + char *physical_schema_name; + char *logical_schema_name; + ArrayType *values; + bool isnull; + int i; + char *partition_name; + + /* Partitioning is not supported for tempopary tables. */ + if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Creation of tempopary partitioned tables is not supported in Babelfish."))); + + /* + * Get partition function name for the provided partition scheme, + * if provided partition scheme exists in current database. + */ + partition_function_name = get_partition_function_name(dbid, partition_scheme_name); + + /* Raise error if provided partition scheme doesn't exists in current database. */ + if (!partition_function_name) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Invalid partition scheme '%s' specifed.", partition_scheme_name))); + } + + /* Extract the datatype of partitioning column from CREATE statement. */ + foreach (elements, stmt->tableElts) + { + Node *element = lfirst(elements); + ColumnDef *coldef; + + if (nodeTag(element) != T_ColumnDef) + continue; + + coldef = castNode(ColumnDef, element); + + if (pg_strcasecmp(coldef->colname, partition_colname) == 0) + { + HeapTuple ctype = LookupTypeName(NULL, coldef->typeName, NULL, true); + Form_pg_type pg_type = (Form_pg_type) GETSTRUCT(ctype); + + partition_column_typoid = pg_type->oid; + partition_column_basetypoid = pg_type->typbasetype; + partition_column_typname = pstrdup(NameStr(pg_type->typname)); + ReleaseSysCache(ctype); + break; + } + } + + /* Get OID of sql_variant type. */ + sql_variant_type_oid = (*common_utility_plugin_ptr->get_tsql_datatype_oid) ("sql_variant"); + + /* + * Extract metadata of partition function like ranges and input parameter type by + * looking up in bbf_partition_function catalog using the partition function name and dbid. + */ + rel = table_open(get_bbf_partition_function_oid(), AccessShareLock); + + ScanKeyInit(&scanKey[0], + Anum_bbf_partition_function_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_partition_function_name, + BTEqualStrategyNumber, InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, CStringGetTextDatum(partition_function_name)); + + scan = systable_beginscan(rel, get_bbf_partition_function_pk_idx_oid(), + false, NULL, 2, scanKey); + + tuple = systable_getnext(scan); + + if (!HeapTupleIsValid(tuple)) /* Sanity check. */ + { + systable_endscan(scan); + table_close(rel, AccessShareLock); + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Partition function '%s' used for the specifed partition scheme '%s' does not exist.", partition_function_name, partition_scheme_name))); + } + + input_parameter_type = TextDatumGetCString(heap_getattr(tuple, Anum_bbf_partition_function_input_parameter_type, RelationGetDescr(rel), &isnull)); + values = DatumGetArrayTypeP(heap_getattr(tuple, Anum_bbf_partition_function_range_values, RelationGetDescr(rel), &isnull)); + deconstruct_array(values, sql_variant_type_oid, -1, false, 'i', &datum_values, &nulls, &nelems); + + systable_endscan(scan); + table_close(rel, AccessShareLock); + + /* + * If the partition columns type is UDT type, then we need + * to use the base type of that type while comparing with + * input parameter type of partition function. + */ + if (OidIsValid(partition_column_basetypoid)) + { + /* Get the TSQL typoid from partitioning column type name. */ + Oid tsql_typoid = (*common_utility_plugin_ptr->get_tsql_datatype_oid) (partition_column_typname); + + /* If the value of tsql_typname is NULL, it indicates that partitioning column is UDT type. */ + if (!OidIsValid(tsql_typoid)) + { + /* Substitute typoid with the base type to facilitate comparison. */ + partition_column_typoid = partition_column_basetypoid; + } + } + + input_type_oid = (*common_utility_plugin_ptr->get_tsql_datatype_oid) (input_parameter_type); + + /* + * Validate that type of partitioning columns is same + * to input parameter type of partition function. + */ + if (partition_column_typoid != input_type_oid) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Partition column '%s' has data type '%s' which is different from the partition function '%s' parameter data type '%s'.", + partition_colname, partition_column_typname, partition_function_name, input_parameter_type))); + } + + /* Check if the input parameter type is (var)binary datatype. */ + input_type_oid = getBaseType(input_type_oid); + if ((*common_utility_plugin_ptr->is_tsql_binary_datatype) (input_type_oid) || + (*common_utility_plugin_ptr->is_tsql_varbinary_datatype) (input_type_oid)) + is_binary_datatype = true; + + /* Convert each sql_variant values to CString. */ + range_values = palloc(nelems * sizeof(Datum)); + for (i = 0; i < nelems; i++) + { + range_values[i] = pltsql_exec_tsql_cast_value(datum_values[i], &isnull, + sql_variant_type_oid, -1, + CSTRINGOID, -1); + } + + /* + * Find default schema for current user when schema + * is not explicitly specified with create statement. + */ + if (!stmt->relation->schemaname) + { + char *db_name = get_cur_db_name(); + const char *user = get_user_for_database(db_name); + logical_schema_name = get_authid_user_ext_schema_name(db_name, user); + physical_schema_name = get_physical_schema_name(db_name, logical_schema_name); + pfree(db_name); + } + else + { + physical_schema_name = pstrdup(stmt->relation->schemaname); + logical_schema_name = (char *) get_logical_schema_name(physical_schema_name, false); + } + + partition_stmt = create_partition_stmt(physical_schema_name, relname); + + if (!partition_stmt) /* Sanity Check. */ + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Failed to construct partitions for relation \"%s\".", relname))); + } + + /* Make a wrapper PlannedStmt. */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = (Node *) partition_stmt; + wrapper->stmt_location = 0; + wrapper->stmt_len = 0; + + /* Construct hash based on partitioned table name. */ + unique_hash = construct_unique_hash(relname); + + for (i = 0; i < nelems + 1; i++) + { + /* + * Construct partition name with unique hash based + * on partitioned table name and partition number. + * And Set the name in CREATE PARTITION statment. + */ + partition_name = psprintf("%s_partition_%d", unique_hash, i); + partition_stmt->relation->relname = partition_name; + + /* Set the range boundaries in CREATE PARTITION statment. */ + set_partition_range_bounds(partition_stmt->partbound, range_values, i, nelems + 1, is_binary_datatype); + + /* Execute the CREATE PARTITION statment. */ + standard_ProcessUtility(wrapper, + "(CREATE PARTITION)", + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + + CommandCounterIncrement(); + pfree(partition_name); + } + + /* + * Add an entry in sys.babelfish_partition_depend to track the + * dependency between partition scheme and partitioned table. + */ + add_entry_to_bbf_partition_depend(dbid, partition_scheme_name, logical_schema_name, relname); + + /* Free the allocated memory. */ + pfree(partition_column_typname); + pfree(partition_function_name); + pfree(physical_schema_name); + pfree(logical_schema_name); + pfree(unique_hash); + pfree(datum_values); + pfree(range_values); +} + +/* + * create_partition_stmt + * Creates a CREATE PARTITION statement using the provided physical schema name and relation name. + * Here, we need to change the dialect to postgres to parse the CREATE PARTITION Postgres statement. + * After parsing, we reset the dialect back to original value. + */ +static CreateStmt* +create_partition_stmt(char *physical_schema_name, char *relname) +{ + CreateStmt *partition_stmt = NULL; + const char *old_dialect = GetConfigOption("babelfishpg_tsql.sql_dialect", true, true); + List *res; + StringInfoData query; + + /* + * We prepare the following query to CREATE PARTITION of partitioned table. + * This will be executed using standard_ProcessUtility(). + */ + initStringInfo(&query); + appendStringInfo(&query, "CREATE TABLE \"%s\".dummy PARTITION OF \"%s\".\"%s\"" + " FOR VALUES FROM ('dummy') TO ('dummy');", + physical_schema_name, physical_schema_name, relname); + PG_TRY(); + { + set_config_option("babelfishpg_tsql.sql_dialect", "postgres", GUC_CONTEXT_CONFIG, + PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + res = raw_parser(query.data, RAW_PARSE_DEFAULT); + partition_stmt = (CreateStmt *) parsetree_nth_stmt(res, 0); + } + PG_FINALLY(); + { + /* Reset dialect back to original value. */ + set_config_option("babelfishpg_tsql.sql_dialect", old_dialect, GUC_CONTEXT_CONFIG, + PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + pfree(query.data); + } + PG_END_TRY(); + return partition_stmt; +} + +/* + * construct_unique_hash + * Constructs a unique hash based on the relation name, + * this is used to construct unique names for partitions. + */ +static char* +construct_unique_hash(char *relation_name) +{ + char *md5; + bool success; + const char *errstr = NULL; + + md5 = (char *) palloc(MD5_HASH_LEN + 1); + + success = pg_md5_hash(relation_name, strlen(relation_name), md5, &errstr); + + if (unlikely(!success)) /* Out of memory. */ + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Constructing unique partition name failed for relation \"%s\": %s.", relation_name, errstr))); + } + + return md5; +} + +/* + * set_partition_range_bounds + * This function sets the lower and upper bounds for a range partition based on its index + * and the total number of partitions. It handles the following cases: + * 1. For the first partition, it sets the lower bound to DEFAULT to + * accommodate NULL values along with other values. + * 2. For the last partition, it sets the upper bound to MAXVALUE. + * 3. For other partitions, it sets the bounds to the corresponding values in the range_values array. + */ +static void +set_partition_range_bounds(PartitionBoundSpec *partbound, Datum *range_values, int idx, + int total_partitions, bool is_binary_datatype) +{ + + /* Set lower bound of partition. */ + if (idx == 0) /* first partition */ + { + partbound->is_default = true; + partbound->location = -1; + partbound->lowerdatums = NIL; + partbound->upperdatums = NIL; + return; + } + else + { + A_Const *node = makeNode(A_Const); + set_node_value_from_datum(node, range_values[idx-1], is_binary_datatype); + partbound->is_default = false; + partbound->lowerdatums = list_make1(node); + } + + /* Set upper bound of partition. */ + if (idx == total_partitions - 1) /* last partition */ + { + ColumnRef *node = makeNode(ColumnRef); + node->fields = list_make1(makeString("maxvalue")); + partbound->is_default = false; + partbound->upperdatums = list_make1(node); + } + else + { + A_Const *node = makeNode(A_Const); + set_node_value_from_datum(node, range_values[idx], is_binary_datatype); + partbound->is_default = false; + partbound->upperdatums = list_make1(node); + } +} + +/* + * set_node_value_from_datum + * Set the value of an A_Const node based on the datatype. + * If the data type is (var)binary, the value is set as a hexadecimal string. + * Otherwise, the value is set as a regular string. + */ +static void +set_node_value_from_datum(A_Const *node, Datum val, bool is_binary_datatype) +{ + if (is_binary_datatype) + { + node->val.sval.type = T_TSQL_HexString; + node->val.hsval.hsval = DatumGetCString(val); + } + else + { + node->val.sval.type = T_String; + node->val.sval.sval = DatumGetCString(val); + } +} + +/* + * bbf_drop_handle_partitioned_table + * When the table is being dropped is: + * 1. babelfish partitioned table, then it removes the entry from bbf_partition_depend catalog. + * 2. partition of babelfish partitioned table, then it throws an error. + * 3. other than above, then it does nothing. + */ +void +bbf_drop_handle_partitioned_table(DropStmt *stmt) +{ + Relation relation; + ListCell *cell; + int16 dbid; + char *physical_schemaname; + char *logical_schemaname; + char *relname; + Form_pg_class form; + + foreach (cell, stmt->objects) + { + relation = NULL; + get_object_address(stmt->removeType, lfirst(cell), &relation, AccessShareLock, true); + if (!relation) + continue; + + form = RelationGetForm(relation); + relname = RelationGetRelationName(relation); + + /* Find dbid and logical schema name of table. */ + physical_schemaname = get_namespace_name(form->relnamespace); + logical_schemaname = (char *) get_logical_schema_name(physical_schemaname, true); + dbid = get_dbid_from_physical_schema_name(physical_schemaname, true); + pfree(physical_schemaname); + + if (!logical_schemaname) /* not a TSQL schema */ + { + relation_close(relation, AccessShareLock); + continue; + } + + if (form->relispartition) /* relation is partition of table */ + { + /* Prevent non-superusers from droping partitions of Babelfish partitioned tables. */ + if (!superuser() && is_bbf_partitioned_table(dbid, logical_schemaname, get_rel_name(get_partition_parent(form->oid, false)))) + { + relation_close(relation, AccessShareLock); + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Cannot drop the babelfish partition table '%s'.", relname))); + } + } + else if (form->relkind == RELKIND_PARTITIONED_TABLE) /* relation is partitioned table */ + { + /* In case of babelfish partitioned table then remove the entry from bbf_partition_depend table. */ + if (is_bbf_partitioned_table(dbid, logical_schemaname, relname)) + remove_entry_from_bbf_partition_depend(dbid, logical_schemaname, relname); + } + relation_close(relation, AccessShareLock); + } +} + +/* + * bbf_validate_partitioned_index_alignment + * Validates whether the index being created on a partitioned table is aligned + * with the table's partition scheme. It checks if the column specified for + * the index is part of the partitioning columns and if the partition scheme + * used for the index matches the partition scheme used for the table. + */ +bool +bbf_validate_partitioned_index_alignment(IndexStmt *stmt) +{ + char *partition_scheme_name = strVal(linitial(stmt->excludeOpNames)); + char *colname = strVal(lsecond(stmt->excludeOpNames)); + char *relname = stmt->relation->relname; + char *physical_schema_name; + char *logical_schema_name; + char *partition_scheme_used_for_table; + int16 dbid = get_cur_db_id(); + char *db_name = get_cur_db_name(); + Oid relid; + HeapTuple tuple; + int attnum; + Relation rel; + PartitionKey key; + int partnatts; + int i; + + /* + * Find default schema for current user when schema + * is not explicitly specified for TDS client. + */ + if (!stmt->relation->schemaname) + { + const char *user = get_user_for_database(db_name); + logical_schema_name = get_authid_user_ext_schema_name(db_name, user); + physical_schema_name = get_physical_schema_name(db_name, logical_schema_name); + } + else + { + physical_schema_name = pstrdup(stmt->relation->schemaname); + logical_schema_name = (char *) get_logical_schema_name(physical_schema_name, false); + } + + relid = get_relname_relid(relname, get_namespace_oid(physical_schema_name, false)); + + pfree(physical_schema_name); + pfree(db_name); + + /* Search for the column specified with partition scheme in table's columns. */ + tuple = SearchSysCacheAttName(relid, colname); + + /* Raise an error if column specified with partition scheme doesn't exists in table. */ + if (!HeapTupleIsValid(tuple)) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column '%s' does not exist", colname))); + } + + attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; + ReleaseSysCache(tuple); + + /* Raise an error if provided partition scheme doesn't exists in the current database. */ + if (!partition_scheme_exists(dbid, partition_scheme_name)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("Invalid object name '%s'.", partition_scheme_name))); + } + + /* Find the partition scheme used to create partitioned table. */ + partition_scheme_used_for_table = get_partition_scheme_for_partitioned_table(dbid, logical_schema_name, relname); + pfree(logical_schema_name); + + /* partition_scheme_used_for_table will be null for non-partitioned table */ + if (!partition_scheme_used_for_table || + pg_strcasecmp(partition_scheme_name, partition_scheme_used_for_table) != 0) + { + if (partition_scheme_used_for_table) + pfree(partition_scheme_used_for_table); + return false; + } + + /* + * Column specified with partition scheme should be part of partitioning columns. + * Otherwise, the index is unaligned. + */ + rel = RelationIdGetRelation(relid); + key = RelationGetPartitionKey(rel); + partnatts = get_partition_natts(key); + + for (i = 0; i < partnatts; i++) + { + if (attnum == get_partition_col_attnum(key, i)) + break; + } + + RelationClose(rel); + + if (partition_scheme_used_for_table) + pfree(partition_scheme_used_for_table); + + if (i == partnatts) /* not part of partitioning columns */ + return false; + return true; +} + +/* + * rename_table_update_bbf_partitions_name + * For a rename operation on a babelfish partitioned table, it renames all partition + * of the table to the new name using hash based on the new name, so that + * name of partitions of any partitioned table doesn't conflict. + */ +void +rename_table_update_bbf_partitions_name(RenameStmt *stmt) +{ + char *physical_schema_name = stmt->relation->schemaname; + char *logical_schema_name; + char *table_name = stmt->relation->relname; + List *partition_names = NIL; + int16 dbid; + char *new_hash; + PlannedStmt *wrapper; + RenameStmt *rename_partition_stmt = NULL; + List *parsetree; + Relation relation; + SysScanDesc scan; + ScanKeyData key; + Oid parentrelid; + Oid inhrelid; + HeapTuple tuple; + const char *old_dialect; + StringInfoData query; + char *partition_name; + char *new_partition_name; + + logical_schema_name = (char *) get_logical_schema_name(physical_schema_name, true); + + if (!logical_schema_name) /* not a TSQL schema */ + return; + + dbid = get_dbid_from_physical_schema_name(physical_schema_name, false); + + if (!is_bbf_partitioned_table(dbid, logical_schema_name, table_name)) + { + pfree(logical_schema_name); + return; + } + + parentrelid = get_relname_relid(stmt->newname, get_namespace_oid(physical_schema_name, false)); + + relation = table_open(InheritsRelationId, AccessShareLock); + + ScanKeyInit(&key, + Anum_pg_inherits_inhparent, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(parentrelid)); + + scan = systable_beginscan(relation, InheritsParentIndexId, true, + NULL, 1, &key); + + while ((tuple = systable_getnext(scan)) != NULL) + { + inhrelid = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid; + partition_names = lappend(partition_names, get_rel_name(inhrelid)); + } + systable_endscan(scan); + table_close(relation, AccessShareLock); + + /* + * We prepare the following query to rename the partitions of partitioned table. + * This will be executed using standard_ProcessUtility(). + */ + initStringInfo(&query); + appendStringInfo(&query, "ALTER TABLE \"%s\".dummy RENAME TO dummy;", physical_schema_name); + + old_dialect = GetConfigOption("babelfishpg_tsql.sql_dialect", true, true); + + /* We need to change the dialect to postgres to parse the RENAME statement. */ + PG_TRY(); + { + set_config_option("babelfishpg_tsql.sql_dialect", "postgres", GUC_CONTEXT_CONFIG, + PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + + parsetree = raw_parser(query.data, RAW_PARSE_DEFAULT); + rename_partition_stmt = (RenameStmt *) parsetree_nth_stmt(parsetree, 0); + } + PG_FINALLY(); + { + /* Reset dialect back to original value. */ + set_config_option("babelfishpg_tsql.sql_dialect", old_dialect, GUC_CONTEXT_CONFIG, + PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + } + PG_END_TRY(); + + if (!rename_partition_stmt) /* Sanity Check. */ + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Failed to rename partitions of relation \"%s\".", table_name))); + } + + /* Need to make a wrapper PlannedStmt. */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = (Node *) rename_partition_stmt; + wrapper->stmt_location = 0; + wrapper->stmt_len = 0; + + /* Construct hash based on new name. */ + new_hash = construct_unique_hash(stmt->newname); + + for (int i = 0; i < list_length(partition_names); i++) + { + partition_name = list_nth(partition_names, i); + + /* + * Generate new partition name by replacing the hash portion + * of existing partition name with new hash value. + */ + new_partition_name = pstrdup(partition_name); + memcpy(new_partition_name, new_hash, MD5_HASH_LEN); + + /* Set the names in RENAME statment. */ + rename_partition_stmt->relation->relname = partition_name; + rename_partition_stmt->newname = new_partition_name; + + /* Execute the rename statment. */ + standard_ProcessUtility(wrapper, + "(RENAME PARTITION)", + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + + CommandCounterIncrement(); + + pfree(partition_name); + pfree(new_partition_name); + } + + /* Free the allocated memory. */ + if (partition_names) + list_free(partition_names); + pfree(logical_schema_name); + pfree(new_hash); + pfree(query.data); +} + +/* + * For Babelfish partitioned tables, non-superusers should not be permitted + * to attach or detach partitions from the partitioned table, and they + * should also be restricted from modifying the partitions from both + * TSQL as well as PG endpoint. + * + * NOTE: We are only blocking operation on Babelfish partitioned tables i.e. + * partitioned tables created from the TSQL endpoint. Existing users who have + * created partitioned tables from the PostgreSQL endpoint can continue to modify, + * attach, and detach partitions as usual. + */ +void +bbf_alter_handle_partitioned_table(AlterTableStmt *stmt) +{ + AlterTableCmd *cmd = (AlterTableCmd *) linitial(stmt->cmds); + int16 dbid; + char *physical_schemaname; + char *logical_schemaname; + Form_pg_class form; + Oid nsp_oid; + HeapTuple tuple; + bool is_partition_table, is_partitioned_table; + Oid relid = RangeVarGetRelid(stmt->relation, NoLock, true); + + if (!OidIsValid(relid)) + return; + + /* Get the namespace OID and rekind type of the table. */ + tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); + + if (!HeapTupleIsValid(tuple)) /* Sanity check. */ + return; + + form = (Form_pg_class) GETSTRUCT(tuple); + is_partition_table = form->relispartition; + is_partitioned_table = (form->relkind == 'p'); + nsp_oid = form->relnamespace; + ReleaseSysCache(tuple); + + /* Proceed further only if table is a partition or partitioned table. */ + if (!is_partition_table && !is_partitioned_table) + return; + + /* Get the schema name from namespace OID. */ + physical_schemaname = get_namespace_name(nsp_oid); + + /* Find dbid logical schema name physical schema name. */ + logical_schemaname = (char *) get_logical_schema_name(physical_schemaname, true); + if (!logical_schemaname) /* not a TSQL schema */ + { + pfree(physical_schemaname); + return; + } + + /* Find dbid from physical schema name for a TSQL schema. */ + dbid = get_dbid_from_physical_schema_name(physical_schemaname, false); + + /* + * For babelfish partitioned table, user should not be + * allowed to attach/detach to table directly. + * These commands can be executed only from PG endpoint. + */ + if (is_partitioned_table && (cmd->subtype == AT_AttachPartition || + cmd->subtype == AT_DetachPartition || cmd->subtype == AT_DetachPartitionFinalize)) + { + if (is_bbf_partitioned_table(dbid, logical_schemaname, stmt->relation->relname)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Cannot %s babelfish partitioned table '%s'.", + cmd->subtype == AT_AttachPartition ? "attach partition to" : "detach partition from", + stmt->relation->relname))); + } + /* + * For babelfish partition table, user should not + * be allowed to modify it. + * This will blocked from both TSQL and PG endpoint. + */ + else if (is_partition_table) + { + char *parent_table_name = get_rel_name(get_partition_parent(relid, false)); + if (is_bbf_partitioned_table(dbid, logical_schemaname, parent_table_name)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table."))); + pfree(parent_table_name); + } + + pfree(physical_schemaname); + pfree(logical_schemaname); +} diff --git a/contrib/babelfishpg_tsql/src/pltsql_partition.h b/contrib/babelfishpg_tsql/src/pltsql_partition.h new file mode 100644 index 00000000000..a84301c2414 --- /dev/null +++ b/contrib/babelfishpg_tsql/src/pltsql_partition.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * pltsql_partition.h + * This file contains declartions of function externs used + * for PL/tsql Partition. + * + * Portions Copyright (c) 2024, AWS + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * contrib/babelfishpg_tsql/src/pltsql_partition.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLTSQL_PARTITION_H +#define PLTSQL_PARTITION_H + +#include "nodes/parsenodes.h" + +/* Max number of partitions allowed for babelfish partitioned tables. */ +#define MAX_PARTITIONS_LIMIT 15000 + +extern void bbf_create_partition_tables(CreateStmt *stmt); +extern void bbf_drop_handle_partitioned_table(DropStmt *stmt); +extern void bbf_alter_handle_partitioned_table(AlterTableStmt *stmt); +extern bool bbf_validate_partitioned_index_alignment(IndexStmt *stmt); +extern void rename_table_update_bbf_partitions_name(RenameStmt *stmt); + +#endif /* PLTSQL_PARTITION_H */ diff --git a/contrib/babelfishpg_tsql/src/schemacmds.c b/contrib/babelfishpg_tsql/src/schemacmds.c index acb4d023400..5c95e5fdfdb 100644 --- a/contrib/babelfishpg_tsql/src/schemacmds.c +++ b/contrib/babelfishpg_tsql/src/schemacmds.c @@ -19,6 +19,7 @@ #include "hooks.h" #include "schemacmds.h" #include "session.h" +#include "pltsql.h" static bool has_ext_info(const char *schemaname); diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index f3805c32824..2eeea8071c3 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -7148,8 +7148,12 @@ post_process_create_table(TSqlParser::Create_tableContext *ctx, PLtsql_stmt_exec if (cctx->ON()) { Assert(cctx->storage_partition_clause()); - removeTokenStringFromQuery(stmt->sqlstmt, cctx->ON(), baseCtx); - removeCtxStringFromQuery(stmt->sqlstmt, cctx->storage_partition_clause(), baseCtx); + /* remove storage_partition_clause only if it's not partitioning clause */ + if (cctx->storage_partition_clause()->id().size() != 2) + { + removeTokenStringFromQuery(stmt->sqlstmt, cctx->ON(), baseCtx); + removeCtxStringFromQuery(stmt->sqlstmt, cctx->storage_partition_clause(), baseCtx); + } } else if (cctx->TEXTIMAGE_ON()) { @@ -7394,12 +7398,6 @@ makeDropFulltextIndexStmt(TSqlParser::Drop_fulltext_indexContext *ctx) static bool post_process_create_index(TSqlParser::Create_indexContext *ctx, PLtsql_stmt_execsql *stmt, TSqlParser::Ddl_statementContext *baseCtx) { - if (ctx->storage_partition_clause()) - { - removeTokenStringFromQuery(stmt->sqlstmt, ctx->ON().back(), baseCtx); /* remove last ON */ - removeCtxStringFromQuery(stmt->sqlstmt, ctx->storage_partition_clause(), baseCtx); - } - if (ctx->clustered() && ctx->clustered()->CLUSTERED()) removeTokenStringFromQuery(stmt->sqlstmt, ctx->clustered()->CLUSTERED(), baseCtx); if (ctx->clustered() && ctx->clustered()->NONCLUSTERED()) diff --git a/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp b/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp index 6ad4312c4e2..36535c6daab 100644 --- a/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp @@ -736,7 +736,10 @@ antlrcpp::Any TsqlUnsupportedFeatureHandlerImpl::visitCreate_table(TSqlParser::C for (auto cctx : ctx->create_table_options()) { - if (cctx->ON() || cctx->TEXTIMAGE_ON() || cctx->FILESTREAM_ON()) + if (cctx->TEXTIMAGE_ON() || cctx->FILESTREAM_ON()) + handle_storage_partition(cctx->storage_partition_clause()); + /* handle storage_partition_clause only if it's not partitioning clause */ + if (cctx->ON() && cctx->storage_partition_clause()->id().size() < 2) handle_storage_partition(cctx->storage_partition_clause()); } @@ -808,7 +811,9 @@ antlrcpp::Any TsqlUnsupportedFeatureHandlerImpl::visitAlter_table(TSqlParser::Al antlrcpp::Any TsqlUnsupportedFeatureHandlerImpl::visitCreate_index(TSqlParser::Create_indexContext *ctx) { - handle_storage_partition(ctx->storage_partition_clause()); + /* handle storage_partition_clause only if it's not partitioning clause */ + if (ctx->storage_partition_clause() && ctx->storage_partition_clause()->id().size() < 2) + handle_storage_partition(ctx->storage_partition_clause()); if (ctx->clustered() && ctx->clustered()->CLUSTERED()) handle(INSTR_UNSUPPORTED_TSQL_COLUMN_OPTION_CLUSTERED, ctx->clustered()->CLUSTERED(), &st_escape_hatch_index_clustering); diff --git a/test/JDBC/expected/BABEL-2515.out b/test/JDBC/expected/BABEL-2515.out deleted file mode 100644 index a065c204e2d..00000000000 --- a/test/JDBC/expected/BABEL-2515.out +++ /dev/null @@ -1,36 +0,0 @@ -use master; -GO - -CREATE TABLE [BABEL-2515] -( - [PartitionId] [smallint] NOT NULL, - CONSTRAINT [PK_DataRecord2056] PRIMARY KEY CLUSTERED ( [PartitionId] ASC ) - WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) - ON [XFPS_DataRecord2056]([PartitionId]) -) -ON [XFPS_DataRecord2056]([PartitionId]); -GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: 'partition scheme' is not currently supported in Babelfish. please use babelfishpg_tsql.escape_hatch_storage_on_partition to ignore)~~ - - -EXEC sp_babelfish_configure 'babelfishpg_tsql.escape_hatch_storage_on_partition', 'ignore'; -GO - -CREATE TABLE [BABEL-2515] -( - [PartitionId] [smallint] NOT NULL, - CONSTRAINT [PK_DataRecord2056] PRIMARY KEY CLUSTERED ( [PartitionId] ASC ) - WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) - ON [XFPS_DataRecord2056]([PartitionId]) -) -ON [XFPS_DataRecord2056]([PartitionId]); -GO - -DROP TABLE [BABEL-2515] -GO - --- reset to default -EXEC sp_babelfish_configure 'babelfishpg_tsql.escape_hatch_storage_on_partition', 'strict'; -GO diff --git a/test/JDBC/expected/BABEL-UNSUPPORTED.out b/test/JDBC/expected/BABEL-UNSUPPORTED.out index 546a8d1aaa4..7148ee8a041 100644 --- a/test/JDBC/expected/BABEL-UNSUPPORTED.out +++ b/test/JDBC/expected/BABEL-UNSUPPORTED.out @@ -437,13 +437,6 @@ ignore -- escape hatch: storage_on_partition. -- 'strict' is default -CREATE TABLE t_unsupported_sop1(a int) ON partition(a); -GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: 'partition scheme' is not currently supported in Babelfish. please use babelfishpg_tsql.escape_hatch_storage_on_partition to ignore)~~ - - CREATE TABLE t_unsupported_sop2(a int) FILESTREAM_ON partition(a); GO ~~ERROR (Code: 33557097)~~ @@ -459,11 +452,6 @@ ignore ~~END~~ -CREATE TABLE t_unsupported_sop1(a int) ON partition(a); -GO -DROP TABLE t_unsupported_sop1; -GO - CREATE TABLE t_unsupported_sop2(a int) FILESTREAM_ON partition(a); GO DROP TABLE t_unsupported_sop2 diff --git a/test/JDBC/expected/PARTITION-vu-cleanup.out b/test/JDBC/expected/PARTITION-vu-cleanup.out index f1b67e4bbdf..81316076b99 100644 --- a/test/JDBC/expected/PARTITION-vu-cleanup.out +++ b/test/JDBC/expected/PARTITION-vu-cleanup.out @@ -13,6 +13,12 @@ GO DROP VIEW GetPartitionSchemesMetadataView GO +DROP VIEW GetPartitionedTableListFromSysTablesView +GO + +DROP VIEW GetPartitionedIndexListFromSysIndexesView +GO + DROP FUNCTION PartitionFunctionContainsDuplicateName GO @@ -25,6 +31,180 @@ GO DROP FUNCTION PartitionSchemeContainsDuplicateIDs GO +-------------------------------------------------- +--- DROP Partitioned Index +-------------------------------------------------- +DROP INDEX partition_vu_prepare_sqlvariant_index ON partition_vu_prepare_sqlvariant_table; +GO + +DROP INDEX partition_vu_prepare_uniqueidentifier_index ON partition_vu_prepare_uniqueidentifier_table; +GO + +DROP INDEX partition_vu_prepare_varbinary_index ON partition_vu_prepare_varbinary_table; +GO + +DROP INDEX partition_vu_prepare_binary_index ON partition_vu_prepare_binary_table; +GO + +DROP INDEX partition_vu_prepare_nchar_index ON partition_vu_prepare_nchar_table; +GO + +DROP INDEX partition_vu_prepare_nvarchar_index ON partition_vu_prepare_nvarchar_table; +GO + +DROP INDEX partition_vu_prepare_varchar_index ON partition_vu_prepare_varchar_table; +GO + +DROP INDEX partition_vu_prepare_char_index ON partition_vu_prepare_char_table; +GO + +DROP INDEX partition_vu_prepare_smalldatetime_index ON partition_vu_prepare_smalldatetime_table; +GO + +DROP INDEX partition_vu_prepare_datetime2_index ON partition_vu_prepare_datetime2_table; +GO + +DROP INDEX partition_vu_prepare_datetime_index ON partition_vu_prepare_datetime_table; +GO + +DROP INDEX partition_vu_prepare_date_index ON partition_vu_prepare_date_table; +GO + +DROP INDEX partition_vu_prepare_smallmoney_index ON partition_vu_prepare_smallmoney_table; +GO + +DROP INDEX partition_vu_prepare_money_index ON partition_vu_prepare_money_table; +GO + +DROP INDEX partition_vu_prepare_numeric_index ON partition_vu_prepare_numeric_table; +GO + +DROP INDEX partition_vu_prepare_decimal_index ON partition_vu_prepare_decimal_table; +GO + +DROP INDEX partition_vu_prepare_tinyint_index ON partition_vu_prepare_tinyint_table; +GO + +DROP INDEX partition_vu_prepare_smallint_index ON partition_vu_prepare_smallint_table; +GO + +DROP INDEX partition_vu_prepare_bigint_index ON partition_vu_prepare_bigint_table; +GO + +DROP INDEX partition_vu_prepare_int_index ON partition_vu_prepare_int_table; +GO + +DROP INDEX PARTITION_INDEXログインαιώνια ON PARTITION_TABLEログインαιώνια +GO + +DROP INDEX [PARTITION_INDEX 유니코드스키마👻 ] ON [PARTITION_TABLE 유니코드스키마👻 ] +GO + +SET QUOTED_IDENTIFIER ON; +GO + +DROP INDEX "PARTITION_INDEX 😎$@ #123 🌍rder " ON "PARTITION_TABLE 😎$@ #123 🌍rder " +GO + +SET QUOTED_IDENTIFIER OFF; +GO + +DROP INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +GO + +DROP INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO +-------------------------------------------------- +--- DROP Partitioned Table +-------------------------------------------------- +DROP TABLE partition_vu_prepare_sqlvariant_table; +GO + +DROP TABLE partition_vu_prepare_uniqueidentifier_table; +GO + +DROP TABLE partition_vu_prepare_varbinary_table; +GO + +DROP TABLE partition_vu_prepare_binary_table; +GO + +DROP TABLE partition_vu_prepare_nchar_table; +GO + +DROP TABLE partition_vu_prepare_nvarchar_table; +GO + +DROP TABLE partition_vu_prepare_varchar_table; +GO + +DROP TABLE partition_vu_prepare_char_table; +GO + +DROP TABLE partition_vu_prepare_smalldatetime_table; +GO + +DROP TABLE partition_vu_prepare_datetime2_table; +GO + +DROP TABLE partition_vu_prepare_datetime_table; +GO + +DROP TABLE partition_vu_prepare_date_table; +GO + +DROP TABLE partition_vu_prepare_smallmoney_table; +GO + +DROP TABLE partition_vu_prepare_money_table; +GO + +DROP TABLE partition_vu_prepare_numeric_table; +GO + +DROP TABLE partition_vu_prepare_decimal_table; +GO + +DROP TABLE partition_vu_prepare_tinyint_table; +GO + +DROP TABLE partition_vu_prepare_smallint_table; +GO + +DROP TABLE partition_vu_prepare_bigint_table; +GO + +DROP TABLE partition_vu_prepare_int_table; +GO + +DROP TABLE PartitionTableNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz +GO + +DROP TABLE PARTITION_TABLEログインαιώνια +GO + +DROP TABLE [PARTITION_TABLE 유니코드스키마👻 ] +GO + +SET QUOTED_IDENTIFIER ON; +GO + +DROP TABLE "PARTITION_TABLE 😎$@ #123 🌍rder " +GO + +SET QUOTED_IDENTIFIER OFF; +GO + +DROP TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +GO + +DROP TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO + +DROP SCHEMA PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +GO -------------------------------------------------- --- DROP Partition Scheme -------------------------------------------------- @@ -46,6 +226,12 @@ GO DROP PARTITION SCHEME NumericPartitionScheme GO +DROP PARTITION SCHEME MoneyPartitionScheme +GO + +DROP PARTITION SCHEME SmallMoneyPartitionScheme +GO + DROP PARTITION SCHEME DatePartitionScheme GO @@ -88,19 +274,22 @@ GO DROP PARTITION SCHEME PARTITION_SCHEMEログインαιώνια GO -DROP PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻] +DROP PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻 ] GO SET QUOTED_IDENTIFIER ON; GO -DROP PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder" +DROP PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder " Go SET QUOTED_IDENTIFIER OFF; GO --------------------------------------------------- +DROP PARTITION SCHEME PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO + +------------------------------------------- --- DROP Partition Function ------------------------------------------- DROP PARTITION FUNCTION IntPartitionFunction @@ -172,16 +361,26 @@ GO DROP PARTITION FUNCTION PARTITION_FUNCTIONログインαιώνια GO -DROP PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻] +DROP PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻 ] GO +DROP PARTITION FUNCTION PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO + + +--------------------------- +--- DROP Procedures +--------------------------- DROP PROCEDURE PartitionProcedureCreatePartitionFunction GO DROP PROCEDURE PartitionProcedureCreatePartitionScheme GO -DROP PROCEDURE PartitionProcedureCreatePartitionFunctionAndScheme +DROP PROCEDURE PartitionProcedureCreatePartitionTable +GO + +DROP PROCEDURE PartitionProcedureCreatePartitionFunctionSchemeAndTable GO DROP PROCEDURE PartitionProcedureDropPartitionFunction @@ -190,14 +389,17 @@ GO DROP PROCEDURE PartitionProcedureDropPartitionScheme GO -DROP PROCEDURE PartitionProcedureDropPartitionFunctionAndScheme +DROP PROCEDURE PartitionProcedureDropPartitionTable +GO + +DROP PROCEDURE PartitionProcedureDropPartitionFunctionSchemeAndTable GO SET QUOTED_IDENTIFIER ON; GO -DROP PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder" +DROP PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder " Go SET QUOTED_IDENTIFIER OFF; @@ -214,3 +416,29 @@ go DROP DATABASE PartitionDb go + +-- psql +-- validate that catalogs don't have stale entries +SELECT count(*) FROM sys.babelfish_partition_function; +GO +~~START~~ +int8 +0 +~~END~~ + + +SELECT count(*) FROM sys.babelfish_partition_scheme +GO +~~START~~ +int8 +0 +~~END~~ + + +SELECT count(*) FROM sys.babelfish_partition_depend +GO +~~START~~ +int8 +0 +~~END~~ + diff --git a/test/JDBC/expected/PARTITION-vu-prepare.out b/test/JDBC/expected/PARTITION-vu-prepare.out index d389c3bde22..c77887d52c9 100644 --- a/test/JDBC/expected/PARTITION-vu-prepare.out +++ b/test/JDBC/expected/PARTITION-vu-prepare.out @@ -135,9 +135,13 @@ RETURN GO + + -------------------------------------------------- --- Supported Datatypes for Partition Function -------------------------------------------------- +-- all datatypes should sort and store the values in ascending order by itself +-- and input values should be implicit casted into specified type -- using local variable in args declare @a int = 0; declare @b int = 500; @@ -146,9 +150,9 @@ CREATE PARTITION FUNCTION IntPartitionFunction (int) AS RANGE RIGHT FOR VALUES (@a, @b, @c); GO --- all datatypes should sort and store the values in ascending order by itself --- and input values should be implicit casted into specified type -CREATE PARTITION FUNCTION BigIntPartitionFunction (bigint) + +-- explicit schema can also be specified with paramater type +CREATE PARTITION FUNCTION BigIntPartitionFunction (sys.bigint) AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); GO @@ -156,7 +160,8 @@ CREATE PARTITION FUNCTION SmallIntPartitionFunction (smallint) AS RANGE RIGHT FOR VALUES (cast(32767 as bigint), -32768, 0); GO -CREATE PARTITION FUNCTION TinyIntPartitionFunction (tinyint) +-- explicit schema can also be specified with paramater type +CREATE PARTITION FUNCTION TinyIntPartitionFunction (sys.tinyint) AS RANGE RIGHT FOR VALUES (0, cast(255 as varchar), 128); GO @@ -237,6 +242,10 @@ CREATE PARTITION FUNCTION PartitionFunctionNameGreaterThan64AndLessThan128abcdef AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); GO +CREATE PARTITION FUNCTION PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder (bigint) +AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); +GO + CREATE PARTITION FUNCTION PartitionFunctionHavingDifferentCollationInput (NVARCHAR(50)) AS RANGE RIGHT FOR VALUES ( @@ -252,17 +261,19 @@ GO --- Partition Scheme -------------------------------------------------- -- without all option +-- filegroups are equal to partition that will generated by function CREATE PARTITION SCHEME IntPartitionScheme AS PARTITION IntPartitionFunction TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY]); GO --- with all option +-- filgroups are more than partition that will generated by function CREATE PARTITION SCHEME BigIntPartitionScheme AS PARTITION BigIntPartitionFunction -ALL TO ([PRIMARY]); +TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY]); GO +-- with all option CREATE PARTITION SCHEME SmallIntPartitionScheme AS PARTITION SmallIntPartitionFunction ALL TO ([PRIMARY]); @@ -283,6 +294,16 @@ PARTITION NumericPartitionFunction ALL TO ([PRIMARY]); GO +CREATE PARTITION SCHEME MoneyPartitionScheme AS +PARTITION MoneyPartitionFunction +ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME SmallMoneyPartitionScheme AS +PARTITION SmallMoneyPartitionFunction +ALL TO ([PRIMARY]); +GO + CREATE PARTITION SCHEME DatePartitionScheme AS PARTITION DatePartitionFunction ALL TO ([PRIMARY]); @@ -349,6 +370,39 @@ PARTITION PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuv ALL TO ([PRIMARY]); GO +CREATE PARTITION SCHEME PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder AS +PARTITION PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +ALL TO ([PRIMARY]); +GO + +CREATE SCHEMA PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +GO + +CREATE TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz ( + PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz BIGINT, + Value sys.varchar(50) +) ON PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz (PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + +CREATE INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz(Value) +ON PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz +(PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + +CREATE TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder ( + PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz BIGINT, + Value sys.varchar(50) +) ON PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +(PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + +CREATE INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder(Value) +ON PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +(PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + -------------------------------------------------- --- name identifiers test -------------------------------------------------- @@ -361,29 +415,62 @@ PARTITION PARTITION_FUNCTIONログインαιώνια ALL TO ([PRIMARY]); GO -CREATE PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻] (int) +CREATE TABLE PARTITION_TABLEログインαιώνια ( + PARTITION_COLUMNログインαιώνια INT, + Value sys.varchar(50) +) ON PARTITION_SCHEMEログインαιώνια(PARTITION_COLUMNログインαιώνια); +GO + +CREATE INDEX PARTITION_INDEXログインαιώνια +ON PARTITION_TABLEログインαιώνια(Value) +ON PARTITION_SCHEMEログインαιώνια(PARTITION_COLUMNログインαιώνια); +GO + +CREATE PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻 ] (int) AS RANGE RIGHT FOR VALUES (0, 500, 1000); GO -CREATE PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻] AS -PARTITION [PARTITION_FUNCTION 유니코드스키마👻] +CREATE PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻 ] AS +PARTITION [PARTITION_FUNCTION 유니코드스키마👻 ] ALL TO ([PRIMARY]); GO +CREATE TABLE [PARTITION_TABLE 유니코드스키마👻 ]( + [PARTITION_COLUMN 유니코드스키마👻 ] INT, + Value sys.varchar(50) +) ON [PARTITION_SCHEME 유니코드스키마👻 ]([PARTITION_COLUMN 유니코드스키마👻 ]); +GO + +CREATE INDEX [PARTITION_INDEX 유니코드스키마👻 ] +ON [PARTITION_TABLE 유니코드스키마👻 ](Value) +ON [PARTITION_SCHEME 유니코드스키마👻 ]([PARTITION_COLUMN 유니코드스키마👻 ]); +GO -- qouted identifer SET QUOTED_IDENTIFIER ON; GO -CREATE PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder" (int) +CREATE PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder " (int) AS RANGE RIGHT FOR VALUES (0, 500, 1000); GO -CREATE PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder" AS -PARTITION "PARTITION_FUNCTION 😎$@ #123 🌍rder" +CREATE PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder " AS +PARTITION "PARTITION_FUNCTION 😎$@ #123 🌍rder " ALL TO ([PRIMARY]); GO + +CREATE TABLE "PARTITION_TABLE 😎$@ #123 🌍rder " ( + "PARTITION_COLUMN 😎$@ #123 🌍rder " INT, + Value sys.varchar(50) +) ON "PARTITION_SCHEME 😎$@ #123 🌍rder " ("PARTITION_COLUMN 😎$@ #123 🌍rder "); +GO + +CREATE INDEX "PARTITION_INDEX 😎$@ #123 🌍rder " +ON "PARTITION_TABLE 😎$@ #123 🌍rder " (Value) +ON "PARTITION_SCHEME 😎$@ #123 🌍rder "("PARTITION_COLUMN 😎$@ #123 🌍rder "); +GO + SET QUOTED_IDENTIFIER OFF; Go @@ -406,11 +493,22 @@ PARTITION PartitionDb_PartitionFunction ALL TO ([PRIMARY]); GO +CREATE TABLE PartitionDb_PartitionTable ( + Id INT, + Value sys.varchar(50) +) ON PartitionDb_PartitionScheme(Id); +GO + +CREATE INDEX PartitionDb_PartitionIndex +ON PartitionDb_PartitionTable(Id) +ON PartitionDb_PartitionScheme (Id); +GO + USE MASTER go --------------------------------------------------------------- ---- CREATE/DROP Partition Function/Scheme inside Procedure +--- CREATE/DROP Partition Function/Scheme/Table inside Procedure --------------------------------------------------------------- CREATE PROCEDURE PartitionProcedureCreatePartitionFunction AS BEGIN @@ -427,14 +525,26 @@ ALL TO ([PRIMARY]) END; GO +CREATE PROCEDURE PartitionProcedureCreatePartitionTable AS +BEGIN +CREATE TABLE PartitionTableInsideProc1( + Id INT, + Value sys.varchar(50) +) ON PartitionSchemeInsideProc1(Id); +END; +GO -CREATE PROCEDURE PartitionProcedureCreatePartitionFunctionAndScheme AS +CREATE PROCEDURE PartitionProcedureCreatePartitionFunctionSchemeAndTable AS BEGIN CREATE PARTITION FUNCTION PartitionFunctionInsideProc2 (int) AS RANGE RIGHT FOR VALUES (500, 1000, 10000); CREATE PARTITION SCHEME PartitionSchemeInsideProc2 AS PARTITION PartitionFunctionInsideProc2 ALL TO ([PRIMARY]); +CREATE TABLE PartitionTableInsideProc2( + Id INT, + Value sys.varchar(50) +) ON PartitionSchemeInsideProc2(Id); END; Go @@ -450,9 +560,640 @@ DROP PARTITION SCHEME PartitionSchemeInsideProc1 END; GO -CREATE PROCEDURE PartitionProcedureDropPartitionFunctionAndScheme AS +CREATE PROCEDURE PartitionProcedureDropPartitionTable AS +BEGIN +DROP TABLE PartitionTableInsideProc1 +END; +GO + +CREATE PROCEDURE PartitionProcedureDropPartitionFunctionSchemeAndTable AS BEGIN +DROP TABLE PartitionTableInsideProc2; DROP PARTITION SCHEME PartitionSchemeInsideProc2; DROP PARTITION FUNCTION PartitionFunctionInsideProc2; END; Go + +USE master; +go +--------------------------------------------------------------------------- +--- CREATE PARTITIONED TABLES with PARTITION SCHEME for different datatypes +--------------------------------------------------------------------------- +-- int data type +CREATE TABLE partition_vu_prepare_int_table ( + Id INT UNIQUE, + Value sys.varchar(50) +) ON IntPartitionScheme(Id); +GO + +-- add constraint +ALTER TABLE partition_vu_prepare_int_table ADD CONSTRAINT check_value_not_null CHECK(value IS NOT NULL); +GO + +-- bigint data type +CREATE TABLE partition_vu_prepare_bigint_table ( + Id BIGINT, + Value sys.varchar(50) +) ON BigIntPartitionScheme--this is comment should get ignored +(Id); +GO + +-- smallint data type +CREATE TABLE partition_vu_prepare_smallint_table ( + Id SMALLINT, + Value sys.varchar(50) +) ON SmallIntPartitionScheme(Id); +GO + +-- tinyint data type +CREATE TABLE partition_vu_prepare_tinyint_table ( + Id TINYINT, + Value sys.varchar(50) +) ON TinyIntPartitionScheme(Id); +GO + +-- decimal data type +CREATE TABLE partition_vu_prepare_decimal_table ( + Id DECIMAL(10, 5), + Value sys.varchar(50) +) ON DecimalPartitionScheme(Id); +GO + +-- numeric data type +CREATE TABLE partition_vu_prepare_numeric_table ( + Id NUMERIC(5, 2), + Value sys.varchar(50) +) ON NumericPartitionScheme(Id); +GO + +-- money data type +CREATE TABLE partition_vu_prepare_money_table ( + Id MONEY, + Value sys.varchar(50) +) ON MoneyPartitionScheme(Id); +GO + +-- smallmoney data type +CREATE TABLE partition_vu_prepare_smallmoney_table ( + Id SMALLMONEY, + Value sys.varchar(50) +) ON SmallMoneyPartitionScheme(Id); +GO + +-- date data type +CREATE TABLE partition_vu_prepare_date_table ( + Id DATE, + Value sys.varchar(50) +) ON DatePartitionScheme(Id); +GO + +-- datetime data type +CREATE TABLE partition_vu_prepare_datetime_table ( + Id DATETIME, + Value sys.varchar(50) +) ON DateTimePartitionScheme(Id); +GO + +-- datetime2 data type +CREATE TABLE partition_vu_prepare_datetime2_table ( + Id DATETIME2(3), + Value sys.varchar(50) +) ON DateTime2PartitionScheme(Id); +GO + +-- smalldatetime data type +CREATE TABLE partition_vu_prepare_smalldatetime_table ( + Id SMALLDATETIME, + Value sys.varchar(50) +) ON SmallDateTimePartitionScheme(Id); +GO + +-- char data type +CREATE TABLE partition_vu_prepare_char_table ( + Id CHAR(5), + Value sys.varchar(50) +) ON CharPartitionScheme(Id); +GO + +-- varchar data type +CREATE TABLE partition_vu_prepare_varchar_table ( + Id VARCHAR(10), + Value sys.varchar(50) +) ON VarCharPartitionScheme(Id); +GO + +-- nvarchar data type +CREATE TABLE partition_vu_prepare_nvarchar_table ( + Id NVARCHAR(10), + Value sys.varchar(50) +) ON NVarCharPartitionScheme(Id); +GO + +-- nchar data type +CREATE TABLE partition_vu_prepare_nchar_table ( + Id NCHAR(5), + Value sys.varchar(50) +) ON NCharPartitionScheme(Id); +GO + +-- binary data type +CREATE TABLE partition_vu_prepare_binary_table ( + Id BINARY(4), + Value sys.varchar(50) +) ON BinaryPartitionScheme(Id); +GO + +-- varbinary data type +CREATE TABLE partition_vu_prepare_varbinary_table ( + Id VARBINARY(8), + Value sys.varchar(50) +) ON VarBinaryPartitionScheme(Id); +GO + +-- uniqueidentifier data type +CREATE TABLE partition_vu_prepare_uniqueidentifier_table ( + Id UNIQUEIDENTIFIER, + Value sys.varchar(50) +) ON UniqueIdentifierPartitionScheme(Id); +GO + +-- sql_variant data type +CREATE TABLE partition_vu_prepare_sqlvariant_table ( + Id SQL_VARIANT, + Value sys.varchar(50) +) ON SqlVariantPartitionScheme(Id); +GO + +-- identifier length greater than 64 +CREATE TABLE PartitionTableNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz ( + Id INT, + Value sys.varchar(50) +) ON IntPartitionScheme(Id); +GO + +CREATE VIEW GetPartitionedTableListFromSysTablesView +AS +( + SELECT + name + FROM + sys.tables + WHERE + name like '%partition_vu_prepare%' + ORDER BY + name +) +GO + +--------------------------------------------------------------------------- +--- CREATE ALIGNED PARTITIONED INDEX with PARTITION SCHEME +--------------------------------------------------------------------------- +-- using schema name +CREATE INDEX partition_vu_prepare_int_index +ON dbo.partition_vu_prepare_int_table(Value) +ON IntPartitionScheme (Id); +GO + +-- without explicit schema name +CREATE INDEX partition_vu_prepare_bigint_index +ON partition_vu_prepare_bigint_table(Id) +ON BigIntPartitionScheme (Id); +GO + +-- without partition scheme should also work +CREATE INDEX partition_vu_prepare_smallint_index +ON partition_vu_prepare_smallint_table--this is comment should get ignored +(Id) +GO + +CREATE INDEX partition_vu_prepare_tinyint_index +ON partition_vu_prepare_tinyint_table(Id) +ON TinyIntPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_decimal_index +ON partition_vu_prepare_decimal_table(Id) +ON DecimalPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_numeric_index +ON partition_vu_prepare_numeric_table(Id) +ON NumericPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_money_index +ON partition_vu_prepare_money_table(Id) +ON MoneyPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_smallmoney_index +ON partition_vu_prepare_smallmoney_table(Id) +ON SmallMoneyPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_date_index +ON partition_vu_prepare_date_table(Id) +ON DatePartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_datetime_index +ON partition_vu_prepare_datetime_table(Id) +ON DateTimePartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_datetime2_index +ON partition_vu_prepare_datetime2_table(Id) +ON DateTime2PartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_smalldatetime_index +ON partition_vu_prepare_smalldatetime_table(Id) +ON SmallDateTimePartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_char_index +ON partition_vu_prepare_char_table(Id) +ON CharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_varchar_index +ON partition_vu_prepare_varchar_table(Id) +ON VarCharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_nvarchar_index +ON partition_vu_prepare_nvarchar_table(Id) +ON NVarCharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_nchar_index +ON partition_vu_prepare_nchar_table(Id) +ON NCharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_binary_index +ON partition_vu_prepare_binary_table(Id) +ON BinaryPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_varbinary_index +ON partition_vu_prepare_varbinary_table(Id) +ON VarBinaryPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_uniqueidentifier_index +ON partition_vu_prepare_uniqueidentifier_table(Id) +ON UniqueIdentifierPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_sqlvariant_index +ON partition_vu_prepare_sqlvariant_table(Id) +ON SqlVariantPartitionScheme (Id); +GO + +CREATE VIEW GetPartitionedIndexListFromSysIndexesView +AS +( + SELECT + name + FROM + sys.indexes + WHERE + name like '%partition_vu_prepare%' + ORDER BY + name +) +GO + +--------------------------------------------------------------------------- +--- Insert data into partitioned tables +--------------------------------------------------------------------------- +-- Insert values into partition_vu_prepare_int_table +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (100, 'Value 100'); +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (10000, 'Value 10000'); +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_bigint_table +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (100, 'Value 100'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (10000, 'Value 10000'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (1000000000, 'Value 1000000000'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_smallint_table +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (-32768, 'Value -32768'); +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (32767, 'Value 32767'); +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_tinyint_table +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (128, 'Value 128'); +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (255, 'Value 255'); +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_decimal_table +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (100.0, 'Value 100.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (200.0, 'Value 200.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (300.0, 'Value 300.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_numeric_table +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (10.0, 'Value 10.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (20.0, 'Value 20.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (30.0, 'Value 30.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_money_table +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (2.56789, 'Value 2.56789'); +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (4.91, 'Value 4.91'); +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_smallmoney_table +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (2.56789, 'Value 2.56789'); +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (4.91, 'Value 4.91'); +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_date_table +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES ('2022-01-01', 'Value 2022-01-01'); +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES ('2022-07-01', 'Value 2022-07-01'); +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES ('2023-01-01', 'Value 2023-01-01'); +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_datetime_table +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES ('2019-01-01', 'Value 2019-01-01'); +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES ('2022-01-01', 'Value 2022-01-01'); +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES ('2022-07-01', 'Value 2022-07-01'); +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_datetime2_table +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES ('2019-01-01 00:00:00.000', 'Value 2019-01-01 00:00:00.000'); +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES ('2022-01-01 00:00:00.000', 'Value 2022-01-01 00:00:00.000'); +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES ('2022-07-01 00:00:00.000', 'Value 2022-07-01 00:00:00.000'); +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_smalldatetime_table +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES ('2019-01-01', 'Value 2019-01-01'); +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES ('2022-01-01', 'Value 2022-01-01'); +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES ('2022-07-01', 'Value 2022-07-01'); +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_char_table +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('A', 'Value A'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('K', 'Value K'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('U', 'Value U'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('D', 'Value D'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_varchar_table +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Apple', 'Value Apple'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Banana', 'Value Banana'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Mango', 'Value Mango'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Cherry', 'Value Cherry'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Date', 'Value Date'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_nvarchar_table +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Apple', N'Value Apple'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Banana', N'Value Banana'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Mango', N'Value Mango'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Cherry', N'Value Cherry'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Date', N'Value Date'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_nchar_table +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'A', N'Value A'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'K', N'Value K'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'U', N'Value U'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'B', N'Value B'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + + +-- BABEL-4957 needs to fixed first otherwise dump/restore will fail +-- Insert values into partition_vu_prepare_binary_table +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0000, 'Value 0x0000'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0400, 'Value 0x0400'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0800, 'Value 0x0800'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0C000, 'Value 0x0C000'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (NULL, 'Value NULL'); +-- GO +-- Insert values into partition_vu_prepare_varbinary_table +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0x0000000000000000, 'Value 0x0000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0x4000000000000000, 'Value 0x4000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0x8000000000000000, 'Value 0x8000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0xC000000000000000, 'Value 0xC000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_uniqueidentifier_table +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES ('00000000-0000-0000-0000-000000000000', 'Value 00000000-0000-0000-0000-000000000000'); +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES ('6F9619FF-8B86-D011-B42D-00C04FC964FF', 'Value 6F9619FF-8B86-D011-B42D-00C04FC964FF'); +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES ('FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', 'Value FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'); +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +-- Insert values into partition_vu_prepare_sqlvariant_table +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST('abc' AS char(5)), 'Value abc'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST(N'xyz' AS nchar(5)), N'Value xyz'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST('Apple' AS VARCHAR(10)), 'Value Apple'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST(N'Banana' AS NVARCHAR(10)), N'Value Banana'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST('Some text' AS SQL_VARIANT), 'Value Some text'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + diff --git a/test/JDBC/expected/PARTITION-vu-verify.out b/test/JDBC/expected/PARTITION-vu-verify.out index db296c2d098..6a158ff01ce 100644 --- a/test/JDBC/expected/PARTITION-vu-verify.out +++ b/test/JDBC/expected/PARTITION-vu-verify.out @@ -1,5 +1,6 @@ + -------------------------------------------------- ---- CREATE PARTITION FUNCTION/SCHEME using procedure +--- CREATE PARTITION FUNCTION/SCHEME/TABLE using procedure -------------------------------------------------- EXEC PartitionProcedureCreatePartitionFunction GO @@ -7,11 +8,14 @@ GO EXEC PartitionProcedureCreatePartitionScheme GO -EXEC PartitionProcedureCreatePartitionFunctionAndScheme +EXEC PartitionProcedureCreatePartitionTable +GO + +EXEC PartitionProcedureCreatePartitionFunctionSchemeAndTable GO -------------------------------------------------- ---- CREATE PARTITION FUNCTION/SCHEME inside Function +--- CREATE PARTITION FUNCTION/SCHEME/TABLE inside Function -------------------------------------------------- CREATE FUNCTION TestFunctionCreatePartitionFunction() RETURNS INT @@ -68,6 +72,34 @@ GO ~~ERROR (Message: Invalid use of a side-effecting operator 'DROP PARTITION SCHEME' within a function.)~~ +CREATE FUNCTION TestFunctionCreatePartitionTable() +RETURNS INT +AS +BEGIN + CREATE TABLE TestPartitionTable ( + Id INT, + Value sys.varchar(20) + ) ON IntPartitionScheme(Id); +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: DDL cannot be used within a function)~~ + + +CREATE FUNCTION TestFunctionDropPartitionTable() +RETURNS INT +AS +BEGIN + DROP TABLE partition_vu_prepare_int_table; + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: DDL cannot be used within a function)~~ + + --------------------------------------------------------- --- CREATE PARTITION FUNCTION/SCHEME using 2-part name @@ -398,6 +430,23 @@ GO ~~ERROR (Message: 'PARTIION FUNCTION with LEFT option' is not currently supported in Babelfish)~~ +-- NULL value is not supported in range values +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NULL values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL, NULL); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NULL values are not allowed in partition function boundary values list.)~~ + + -------------------------------------------------- --- Duplicate Create of Partition Function/Scheme -------------------------------------------------- @@ -476,6 +525,16 @@ GO ~~ERROR (Message: Partition function 'IntPartitionFunction' is being used by one or more partition schemes.)~~ +----------------------------------------------------------------------------------- +--- Drop of of Partition Scheme when there is dependent Table on it +----------------------------------------------------------------------------------- +DROP PARTITION SCHEME IntPartitionScheme +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The partition scheme "IntPartitionScheme" is currently being used to partition one or more tables.)~~ + + ----------------------------------------------- @@ -558,13 +617,14 @@ MoneyPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 NCharPartitionFunction#!#R #!#RANGE#!#8#!#1#!#0 NumericPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 NVarCharPartitionFunction#!#R #!#RANGE#!#6#!#1#!#0 -PARTITION_FUNCTION 유니코드스키마👻#!#R #!#RANGE#!#4#!#1#!#0 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#R #!#RANGE#!#4#!#1#!#0 +PARTITION_FUNCTION 유니코드스키마👻 #!#R #!#RANGE#!#4#!#1#!#0 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#R #!#RANGE#!#4#!#1#!#0 PARTITION_FUNCTIONログインαιώνια#!#R #!#RANGE#!#4#!#1#!#0 PartitionFunctionHavingDifferentCollationInput#!#R #!#RANGE#!#5#!#1#!#0 PartitionFunctionInsideProc1#!#R #!#RANGE#!#4#!#1#!#0 PartitionFunctionInsideProc2#!#R #!#RANGE#!#4#!#1#!#0 PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#R #!#RANGE#!#5#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#R #!#RANGE#!#5#!#1#!#0 SmallDateTimePartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 SmallIntPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 SmallMoneyPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 @@ -626,12 +686,12 @@ NVarCharPartitionFunction#!#1#!#2#!#Banana NVarCharPartitionFunction#!#1#!#3#!#Cherry NVarCharPartitionFunction#!#1#!#4#!#Date NVarCharPartitionFunction#!#1#!#5#!#Mango -PARTITION_FUNCTION 유니코드스키마👻#!#1#!#1#!#0 -PARTITION_FUNCTION 유니코드스키마👻#!#1#!#2#!#500 -PARTITION_FUNCTION 유니코드스키마👻#!#1#!#3#!#1000 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#1#!#1#!#0 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#1#!#2#!#500 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#1#!#3#!#1000 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#1#!#0 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#2#!#500 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#3#!#1000 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#1#!#0 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#2#!#500 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#3#!#1000 PARTITION_FUNCTIONログインαιώνια#!#1#!#1#!#0 PARTITION_FUNCTIONログインαιώνια#!#1#!#2#!#500 PARTITION_FUNCTIONログインαιώνια#!#1#!#3#!#1000 @@ -649,6 +709,10 @@ PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#! PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#2#!#100 PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#3#!#1000 PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#4#!#10000 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#2#!#100 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#3#!#1000 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#4#!#10000 SmallDateTimePartitionFunction#!#1#!#1#!#2019-01-01 00:00:00.0 SmallDateTimePartitionFunction#!#1#!#2#!#2022-01-01 00:00:00.0 SmallDateTimePartitionFunction#!#1#!#3#!#2022-07-01 00:00:00.0 @@ -708,13 +772,14 @@ MoneyPartitionFunction#!#money#!#1#!#8#!#19#!#4#!# NCharPartitionFunction#!#nchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as NumericPartitionFunction#!#numeric#!#1#!#17#!#38#!#38#!# NVarCharPartitionFunction#!#nvarchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as -PARTITION_FUNCTION 유니코드스키마👻#!#int#!#1#!#4#!#10#!#0#!# -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#int#!#1#!#4#!#10#!#0#!# +PARTITION_FUNCTION 유니코드스키마👻 #!#int#!#1#!#4#!#10#!#0#!# +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#int#!#1#!#4#!#10#!#0#!# PARTITION_FUNCTIONログインαιώνια#!#int#!#1#!#4#!#10#!#0#!# PartitionFunctionHavingDifferentCollationInput#!#nvarchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as PartitionFunctionInsideProc1#!#int#!#1#!#4#!#10#!#0#!# PartitionFunctionInsideProc2#!#int#!#1#!#4#!#10#!#0#!# PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#bigint#!#1#!#8#!#19#!#0#!# +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#bigint#!#1#!#8#!#19#!#0#!# SmallDateTimePartitionFunction#!#smalldatetime#!#1#!#4#!#16#!#0#!# SmallIntPartitionFunction#!#smallint#!#1#!#2#!#5#!#0#!# SmallMoneyPartitionFunction#!#smallmoney#!#1#!#4#!#10#!#4#!# @@ -738,17 +803,20 @@ DateTime2PartitionScheme#!#DateTime2PartitionFunction#!#PS#!#PARTITION_SCHEME#!# DateTimePartitionScheme#!#DateTimePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 DecimalPartitionScheme#!#DecimalPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 IntPartitionScheme#!#IntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +MoneyPartitionScheme#!#MoneyPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 NCharPartitionScheme#!#NCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 NumericPartitionScheme#!#NumericPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 NVarCharPartitionScheme#!#NVarCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 -PARTITION_SCHEME 유니코드스키마👻#!#PARTITION_FUNCTION 유니코드스키마👻#!#PS#!#PARTITION_SCHEME#!#0#!#0 -PARTITION_SCHEME 😎$@ #123 🌍rder#!#PARTITION_FUNCTION 😎$@ #123 🌍rder#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEME 유니코드스키마👻 #!#PARTITION_FUNCTION 유니코드스키마👻 #!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEME 😎$@ #123 🌍rder #!#PARTITION_FUNCTION 😎$@ #123 🌍rder #!#PS#!#PARTITION_SCHEME#!#0#!#0 PARTITION_SCHEMEログインαιώνια#!#PARTITION_FUNCTIONログインαιώνια#!#PS#!#PARTITION_SCHEME#!#0#!#0 PartitionSchemeInsideProc1#!#PartitionFunctionInsideProc1#!#PS#!#PARTITION_SCHEME#!#0#!#0 PartitionSchemeInsideProc2#!#PartitionFunctionInsideProc2#!#PS#!#PARTITION_SCHEME#!#0#!#0 PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#PS#!#PARTITION_SCHEME#!#0#!#0 SmallDateTimePartitionScheme#!#SmallDateTimePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 SmallIntPartitionScheme#!#SmallIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +SmallMoneyPartitionScheme#!#SmallMoneyPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 SqlVariantPartitionScheme#!#SqlVariantPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 TinyIntPartitionScheme#!#TinyIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 UniqueIdentifierPartitionScheme#!#UniqueIdentifierPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 @@ -895,7 +963,12 @@ partition_u1 ~~END~~ + -- CREATE/DROP should throw permission error +------------------------------------------------------------ +--- only db owner and logins which are member of sysadmin +--- are allowed to create/drop partition function and scheme +------------------------------------------------------------ CREATE PARTITION FUNCTION TestPartitionFunction (int) AS RANGE RIGHT FOR VALUES (500, 1000, 10000); Go @@ -927,7 +1000,9 @@ go ~~ERROR (Message: Cannot drop the partition scheme 'IntPartitionScheme', because it does not exist or you do not have permission.)~~ --- but they can access the metadata +------------------------------------------ +--- all user can access the metadata +------------------------------------------ SELECT name, type, type_desc, fanout, boundary_value_on_right, is_system FROM @@ -952,7 +1027,68 @@ PartitionDb_PartitionScheme#!#PartitionDb_PartitionFunction#!#PS#!#PARTITION_SCH ~~END~~ + +-- psql + +------------------------------------------------------------ +--- all user can use the metadata of the partition scheme +--- to create table if they permission to create table +------------------------------------------------------------ +-- grant create permission to user on schema so that it can create table +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + EXECUTE 'GRANT CREATE ON SCHEMA ' || quote_ident(schema_name) || ' TO partitiondb_partition_u1'; +END$$; +GO + +-- tsql user=partition_l1 password=12345678 +USE PartitionDb; +GO + +SELECT CURRENT_USER +GO +~~START~~ +varchar +partition_u1 +~~END~~ + + +CREATE TABLE PartitionDb_TestPartitionTable ( + Id INT, + Value sys.varchar(20) +) ON PartitionDb_PartitionScheme(Id); +GO + +DROP TABLE PartitionDb_TestPartitionTable +GO + +-- psql + +-- revoke create permission from user on schema +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + EXECUTE 'REVOKE CREATE ON SCHEMA ' || quote_ident(schema_name) || ' FROM partitiondb_partition_u1'; +END$$; +GO + -- tsql +----------------------------------------------------------------------------------- +--- DB owner should be able to create/drop partition function and scheme +---------------------------------------------------------------------------------- -- make the user a DB owner USE PartitionDb; GO @@ -1115,13 +1251,1793 @@ GO -------------------------------------------------- ---- DROP PARTITION FUNCTION/SCHEME using procedure +--- DROP PARTITION FUNCTION/SCHEME/TABLE using procedure -------------------------------------------------- +EXEC PartitionProcedureDropPartitionTable +GO + EXEC PartitionProcedureDropPartitionScheme GO EXEC PartitionProcedureDropPartitionFunction GO -EXEC PartitionProcedureDropPartitionFunctionAndScheme +EXEC PartitionProcedureDropPartitionFunctionSchemeAndTable +GO + + +--------------------------------------------------------------------------- +--- PARTITIONED TABLES test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedTableListFromSysTablesView +GO +~~START~~ +varchar +partition_vu_prepare_bigint_table +partition_vu_prepare_binary_table +partition_vu_prepare_char_table +partition_vu_prepare_date_table +partition_vu_prepare_datetime_table +partition_vu_prepare_datetime2_table +partition_vu_prepare_decimal_table +partition_vu_prepare_int_table +partition_vu_prepare_money_table +partition_vu_prepare_nchar_table +partition_vu_prepare_numeric_table +partition_vu_prepare_nvarchar_table +partition_vu_prepare_smalldatetime_table +partition_vu_prepare_smallint_table +partition_vu_prepare_smallmoney_table +partition_vu_prepare_sqlvariant_table +partition_vu_prepare_tinyint_table +partition_vu_prepare_uniqueidentifier_table +partition_vu_prepare_varbinary_table +partition_vu_prepare_varchar_table +~~END~~ + + +--------------------------------------------------------------------------- +--- PARTITIONED INDEX test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedIndexListFromSysIndexesView +GO +~~START~~ +varchar +partition_vu_prepare_bigint_ind877afb285426cec9d46b047e3cf96f63 +partition_vu_prepare_binary_ind48a88b3c8178211af1ed1dcf4cfbe503 +partition_vu_prepare_char_index32fed8129381de1b5745e90cd811516f +partition_vu_prepare_date_indexf571a291edad587ba646fc34c4566844 +partition_vu_prepare_datetime_i364577d0a406eee6e806be980ac15d2e +partition_vu_prepare_datetime2_4cad7647322c234b34b97cddb3cd1ad6 +partition_vu_prepare_decimal_infc7570aeccbb040dde39974c476a7ec9 +partition_vu_prepare_int_indexpbbe9a6f0ef5edf6e63fa853dac4ed046 +partition_vu_prepare_int_table_id_key +partition_vu_prepare_money_inde9b6a61ad06c0883c6d0f95b2fec9eeee +partition_vu_prepare_nchar_indecdc4872501ea902494c8f710f4e9dbb1 +partition_vu_prepare_numeric_inf04f315c86929345e23bee80713cf963 +partition_vu_prepare_nvarchar_if89fa8cc46282fa6dc23e9f5b834f3ec +partition_vu_prepare_smalldatetfe8f8bfb8c766f9a1bcd804238ff35d8 +partition_vu_prepare_smallint_i3eae48e3a131ed23416aa2891b58d579 +partition_vu_prepare_smallmoney68389bf5dc5c581b33c4dbb8a3dc1dc8 +partition_vu_prepare_sqlvariant2cb9b179fd5df94b1777b1976b05ad47 +partition_vu_prepare_tinyint_in02b271c73e639954190c6a45bd5dd1bb +partition_vu_prepare_uniqueidend39220cd3f46c5b2cea8c338a387aedf +partition_vu_prepare_varbinary_26e1223f68c4186a96126a57446ac386 +partition_vu_prepare_varchar_inc528f397ba573964de161e03035b8f08 +~~END~~ + + + +---------------------------------------------------------------------------------------------- +--- System views should list only metadata of Partitioned table(not of the partitions) +---------------------------------------------------------------------------------------------- +SELECT count(*) from sys.tables where name = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +3 +~~END~~ + + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.all_objects where name = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from information_schema.columns where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.tables where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +--------------------------------------------------------- +--- System views should not list metadata of Partitions +--------------------------------------------------------- +SELECT count(*) from sys.tables where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.all_objects where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.columns where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.tables where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + + + +-- psql +--------------------------------------------------------------------------- +--- Run analyze on each table and enable query plan +--------------------------------------------------------------------------- +ANALYZE master_dbo.partition_vu_prepare_int_table; +ANALYZE master_dbo.partition_vu_prepare_bigint_table; +ANALYZE master_dbo.partition_vu_prepare_smallint_table; +ANALYZE master_dbo.partition_vu_prepare_tinyint_table; +ANALYZE master_dbo.partition_vu_prepare_decimal_table; +ANALYZE master_dbo.partition_vu_prepare_numeric_table; +ANALYZE master_dbo.partition_vu_prepare_money_table; +ANALYZE master_dbo.partition_vu_prepare_smallmoney_table; +ANALYZE master_dbo.partition_vu_prepare_date_table; +ANALYZE master_dbo.partition_vu_prepare_datetime_table; +ANALYZE master_dbo.partition_vu_prepare_datetime2_table; +ANALYZE master_dbo.partition_vu_prepare_smalldatetime_table; +ANALYZE master_dbo.partition_vu_prepare_char_table; +ANALYZE master_dbo.partition_vu_prepare_varchar_table; +ANALYZE master_dbo.partition_vu_prepare_nvarchar_table; +ANALYZE master_dbo.partition_vu_prepare_nchar_table; +ANALYZE master_dbo.partition_vu_prepare_binary_table; +ANALYZE master_dbo.partition_vu_prepare_varbinary_table; +ANALYZE master_dbo.partition_vu_prepare_uniqueidentifier_table; +ANALYZE master_dbo.partition_vu_prepare_sqlvariant_table; +GO + +-- tsql +SELECT set_config('babelfishpg_tsql.explain_costs', 'off', false) +GO +~~START~~ +text +off +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +--------------------------------------------------------------------------- +--- Query plan of select on partitioned tables +--------------------------------------------------------------------------- +SELECT * FROM partition_vu_prepare_int_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_int_table +Append + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_1" partition_vu_prepare_int_table_1 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_2" partition_vu_prepare_int_table_2 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_3" partition_vu_prepare_int_table_3 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_0" partition_vu_prepare_int_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.782 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_bigint_table; GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_bigint_table +Append + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_1" partition_vu_prepare_bigint_table_1 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_2" partition_vu_prepare_bigint_table_2 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_3" partition_vu_prepare_bigint_table_3 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_4" partition_vu_prepare_bigint_table_4 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_0" partition_vu_prepare_bigint_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.120 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallint_table +Append + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_1" partition_vu_prepare_smallint_table_1 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_2" partition_vu_prepare_smallint_table_2 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_3" partition_vu_prepare_smallint_table_3 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_0" partition_vu_prepare_smallint_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.131 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_tinyint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_tinyint_table +Append + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_1" partition_vu_prepare_tinyint_table_1 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_2" partition_vu_prepare_tinyint_table_2 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_3" partition_vu_prepare_tinyint_table_3 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_0" partition_vu_prepare_tinyint_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.120 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_decimal_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_decimal_table +Append + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_1 partition_vu_prepare_decimal_table_1 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_2 partition_vu_prepare_decimal_table_2 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_3 partition_vu_prepare_decimal_table_3 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_4 partition_vu_prepare_decimal_table_4 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_0 partition_vu_prepare_decimal_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.121 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_numeric_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_numeric_table +Append + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_1" partition_vu_prepare_numeric_table_1 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_2" partition_vu_prepare_numeric_table_2 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_3" partition_vu_prepare_numeric_table_3 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_4" partition_vu_prepare_numeric_table_4 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_0" partition_vu_prepare_numeric_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.088 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_money_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_money_table +Append + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_1" partition_vu_prepare_money_table_1 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_2" partition_vu_prepare_money_table_2 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_3" partition_vu_prepare_money_table_3 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_0" partition_vu_prepare_money_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.121 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallmoney_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallmoney_table +Append + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1" partition_vu_prepare_smallmoney_table_1 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_2" partition_vu_prepare_smallmoney_table_2 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_3" partition_vu_prepare_smallmoney_table_3 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0" partition_vu_prepare_smallmoney_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.101 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_date_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_date_table +Append + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_1" partition_vu_prepare_date_table_1 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_2" partition_vu_prepare_date_table_2 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_3" partition_vu_prepare_date_table_3 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_0" partition_vu_prepare_date_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.123 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime_table +Append + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_1" partition_vu_prepare_datetime_table_1 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_2" partition_vu_prepare_datetime_table_2 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_3" partition_vu_prepare_datetime_table_3 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_0" partition_vu_prepare_datetime_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.122 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime2_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime2_table +Append + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_1" partition_vu_prepare_datetime2_table_1 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_2" partition_vu_prepare_datetime2_table_2 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_3" partition_vu_prepare_datetime2_table_3 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_0" partition_vu_prepare_datetime2_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.091 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smalldatetime_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smalldatetime_table +Append + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_1 partition_vu_prepare_smalldatetime_table_1 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_2 partition_vu_prepare_smalldatetime_table_2 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_3 partition_vu_prepare_smalldatetime_table_3 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_0 partition_vu_prepare_smalldatetime_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.089 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_char_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_char_table +Append + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_1" partition_vu_prepare_char_table_1 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_2" partition_vu_prepare_char_table_2 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_3" partition_vu_prepare_char_table_3 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_4" partition_vu_prepare_char_table_4 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_5" partition_vu_prepare_char_table_5 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_6" partition_vu_prepare_char_table_6 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_7" partition_vu_prepare_char_table_7 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_0" partition_vu_prepare_char_table_8 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.124 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varchar_table +Append + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_1" partition_vu_prepare_varchar_table_1 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_2" partition_vu_prepare_varchar_table_2 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_3" partition_vu_prepare_varchar_table_3 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_4" partition_vu_prepare_varchar_table_4 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_5" partition_vu_prepare_varchar_table_5 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_0" partition_vu_prepare_varchar_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.107 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nvarchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nvarchar_table +Append + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_1" partition_vu_prepare_nvarchar_table_1 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_2" partition_vu_prepare_nvarchar_table_2 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_3" partition_vu_prepare_nvarchar_table_3 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_4" partition_vu_prepare_nvarchar_table_4 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_5" partition_vu_prepare_nvarchar_table_5 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_0" partition_vu_prepare_nvarchar_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.099 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nchar_table +Append + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_1 partition_vu_prepare_nchar_table_1 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_2 partition_vu_prepare_nchar_table_2 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_3 partition_vu_prepare_nchar_table_3 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_4 partition_vu_prepare_nchar_table_4 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_5 partition_vu_prepare_nchar_table_5 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_6 partition_vu_prepare_nchar_table_6 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_7 partition_vu_prepare_nchar_table_7 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_0 partition_vu_prepare_nchar_table_8 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.088 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_binary_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_binary_table +Append + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_1" partition_vu_prepare_binary_table_1 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_2" partition_vu_prepare_binary_table_2 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_3" partition_vu_prepare_binary_table_3 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_4" partition_vu_prepare_binary_table_4 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_0" partition_vu_prepare_binary_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varbinary_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varbinary_table +Append + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_1" partition_vu_prepare_varbinary_table_1 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_2" partition_vu_prepare_varbinary_table_2 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_3" partition_vu_prepare_varbinary_table_3 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_4" partition_vu_prepare_varbinary_table_4 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_0" partition_vu_prepare_varbinary_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_uniqueidentifier_table +Append + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_1 partition_vu_prepare_uniqueidentifier_table_1 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_2 partition_vu_prepare_uniqueidentifier_table_2 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_3 partition_vu_prepare_uniqueidentifier_table_3 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_0 partition_vu_prepare_uniqueidentifier_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.106 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_sqlvariant_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_sqlvariant_table +Append + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_1" partition_vu_prepare_sqlvariant_table_1 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_2" partition_vu_prepare_sqlvariant_table_2 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_3" partition_vu_prepare_sqlvariant_table_3 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_4" partition_vu_prepare_sqlvariant_table_4 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_5" partition_vu_prepare_sqlvariant_table_5 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_0" partition_vu_prepare_sqlvariant_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.142 ms +~~END~~ + + + +----------------------------------------------------------------------------------------- +--- Query plan of select on partitioned tables with predicate and enforced index scan +----------------------------------------------------------------------------------------- +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'off', false); +SELECT set_config('enable_bitmapscan', 'off', false); +GO +~~START~~ +text +off +~~END~~ + +~~START~~ +text +off +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500 +Index Scan using "363863941f079adaa9aa733200e57c9f_partition_1_id_key" on "363863941f079adaa9aa733200e57c9f_partition_1" partition_vu_prepare_int_table + Index Cond: ((id >= 0) AND (id < 500)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 34.743 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100 +Index Scan using "548bb344374ce8d65342b36428375873_partition_1_id_idx" on "548bb344374ce8d65342b36428375873_partition_1" partition_vu_prepare_bigint_table + Index Cond: ((id >= 0) AND (id < 100)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.201 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0 +Index Scan using "12025e103721b70925744c196ce004cd_partition_1_id_idx" on "12025e103721b70925744c196ce004cd_partition_1" partition_vu_prepare_smallint_table + Index Cond: ((id >= '-32768'::integer) AND (id < 0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 7.419 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128 +Index Scan using "61446d711d19b5970809387caa7fd3d3_partition_1_id_idx" on "61446d711d19b5970809387caa7fd3d3_partition_1" partition_vu_prepare_tinyint_table + Index Cond: (((id)::smallint >= 0) AND ((id)::smallint < 128)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.167 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0 +Index Scan using cda2902d769fd61eb60b1a461650212f_partition_1_id_idx on cda2902d769fd61eb60b1a461650212f_partition_1 partition_vu_prepare_decimal_table + Index Cond: (((id)::numeric >= 0.0) AND ((id)::numeric < 100.0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.571 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0 +Index Scan using "57405760297bb338f333c148aac5f845_partition_1_id_idx" on "57405760297bb338f333c148aac5f845_partition_1" partition_vu_prepare_numeric_table + Index Cond: ((id >= 0.0) AND (id < 10.0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.237 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789 +Append + -> Index Scan using "640187c54e2c2984d190957d245a5fa5_partition_1_id_idx" on "640187c54e2c2984d190957d245a5fa5_partition_1" partition_vu_prepare_money_table_1 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) + -> Index Scan using "640187c54e2c2984d190957d245a5fa5_partition_0_id_idx" on "640187c54e2c2984d190957d245a5fa5_partition_0" partition_vu_prepare_money_table_2 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.223 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789 +Append + -> Index Scan using "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1_id_idx" on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1" partition_vu_prepare_smallmoney_table_1 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) + -> Index Scan using "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0_id_idx" on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0" partition_vu_prepare_smallmoney_table_2 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.154 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01' +Index Scan using "4867824426e52acac5c93d9cbe8aa366_partition_1_id_idx" on "4867824426e52acac5c93d9cbe8aa366_partition_1" partition_vu_prepare_date_table + Index Cond: ((id >= '2022-01-01'::date) AND (id < '2022-07-01'::date)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.603 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Index Scan using "751ce655481adf15600727bf291667f7_partition_1_id_idx" on "751ce655481adf15600727bf291667f7_partition_1" partition_vu_prepare_datetime_table + Index Cond: ((id >= '2019-01-01 00:00:00'::datetime) AND (id < '2022-01-01 00:00:00'::datetime)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.184 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Index Scan using "5ed003cf80dacbb8cce0b21e175f7f94_partition_1_id_idx" on "5ed003cf80dacbb8cce0b21e175f7f94_partition_1" partition_vu_prepare_datetime2_table + Index Cond: ((id >= '2019-01-01 00:00:00'::datetime2) AND (id < '2022-01-01 00:00:00'::datetime2)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.159 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Index Scan using b5c2e665ec4a1219ba8510e33e45379b_partition_1_id_idx on b5c2e665ec4a1219ba8510e33e45379b_partition_1 partition_vu_prepare_smalldatetime_table + Index Cond: ((id >= '2019-01-01 00:00:00'::smalldatetime) AND (id < '2022-01-01 00:00:00'::smalldatetime)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.226 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B' +Index Scan using "5d20bd977eb6e6f1304dec45598c09f5_partition_1_id_idx" on "5d20bd977eb6e6f1304dec45598c09f5_partition_1" partition_vu_prepare_char_table + Index Cond: ((id >= 'A'::bpchar) AND (id < 'B'::bpchar)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.241 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana' +Index Scan using "933a5c7f0de13890324e53ee0711424b_partition_1_id_idx" on "933a5c7f0de13890324e53ee0711424b_partition_1" partition_vu_prepare_varchar_table + Index Cond: ((id >= 'Apple'::"varchar") AND (id < 'Banana'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.170 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana' +Index Scan using "320465af1d1bd21f5b29c57f9f4e5c51_partition_1_id_idx" on "320465af1d1bd21f5b29c57f9f4e5c51_partition_1" partition_vu_prepare_nvarchar_table + Index Cond: (((id)::"varchar" >= 'Apple'::"varchar") AND ((id)::"varchar" < 'Banana'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.161 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B' +Gather + Workers Planned: 2 + -> Parallel Append + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_3 partition_vu_prepare_nchar_table_3 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_5 partition_vu_prepare_nchar_table_5 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_7 partition_vu_prepare_nchar_table_7 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_1 partition_vu_prepare_nchar_table_1 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_2 partition_vu_prepare_nchar_table_2 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_4 partition_vu_prepare_nchar_table_4 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_6 partition_vu_prepare_nchar_table_6 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_0 partition_vu_prepare_nchar_table_8 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.159 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400 +Gather + Workers Planned: 2 + -> Parallel Append + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_1" partition_vu_prepare_binary_table_1 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_2" partition_vu_prepare_binary_table_2 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_3" partition_vu_prepare_binary_table_3 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_4" partition_vu_prepare_binary_table_4 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_0" partition_vu_prepare_binary_table_5 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.824 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000 +Index Scan using "77718961234110c3a22a3c977bc252d8_partition_1_id_idx" on "77718961234110c3a22a3c977bc252d8_partition_1" partition_vu_prepare_varbinary_table + Index Cond: (((id)::bbf_varbinary >= '0x0000000000000000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x4000000000000000'::bbf_varbinary)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.166 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF' +Index Scan using f3baf999c06d6ea82082a4c549baeb77_partition_1_id_idx on f3baf999c06d6ea82082a4c549baeb77_partition_1 partition_vu_prepare_uniqueidentifier_table + Index Cond: ((id >= '00000000-0000-0000-0000-000000000000'::uniqueidentifier) AND (id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'::uniqueidentifier)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.188 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)); +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)) +Index Scan using "69727aecbd7d094d31958d173a958827_partition_1_id_idx" on "69727aecbd7d094d31958d173a958827_partition_1" partition_vu_prepare_sqlvariant_table + Index Cond: ((id >= 'abc '::sql_variant) AND (id < 'Apple'::sql_variant)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 7.191 ms +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'on', false); +SELECT set_config('enable_bitmapscan', 'on', false); +SELECT set_config('babelfishpg_tsql.explain_costs', 'on', false) +GO +~~START~~ +text +on +~~END~~ + +~~START~~ +text +on +~~END~~ + +~~START~~ +text +on +~~END~~ + + + + +-- psql +------------------------------------------ +--- Blocked Operation For Partitioned Tables +------------------------------------------- +-- user should not be allowed to CREATE/ATTACH/DETACH partition +-- to babelfish partitioned table from psql endpoint +SET ROLE master_dbo; +GO + +-- Attempt to create new partition with random values +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +FOR VALUES FROM (0) TO (500); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: partition "nonexistenttable" would overlap partition "363863941f079adaa9aa733200e57c9f_partition_1" + Position: 157 + Server SQLState: 42P17)~~ + + +-- Attempt to create new partition with DEFAULT +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +DEFAULT +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: partition "nonexistenttable" conflicts with existing default partition "363863941f079adaa9aa733200e57c9f_partition_0" + Position: 134 + Server SQLState: 42P17)~~ + + +-- Attempt to drop partition of babelfish partitioned table from psql endpoint +DROP TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot drop the babelfish partition table '363863941f079adaa9aa733200e57c9f_partition_0'. + Server SQLState: 42704)~~ + + + +-- Attempt to detach +-- explicit schema name specified +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +RESET search_path; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to detach using CONCURRENTLY option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +CONCURRENTLY; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to detach using FINALIZE option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +FINALIZE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to attach with Default value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable DEFAULT; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot attach partition to babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to attach with random value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable FOR VALUES FROM (10) TO (20); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot attach partition to babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + + +-- user should not be allowed to modify partition +-- of babelfish partitioned table neither from psql nor tsql endpoint +-- explicit schema name specified +ALTER TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table. + Server SQLState: 0A000)~~ + + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE "363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +RESET search_path; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table. + Server SQLState: 0A000)~~ + + +RESET ROLE; +GO + +-- Attempt to ADD storage parameter to babelfish partitioned table (not on the partitions) +SET babelfishpg_tsql.sql_dialect = "tsql"; +GO + +ALTER TABLE master_dbo.partition_vu_prepare_int_table SET (autovacuum_enabled = false); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: cannot specify storage parameters for a partitioned table + Hint: Specify storage parameters for its leaf partitions instead. + Server SQLState: 42809)~~ + + +RESET babelfishpg_tsql.sql_dialect; +GO + + +-- tsql +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + + +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +-- with explicity schema name +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +-- Attempt to drop partition of babelfish partitioned table from tsql endpoint +DROP TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the babelfish partition table '363863941f079adaa9aa733200e57c9f_partition_0'.)~~ + + +-------------------------------------------------------------------- +--- Unsupported Option with CREATE TABLE with PARTITION SCHEME +-------------------------------------------------------------------- +-- Computed column as partitioning column is not yet supported in babelfish +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value +) +ON IntPartitionScheme(computed_col); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot use generated column in partition key)~~ + + +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value PERSISTED +) +ON IntPartitionScheme(computed_col); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot use generated column in partition key)~~ + + +-- temporary table +CREATE TABLE #TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Creation of tempopary partitioned tables is not supported in Babelfish.)~~ + + + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--------------------------------------------------------------- +-- Attempt to create with multiple columns as partitioning scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id, value); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ',' at line 10 and character position 24)~~ + + +-- Attempt to create with a partition scheme that doesn't exist and column that doesn't exist in the table +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(NonExistentColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "nonexistentcolumn" named in partition key does not exist)~~ + + +-- Attempt to create with a partition scheme that doesn't exist +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid partition scheme 'NonExistentPartitionScheme' specifed.)~~ + + +-- Attempt to use two part name with partition scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON master.IntPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '.' at line 7 and character position 9)~~ + + +-- Attempt to create with a unique constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT UNIQUE +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: unique constraint on partitioned table must include all partitioning columns)~~ + + +-- Attempt to create with a primary key constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT PRIMARY KEY +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: unique constraint on partitioned table must include all partitioning columns)~~ + + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--- Attempt to create with an incompatible partition column data type +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable1 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'IntPartitionFunction' parameter data type 'int'.)~~ + + +CREATE TABLE TestPartitionedTable2 +( + Id INT, + PartitionColumn DATETIME +) +ON DatePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime' which is different from the partition function 'DatePartitionFunction' parameter data type 'date'.)~~ + + +CREATE TABLE TestPartitionedTable3 +( + Id INT, + PartitionColumn VARCHAR(10) +) +ON CharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'varchar' which is different from the partition function 'CharPartitionFunction' parameter data type 'char'.)~~ + + +CREATE TABLE TestPartitionedTable4 +( + Id INT, + PartitionColumn VARBINARY(10) +) +ON BinaryPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'varbinary' which is different from the partition function 'BinaryPartitionFunction' parameter data type 'binary'.)~~ + + +CREATE TABLE TestPartitionedTable5 +( + Id INT, + PartitionColumn SMALLINT +) +ON BigIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int2' which is different from the partition function 'BigIntPartitionFunction' parameter data type 'bigint'.)~~ + + +CREATE TABLE TestPartitionedTable6 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON SmallIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'SmallIntPartitionFunction' parameter data type 'smallint'.)~~ + + +CREATE TABLE TestPartitionedTable7 +( + Id INT, + PartitionColumn DECIMAL(10, 5) +) +ON TinyIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'TinyIntPartitionFunction' parameter data type 'tinyint'.)~~ + + +CREATE TABLE TestPartitionedTable8 +( + Id INT, + PartitionColumn BIGINT +) +ON DecimalPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int8' which is different from the partition function 'DecimalPartitionFunction' parameter data type 'decimal'.)~~ + + +CREATE TABLE TestPartitionedTable9 +( + Id INT, + PartitionColumn MONEY +) +ON NumericPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'money' which is different from the partition function 'NumericPartitionFunction' parameter data type 'numeric'.)~~ + + +CREATE TABLE TestPartitionedTable10 +( + Id INT, + PartitionColumn INT +) +ON MoneyPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'MoneyPartitionFunction' parameter data type 'money'.)~~ + + +CREATE TABLE TestPartitionedTable11 +( + Id INT, + PartitionColumn DATETIME +) +ON SmallMoneyPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime' which is different from the partition function 'SmallMoneyPartitionFunction' parameter data type 'smallmoney'.)~~ + + +CREATE TABLE TestPartitionedTable12 +( + Id INT, + PartitionColumn DATETIME2(3) +) +ON DateTimePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime2' which is different from the partition function 'DateTimePartitionFunction' parameter data type 'datetime'.)~~ + + +CREATE TABLE TestPartitionedTable13 +( + Id INT, + PartitionColumn SMALLDATETIME +) +ON DateTime2PartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'smalldatetime' which is different from the partition function 'DateTime2PartitionFunction' parameter data type 'datetime2'.)~~ + + +CREATE TABLE TestPartitionedTable14 +( + Id INT, + PartitionColumn NVARCHAR(10) +) +ON SmallDateTimePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'nvarchar' which is different from the partition function 'SmallDateTimePartitionFunction' parameter data type 'smalldatetime'.)~~ + + +CREATE TABLE TestPartitionedTable15 +( + Id INT, + PartitionColumn INT +) +ON NVarCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'NVarCharPartitionFunction' parameter data type 'nvarchar'.)~~ + + +CREATE TABLE TestPartitionedTable16 +( + Id INT, + PartitionColumn NCHAR(5) +) +ON VarCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'nchar' which is different from the partition function 'VarCharPartitionFunction' parameter data type 'varchar'.)~~ + + +CREATE TABLE TestPartitionedTable17 +( + Id INT, + PartitionColumn INT +) +ON NCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'NCharPartitionFunction' parameter data type 'nchar'.)~~ + + +-- using user defined type +CREATE TYPE PartitionUserDefinedType FROM SMALLINT; +GO + +CREATE TABLE TestPartitionedTable18 +( + Id INT, + PartitionColumn PartitionUserDefinedType +) +ON BigIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'partitionuserdefinedtype' which is different from the partition function 'BigIntPartitionFunction' parameter data type 'bigint'.)~~ + + +DROP TYPE PartitionUserDefinedType +GO + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE Index with PARTITION SCHEME +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable ( + PartitionColumn INT, + NonPartitionColumn INT +) ON IntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestNonPartitionedTable ( + a INT, + b INT +) +GO + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonExistentColumn1) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "nonexistentcolumn1" does not exist)~~ + + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column 'nonexistentcolumn2' does not exist)~~ + + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid object name 'NonExistentPartitionScheme'.)~~ + + +-- scheme is different from the partition scheme used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON BigIntPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + +-- column specified with partition scheme is different +-- from the partition column used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + +-- should work +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (PartitionColumn); +GO + +DROP INDEX TestPartitionIndex ON TestPartitionedTable +GO + +-- usage of partition scheme on non-partitioned table (should fail) +CREATE INDEX TestPartitionIndex +ON TestNonPartitionedTable(a) +ON IntPartitionScheme (a); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + + +DROP TABLE TestPartitionedTable +GO + +DROP TABLE TestNonPartitionedTable +GO +-- psql +------------------------------------------------------------------------------------------- +--- Rename Operation on Partitioned Tables should update name in babelfish_partition_depend +--- and it should also update the name of all the partitions +------------------------------------------------------------------------------------------- +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO +~~START~~ +regclass +master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_1" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_2" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_3" +~~END~~ + + +-- tsql +-- trigger rename from TSQL endpoint +EXEC sp_rename 'partition_vu_prepare_int_table', 'partition_vu_prepare_int_table_renamed', 'OBJECT' +GO + +-- psql +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table_renamed'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table_renamed +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table_renamed')::regclass; +GO +~~START~~ +regclass +master_dbo.c2647401dc3e9a950809daafcd188637_partition_0 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_1 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_2 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_3 +~~END~~ + + +-- trigger rename from PSQL endpoint +ALTER TABLE master_dbo.partition_vu_prepare_int_table_renamed RENAME TO partition_vu_prepare_int_table; +GO + +-- we should get orginal here +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO +~~START~~ +regclass +master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_1" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_2" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_3" +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out index 51e9ee644dc..fff275f7879 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out @@ -437,13 +437,6 @@ ignore -- escape hatch: storage_on_partition. -- 'strict' is default -CREATE TABLE t_unsupported_sop1(a int) ON partition(a); -GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: 'partition scheme' is not currently supported in Babelfish. please use babelfishpg_tsql.escape_hatch_storage_on_partition to ignore)~~ - - CREATE TABLE t_unsupported_sop2(a int) FILESTREAM_ON partition(a); GO ~~ERROR (Code: 33557097)~~ @@ -459,11 +452,6 @@ ignore ~~END~~ -CREATE TABLE t_unsupported_sop1(a int) ON partition(a); -GO -DROP TABLE t_unsupported_sop1; -GO - CREATE TABLE t_unsupported_sop2(a int) FILESTREAM_ON partition(a); GO DROP TABLE t_unsupported_sop2 diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/PARTITION-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/PARTITION-vu-verify.out index f163e2637fa..312d2dea65d 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/PARTITION-vu-verify.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/PARTITION-vu-verify.out @@ -1,5 +1,6 @@ + -------------------------------------------------- ---- CREATE PARTITION FUNCTION/SCHEME using procedure +--- CREATE PARTITION FUNCTION/SCHEME/TABLE using procedure -------------------------------------------------- EXEC PartitionProcedureCreatePartitionFunction GO @@ -7,11 +8,14 @@ GO EXEC PartitionProcedureCreatePartitionScheme GO -EXEC PartitionProcedureCreatePartitionFunctionAndScheme +EXEC PartitionProcedureCreatePartitionTable +GO + +EXEC PartitionProcedureCreatePartitionFunctionSchemeAndTable GO -------------------------------------------------- ---- CREATE PARTITION FUNCTION/SCHEME inside Function +--- CREATE PARTITION FUNCTION/SCHEME/TABLE inside Function -------------------------------------------------- CREATE FUNCTION TestFunctionCreatePartitionFunction() RETURNS INT @@ -68,6 +72,34 @@ GO ~~ERROR (Message: Invalid use of a side-effecting operator 'DROP PARTITION SCHEME' within a function.)~~ +CREATE FUNCTION TestFunctionCreatePartitionTable() +RETURNS INT +AS +BEGIN + CREATE TABLE TestPartitionTable ( + Id INT, + Value sys.varchar(20) + ) ON IntPartitionScheme(Id); +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: DDL cannot be used within a function)~~ + + +CREATE FUNCTION TestFunctionDropPartitionTable() +RETURNS INT +AS +BEGIN + DROP TABLE partition_vu_prepare_int_table; + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: DDL cannot be used within a function)~~ + + --------------------------------------------------------- --- CREATE PARTITION FUNCTION/SCHEME using 2-part name @@ -398,6 +430,23 @@ GO ~~ERROR (Message: 'PARTIION FUNCTION with LEFT option' is not currently supported in Babelfish)~~ +-- NULL value is not supported in range values +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NULL values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL, NULL); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NULL values are not allowed in partition function boundary values list.)~~ + + -------------------------------------------------- --- Duplicate Create of Partition Function/Scheme -------------------------------------------------- @@ -476,6 +525,16 @@ GO ~~ERROR (Message: Partition function 'IntPartitionFunction' is being used by one or more partition schemes.)~~ +----------------------------------------------------------------------------------- +--- Drop of of Partition Scheme when there is dependent Table on it +----------------------------------------------------------------------------------- +DROP PARTITION SCHEME IntPartitionScheme +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The partition scheme "IntPartitionScheme" is currently being used to partition one or more tables.)~~ + + ----------------------------------------------- @@ -558,13 +617,14 @@ MoneyPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 NCharPartitionFunction#!#R #!#RANGE#!#8#!#1#!#0 NumericPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 NVarCharPartitionFunction#!#R #!#RANGE#!#6#!#1#!#0 -PARTITION_FUNCTION 유니코드스키마👻#!#R #!#RANGE#!#4#!#1#!#0 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#R #!#RANGE#!#4#!#1#!#0 +PARTITION_FUNCTION 유니코드스키마👻 #!#R #!#RANGE#!#4#!#1#!#0 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#R #!#RANGE#!#4#!#1#!#0 PARTITION_FUNCTIONログインαιώνια#!#R #!#RANGE#!#4#!#1#!#0 PartitionFunctionHavingDifferentCollationInput#!#R #!#RANGE#!#5#!#1#!#0 PartitionFunctionInsideProc1#!#R #!#RANGE#!#4#!#1#!#0 PartitionFunctionInsideProc2#!#R #!#RANGE#!#4#!#1#!#0 PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#R #!#RANGE#!#5#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#R #!#RANGE#!#5#!#1#!#0 SmallDateTimePartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 SmallIntPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 SmallMoneyPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 @@ -626,12 +686,12 @@ NVarCharPartitionFunction#!#1#!#2#!#Banana NVarCharPartitionFunction#!#1#!#3#!#Cherry NVarCharPartitionFunction#!#1#!#4#!#Date NVarCharPartitionFunction#!#1#!#5#!#Mango -PARTITION_FUNCTION 유니코드스키마👻#!#1#!#1#!#0 -PARTITION_FUNCTION 유니코드스키마👻#!#1#!#2#!#500 -PARTITION_FUNCTION 유니코드스키마👻#!#1#!#3#!#1000 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#1#!#1#!#0 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#1#!#2#!#500 -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#1#!#3#!#1000 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#1#!#0 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#2#!#500 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#3#!#1000 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#1#!#0 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#2#!#500 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#3#!#1000 PARTITION_FUNCTIONログインαιώνια#!#1#!#1#!#0 PARTITION_FUNCTIONログインαιώνια#!#1#!#2#!#500 PARTITION_FUNCTIONログインαιώνια#!#1#!#3#!#1000 @@ -649,6 +709,10 @@ PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#! PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#2#!#100 PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#3#!#1000 PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#4#!#10000 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#2#!#100 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#3#!#1000 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#4#!#10000 SmallDateTimePartitionFunction#!#1#!#1#!#2019-01-01 00:00:00.0 SmallDateTimePartitionFunction#!#1#!#2#!#2022-01-01 00:00:00.0 SmallDateTimePartitionFunction#!#1#!#3#!#2022-07-01 00:00:00.0 @@ -708,13 +772,14 @@ MoneyPartitionFunction#!#money#!#1#!#8#!#19#!#4#!# NCharPartitionFunction#!#nchar#!#1#!#8000#!#0#!#0#!#chinese_prc_ci_as NumericPartitionFunction#!#numeric#!#1#!#17#!#38#!#38#!# NVarCharPartitionFunction#!#nvarchar#!#1#!#8000#!#0#!#0#!#chinese_prc_ci_as -PARTITION_FUNCTION 유니코드스키마👻#!#int#!#1#!#4#!#10#!#0#!# -PARTITION_FUNCTION 😎$@ #123 🌍rder#!#int#!#1#!#4#!#10#!#0#!# +PARTITION_FUNCTION 유니코드스키마👻 #!#int#!#1#!#4#!#10#!#0#!# +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#int#!#1#!#4#!#10#!#0#!# PARTITION_FUNCTIONログインαιώνια#!#int#!#1#!#4#!#10#!#0#!# PartitionFunctionHavingDifferentCollationInput#!#nvarchar#!#1#!#8000#!#0#!#0#!#chinese_prc_ci_as PartitionFunctionInsideProc1#!#int#!#1#!#4#!#10#!#0#!# PartitionFunctionInsideProc2#!#int#!#1#!#4#!#10#!#0#!# PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#bigint#!#1#!#8#!#19#!#0#!# +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#bigint#!#1#!#8#!#19#!#0#!# SmallDateTimePartitionFunction#!#smalldatetime#!#1#!#4#!#16#!#0#!# SmallIntPartitionFunction#!#smallint#!#1#!#2#!#5#!#0#!# SmallMoneyPartitionFunction#!#smallmoney#!#1#!#4#!#10#!#4#!# @@ -738,17 +803,20 @@ DateTime2PartitionScheme#!#DateTime2PartitionFunction#!#PS#!#PARTITION_SCHEME#!# DateTimePartitionScheme#!#DateTimePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 DecimalPartitionScheme#!#DecimalPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 IntPartitionScheme#!#IntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +MoneyPartitionScheme#!#MoneyPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 NCharPartitionScheme#!#NCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 NumericPartitionScheme#!#NumericPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 NVarCharPartitionScheme#!#NVarCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 -PARTITION_SCHEME 유니코드스키마👻#!#PARTITION_FUNCTION 유니코드스키마👻#!#PS#!#PARTITION_SCHEME#!#0#!#0 -PARTITION_SCHEME 😎$@ #123 🌍rder#!#PARTITION_FUNCTION 😎$@ #123 🌍rder#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEME 유니코드스키마👻 #!#PARTITION_FUNCTION 유니코드스키마👻 #!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEME 😎$@ #123 🌍rder #!#PARTITION_FUNCTION 😎$@ #123 🌍rder #!#PS#!#PARTITION_SCHEME#!#0#!#0 PARTITION_SCHEMEログインαιώνια#!#PARTITION_FUNCTIONログインαιώνια#!#PS#!#PARTITION_SCHEME#!#0#!#0 PartitionSchemeInsideProc1#!#PartitionFunctionInsideProc1#!#PS#!#PARTITION_SCHEME#!#0#!#0 PartitionSchemeInsideProc2#!#PartitionFunctionInsideProc2#!#PS#!#PARTITION_SCHEME#!#0#!#0 PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#PS#!#PARTITION_SCHEME#!#0#!#0 SmallDateTimePartitionScheme#!#SmallDateTimePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 SmallIntPartitionScheme#!#SmallIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +SmallMoneyPartitionScheme#!#SmallMoneyPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 SqlVariantPartitionScheme#!#SqlVariantPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 TinyIntPartitionScheme#!#TinyIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 UniqueIdentifierPartitionScheme#!#UniqueIdentifierPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 @@ -895,7 +963,12 @@ partition_u1 ~~END~~ + -- CREATE/DROP should throw permission error +------------------------------------------------------------ +--- only db owner and logins which are member of sysadmin +--- are allowed to create/drop partition function and scheme +------------------------------------------------------------ CREATE PARTITION FUNCTION TestPartitionFunction (int) AS RANGE RIGHT FOR VALUES (500, 1000, 10000); Go @@ -927,7 +1000,9 @@ go ~~ERROR (Message: Cannot drop the partition scheme 'IntPartitionScheme', because it does not exist or you do not have permission.)~~ --- but they can access the metadata +------------------------------------------ +--- all user can access the metadata +------------------------------------------ SELECT name, type, type_desc, fanout, boundary_value_on_right, is_system FROM @@ -952,7 +1027,68 @@ PartitionDb_PartitionScheme#!#PartitionDb_PartitionFunction#!#PS#!#PARTITION_SCH ~~END~~ + +-- psql + +------------------------------------------------------------ +--- all user can use the metadata of the partition scheme +--- to create table if they permission to create table +------------------------------------------------------------ +-- grant create permission to user on schema so that it can create table +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + EXECUTE 'GRANT CREATE ON SCHEMA ' || quote_ident(schema_name) || ' TO partitiondb_partition_u1'; +END$$; +GO + +-- tsql user=partition_l1 password=12345678 +USE PartitionDb; +GO + +SELECT CURRENT_USER +GO +~~START~~ +varchar +partition_u1 +~~END~~ + + +CREATE TABLE PartitionDb_TestPartitionTable ( + Id INT, + Value sys.varchar(20) +) ON PartitionDb_PartitionScheme(Id); +GO + +DROP TABLE PartitionDb_TestPartitionTable +GO + +-- psql + +-- revoke create permission from user on schema +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + EXECUTE 'REVOKE CREATE ON SCHEMA ' || quote_ident(schema_name) || ' FROM partitiondb_partition_u1'; +END$$; +GO + -- tsql +----------------------------------------------------------------------------------- +--- DB owner should be able to create/drop partition function and scheme +---------------------------------------------------------------------------------- -- make the user a DB owner USE PartitionDb; GO @@ -1115,13 +1251,1793 @@ GO -------------------------------------------------- ---- DROP PARTITION FUNCTION/SCHEME using procedure +--- DROP PARTITION FUNCTION/SCHEME/TABLE using procedure -------------------------------------------------- +EXEC PartitionProcedureDropPartitionTable +GO + EXEC PartitionProcedureDropPartitionScheme GO EXEC PartitionProcedureDropPartitionFunction GO -EXEC PartitionProcedureDropPartitionFunctionAndScheme +EXEC PartitionProcedureDropPartitionFunctionSchemeAndTable +GO + + +--------------------------------------------------------------------------- +--- PARTITIONED TABLES test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedTableListFromSysTablesView +GO +~~START~~ +varchar +partition_vu_prepare_bigint_table +partition_vu_prepare_binary_table +partition_vu_prepare_char_table +partition_vu_prepare_date_table +partition_vu_prepare_datetime_table +partition_vu_prepare_datetime2_table +partition_vu_prepare_decimal_table +partition_vu_prepare_int_table +partition_vu_prepare_money_table +partition_vu_prepare_nchar_table +partition_vu_prepare_numeric_table +partition_vu_prepare_nvarchar_table +partition_vu_prepare_smalldatetime_table +partition_vu_prepare_smallint_table +partition_vu_prepare_smallmoney_table +partition_vu_prepare_sqlvariant_table +partition_vu_prepare_tinyint_table +partition_vu_prepare_uniqueidentifier_table +partition_vu_prepare_varbinary_table +partition_vu_prepare_varchar_table +~~END~~ + + +--------------------------------------------------------------------------- +--- PARTITIONED INDEX test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedIndexListFromSysIndexesView +GO +~~START~~ +varchar +partition_vu_prepare_bigint_ind877afb285426cec9d46b047e3cf96f63 +partition_vu_prepare_binary_ind48a88b3c8178211af1ed1dcf4cfbe503 +partition_vu_prepare_char_index32fed8129381de1b5745e90cd811516f +partition_vu_prepare_date_indexf571a291edad587ba646fc34c4566844 +partition_vu_prepare_datetime_i364577d0a406eee6e806be980ac15d2e +partition_vu_prepare_datetime2_4cad7647322c234b34b97cddb3cd1ad6 +partition_vu_prepare_decimal_infc7570aeccbb040dde39974c476a7ec9 +partition_vu_prepare_int_indexpbbe9a6f0ef5edf6e63fa853dac4ed046 +partition_vu_prepare_int_table_id_key +partition_vu_prepare_money_inde9b6a61ad06c0883c6d0f95b2fec9eeee +partition_vu_prepare_nchar_indecdc4872501ea902494c8f710f4e9dbb1 +partition_vu_prepare_numeric_inf04f315c86929345e23bee80713cf963 +partition_vu_prepare_nvarchar_if89fa8cc46282fa6dc23e9f5b834f3ec +partition_vu_prepare_smalldatetfe8f8bfb8c766f9a1bcd804238ff35d8 +partition_vu_prepare_smallint_i3eae48e3a131ed23416aa2891b58d579 +partition_vu_prepare_smallmoney68389bf5dc5c581b33c4dbb8a3dc1dc8 +partition_vu_prepare_sqlvariant2cb9b179fd5df94b1777b1976b05ad47 +partition_vu_prepare_tinyint_in02b271c73e639954190c6a45bd5dd1bb +partition_vu_prepare_uniqueidend39220cd3f46c5b2cea8c338a387aedf +partition_vu_prepare_varbinary_26e1223f68c4186a96126a57446ac386 +partition_vu_prepare_varchar_inc528f397ba573964de161e03035b8f08 +~~END~~ + + + +---------------------------------------------------------------------------------------------- +--- System views should list only metadata of Partitioned table(not of the partitions) +---------------------------------------------------------------------------------------------- +SELECT count(*) from sys.tables where name = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +3 +~~END~~ + + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.all_objects where name = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from information_schema.columns where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.tables where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +--------------------------------------------------------- +--- System views should not list metadata of Partitions +--------------------------------------------------------- +SELECT count(*) from sys.tables where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.all_objects where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.columns where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.tables where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + + + +-- psql +--------------------------------------------------------------------------- +--- Run analyze on each table and enable query plan +--------------------------------------------------------------------------- +ANALYZE master_dbo.partition_vu_prepare_int_table; +ANALYZE master_dbo.partition_vu_prepare_bigint_table; +ANALYZE master_dbo.partition_vu_prepare_smallint_table; +ANALYZE master_dbo.partition_vu_prepare_tinyint_table; +ANALYZE master_dbo.partition_vu_prepare_decimal_table; +ANALYZE master_dbo.partition_vu_prepare_numeric_table; +ANALYZE master_dbo.partition_vu_prepare_money_table; +ANALYZE master_dbo.partition_vu_prepare_smallmoney_table; +ANALYZE master_dbo.partition_vu_prepare_date_table; +ANALYZE master_dbo.partition_vu_prepare_datetime_table; +ANALYZE master_dbo.partition_vu_prepare_datetime2_table; +ANALYZE master_dbo.partition_vu_prepare_smalldatetime_table; +ANALYZE master_dbo.partition_vu_prepare_char_table; +ANALYZE master_dbo.partition_vu_prepare_varchar_table; +ANALYZE master_dbo.partition_vu_prepare_nvarchar_table; +ANALYZE master_dbo.partition_vu_prepare_nchar_table; +ANALYZE master_dbo.partition_vu_prepare_binary_table; +ANALYZE master_dbo.partition_vu_prepare_varbinary_table; +ANALYZE master_dbo.partition_vu_prepare_uniqueidentifier_table; +ANALYZE master_dbo.partition_vu_prepare_sqlvariant_table; +GO + +-- tsql +SELECT set_config('babelfishpg_tsql.explain_costs', 'off', false) +GO +~~START~~ +text +off +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +--------------------------------------------------------------------------- +--- Query plan of select on partitioned tables +--------------------------------------------------------------------------- +SELECT * FROM partition_vu_prepare_int_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_int_table +Append + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_1" partition_vu_prepare_int_table_1 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_2" partition_vu_prepare_int_table_2 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_3" partition_vu_prepare_int_table_3 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_0" partition_vu_prepare_int_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.782 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_bigint_table; GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_bigint_table +Append + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_1" partition_vu_prepare_bigint_table_1 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_2" partition_vu_prepare_bigint_table_2 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_3" partition_vu_prepare_bigint_table_3 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_4" partition_vu_prepare_bigint_table_4 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_0" partition_vu_prepare_bigint_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.120 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallint_table +Append + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_1" partition_vu_prepare_smallint_table_1 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_2" partition_vu_prepare_smallint_table_2 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_3" partition_vu_prepare_smallint_table_3 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_0" partition_vu_prepare_smallint_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.131 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_tinyint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_tinyint_table +Append + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_1" partition_vu_prepare_tinyint_table_1 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_2" partition_vu_prepare_tinyint_table_2 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_3" partition_vu_prepare_tinyint_table_3 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_0" partition_vu_prepare_tinyint_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.120 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_decimal_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_decimal_table +Append + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_1 partition_vu_prepare_decimal_table_1 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_2 partition_vu_prepare_decimal_table_2 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_3 partition_vu_prepare_decimal_table_3 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_4 partition_vu_prepare_decimal_table_4 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_0 partition_vu_prepare_decimal_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.121 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_numeric_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_numeric_table +Append + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_1" partition_vu_prepare_numeric_table_1 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_2" partition_vu_prepare_numeric_table_2 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_3" partition_vu_prepare_numeric_table_3 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_4" partition_vu_prepare_numeric_table_4 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_0" partition_vu_prepare_numeric_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.088 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_money_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_money_table +Append + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_1" partition_vu_prepare_money_table_1 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_2" partition_vu_prepare_money_table_2 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_3" partition_vu_prepare_money_table_3 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_0" partition_vu_prepare_money_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.121 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallmoney_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallmoney_table +Append + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1" partition_vu_prepare_smallmoney_table_1 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_2" partition_vu_prepare_smallmoney_table_2 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_3" partition_vu_prepare_smallmoney_table_3 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0" partition_vu_prepare_smallmoney_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.101 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_date_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_date_table +Append + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_1" partition_vu_prepare_date_table_1 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_2" partition_vu_prepare_date_table_2 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_3" partition_vu_prepare_date_table_3 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_0" partition_vu_prepare_date_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.123 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime_table +Append + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_1" partition_vu_prepare_datetime_table_1 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_2" partition_vu_prepare_datetime_table_2 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_3" partition_vu_prepare_datetime_table_3 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_0" partition_vu_prepare_datetime_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.122 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime2_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime2_table +Append + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_1" partition_vu_prepare_datetime2_table_1 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_2" partition_vu_prepare_datetime2_table_2 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_3" partition_vu_prepare_datetime2_table_3 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_0" partition_vu_prepare_datetime2_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.091 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smalldatetime_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smalldatetime_table +Append + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_1 partition_vu_prepare_smalldatetime_table_1 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_2 partition_vu_prepare_smalldatetime_table_2 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_3 partition_vu_prepare_smalldatetime_table_3 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_0 partition_vu_prepare_smalldatetime_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.089 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_char_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_char_table +Append + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_1" partition_vu_prepare_char_table_1 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_2" partition_vu_prepare_char_table_2 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_3" partition_vu_prepare_char_table_3 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_4" partition_vu_prepare_char_table_4 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_5" partition_vu_prepare_char_table_5 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_6" partition_vu_prepare_char_table_6 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_7" partition_vu_prepare_char_table_7 + -> Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_0" partition_vu_prepare_char_table_8 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.124 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varchar_table +Append + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_1" partition_vu_prepare_varchar_table_1 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_2" partition_vu_prepare_varchar_table_2 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_3" partition_vu_prepare_varchar_table_3 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_4" partition_vu_prepare_varchar_table_4 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_5" partition_vu_prepare_varchar_table_5 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_0" partition_vu_prepare_varchar_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.107 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nvarchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nvarchar_table +Append + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_1" partition_vu_prepare_nvarchar_table_1 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_2" partition_vu_prepare_nvarchar_table_2 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_3" partition_vu_prepare_nvarchar_table_3 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_4" partition_vu_prepare_nvarchar_table_4 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_5" partition_vu_prepare_nvarchar_table_5 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_0" partition_vu_prepare_nvarchar_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.099 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nchar_table +Append + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_1 partition_vu_prepare_nchar_table_1 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_2 partition_vu_prepare_nchar_table_2 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_3 partition_vu_prepare_nchar_table_3 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_4 partition_vu_prepare_nchar_table_4 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_5 partition_vu_prepare_nchar_table_5 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_6 partition_vu_prepare_nchar_table_6 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_7 partition_vu_prepare_nchar_table_7 + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_0 partition_vu_prepare_nchar_table_8 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.088 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_binary_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_binary_table +Append + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_1" partition_vu_prepare_binary_table_1 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_2" partition_vu_prepare_binary_table_2 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_3" partition_vu_prepare_binary_table_3 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_4" partition_vu_prepare_binary_table_4 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_0" partition_vu_prepare_binary_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varbinary_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varbinary_table +Append + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_1" partition_vu_prepare_varbinary_table_1 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_2" partition_vu_prepare_varbinary_table_2 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_3" partition_vu_prepare_varbinary_table_3 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_4" partition_vu_prepare_varbinary_table_4 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_0" partition_vu_prepare_varbinary_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_uniqueidentifier_table +Append + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_1 partition_vu_prepare_uniqueidentifier_table_1 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_2 partition_vu_prepare_uniqueidentifier_table_2 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_3 partition_vu_prepare_uniqueidentifier_table_3 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_0 partition_vu_prepare_uniqueidentifier_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.106 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_sqlvariant_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_sqlvariant_table +Append + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_1" partition_vu_prepare_sqlvariant_table_1 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_2" partition_vu_prepare_sqlvariant_table_2 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_3" partition_vu_prepare_sqlvariant_table_3 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_4" partition_vu_prepare_sqlvariant_table_4 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_5" partition_vu_prepare_sqlvariant_table_5 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_0" partition_vu_prepare_sqlvariant_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.142 ms +~~END~~ + + + +----------------------------------------------------------------------------------------- +--- Query plan of select on partitioned tables with predicate and enforced index scan +----------------------------------------------------------------------------------------- +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'off', false); +SELECT set_config('enable_bitmapscan', 'off', false); +GO +~~START~~ +text +off +~~END~~ + +~~START~~ +text +off +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500 +Index Scan using "363863941f079adaa9aa733200e57c9f_partition_1_id_key" on "363863941f079adaa9aa733200e57c9f_partition_1" partition_vu_prepare_int_table + Index Cond: ((id >= 0) AND (id < 500)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 34.743 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100 +Index Scan using "548bb344374ce8d65342b36428375873_partition_1_id_idx" on "548bb344374ce8d65342b36428375873_partition_1" partition_vu_prepare_bigint_table + Index Cond: ((id >= 0) AND (id < 100)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.201 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0 +Index Scan using "12025e103721b70925744c196ce004cd_partition_1_id_idx" on "12025e103721b70925744c196ce004cd_partition_1" partition_vu_prepare_smallint_table + Index Cond: ((id >= '-32768'::integer) AND (id < 0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 7.419 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128 +Index Scan using "61446d711d19b5970809387caa7fd3d3_partition_1_id_idx" on "61446d711d19b5970809387caa7fd3d3_partition_1" partition_vu_prepare_tinyint_table + Index Cond: (((id)::smallint >= 0) AND ((id)::smallint < 128)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.167 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0 +Index Scan using cda2902d769fd61eb60b1a461650212f_partition_1_id_idx on cda2902d769fd61eb60b1a461650212f_partition_1 partition_vu_prepare_decimal_table + Index Cond: (((id)::numeric >= 0.0) AND ((id)::numeric < 100.0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.571 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0 +Index Scan using "57405760297bb338f333c148aac5f845_partition_1_id_idx" on "57405760297bb338f333c148aac5f845_partition_1" partition_vu_prepare_numeric_table + Index Cond: ((id >= 0.0) AND (id < 10.0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.237 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789 +Append + -> Index Scan using "640187c54e2c2984d190957d245a5fa5_partition_1_id_idx" on "640187c54e2c2984d190957d245a5fa5_partition_1" partition_vu_prepare_money_table_1 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) + -> Index Scan using "640187c54e2c2984d190957d245a5fa5_partition_0_id_idx" on "640187c54e2c2984d190957d245a5fa5_partition_0" partition_vu_prepare_money_table_2 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.223 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789 +Append + -> Index Scan using "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1_id_idx" on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1" partition_vu_prepare_smallmoney_table_1 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) + -> Index Scan using "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0_id_idx" on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0" partition_vu_prepare_smallmoney_table_2 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.154 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01' +Index Scan using "4867824426e52acac5c93d9cbe8aa366_partition_1_id_idx" on "4867824426e52acac5c93d9cbe8aa366_partition_1" partition_vu_prepare_date_table + Index Cond: ((id >= '2022-01-01'::date) AND (id < '2022-07-01'::date)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.603 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Index Scan using "751ce655481adf15600727bf291667f7_partition_1_id_idx" on "751ce655481adf15600727bf291667f7_partition_1" partition_vu_prepare_datetime_table + Index Cond: ((id >= '2019-01-01 00:00:00'::datetime) AND (id < '2022-01-01 00:00:00'::datetime)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.184 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Index Scan using "5ed003cf80dacbb8cce0b21e175f7f94_partition_1_id_idx" on "5ed003cf80dacbb8cce0b21e175f7f94_partition_1" partition_vu_prepare_datetime2_table + Index Cond: ((id >= '2019-01-01 00:00:00'::datetime2) AND (id < '2022-01-01 00:00:00'::datetime2)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.159 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Index Scan using b5c2e665ec4a1219ba8510e33e45379b_partition_1_id_idx on b5c2e665ec4a1219ba8510e33e45379b_partition_1 partition_vu_prepare_smalldatetime_table + Index Cond: ((id >= '2019-01-01 00:00:00'::smalldatetime) AND (id < '2022-01-01 00:00:00'::smalldatetime)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.226 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B' +Index Scan using "5d20bd977eb6e6f1304dec45598c09f5_partition_1_id_idx" on "5d20bd977eb6e6f1304dec45598c09f5_partition_1" partition_vu_prepare_char_table + Index Cond: ((id >= 'A'::bpchar) AND (id < 'B'::bpchar)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.241 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana' +Index Scan using "933a5c7f0de13890324e53ee0711424b_partition_1_id_idx" on "933a5c7f0de13890324e53ee0711424b_partition_1" partition_vu_prepare_varchar_table + Index Cond: ((id >= 'Apple'::"varchar") AND (id < 'Banana'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.170 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana' +Index Scan using "320465af1d1bd21f5b29c57f9f4e5c51_partition_1_id_idx" on "320465af1d1bd21f5b29c57f9f4e5c51_partition_1" partition_vu_prepare_nvarchar_table + Index Cond: (((id)::"varchar" >= 'Apple'::"varchar") AND ((id)::"varchar" < 'Banana'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.161 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B' +Gather + Workers Planned: 2 + -> Parallel Append + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_3 partition_vu_prepare_nchar_table_3 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_5 partition_vu_prepare_nchar_table_5 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_7 partition_vu_prepare_nchar_table_7 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_1 partition_vu_prepare_nchar_table_1 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_2 partition_vu_prepare_nchar_table_2 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_4 partition_vu_prepare_nchar_table_4 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_6 partition_vu_prepare_nchar_table_6 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_0 partition_vu_prepare_nchar_table_8 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.159 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400 +Gather + Workers Planned: 2 + -> Parallel Append + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_1" partition_vu_prepare_binary_table_1 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_2" partition_vu_prepare_binary_table_2 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_3" partition_vu_prepare_binary_table_3 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_4" partition_vu_prepare_binary_table_4 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_0" partition_vu_prepare_binary_table_5 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.824 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000 +Index Scan using "77718961234110c3a22a3c977bc252d8_partition_1_id_idx" on "77718961234110c3a22a3c977bc252d8_partition_1" partition_vu_prepare_varbinary_table + Index Cond: (((id)::bbf_varbinary >= '0x0000000000000000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x4000000000000000'::bbf_varbinary)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.166 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF' +Index Scan using f3baf999c06d6ea82082a4c549baeb77_partition_1_id_idx on f3baf999c06d6ea82082a4c549baeb77_partition_1 partition_vu_prepare_uniqueidentifier_table + Index Cond: ((id >= '00000000-0000-0000-0000-000000000000'::uniqueidentifier) AND (id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'::uniqueidentifier)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.188 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)); +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)) +Index Scan using "69727aecbd7d094d31958d173a958827_partition_1_id_idx" on "69727aecbd7d094d31958d173a958827_partition_1" partition_vu_prepare_sqlvariant_table + Index Cond: ((id >= 'abc '::sql_variant) AND (id < 'Apple'::sql_variant)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 7.191 ms +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'on', false); +SELECT set_config('enable_bitmapscan', 'on', false); +SELECT set_config('babelfishpg_tsql.explain_costs', 'on', false) +GO +~~START~~ +text +on +~~END~~ + +~~START~~ +text +on +~~END~~ + +~~START~~ +text +on +~~END~~ + + + + +-- psql +------------------------------------------ +--- Blocked Operation For Partitioned Tables +------------------------------------------- +-- user should not be allowed to CREATE/ATTACH/DETACH partition +-- to babelfish partitioned table from psql endpoint +SET ROLE master_dbo; +GO + +-- Attempt to create new partition with random values +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +FOR VALUES FROM (0) TO (500); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: partition "nonexistenttable" would overlap partition "363863941f079adaa9aa733200e57c9f_partition_1" + Position: 157 + Server SQLState: 42P17)~~ + + +-- Attempt to create new partition with DEFAULT +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +DEFAULT +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: partition "nonexistenttable" conflicts with existing default partition "363863941f079adaa9aa733200e57c9f_partition_0" + Position: 134 + Server SQLState: 42P17)~~ + + +-- Attempt to drop partition of babelfish partitioned table from psql endpoint +DROP TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot drop the babelfish partition table '363863941f079adaa9aa733200e57c9f_partition_0'. + Server SQLState: 42704)~~ + + + +-- Attempt to detach +-- explicit schema name specified +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +RESET search_path; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to detach using CONCURRENTLY option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +CONCURRENTLY; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to detach using FINALIZE option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +FINALIZE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to attach with Default value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable DEFAULT; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot attach partition to babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to attach with random value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable FOR VALUES FROM (10) TO (20); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot attach partition to babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + + +-- user should not be allowed to modify partition +-- of babelfish partitioned table neither from psql nor tsql endpoint +-- explicit schema name specified +ALTER TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table. + Server SQLState: 0A000)~~ + + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE "363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +RESET search_path; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table. + Server SQLState: 0A000)~~ + + +RESET ROLE; +GO + +-- Attempt to ADD storage parameter to babelfish partitioned table (not on the partitions) +SET babelfishpg_tsql.sql_dialect = "tsql"; +GO + +ALTER TABLE master_dbo.partition_vu_prepare_int_table SET (autovacuum_enabled = false); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: cannot specify storage parameters for a partitioned table + Hint: Specify storage parameters for its leaf partitions instead. + Server SQLState: 42809)~~ + + +RESET babelfishpg_tsql.sql_dialect; +GO + + +-- tsql +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + + +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +-- with explicity schema name +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +-- Attempt to drop partition of babelfish partitioned table from tsql endpoint +DROP TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the babelfish partition table '363863941f079adaa9aa733200e57c9f_partition_0'.)~~ + + +-------------------------------------------------------------------- +--- Unsupported Option with CREATE TABLE with PARTITION SCHEME +-------------------------------------------------------------------- +-- Computed column as partitioning column is not yet supported in babelfish +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value +) +ON IntPartitionScheme(computed_col); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot use generated column in partition key)~~ + + +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value PERSISTED +) +ON IntPartitionScheme(computed_col); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot use generated column in partition key)~~ + + +-- temporary table +CREATE TABLE #TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Creation of tempopary partitioned tables is not supported in Babelfish.)~~ + + + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--------------------------------------------------------------- +-- Attempt to create with multiple columns as partitioning scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id, value); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ',' at line 10 and character position 24)~~ + + +-- Attempt to create with a partition scheme that doesn't exist and column that doesn't exist in the table +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(NonExistentColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "nonexistentcolumn" named in partition key does not exist)~~ + + +-- Attempt to create with a partition scheme that doesn't exist +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid partition scheme 'NonExistentPartitionScheme' specifed.)~~ + + +-- Attempt to use two part name with partition scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON master.IntPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '.' at line 7 and character position 9)~~ + + +-- Attempt to create with a unique constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT UNIQUE +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: unique constraint on partitioned table must include all partitioning columns)~~ + + +-- Attempt to create with a primary key constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT PRIMARY KEY +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: unique constraint on partitioned table must include all partitioning columns)~~ + + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--- Attempt to create with an incompatible partition column data type +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable1 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'IntPartitionFunction' parameter data type 'int'.)~~ + + +CREATE TABLE TestPartitionedTable2 +( + Id INT, + PartitionColumn DATETIME +) +ON DatePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime' which is different from the partition function 'DatePartitionFunction' parameter data type 'date'.)~~ + + +CREATE TABLE TestPartitionedTable3 +( + Id INT, + PartitionColumn VARCHAR(10) +) +ON CharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'varchar' which is different from the partition function 'CharPartitionFunction' parameter data type 'char'.)~~ + + +CREATE TABLE TestPartitionedTable4 +( + Id INT, + PartitionColumn VARBINARY(10) +) +ON BinaryPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'varbinary' which is different from the partition function 'BinaryPartitionFunction' parameter data type 'binary'.)~~ + + +CREATE TABLE TestPartitionedTable5 +( + Id INT, + PartitionColumn SMALLINT +) +ON BigIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int2' which is different from the partition function 'BigIntPartitionFunction' parameter data type 'bigint'.)~~ + + +CREATE TABLE TestPartitionedTable6 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON SmallIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'SmallIntPartitionFunction' parameter data type 'smallint'.)~~ + + +CREATE TABLE TestPartitionedTable7 +( + Id INT, + PartitionColumn DECIMAL(10, 5) +) +ON TinyIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'TinyIntPartitionFunction' parameter data type 'tinyint'.)~~ + + +CREATE TABLE TestPartitionedTable8 +( + Id INT, + PartitionColumn BIGINT +) +ON DecimalPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int8' which is different from the partition function 'DecimalPartitionFunction' parameter data type 'decimal'.)~~ + + +CREATE TABLE TestPartitionedTable9 +( + Id INT, + PartitionColumn MONEY +) +ON NumericPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'money' which is different from the partition function 'NumericPartitionFunction' parameter data type 'numeric'.)~~ + + +CREATE TABLE TestPartitionedTable10 +( + Id INT, + PartitionColumn INT +) +ON MoneyPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'MoneyPartitionFunction' parameter data type 'money'.)~~ + + +CREATE TABLE TestPartitionedTable11 +( + Id INT, + PartitionColumn DATETIME +) +ON SmallMoneyPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime' which is different from the partition function 'SmallMoneyPartitionFunction' parameter data type 'smallmoney'.)~~ + + +CREATE TABLE TestPartitionedTable12 +( + Id INT, + PartitionColumn DATETIME2(3) +) +ON DateTimePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime2' which is different from the partition function 'DateTimePartitionFunction' parameter data type 'datetime'.)~~ + + +CREATE TABLE TestPartitionedTable13 +( + Id INT, + PartitionColumn SMALLDATETIME +) +ON DateTime2PartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'smalldatetime' which is different from the partition function 'DateTime2PartitionFunction' parameter data type 'datetime2'.)~~ + + +CREATE TABLE TestPartitionedTable14 +( + Id INT, + PartitionColumn NVARCHAR(10) +) +ON SmallDateTimePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'nvarchar' which is different from the partition function 'SmallDateTimePartitionFunction' parameter data type 'smalldatetime'.)~~ + + +CREATE TABLE TestPartitionedTable15 +( + Id INT, + PartitionColumn INT +) +ON NVarCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'NVarCharPartitionFunction' parameter data type 'nvarchar'.)~~ + + +CREATE TABLE TestPartitionedTable16 +( + Id INT, + PartitionColumn NCHAR(5) +) +ON VarCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'nchar' which is different from the partition function 'VarCharPartitionFunction' parameter data type 'varchar'.)~~ + + +CREATE TABLE TestPartitionedTable17 +( + Id INT, + PartitionColumn INT +) +ON NCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'NCharPartitionFunction' parameter data type 'nchar'.)~~ + + +-- using user defined type +CREATE TYPE PartitionUserDefinedType FROM SMALLINT; +GO + +CREATE TABLE TestPartitionedTable18 +( + Id INT, + PartitionColumn PartitionUserDefinedType +) +ON BigIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'partitionuserdefinedtype' which is different from the partition function 'BigIntPartitionFunction' parameter data type 'bigint'.)~~ + + +DROP TYPE PartitionUserDefinedType +GO + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE Index with PARTITION SCHEME +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable ( + PartitionColumn INT, + NonPartitionColumn INT +) ON IntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestNonPartitionedTable ( + a INT, + b INT +) +GO + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonExistentColumn1) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "nonexistentcolumn1" does not exist)~~ + + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column 'nonexistentcolumn2' does not exist)~~ + + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid object name 'NonExistentPartitionScheme'.)~~ + + +-- scheme is different from the partition scheme used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON BigIntPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + +-- column specified with partition scheme is different +-- from the partition column used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + +-- should work +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (PartitionColumn); +GO + +DROP INDEX TestPartitionIndex ON TestPartitionedTable +GO + +-- usage of partition scheme on non-partitioned table (should fail) +CREATE INDEX TestPartitionIndex +ON TestNonPartitionedTable(a) +ON IntPartitionScheme (a); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + + +DROP TABLE TestPartitionedTable +GO + +DROP TABLE TestNonPartitionedTable +GO +-- psql +------------------------------------------------------------------------------------------- +--- Rename Operation on Partitioned Tables should update name in babelfish_partition_depend +--- and it should also update the name of all the partitions +------------------------------------------------------------------------------------------- +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO +~~START~~ +regclass +master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_1" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_2" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_3" +~~END~~ + + +-- tsql +-- trigger rename from TSQL endpoint +EXEC sp_rename 'partition_vu_prepare_int_table', 'partition_vu_prepare_int_table_renamed', 'OBJECT' +GO + +-- psql +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table_renamed'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table_renamed +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table_renamed')::regclass; +GO +~~START~~ +regclass +master_dbo.c2647401dc3e9a950809daafcd188637_partition_0 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_1 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_2 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_3 +~~END~~ + + +-- trigger rename from PSQL endpoint +ALTER TABLE master_dbo.partition_vu_prepare_int_table_renamed RENAME TO partition_vu_prepare_int_table; +GO + +-- we should get orginal here +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO +~~START~~ +regclass +master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_1" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_2" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_3" +~~END~~ + diff --git a/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out b/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out new file mode 100644 index 00000000000..5b075c54f80 --- /dev/null +++ b/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out @@ -0,0 +1,3154 @@ + +-------------------------------------------------- +--- CREATE PARTITION FUNCTION/SCHEME/TABLE using procedure +-------------------------------------------------- +EXEC PartitionProcedureCreatePartitionFunction +GO + +EXEC PartitionProcedureCreatePartitionScheme +GO + +EXEC PartitionProcedureCreatePartitionTable +GO + +EXEC PartitionProcedureCreatePartitionFunctionSchemeAndTable +GO + +-------------------------------------------------- +--- CREATE PARTITION FUNCTION/SCHEME/TABLE inside Function +-------------------------------------------------- +CREATE FUNCTION TestFunctionCreatePartitionFunction() +RETURNS INT +AS +BEGIN + CREATE PARTITION FUNCTION TestPartitionFunction (int) + AS RANGE RIGHT FOR VALUES (500, 1000, 10000); + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'CREATE PARTITION FUNCTION' within a function.)~~ + + +CREATE FUNCTION TestFunctionDropPartitionFunction() +RETURNS INT +AS +BEGIN + DROP PARTITION FUNCTION IntPartitionFunction; + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'DROP PARTITION FUNCTION' within a function.)~~ + + +CREATE FUNCTION TestFunctionCreatePartitionScheme() +RETURNS INT +AS +BEGIN + CREATE PARTITION SCHEME TestPartitionScheme AS + PARTITION IntPartitionFunction + ALL TO ([PRIMARY]); + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'CREATE PARTITION SCHEME' within a function.)~~ + + +CREATE FUNCTION TestFunctionDropPartitionScheme() +RETURNS INT +AS +BEGIN + DROP PARTITION SCHEME IntPartitionScheme; + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'DROP PARTITION SCHEME' within a function.)~~ + + +CREATE FUNCTION TestFunctionCreatePartitionTable() +RETURNS INT +AS +BEGIN + CREATE TABLE TestPartitionTable ( + Id INT, + Value sys.varchar(20) + ) ON IntPartitionScheme(Id); +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: DDL cannot be used within a function)~~ + + +CREATE FUNCTION TestFunctionDropPartitionTable() +RETURNS INT +AS +BEGIN + DROP TABLE partition_vu_prepare_int_table; + RETURN 1; +END; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: DDL cannot be used within a function)~~ + + + +--------------------------------------------------------- +--- CREATE PARTITION FUNCTION/SCHEME using 2-part name +--------------------------------------------------------- +CREATE PARTITION FUNCTION [TestDb].[TwoPartParitionFunction](DATE) +AS RANGE RIGHT FOR VALUES ('20230101', '20230201', '20230301', '20230401'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '.' at line 4 and character position 34)~~ + + +CREATE PARTITION SCHEME [TestDb].[TwoPartParitionScheme] +AS PARTITION [TestDb].[TwoPartPF] +TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '.' at line 1 and character position 32)~~ + + +-------------------------------------------------- +--- Unsupported Datatypes for Partition Function +-------------------------------------------------- +CREATE PARTITION FUNCTION VarcharMaxPartitionFunction (VARCHAR(MAX)) +AS RANGE RIGHT FOR VALUES ('A', 'B', 'C', 'D'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'varchar(max)' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION NVarcharMaxPartitionFunction (NVARCHAR(MAX)) +AS RANGE RIGHT FOR VALUES (N'A', N'B', N'C', N'D'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'nvarchar(max)' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION VarbinaryMaxPartitionFunction (VARBINARY(MAX)) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'varbinary(max)' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION BinaryMaxPartitionFunction (BINARY(MAX)) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Incorrect syntax near the keyword 'binary'.)~~ + + +CREATE PARTITION FUNCTION TextPartitionFunction (text) +AS RANGE RIGHT FOR VALUES ('a', 'b', 'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'text' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION NTextPartitionFunction (ntext) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'ntext' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION ImagePartitionFunction (image) +AS RANGE RIGHT FOR VALUES (0x123456, 0x789ABC, 0xDEF012); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'image' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION XmlPartitionFunction (xml) +AS RANGE RIGHT FOR VALUES ('1', '2', '3'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'xml' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION GeometryPartitionFunction (GEOMETRY) +AS RANGE RIGHT FOR VALUES (GEOMETRY::STGeomFromText('POINT(1 1)', 0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'geometry' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION GeometryPartitionFunction (GEOGRAPHY) +AS RANGE RIGHT FOR VALUES (GEOMETRY::STGeomFromText('POINT(1 1)', 0)); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'geography' is not valid for this operation.)~~ + + +-- to test rowversion and timestamp +SELECT SET_CONFIG('babelfishpg_tsql.escape_hatch_rowversion', 'ignore', 'false') +go +~~START~~ +text +ignore +~~END~~ + + +CREATE PARTITION FUNCTION RowVersionPartitionFunction (ROWVERSION) +AS RANGE RIGHT FOR VALUES (0x0000000000000000, 0x0000000000000001, 0x0000000000000002); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'rowversion' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION TimestampPartitionFunction (TIMESTAMP) +AS RANGE RIGHT FOR VALUES (0x0000000000000000, 0x0000000000000001, 0x0000000000000002); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'timestamp' is not valid for this operation.)~~ + + +-- reset back the escape hatch +SELECT SET_CONFIG('babelfishpg_tsql.escape_hatch_rowversion', 'strict', 'true') +go +~~START~~ +text +strict +~~END~~ + + +-- user defined type +CREATE TYPE PartitionUserDefinedType FROM VARCHAR(10); +GO + +CREATE PARTITION FUNCTION UdtPartitionFunction (PartitionUserDefinedType) +AS RANGE RIGHT FOR VALUES ('a', 'b', 'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'partitionuserdefinedtype' is not valid for this operation.)~~ + + +DROP type PartitionUserDefinedType +GO + +------------------------------------------------------------------------------ +--- Duplicate range values for all supported datatypes in Partition Function +------------------------------------------------------------------------------ +CREATE PARTITION FUNCTION IntPartitionFunctionContainsDuplicateValue (int) +AS RANGE RIGHT FOR VALUES (0, 100, 1000, 100); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION BigIntPartitionFunctionContainsDuplicateValue (bigint) +AS RANGE RIGHT FOR VALUES (0, 500, 100, 500, 1000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION SmallIntPartitionFunctionContainsDuplicateValue (smallint) +AS RANGE RIGHT FOR VALUES (32767, 10, -32768, 0, 10); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION TinyIntPartitionFunctionContainsDuplicateValue (tinyint) +AS RANGE RIGHT FOR VALUES (0, 255, 128, 255); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION DecimalPartitionFunctionContainsDuplicateValue (decimal(10, 5)) +AS RANGE RIGHT FOR VALUES (0.0, 300.0, 200.0, 100.0, 300.0); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION NumericPartitionFunctionContainsDuplicateValue (numeric(5, 2)) +AS RANGE RIGHT FOR VALUES (0.0, 30.0, 10.0, 20.0, 30.0); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION DatePartitionFunctionContainsDuplicateValue (date) +AS RANGE RIGHT FOR VALUES ('2022-07-01', '2022-01-01','2023-01-01','2022-01-01'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION DateTimePartitionFunctionContainsDuplicateValue (datetime) +AS RANGE RIGHT FOR VALUES ('2022-01-01', '2022-07-01 00:00:00', '2019-01-01 00:00:00', '2022-01-01'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION DateTime2PartitionFunctionContainsDuplicateValue (datetime2(3)) +AS RANGE RIGHT FOR VALUES ('2022-01-01 00:00:00.000', '2022-07-01 00:00:00.000', '2019-01-01 00:00:00.000', '2022-07-01 00:00:00.000'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION SmallDateTimePartitionFunctionContainsDuplicateValue (smalldatetime) +AS RANGE RIGHT FOR VALUES ('2022-01-01', '2022-07-01', '2019-01-01', '2022-07-01'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION CharPartitionFunctionContainsDuplicateValue (char(5)) +AS RANGE RIGHT FOR VALUES ('A', 'F', 'K', 'P', 'U', 'Z', 'D', 'K'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION VarCharPartitionFunctionContainsDuplicateValue (varchar(10)) +AS RANGE RIGHT FOR VALUES ('Apple', 'Banana', 'Mango', 'Cherry', 'Date', 'Banana'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION NVarCharPartitionFunctionContainsDuplicateValue (nvarchar(10)) +AS RANGE RIGHT FOR VALUES (N'Apple', N'Banana', N'Mango', N'Cherry', N'Date', N'Banana'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION NCharPartitionFunctionContainsDuplicateValue (nchar(5)) +AS RANGE RIGHT FOR VALUES (N'A', N'F', N'K', N'P', N'U', N'Z', N'B', N'K'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION BinaryPartitionFunctionContainsDuplicateValue (binary(4)) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000, 0x800); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION VarBinaryPartitionFunctionContainsDuplicateValue (varbinary(8)) +AS RANGE RIGHT FOR VALUES (0x0000000000000000, 0x8000000000000000, 0x4000000000000000, 0xC000000000000000, 0x8000000000000000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION UniqueIdentifierPartitionFunctionContainsDuplicateValue (uniqueidentifier) +AS RANGE RIGHT FOR VALUES ('00000000-0000-0000-0000-000000000000', '6F9619FF-8B86-D011-B42D-00C04FC964FF', 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', '6F9619FF-8B86-D011-B42D-00C04FC964FF'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION SqlVariantPartitionFunctionContainsDuplicateValue (sql_variant) +AS RANGE RIGHT FOR VALUES (1, 'abc', CONVERT(DATETIME, '2023-05-01'), 'abc'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +-- duplicate value with different basetype +CREATE PARTITION FUNCTION SqlVariantPartitionFunctionContainsDuplicateValue (sql_variant) +AS RANGE RIGHT FOR VALUES (1, cast('abc' as varchar(10)), CONVERT(DATETIME, '2023-05-01'), cast('abc' as nvarchar(10))); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +-------------------------------------------------- +--- Unsupported Options with Partition Function +-------------------------------------------------- +-- LEFT option is not supported in Babelfish +CREATE PARTITION FUNCTION PartitionFunctionWithLeft (int) +AS RANGE LEFT FOR VALUES (10, 1000, 10000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'PARTIION FUNCTION with LEFT option' is not currently supported in Babelfish)~~ + + +-- by default it is LEFT and it should throw error +CREATE PARTITION FUNCTION PartitionFunctionWithLeft (int) +AS RANGE FOR VALUES (10, 1000, 10000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'PARTIION FUNCTION with LEFT option' is not currently supported in Babelfish)~~ + + +-- NULL value is not supported in range values +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NULL values are not allowed in partition function boundary values list.)~~ + + +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL, NULL); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NULL values are not allowed in partition function boundary values list.)~~ + + +-------------------------------------------------- +--- Duplicate Create of Partition Function/Scheme +-------------------------------------------------- +CREATE PARTITION FUNCTION IntPartitionFunction (int) +AS RANGE RIGHT FOR VALUES (500, 1000, 10000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: There is already an object named 'IntPartitionFunction' in the database.)~~ + + +-- duplicate partition function with invalid args +CREATE PARTITION FUNCTION IntPartitionFunction (int) +AS RANGE RIGHT FOR VALUES ('xyz', CONVERT(DATETIME, '2023-05-01'), 0x789ABC); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: There is already an object named 'IntPartitionFunction' in the database.)~~ + + +CREATE PARTITION SCHEME IntPartitionScheme AS +PARTITION IntPartitionFunction +ALL TO ([PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: There is already an object named 'IntPartitionScheme' in the database.)~~ + + +-- duplicate partition scheme with invalid Partition function +CREATE PARTITION SCHEME IntPartitionScheme AS +PARTITION PartitionFunctionDoesNotExists +ALL TO ([PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid object name 'PartitionFunctionDoesNotExists'.)~~ + + +----------------------------------------------------------------------------------- +--- Drop of of Partition Function/Scheme when it does not exists +----------------------------------------------------------------------------------- +DROP PARTITION FUNCTION PartitionFunctionDoesNotExists +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the partition function 'PartitionFunctionDoesNotExists', because it does not exist or you do not have permission.)~~ + + +DROP PARTITION SCHEME PartitionSchemeDoesNotExists +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the partition scheme 'PartitionSchemeDoesNotExists', because it does not exist or you do not have permission.)~~ + + +----------------------------------------------------------------------------------- +--- Create of Partition Scheme when provided partition function doesn't exists +----------------------------------------------------------------------------------- +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION PartitionFunctionDoesNotExists +ALL TO ([PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid object name 'PartitionFunctionDoesNotExists'.)~~ + + +----------------------------------------------------------------------------------- +--- Drop of of Partition Function when there is dependent Partition Scheme +----------------------------------------------------------------------------------- +DROP PARTITION FUNCTION IntPartitionFunction +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition function 'IntPartitionFunction' is being used by one or more partition schemes.)~~ + + +----------------------------------------------------------------------------------- +--- Drop of of Partition Scheme when there is dependent Table on it +----------------------------------------------------------------------------------- +DROP PARTITION SCHEME IntPartitionScheme +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The partition scheme "IntPartitionScheme" is currently being used to partition one or more tables.)~~ + + + + +----------------------------------------------- +--- Filegroup behaviour with Partition Scheme +----------------------------------------------- +-- by default user filegroup will be treated as PRIMARY filegroup +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION IntPartitionFunction +ALL TO (user_filegroup); +GO + +DROP PARTITION SCHEME TestPartitionScheme +GO + +-- User can configure the "escape_hatch_storage_options" to STRICT to disallow user filegroups +SELECT SET_CONFIG('babelfishpg_tsql.escape_hatch_storage_options', 'strict', 'false') +GO +~~START~~ +text +strict +~~END~~ + + +-- should throw error +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION IntPartitionFunction +ALL TO (user_filegroup); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'user filegroup' is not currently supported in Babelfish. please use babelfishpg_tsql.escape_hatch_storage_options to ignore)~~ + + +-- reset it back +SELECT SET_CONFIG('babelfishpg_tsql.escape_hatch_storage_options', 'ignore', 'false') +GO +~~START~~ +text +ignore +~~END~~ + + +-- when more than one filegroup are specified with ALL option +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION IntPartitionFunction +ALL TO ([PRIMARY], [PRIMARY], [PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only a single filegroup can be specified while creating partition scheme using option ALL to specify all the filegroups.)~~ + + +-- when partition function generates more partition than specified filegroups +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION IntPartitionFunction +TO ([PRIMARY], [PRIMARY], [PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The associated partition function 'IntPartitionFunction' generates more partitions than there are file groups mentioned in the scheme 'TestPartitionScheme'.)~~ + + + +--------------------------------- +--- Metadata Related Tests +--------------------------------- +SELECT * FROM GetPartitionFunctionMetadataView +GO +~~START~~ +nvarchar#!#char#!#nvarchar#!#int#!#bit#!#bit +BigIntPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 +BinaryPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 +CharPartitionFunction#!#R #!#RANGE#!#8#!#1#!#0 +DatePartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +DateTime2PartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +DateTimePartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +DecimalPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 +IntPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +MoneyPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +NCharPartitionFunction#!#R #!#RANGE#!#8#!#1#!#0 +NumericPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 +NVarCharPartitionFunction#!#R #!#RANGE#!#6#!#1#!#0 +PARTITION_FUNCTION 유니코드스키마👻 #!#R #!#RANGE#!#4#!#1#!#0 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#R #!#RANGE#!#4#!#1#!#0 +PARTITION_FUNCTIONログインαιώνια#!#R #!#RANGE#!#4#!#1#!#0 +PartitionFunctionHavingDifferentCollationInput#!#R #!#RANGE#!#5#!#1#!#0 +PartitionFunctionInsideProc1#!#R #!#RANGE#!#4#!#1#!#0 +PartitionFunctionInsideProc2#!#R #!#RANGE#!#4#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#R #!#RANGE#!#5#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#R #!#RANGE#!#5#!#1#!#0 +SmallDateTimePartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +SmallIntPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +SmallMoneyPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +SqlVariantPartitionFunction#!#R #!#RANGE#!#6#!#1#!#0 +TinyIntPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +UniqueIdentifierPartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +VarBinaryPartitionFunction#!#R #!#RANGE#!#5#!#1#!#0 +VarCharPartitionFunction#!#R #!#RANGE#!#6#!#1#!#0 +~~END~~ + + +SELECT * FROM GetRangeMetadataView +GO +~~START~~ +nvarchar#!#int#!#int#!#sql_variant +BigIntPartitionFunction#!#1#!#1#!#0 +BigIntPartitionFunction#!#1#!#2#!#100 +BigIntPartitionFunction#!#1#!#3#!#1000 +BigIntPartitionFunction#!#1#!#4#!#10000 +CharPartitionFunction#!#1#!#1#!#A +CharPartitionFunction#!#1#!#2#!#D +CharPartitionFunction#!#1#!#3#!#F +CharPartitionFunction#!#1#!#4#!#K +CharPartitionFunction#!#1#!#5#!#P +CharPartitionFunction#!#1#!#6#!#U +CharPartitionFunction#!#1#!#7#!#Z +DatePartitionFunction#!#1#!#1#!#2022-01-01 +DatePartitionFunction#!#1#!#2#!#2022-07-01 +DatePartitionFunction#!#1#!#3#!#2023-01-01 +DateTime2PartitionFunction#!#1#!#1#!#2019-01-01 00:00:00.0 +DateTime2PartitionFunction#!#1#!#2#!#2022-01-01 00:00:00.0 +DateTime2PartitionFunction#!#1#!#3#!#2022-07-01 00:00:00.0 +DateTimePartitionFunction#!#1#!#1#!#2019-01-01 00:00:00.0 +DateTimePartitionFunction#!#1#!#2#!#2022-01-01 00:00:00.0 +DateTimePartitionFunction#!#1#!#3#!#2022-07-01 00:00:00.0 +DecimalPartitionFunction#!#1#!#1#!#0.00000 +DecimalPartitionFunction#!#1#!#2#!#100.00000 +DecimalPartitionFunction#!#1#!#3#!#200.00000 +DecimalPartitionFunction#!#1#!#4#!#300.00000 +IntPartitionFunction#!#1#!#1#!#0 +IntPartitionFunction#!#1#!#2#!#500 +IntPartitionFunction#!#1#!#3#!#1000 +MoneyPartitionFunction#!#1#!#1#!#2.5679 +MoneyPartitionFunction#!#1#!#2#!#3.5679 +MoneyPartitionFunction#!#1#!#3#!#4.9100 +NCharPartitionFunction#!#1#!#1#!#A +NCharPartitionFunction#!#1#!#2#!#B +NCharPartitionFunction#!#1#!#3#!#F +NCharPartitionFunction#!#1#!#4#!#K +NCharPartitionFunction#!#1#!#5#!#P +NCharPartitionFunction#!#1#!#6#!#U +NCharPartitionFunction#!#1#!#7#!#Z +NumericPartitionFunction#!#1#!#1#!#0.00 +NumericPartitionFunction#!#1#!#2#!#10.00 +NumericPartitionFunction#!#1#!#3#!#20.00 +NumericPartitionFunction#!#1#!#4#!#30.00 +NVarCharPartitionFunction#!#1#!#1#!#Apple +NVarCharPartitionFunction#!#1#!#2#!#Banana +NVarCharPartitionFunction#!#1#!#3#!#Cherry +NVarCharPartitionFunction#!#1#!#4#!#Date +NVarCharPartitionFunction#!#1#!#5#!#Mango +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#1#!#0 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#2#!#500 +PARTITION_FUNCTION 유니코드스키마👻 #!#1#!#3#!#1000 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#1#!#0 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#2#!#500 +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#1#!#3#!#1000 +PARTITION_FUNCTIONログインαιώνια#!#1#!#1#!#0 +PARTITION_FUNCTIONログインαιώνια#!#1#!#2#!#500 +PARTITION_FUNCTIONログインαιώνια#!#1#!#3#!#1000 +PartitionFunctionHavingDifferentCollationInput#!#1#!#1#!#châu phố +PartitionFunctionHavingDifferentCollationInput#!#1#!#2#!#Jane Smith +PartitionFunctionHavingDifferentCollationInput#!#1#!#3#!#John Doe +PartitionFunctionHavingDifferentCollationInput#!#1#!#4#!#Müller GmbH +PartitionFunctionInsideProc1#!#1#!#1#!#500 +PartitionFunctionInsideProc1#!#1#!#2#!#1000 +PartitionFunctionInsideProc1#!#1#!#3#!#10000 +PartitionFunctionInsideProc2#!#1#!#1#!#500 +PartitionFunctionInsideProc2#!#1#!#2#!#1000 +PartitionFunctionInsideProc2#!#1#!#3#!#10000 +PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#2#!#100 +PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#3#!#1000 +PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#1#!#4#!#10000 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#1#!#0 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#2#!#100 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#3#!#1000 +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#1#!#4#!#10000 +SmallDateTimePartitionFunction#!#1#!#1#!#2019-01-01 00:00:00.0 +SmallDateTimePartitionFunction#!#1#!#2#!#2022-01-01 00:00:00.0 +SmallDateTimePartitionFunction#!#1#!#3#!#2022-07-01 00:00:00.0 +SmallIntPartitionFunction#!#1#!#1#!#-32768 +SmallIntPartitionFunction#!#1#!#2#!#0 +SmallIntPartitionFunction#!#1#!#3#!#32767 +SmallMoneyPartitionFunction#!#1#!#1#!#2.5679 +SmallMoneyPartitionFunction#!#1#!#2#!#3.5679 +SmallMoneyPartitionFunction#!#1#!#3#!#4.9100 +SqlVariantPartitionFunction#!#1#!#1#!#abc +SqlVariantPartitionFunction#!#1#!#2#!#Apple +SqlVariantPartitionFunction#!#1#!#3#!#Banana +SqlVariantPartitionFunction#!#1#!#4#!#Some text +SqlVariantPartitionFunction#!#1#!#5#!#xyz +TinyIntPartitionFunction#!#1#!#1#!#0 +TinyIntPartitionFunction#!#1#!#2#!#128 +TinyIntPartitionFunction#!#1#!#3#!#255 +UniqueIdentifierPartitionFunction#!#1#!#1#!#00000000-0000-0000-0000-000000000000 +UniqueIdentifierPartitionFunction#!#1#!#2#!#6F9619FF-8B86-D011-B42D-00C04FC964FF +UniqueIdentifierPartitionFunction#!#1#!#3#!#FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF +VarCharPartitionFunction#!#1#!#1#!#Apple +VarCharPartitionFunction#!#1#!#2#!#Banana +VarCharPartitionFunction#!#1#!#3#!#Cherry +VarCharPartitionFunction#!#1#!#4#!#Date +VarCharPartitionFunction#!#1#!#5#!#Mango +~~END~~ + + +SELECT * FROM GetRangeMetadataVarBinaryFunctionView +GO +~~START~~ +nvarchar#!#int#!#int#!#varbinary +BinaryPartitionFunction#!#1#!#1#!#00000000 +BinaryPartitionFunction#!#1#!#2#!#04000000 +BinaryPartitionFunction#!#1#!#3#!#08000000 +BinaryPartitionFunction#!#1#!#4#!#C0000000 +VarBinaryPartitionFunction#!#1#!#1#!#0000000000000000 +VarBinaryPartitionFunction#!#1#!#2#!#4000000000000000 +VarBinaryPartitionFunction#!#1#!#3#!#8000000000000000 +VarBinaryPartitionFunction#!#1#!#4#!#C000000000000000 +~~END~~ + + +SELECT * FROM GetParameterMetadataView +GO +~~START~~ +nvarchar#!#varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar +BigIntPartitionFunction#!#bigint#!#1#!#8#!#19#!#0#!# +BinaryPartitionFunction#!#binary#!#1#!#8000#!#0#!#0#!# +CharPartitionFunction#!#char#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as +DatePartitionFunction#!#date#!#1#!#3#!#10#!#0#!# +DateTime2PartitionFunction#!#datetime2#!#1#!#8#!#26#!#6#!# +DateTimePartitionFunction#!#datetime#!#1#!#8#!#23#!#3#!# +DecimalPartitionFunction#!#decimal#!#1#!#17#!#38#!#38#!# +IntPartitionFunction#!#int#!#1#!#4#!#10#!#0#!# +MoneyPartitionFunction#!#money#!#1#!#8#!#19#!#4#!# +NCharPartitionFunction#!#nchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as +NumericPartitionFunction#!#numeric#!#1#!#17#!#38#!#38#!# +NVarCharPartitionFunction#!#nvarchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as +PARTITION_FUNCTION 유니코드스키마👻 #!#int#!#1#!#4#!#10#!#0#!# +PARTITION_FUNCTION 😎$@ #123 🌍rder #!#int#!#1#!#4#!#10#!#0#!# +PARTITION_FUNCTIONログインαιώνια#!#int#!#1#!#4#!#10#!#0#!# +PartitionFunctionHavingDifferentCollationInput#!#nvarchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as +PartitionFunctionInsideProc1#!#int#!#1#!#4#!#10#!#0#!# +PartitionFunctionInsideProc2#!#int#!#1#!#4#!#10#!#0#!# +PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#bigint#!#1#!#8#!#19#!#0#!# +PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#bigint#!#1#!#8#!#19#!#0#!# +SmallDateTimePartitionFunction#!#smalldatetime#!#1#!#4#!#16#!#0#!# +SmallIntPartitionFunction#!#smallint#!#1#!#2#!#5#!#0#!# +SmallMoneyPartitionFunction#!#smallmoney#!#1#!#4#!#10#!#4#!# +SqlVariantPartitionFunction#!#sql_variant#!#1#!#8016#!#0#!#0#!#bbf_unicode_cp1_ci_as +TinyIntPartitionFunction#!#tinyint#!#1#!#1#!#3#!#0#!# +UniqueIdentifierPartitionFunction#!#uniqueidentifier#!#1#!#16#!#0#!#0#!# +VarBinaryPartitionFunction#!#varbinary#!#1#!#8000#!#0#!#0#!# +VarCharPartitionFunction#!#varchar#!#1#!#8000#!#0#!#0#!#bbf_unicode_cp1_ci_as +~~END~~ + + +SELECT * FROM GetPartitionSchemesMetadataView +GO +~~START~~ +nvarchar#!#nvarchar#!#char#!#nvarchar#!#bit#!#bit +BigIntPartitionScheme#!#BigIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +BinaryPartitionScheme#!#BinaryPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +CharPartitionScheme#!#CharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +DatePartitionScheme#!#DatePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +DateTime2PartitionScheme#!#DateTime2PartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +DateTimePartitionScheme#!#DateTimePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +DecimalPartitionScheme#!#DecimalPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +IntPartitionScheme#!#IntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +MoneyPartitionScheme#!#MoneyPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +NCharPartitionScheme#!#NCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +NumericPartitionScheme#!#NumericPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +NVarCharPartitionScheme#!#NVarCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEME 유니코드스키마👻 #!#PARTITION_FUNCTION 유니코드스키마👻 #!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEME 😎$@ #123 🌍rder #!#PARTITION_FUNCTION 😎$@ #123 🌍rder #!#PS#!#PARTITION_SCHEME#!#0#!#0 +PARTITION_SCHEMEログインαιώνια#!#PARTITION_FUNCTIONログインαιώνια#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PartitionSchemeInsideProc1#!#PartitionFunctionInsideProc1#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PartitionSchemeInsideProc2#!#PartitionFunctionInsideProc2#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder#!#PS#!#PARTITION_SCHEME#!#0#!#0 +SmallDateTimePartitionScheme#!#SmallDateTimePartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +SmallIntPartitionScheme#!#SmallIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +SmallMoneyPartitionScheme#!#SmallMoneyPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +SqlVariantPartitionScheme#!#SqlVariantPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +TinyIntPartitionScheme#!#TinyIntPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +UniqueIdentifierPartitionScheme#!#UniqueIdentifierPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +VarBinaryPartitionScheme#!#VarBinaryPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +VarCharPartitionScheme#!#VarCharPartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +~~END~~ + + +SELECT * FROM PartitionFunctionContainsDuplicateName() +GO +~~START~~ +nvarchar +~~END~~ + + +SELECT * FROM PartitionFunctionContainsDuplicateIDs() +GO +~~START~~ +int +~~END~~ + + +SELECT * FROM PartitionSchemeContainsDuplicateName() +GO +~~START~~ +nvarchar +~~END~~ + + +SELECT * FROM PartitionSchemeContainsDuplicateIDs() +GO +~~START~~ +int +~~END~~ + + + + + + + + + + +-------------------------------------------------- +--- Test Partition Function Argument Limit +-------------------------------------------------- +-- create with max allowed limit +DECLARE @partition_count INT = 14998; +DECLARE @partition_interval INT = 1000; +DECLARE @partition_function_definition VARCHAR(MAX) = 'CREATE PARTITION FUNCTION PartitionFunctionWith14999Arg (int) AS RANGE RIGHT FOR VALUES ('; +-- Build the partition function definition +DECLARE @i INT = 1; +WHILE @i <= @partition_count +BEGIN + SET @partition_function_definition = @partition_function_definition + CAST((@i * @partition_interval) AS VARCHAR(10)) + ', ' + SET @i = @i + 1; +END +SET @partition_function_definition = @partition_function_definition + CAST((@i * @partition_interval) AS VARCHAR(10)) + ')' +-- Execute the partition function creation +EXEC (@partition_function_definition) +GO + +SELECT fanout FROM sys.partition_functions WHERE name = 'PartitionFunctionWith14999Arg' +GO +~~START~~ +int +15000 +~~END~~ + + +DROP PARTITION FUNCTION PartitionFunctionWith14999Arg +GO + + + + + + + +-- create when arg > max allowed limit should throw error +DECLARE @partition_count INT = 14999; +DECLARE @partition_interval INT = 1000; +DECLARE @partition_function_definition VARCHAR(MAX) = 'CREATE PARTITION FUNCTION PartitionFunctionWith15000Arg (int) AS RANGE RIGHT FOR VALUES ('; +-- Build the partition function definition +DECLARE @i INT = 1; +WHILE @i <= @partition_count +BEGIN + SET @partition_function_definition = @partition_function_definition + CAST((@i * @partition_interval) AS VARCHAR(10)) + ', ' + SET @i = @i + 1; +END +SET @partition_function_definition = @partition_function_definition + CAST((@i * @partition_interval) AS VARCHAR(10)) + ')' +-- Execute the partition function creation +EXEC (@partition_function_definition) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: CREATE/ALTER partition function failed as only a maximum of 15000 partitions can be created.)~~ + + + +-------------------------------------------------- +--- Test Partition Function/Scheme Name Limit +-------------------------------------------------- +CREATE PARTITION FUNCTION PartitionFunctionNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz (bigint) +AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The identifier that starts with 'PartitionFunctionNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno' is too long. Maximum length is 128.)~~ + + +CREATE PARTITION SCHEME PartitionSchemeNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz AS +PARTITION PartitionFunctionDoesNotExists +ALL TO ([PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The identifier that starts with 'PartitionSchemeNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq' is too long. Maximum length is 128.)~~ + + + +-------------------------------------------------- +--- TO test Permission +-------------------------------------------------- +USE PartitionDb; +GO + +CREATE LOGIN partition_l1 WITH PASSWORD = '12345678'; +GO + +CREATE USER partition_u1 FOR LOGIN partition_l1; +GO + +-- tsql user=partition_l1 password=12345678 +USE PartitionDb; +GO + +SELECT CURRENT_USER +GO +~~START~~ +varchar +partition_u1 +~~END~~ + + + +-- CREATE/DROP should throw permission error +------------------------------------------------------------ +--- only db owner and logins which are member of sysadmin +--- are allowed to create/drop partition function and scheme +------------------------------------------------------------ +CREATE PARTITION FUNCTION TestPartitionFunction (int) +AS RANGE RIGHT FOR VALUES (500, 1000, 10000); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + + +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION PartitionFunctionDoesNotExists +ALL TO ([PRIMARY]); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + + +DROP PARTITION FUNCTION IntPartitionFunction +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the partition function 'IntPartitionFunction', because it does not exist or you do not have permission.)~~ + + +DROP PARTITION SCHEME IntPartitionScheme +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the partition scheme 'IntPartitionScheme', because it does not exist or you do not have permission.)~~ + + +------------------------------------------ +--- all user can access the metadata +------------------------------------------ +SELECT + name, type, type_desc, fanout, boundary_value_on_right, is_system + FROM + sys.partition_functions +go +~~START~~ +nvarchar#!#char#!#nvarchar#!#int#!#bit#!#bit +PartitionDb_PartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +~~END~~ + + +SELECT + ps.name as scheme_name, pf.name as function_name, ps.type, ps.type_desc, ps.is_default, ps.is_system + FROM + sys.partition_schemes ps + INNER JOIN + sys.partition_functions pf on (ps.function_id = pf.function_id) +go +~~START~~ +nvarchar#!#nvarchar#!#char#!#nvarchar#!#bit#!#bit +PartitionDb_PartitionScheme#!#PartitionDb_PartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +~~END~~ + + + +-- psql + +------------------------------------------------------------ +--- all user can use the metadata of the partition scheme +--- to create table if they permission to create table +------------------------------------------------------------ +-- grant create permission to user on schema so that it can create table +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + EXECUTE 'GRANT CREATE ON SCHEMA ' || quote_ident(schema_name) || ' TO partitiondb_partition_u1'; +END$$; +GO + +-- tsql user=partition_l1 password=12345678 +USE PartitionDb; +GO + +SELECT CURRENT_USER +GO +~~START~~ +varchar +partition_u1 +~~END~~ + + +CREATE TABLE PartitionDb_TestPartitionTable ( + Id INT, + Value sys.varchar(20) +) ON PartitionDb_PartitionScheme(Id); +GO + +DROP TABLE PartitionDb_TestPartitionTable +GO + +-- psql + +-- revoke create permission from user on schema +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + EXECUTE 'REVOKE CREATE ON SCHEMA ' || quote_ident(schema_name) || ' FROM partitiondb_partition_u1'; +END$$; +GO + +-- tsql +----------------------------------------------------------------------------------- +--- DB owner should be able to create/drop partition function and scheme +---------------------------------------------------------------------------------- +-- make the user a DB owner +USE PartitionDb; +GO + +DROP USER partition_u1; +GO + +execute sp_changedbowner 'partition_l1' +GO + +-- tsql user=partition_l1 password=12345678 +USE PartitionDb; +GO + +SELECT CURRENT_USER +GO +~~START~~ +varchar +dbo +~~END~~ + +-- CREATE/DROP should work now +CREATE PARTITION FUNCTION TestPartitionFunction (int) +AS RANGE RIGHT FOR VALUES (500, 1000, 10000); +Go + +CREATE PARTITION SCHEME TestPartitionScheme AS +PARTITION TestPartitionFunction +ALL TO ([PRIMARY]); +GO + +DROP PARTITION SCHEME TestPartitionScheme +go + +DROP PARTITION FUNCTION TestPartitionFunction +go + +-- tsql +USE master +GO + + +------------------------------------------------------------------------------------------------------------ +--- Test error during Implicit Conversion of range values in Partition Function for each datatypes +------------------------------------------------------------------------------------------------------------ +CREATE PARTITION FUNCTION NewIntPartitionFunction (int) +AS RANGE RIGHT FOR VALUES (500, 1000, cast('xyz' as varchar)); +-- having duplicates also, but first it should try to convert and fail +CREATE PARTITION FUNCTION NewBigIntPartitionFunction (bigint) +AS RANGE RIGHT FOR VALUES (1000, 1000, 1000, cast('xyz' as varchar), 1000, 1000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewSmallIntPartitionFunction (smallint) +AS RANGE RIGHT FOR VALUES ('xyz', 32767, -32768); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 1 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewTinyIntPartitionFunction (tinyint) +AS RANGE RIGHT FOR VALUES (0, 255, cast('xyz' as varchar)); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewDecimalPartitionFunction (decimal(10, 5)) +AS RANGE RIGHT FOR VALUES (0.0, 300.0, 200.0, 'xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 4 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewNumericPartitionFunction (numeric(5, 2)) +AS RANGE RIGHT FOR VALUES (0.0, 30.0, 10.0, 'xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 4 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewDatePartitionFunction (date) +AS RANGE RIGHT FOR VALUES ('2022-07-01', '2022-01-01','xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewDateTimePartitionFunction (datetime) +AS RANGE RIGHT FOR VALUES ('2022-01-01', '2022-07-01 00:00:00', 'xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewDateTime2PartitionFunction (datetime2(3)) +AS RANGE RIGHT FOR VALUES ('2022-01-01 00:00:00.000', '2022-07-01 00:00:00.000', 'xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewSmallDateTimePartitionFunction (smalldatetime) +AS RANGE RIGHT FOR VALUES ('2022-01-01', '2022-07-01', cast(0x123 as binary(4))); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewCharPartitionFunction (char(5)) +AS RANGE RIGHT FOR VALUES ('A', 'F', 'K', 'P', 'U', 'Z', cast(0x123 as binary(4))); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 7 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewNCharPartitionFunction (nchar(5)) +AS RANGE RIGHT FOR VALUES (N'A', N'F', N'K', N'P', N'U', N'Z', cast(0x123 as binary(4))); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 7 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewBinaryPartitionFunction (binary(4)) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 'xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 4 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewVarBinaryPartitionFunction (varbinary(8)) +AS RANGE RIGHT FOR VALUES (0x0000000000000000, 0x8000000000000000, 0x4000000000000000, 'xyz'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 4 to partition function parameter type.)~~ + + +CREATE PARTITION FUNCTION NewUniqueIdentifierPartitionFunction (uniqueidentifier) +AS RANGE RIGHT FOR VALUES ('00000000-0000-0000-0000-000000000000', 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', 123); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could not implicitly convert range values type specified at ordinal 3 to partition function parameter type.)~~ + + + +-------------------------------------------------- +--- DROP PARTITION FUNCTION/SCHEME/TABLE using procedure +-------------------------------------------------- +EXEC PartitionProcedureDropPartitionTable +GO + +EXEC PartitionProcedureDropPartitionScheme +GO + +EXEC PartitionProcedureDropPartitionFunction +GO + +EXEC PartitionProcedureDropPartitionFunctionSchemeAndTable +GO + + +--------------------------------------------------------------------------- +--- PARTITIONED TABLES test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedTableListFromSysTablesView +GO +~~START~~ +varchar +partition_vu_prepare_bigint_table +partition_vu_prepare_binary_table +partition_vu_prepare_char_table +partition_vu_prepare_date_table +partition_vu_prepare_datetime_table +partition_vu_prepare_datetime2_table +partition_vu_prepare_decimal_table +partition_vu_prepare_int_table +partition_vu_prepare_money_table +partition_vu_prepare_nchar_table +partition_vu_prepare_numeric_table +partition_vu_prepare_nvarchar_table +partition_vu_prepare_smalldatetime_table +partition_vu_prepare_smallint_table +partition_vu_prepare_smallmoney_table +partition_vu_prepare_sqlvariant_table +partition_vu_prepare_tinyint_table +partition_vu_prepare_uniqueidentifier_table +partition_vu_prepare_varbinary_table +partition_vu_prepare_varchar_table +~~END~~ + + +--------------------------------------------------------------------------- +--- PARTITIONED INDEX test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedIndexListFromSysIndexesView +GO +~~START~~ +varchar +partition_vu_prepare_bigint_ind877afb285426cec9d46b047e3cf96f63 +partition_vu_prepare_binary_ind48a88b3c8178211af1ed1dcf4cfbe503 +partition_vu_prepare_char_index32fed8129381de1b5745e90cd811516f +partition_vu_prepare_date_indexf571a291edad587ba646fc34c4566844 +partition_vu_prepare_datetime_i364577d0a406eee6e806be980ac15d2e +partition_vu_prepare_datetime2_4cad7647322c234b34b97cddb3cd1ad6 +partition_vu_prepare_decimal_infc7570aeccbb040dde39974c476a7ec9 +partition_vu_prepare_int_indexpbbe9a6f0ef5edf6e63fa853dac4ed046 +partition_vu_prepare_int_table_id_key +partition_vu_prepare_money_inde9b6a61ad06c0883c6d0f95b2fec9eeee +partition_vu_prepare_nchar_indecdc4872501ea902494c8f710f4e9dbb1 +partition_vu_prepare_numeric_inf04f315c86929345e23bee80713cf963 +partition_vu_prepare_nvarchar_if89fa8cc46282fa6dc23e9f5b834f3ec +partition_vu_prepare_smalldatetfe8f8bfb8c766f9a1bcd804238ff35d8 +partition_vu_prepare_smallint_i3eae48e3a131ed23416aa2891b58d579 +partition_vu_prepare_smallmoney68389bf5dc5c581b33c4dbb8a3dc1dc8 +partition_vu_prepare_sqlvariant2cb9b179fd5df94b1777b1976b05ad47 +partition_vu_prepare_tinyint_in02b271c73e639954190c6a45bd5dd1bb +partition_vu_prepare_uniqueidend39220cd3f46c5b2cea8c338a387aedf +partition_vu_prepare_varbinary_26e1223f68c4186a96126a57446ac386 +partition_vu_prepare_varchar_inc528f397ba573964de161e03035b8f08 +~~END~~ + + + +---------------------------------------------------------------------------------------------- +--- System views should list only metadata of Partitioned table(not of the partitions) +---------------------------------------------------------------------------------------------- +SELECT count(*) from sys.tables where name = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +3 +~~END~~ + + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from sys.all_objects where name = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from information_schema.columns where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.tables where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +2 +~~END~~ + + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = 'partition_vu_prepare_int_table' +GO +~~START~~ +int +1 +~~END~~ + + +--------------------------------------------------------- +--- System views should not list metadata of Partitions +--------------------------------------------------------- +SELECT count(*) from sys.tables where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.all_objects where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.columns where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.tables where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO +~~START~~ +int +0 +~~END~~ + + + + +-- psql +--------------------------------------------------------------------------- +--- Run analyze on each table and enable query plan +--------------------------------------------------------------------------- +ANALYZE master_dbo.partition_vu_prepare_int_table; +ANALYZE master_dbo.partition_vu_prepare_bigint_table; +ANALYZE master_dbo.partition_vu_prepare_smallint_table; +ANALYZE master_dbo.partition_vu_prepare_tinyint_table; +ANALYZE master_dbo.partition_vu_prepare_decimal_table; +ANALYZE master_dbo.partition_vu_prepare_numeric_table; +ANALYZE master_dbo.partition_vu_prepare_money_table; +ANALYZE master_dbo.partition_vu_prepare_smallmoney_table; +ANALYZE master_dbo.partition_vu_prepare_date_table; +ANALYZE master_dbo.partition_vu_prepare_datetime_table; +ANALYZE master_dbo.partition_vu_prepare_datetime2_table; +ANALYZE master_dbo.partition_vu_prepare_smalldatetime_table; +ANALYZE master_dbo.partition_vu_prepare_char_table; +ANALYZE master_dbo.partition_vu_prepare_varchar_table; +ANALYZE master_dbo.partition_vu_prepare_nvarchar_table; +ANALYZE master_dbo.partition_vu_prepare_nchar_table; +ANALYZE master_dbo.partition_vu_prepare_binary_table; +ANALYZE master_dbo.partition_vu_prepare_varbinary_table; +ANALYZE master_dbo.partition_vu_prepare_uniqueidentifier_table; +ANALYZE master_dbo.partition_vu_prepare_sqlvariant_table; +GO + +-- tsql +SELECT set_config('babelfishpg_tsql.explain_costs', 'off', false) +GO +~~START~~ +text +off +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +--------------------------------------------------------------------------- +--- Query plan of select on partitioned tables +--------------------------------------------------------------------------- +SELECT * FROM partition_vu_prepare_int_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_int_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_1" partition_vu_prepare_int_table_1 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_2" partition_vu_prepare_int_table_2 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_3" partition_vu_prepare_int_table_3 + -> Seq Scan on "363863941f079adaa9aa733200e57c9f_partition_0" partition_vu_prepare_int_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.744 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_bigint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_bigint_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_1" partition_vu_prepare_bigint_table_1 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_2" partition_vu_prepare_bigint_table_2 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_3" partition_vu_prepare_bigint_table_3 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_4" partition_vu_prepare_bigint_table_4 + -> Seq Scan on "548bb344374ce8d65342b36428375873_partition_0" partition_vu_prepare_bigint_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.115 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallint_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_1" partition_vu_prepare_smallint_table_1 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_2" partition_vu_prepare_smallint_table_2 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_3" partition_vu_prepare_smallint_table_3 + -> Seq Scan on "12025e103721b70925744c196ce004cd_partition_0" partition_vu_prepare_smallint_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.105 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_tinyint_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_tinyint_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_1" partition_vu_prepare_tinyint_table_1 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_2" partition_vu_prepare_tinyint_table_2 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_3" partition_vu_prepare_tinyint_table_3 + -> Seq Scan on "61446d711d19b5970809387caa7fd3d3_partition_0" partition_vu_prepare_tinyint_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_decimal_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_decimal_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_1 partition_vu_prepare_decimal_table_1 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_2 partition_vu_prepare_decimal_table_2 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_3 partition_vu_prepare_decimal_table_3 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_4 partition_vu_prepare_decimal_table_4 + -> Seq Scan on cda2902d769fd61eb60b1a461650212f_partition_0 partition_vu_prepare_decimal_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.088 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_numeric_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_numeric_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_1" partition_vu_prepare_numeric_table_1 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_2" partition_vu_prepare_numeric_table_2 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_3" partition_vu_prepare_numeric_table_3 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_4" partition_vu_prepare_numeric_table_4 + -> Seq Scan on "57405760297bb338f333c148aac5f845_partition_0" partition_vu_prepare_numeric_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.088 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_money_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_money_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_1" partition_vu_prepare_money_table_1 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_2" partition_vu_prepare_money_table_2 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_3" partition_vu_prepare_money_table_3 + -> Seq Scan on "640187c54e2c2984d190957d245a5fa5_partition_0" partition_vu_prepare_money_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.086 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallmoney_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallmoney_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1" partition_vu_prepare_smallmoney_table_1 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_2" partition_vu_prepare_smallmoney_table_2 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_3" partition_vu_prepare_smallmoney_table_3 + -> Seq Scan on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0" partition_vu_prepare_smallmoney_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.092 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_date_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_date_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_1" partition_vu_prepare_date_table_1 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_2" partition_vu_prepare_date_table_2 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_3" partition_vu_prepare_date_table_3 + -> Seq Scan on "4867824426e52acac5c93d9cbe8aa366_partition_0" partition_vu_prepare_date_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.089 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_1" partition_vu_prepare_datetime_table_1 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_2" partition_vu_prepare_datetime_table_2 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_3" partition_vu_prepare_datetime_table_3 + -> Seq Scan on "751ce655481adf15600727bf291667f7_partition_0" partition_vu_prepare_datetime_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.096 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime2_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime2_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_1" partition_vu_prepare_datetime2_table_1 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_2" partition_vu_prepare_datetime2_table_2 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_3" partition_vu_prepare_datetime2_table_3 + -> Seq Scan on "5ed003cf80dacbb8cce0b21e175f7f94_partition_0" partition_vu_prepare_datetime2_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.092 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smalldatetime_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smalldatetime_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_1 partition_vu_prepare_smalldatetime_table_1 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_2 partition_vu_prepare_smalldatetime_table_2 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_3 partition_vu_prepare_smalldatetime_table_3 + -> Seq Scan on b5c2e665ec4a1219ba8510e33e45379b_partition_0 partition_vu_prepare_smalldatetime_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_char_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_char_table +Gather + Workers Planned: 4 + -> Parallel Append + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_1" partition_vu_prepare_char_table_1 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_2" partition_vu_prepare_char_table_2 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_4" partition_vu_prepare_char_table_4 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_6" partition_vu_prepare_char_table_6 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_0" partition_vu_prepare_char_table_8 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_3" partition_vu_prepare_char_table_3 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_5" partition_vu_prepare_char_table_5 + -> Parallel Seq Scan on "5d20bd977eb6e6f1304dec45598c09f5_partition_7" partition_vu_prepare_char_table_7 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.091 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varchar_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_1" partition_vu_prepare_varchar_table_1 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_2" partition_vu_prepare_varchar_table_2 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_3" partition_vu_prepare_varchar_table_3 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_4" partition_vu_prepare_varchar_table_4 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_5" partition_vu_prepare_varchar_table_5 + -> Seq Scan on "933a5c7f0de13890324e53ee0711424b_partition_0" partition_vu_prepare_varchar_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.093 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nvarchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nvarchar_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_1" partition_vu_prepare_nvarchar_table_1 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_2" partition_vu_prepare_nvarchar_table_2 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_3" partition_vu_prepare_nvarchar_table_3 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_4" partition_vu_prepare_nvarchar_table_4 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_5" partition_vu_prepare_nvarchar_table_5 + -> Seq Scan on "320465af1d1bd21f5b29c57f9f4e5c51_partition_0" partition_vu_prepare_nvarchar_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.092 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nchar_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nchar_table +Gather + Workers Planned: 4 + -> Parallel Append + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_1 partition_vu_prepare_nchar_table_1 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_2 partition_vu_prepare_nchar_table_2 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_4 partition_vu_prepare_nchar_table_4 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_6 partition_vu_prepare_nchar_table_6 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_0 partition_vu_prepare_nchar_table_8 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_3 partition_vu_prepare_nchar_table_3 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_5 partition_vu_prepare_nchar_table_5 + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_7 partition_vu_prepare_nchar_table_7 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_binary_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_binary_table +Gather + Workers Planned: 3 + -> Parallel Append + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_1" partition_vu_prepare_binary_table_1 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_2" partition_vu_prepare_binary_table_2 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_3" partition_vu_prepare_binary_table_3 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_4" partition_vu_prepare_binary_table_4 + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_0" partition_vu_prepare_binary_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varbinary_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varbinary_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_1" partition_vu_prepare_varbinary_table_1 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_2" partition_vu_prepare_varbinary_table_2 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_3" partition_vu_prepare_varbinary_table_3 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_4" partition_vu_prepare_varbinary_table_4 + -> Seq Scan on "77718961234110c3a22a3c977bc252d8_partition_0" partition_vu_prepare_varbinary_table_5 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.100 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_uniqueidentifier_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_1 partition_vu_prepare_uniqueidentifier_table_1 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_2 partition_vu_prepare_uniqueidentifier_table_2 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_3 partition_vu_prepare_uniqueidentifier_table_3 + -> Seq Scan on f3baf999c06d6ea82082a4c549baeb77_partition_0 partition_vu_prepare_uniqueidentifier_table_4 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.092 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_sqlvariant_table; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_sqlvariant_table +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_1" partition_vu_prepare_sqlvariant_table_1 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_2" partition_vu_prepare_sqlvariant_table_2 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_3" partition_vu_prepare_sqlvariant_table_3 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_4" partition_vu_prepare_sqlvariant_table_4 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_5" partition_vu_prepare_sqlvariant_table_5 + -> Seq Scan on "69727aecbd7d094d31958d173a958827_partition_0" partition_vu_prepare_sqlvariant_table_6 +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.090 ms +~~END~~ + + + +----------------------------------------------------------------------------------------- +--- Query plan of select on partitioned tables with predicate and enforced index scan +----------------------------------------------------------------------------------------- +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'off', false); +SELECT set_config('enable_bitmapscan', 'off', false); +GO +~~START~~ +text +off +~~END~~ + +~~START~~ +text +off +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "363863941f079adaa9aa733200e57c9f_partition_1_id_key" on "363863941f079adaa9aa733200e57c9f_partition_1" partition_vu_prepare_int_table + Index Cond: ((id >= 0) AND (id < 500)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 34.406 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "548bb344374ce8d65342b36428375873_partition_1_id_idx" on "548bb344374ce8d65342b36428375873_partition_1" partition_vu_prepare_bigint_table + Index Cond: ((id >= 0) AND (id < 100)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.198 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "12025e103721b70925744c196ce004cd_partition_1_id_idx" on "12025e103721b70925744c196ce004cd_partition_1" partition_vu_prepare_smallint_table + Index Cond: ((id >= '-32768'::integer) AND (id < 0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 7.314 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "61446d711d19b5970809387caa7fd3d3_partition_1_id_idx" on "61446d711d19b5970809387caa7fd3d3_partition_1" partition_vu_prepare_tinyint_table + Index Cond: (((id)::smallint >= 0) AND ((id)::smallint < 128)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.157 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using cda2902d769fd61eb60b1a461650212f_partition_1_id_idx on cda2902d769fd61eb60b1a461650212f_partition_1 partition_vu_prepare_decimal_table + Index Cond: (((id)::numeric >= 0.0) AND ((id)::numeric < 100.0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.493 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "57405760297bb338f333c148aac5f845_partition_1_id_idx" on "57405760297bb338f333c148aac5f845_partition_1" partition_vu_prepare_numeric_table + Index Cond: ((id >= 0.0) AND (id < 10.0)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.158 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789 +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Index Scan using "640187c54e2c2984d190957d245a5fa5_partition_1_id_idx" on "640187c54e2c2984d190957d245a5fa5_partition_1" partition_vu_prepare_money_table_1 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) + -> Index Scan using "640187c54e2c2984d190957d245a5fa5_partition_0_id_idx" on "640187c54e2c2984d190957d245a5fa5_partition_0" partition_vu_prepare_money_table_2 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.218 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789 +Gather + Workers Planned: 1 + Single Copy: true + -> Append + -> Index Scan using "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1_id_idx" on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_1" partition_vu_prepare_smallmoney_table_1 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) + -> Index Scan using "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0_id_idx" on "8acfdf2e7ec8a3fb29dd9f735c4d58b5_partition_0" partition_vu_prepare_smallmoney_table_2 + Index Cond: (((id)::fixeddecimal >= 2.56789) AND ((id)::fixeddecimal < 3.56789)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.156 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "4867824426e52acac5c93d9cbe8aa366_partition_1_id_idx" on "4867824426e52acac5c93d9cbe8aa366_partition_1" partition_vu_prepare_date_table + Index Cond: ((id >= '2022-01-01'::date) AND (id < '2022-07-01'::date)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.605 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "751ce655481adf15600727bf291667f7_partition_1_id_idx" on "751ce655481adf15600727bf291667f7_partition_1" partition_vu_prepare_datetime_table + Index Cond: ((id >= '2019-01-01 00:00:00'::datetime) AND (id < '2022-01-01 00:00:00'::datetime)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.174 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "5ed003cf80dacbb8cce0b21e175f7f94_partition_1_id_idx" on "5ed003cf80dacbb8cce0b21e175f7f94_partition_1" partition_vu_prepare_datetime2_table + Index Cond: ((id >= '2019-01-01 00:00:00'::datetime2) AND (id < '2022-01-01 00:00:00'::datetime2)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.163 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using b5c2e665ec4a1219ba8510e33e45379b_partition_1_id_idx on b5c2e665ec4a1219ba8510e33e45379b_partition_1 partition_vu_prepare_smalldatetime_table + Index Cond: ((id >= '2019-01-01 00:00:00'::smalldatetime) AND (id < '2022-01-01 00:00:00'::smalldatetime)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.161 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "5d20bd977eb6e6f1304dec45598c09f5_partition_1_id_idx" on "5d20bd977eb6e6f1304dec45598c09f5_partition_1" partition_vu_prepare_char_table + Index Cond: ((id >= 'A'::bpchar) AND (id < 'B'::bpchar)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.167 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "933a5c7f0de13890324e53ee0711424b_partition_1_id_idx" on "933a5c7f0de13890324e53ee0711424b_partition_1" partition_vu_prepare_varchar_table + Index Cond: ((id >= 'Apple'::"varchar") AND (id < 'Banana'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.160 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "320465af1d1bd21f5b29c57f9f4e5c51_partition_1_id_idx" on "320465af1d1bd21f5b29c57f9f4e5c51_partition_1" partition_vu_prepare_nvarchar_table + Index Cond: (((id)::"varchar" >= 'Apple'::"varchar") AND ((id)::"varchar" < 'Banana'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.162 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B' +Gather + Workers Planned: 4 + -> Parallel Append + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_3 partition_vu_prepare_nchar_table_3 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_5 partition_vu_prepare_nchar_table_5 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_7 partition_vu_prepare_nchar_table_7 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_1 partition_vu_prepare_nchar_table_1 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_2 partition_vu_prepare_nchar_table_2 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_4 partition_vu_prepare_nchar_table_4 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_6 partition_vu_prepare_nchar_table_6 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) + -> Parallel Seq Scan on e3b6f45b64d480f285db54a94209b4bc_partition_0 partition_vu_prepare_nchar_table_8 + Filter: (((id)::"varchar" >= 'A'::"varchar") AND ((id)::"varchar" < 'B'::"varchar")) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.165 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400 +Gather + Workers Planned: 3 + -> Parallel Append + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_1" partition_vu_prepare_binary_table_1 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_2" partition_vu_prepare_binary_table_2 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_3" partition_vu_prepare_binary_table_3 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_4" partition_vu_prepare_binary_table_4 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) + -> Seq Scan on "3a3cd2fe373a5dc4b9281d49f7960143_partition_0" partition_vu_prepare_binary_table_5 + Filter: (((id)::bbf_varbinary >= '0x0000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x0400'::bbf_varbinary)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 6.791 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000 +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "77718961234110c3a22a3c977bc252d8_partition_1_id_idx" on "77718961234110c3a22a3c977bc252d8_partition_1" partition_vu_prepare_varbinary_table + Index Cond: (((id)::bbf_varbinary >= '0x0000000000000000'::bbf_varbinary) AND ((id)::bbf_varbinary < '0x4000000000000000'::bbf_varbinary)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.163 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'; +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF' +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using f3baf999c06d6ea82082a4c549baeb77_partition_1_id_idx on f3baf999c06d6ea82082a4c549baeb77_partition_1 partition_vu_prepare_uniqueidentifier_table + Index Cond: ((id >= '00000000-0000-0000-0000-000000000000'::uniqueidentifier) AND (id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'::uniqueidentifier)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 0.187 ms +~~END~~ + + +SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)); +GO +~~START~~ +text +Query Text: SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)) +Gather + Workers Planned: 1 + Single Copy: true + -> Index Scan using "69727aecbd7d094d31958d173a958827_partition_1_id_idx" on "69727aecbd7d094d31958d173a958827_partition_1" partition_vu_prepare_sqlvariant_table + Index Cond: ((id >= 'abc '::sql_variant) AND (id < 'Apple'::sql_variant)) +~~END~~ + +~~START~~ +text +Babelfish T-SQL Batch Parsing Time: 7.057 ms +~~END~~ + + +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'on', false); +SELECT set_config('enable_bitmapscan', 'on', false); +SELECT set_config('babelfishpg_tsql.explain_costs', 'on', false) +GO +~~START~~ +text +on +~~END~~ + +~~START~~ +text +on +~~END~~ + +~~START~~ +text +on +~~END~~ + + + + +-- psql +------------------------------------------ +--- Blocked Operation For Partitioned Tables +------------------------------------------- +-- user should not be allowed to CREATE/ATTACH/DETACH partition +-- to babelfish partitioned table from psql endpoint +SET ROLE master_dbo; +GO + +-- Attempt to create new partition with random values +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +FOR VALUES FROM (0) TO (500); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: partition "nonexistenttable" would overlap partition "363863941f079adaa9aa733200e57c9f_partition_1" + Position: 157 + Server SQLState: 42P17)~~ + + +-- Attempt to create new partition with DEFAULT +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +DEFAULT +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: partition "nonexistenttable" conflicts with existing default partition "363863941f079adaa9aa733200e57c9f_partition_0" + Position: 134 + Server SQLState: 42P17)~~ + + +-- Attempt to drop partition of babelfish partitioned table from psql endpoint +DROP TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot drop the babelfish partition table '363863941f079adaa9aa733200e57c9f_partition_0'. + Server SQLState: 42704)~~ + + + +-- Attempt to detach +-- explicit schema name specified +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +RESET search_path; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to detach using CONCURRENTLY option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +CONCURRENTLY; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to detach using FINALIZE option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +FINALIZE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot detach partition from babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to attach with Default value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable DEFAULT; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot attach partition to babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + +-- Attempt to attach with random value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable FOR VALUES FROM (10) TO (20); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Cannot attach partition to babelfish partitioned table 'partition_vu_prepare_int_table'. + Server SQLState: 0A000)~~ + + + +-- user should not be allowed to modify partition +-- of babelfish partitioned table neither from psql nor tsql endpoint +-- explicit schema name specified +ALTER TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table. + Server SQLState: 0A000)~~ + + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE "363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +RESET search_path; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table. + Server SQLState: 0A000)~~ + + +RESET ROLE; +GO + +-- Attempt to ADD storage parameter to babelfish partitioned table (not on the partitions) +SET babelfishpg_tsql.sql_dialect = "tsql"; +GO + +ALTER TABLE master_dbo.partition_vu_prepare_int_table SET (autovacuum_enabled = false); +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: cannot specify storage parameters for a partitioned table + Hint: Specify storage parameters for its leaf partitions instead. + Server SQLState: 42809)~~ + + +RESET babelfishpg_tsql.sql_dialect; +GO + + +-- tsql +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + + +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +-- with explicity schema name +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Modifying partitions directly is not supported. You can modify the partitions by modifying the parent table.)~~ + + +-- Attempt to drop partition of babelfish partitioned table from tsql endpoint +DROP TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the babelfish partition table '363863941f079adaa9aa733200e57c9f_partition_0'.)~~ + + +-------------------------------------------------------------------- +--- Unsupported Option with CREATE TABLE with PARTITION SCHEME +-------------------------------------------------------------------- +-- Computed column as partitioning column is not yet supported in babelfish +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value +) +ON IntPartitionScheme(computed_col); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot use generated column in partition key)~~ + + +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value PERSISTED +) +ON IntPartitionScheme(computed_col); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot use generated column in partition key)~~ + + +-- temporary table +CREATE TABLE #TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Creation of tempopary partitioned tables is not supported in Babelfish.)~~ + + + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--------------------------------------------------------------- +-- Attempt to create with multiple columns as partitioning scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id, value); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ',' at line 10 and character position 24)~~ + + +-- Attempt to create with a partition scheme that doesn't exist and column that doesn't exist in the table +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(NonExistentColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "nonexistentcolumn" named in partition key does not exist)~~ + + +-- Attempt to create with a partition scheme that doesn't exist +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid partition scheme 'NonExistentPartitionScheme' specifed.)~~ + + +-- Attempt to use two part name with partition scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON master.IntPartitionScheme(id); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '.' at line 7 and character position 9)~~ + + +-- Attempt to create with a unique constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT UNIQUE +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: unique constraint on partitioned table must include all partitioning columns)~~ + + +-- Attempt to create with a primary key constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT PRIMARY KEY +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: unique constraint on partitioned table must include all partitioning columns)~~ + + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--- Attempt to create with an incompatible partition column data type +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable1 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON IntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'IntPartitionFunction' parameter data type 'int'.)~~ + + +CREATE TABLE TestPartitionedTable2 +( + Id INT, + PartitionColumn DATETIME +) +ON DatePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime' which is different from the partition function 'DatePartitionFunction' parameter data type 'date'.)~~ + + +CREATE TABLE TestPartitionedTable3 +( + Id INT, + PartitionColumn VARCHAR(10) +) +ON CharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'varchar' which is different from the partition function 'CharPartitionFunction' parameter data type 'char'.)~~ + + +CREATE TABLE TestPartitionedTable4 +( + Id INT, + PartitionColumn VARBINARY(10) +) +ON BinaryPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'varbinary' which is different from the partition function 'BinaryPartitionFunction' parameter data type 'binary'.)~~ + + +CREATE TABLE TestPartitionedTable5 +( + Id INT, + PartitionColumn SMALLINT +) +ON BigIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int2' which is different from the partition function 'BigIntPartitionFunction' parameter data type 'bigint'.)~~ + + +CREATE TABLE TestPartitionedTable6 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON SmallIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'SmallIntPartitionFunction' parameter data type 'smallint'.)~~ + + +CREATE TABLE TestPartitionedTable7 +( + Id INT, + PartitionColumn DECIMAL(10, 5) +) +ON TinyIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'decimal' which is different from the partition function 'TinyIntPartitionFunction' parameter data type 'tinyint'.)~~ + + +CREATE TABLE TestPartitionedTable8 +( + Id INT, + PartitionColumn BIGINT +) +ON DecimalPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int8' which is different from the partition function 'DecimalPartitionFunction' parameter data type 'decimal'.)~~ + + +CREATE TABLE TestPartitionedTable9 +( + Id INT, + PartitionColumn MONEY +) +ON NumericPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'money' which is different from the partition function 'NumericPartitionFunction' parameter data type 'numeric'.)~~ + + +CREATE TABLE TestPartitionedTable10 +( + Id INT, + PartitionColumn INT +) +ON MoneyPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'MoneyPartitionFunction' parameter data type 'money'.)~~ + + +CREATE TABLE TestPartitionedTable11 +( + Id INT, + PartitionColumn DATETIME +) +ON SmallMoneyPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime' which is different from the partition function 'SmallMoneyPartitionFunction' parameter data type 'smallmoney'.)~~ + + +CREATE TABLE TestPartitionedTable12 +( + Id INT, + PartitionColumn DATETIME2(3) +) +ON DateTimePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'datetime2' which is different from the partition function 'DateTimePartitionFunction' parameter data type 'datetime'.)~~ + + +CREATE TABLE TestPartitionedTable13 +( + Id INT, + PartitionColumn SMALLDATETIME +) +ON DateTime2PartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'smalldatetime' which is different from the partition function 'DateTime2PartitionFunction' parameter data type 'datetime2'.)~~ + + +CREATE TABLE TestPartitionedTable14 +( + Id INT, + PartitionColumn NVARCHAR(10) +) +ON SmallDateTimePartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'nvarchar' which is different from the partition function 'SmallDateTimePartitionFunction' parameter data type 'smalldatetime'.)~~ + + +CREATE TABLE TestPartitionedTable15 +( + Id INT, + PartitionColumn INT +) +ON NVarCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'NVarCharPartitionFunction' parameter data type 'nvarchar'.)~~ + + +CREATE TABLE TestPartitionedTable16 +( + Id INT, + PartitionColumn NCHAR(5) +) +ON VarCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'nchar' which is different from the partition function 'VarCharPartitionFunction' parameter data type 'varchar'.)~~ + + +CREATE TABLE TestPartitionedTable17 +( + Id INT, + PartitionColumn INT +) +ON NCharPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'int4' which is different from the partition function 'NCharPartitionFunction' parameter data type 'nchar'.)~~ + + +-- using user defined type +CREATE TYPE PartitionUserDefinedType FROM SMALLINT; +GO + +CREATE TABLE TestPartitionedTable18 +( + Id INT, + PartitionColumn PartitionUserDefinedType +) +ON BigIntPartitionScheme(PartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitioncolumn' has data type 'partitionuserdefinedtype' which is different from the partition function 'BigIntPartitionFunction' parameter data type 'bigint'.)~~ + + +DROP TYPE PartitionUserDefinedType +GO + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE Index with PARTITION SCHEME +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable ( + PartitionColumn INT, + NonPartitionColumn INT +) ON IntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestNonPartitionedTable ( + a INT, + b INT +) +GO + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonExistentColumn1) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "nonexistentcolumn1" does not exist)~~ + + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column 'nonexistentcolumn2' does not exist)~~ + + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid object name 'NonExistentPartitionScheme'.)~~ + + +-- scheme is different from the partition scheme used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON BigIntPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + +-- column specified with partition scheme is different +-- from the partition column used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (NonPartitionColumn); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + +-- should work +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (PartitionColumn); +GO + +DROP INDEX TestPartitionIndex ON TestPartitionedTable +GO + +-- usage of partition scheme on non-partitioned table (should fail) +CREATE INDEX TestPartitionIndex +ON TestNonPartitionedTable(a) +ON IntPartitionScheme (a); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Un-aligned Index is not supported in Babelfish.)~~ + + + +DROP TABLE TestPartitionedTable +GO + +DROP TABLE TestNonPartitionedTable +GO +-- psql +------------------------------------------------------------------------------------------- +--- Rename Operation on Partitioned Tables should update name in babelfish_partition_depend +--- and it should also update the name of all the partitions +------------------------------------------------------------------------------------------- +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO +~~START~~ +regclass +master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_1" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_2" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_3" +~~END~~ + + +-- tsql +-- trigger rename from TSQL endpoint +EXEC sp_rename 'partition_vu_prepare_int_table', 'partition_vu_prepare_int_table_renamed', 'OBJECT' +GO + +-- psql +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table_renamed'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table_renamed +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table_renamed')::regclass; +GO +~~START~~ +regclass +master_dbo.c2647401dc3e9a950809daafcd188637_partition_0 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_1 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_2 +master_dbo.c2647401dc3e9a950809daafcd188637_partition_3 +~~END~~ + + +-- trigger rename from PSQL endpoint +ALTER TABLE master_dbo.partition_vu_prepare_int_table_renamed RENAME TO partition_vu_prepare_int_table; +GO + +-- we should get orginal here +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" +master#!#IntPartitionScheme#!#dbo#!#partition_vu_prepare_int_table +~~END~~ + + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO +~~START~~ +regclass +master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_1" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_2" +master_dbo."363863941f079adaa9aa733200e57c9f_partition_3" +~~END~~ + diff --git a/test/JDBC/input/BABEL-2515.sql b/test/JDBC/input/BABEL-2515.sql deleted file mode 100644 index 512a0710d32..00000000000 --- a/test/JDBC/input/BABEL-2515.sql +++ /dev/null @@ -1,32 +0,0 @@ -use master; -GO - -CREATE TABLE [BABEL-2515] -( - [PartitionId] [smallint] NOT NULL, - CONSTRAINT [PK_DataRecord2056] PRIMARY KEY CLUSTERED ( [PartitionId] ASC ) - WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) - ON [XFPS_DataRecord2056]([PartitionId]) -) -ON [XFPS_DataRecord2056]([PartitionId]); -GO - -EXEC sp_babelfish_configure 'babelfishpg_tsql.escape_hatch_storage_on_partition', 'ignore'; -GO - -CREATE TABLE [BABEL-2515] -( - [PartitionId] [smallint] NOT NULL, - CONSTRAINT [PK_DataRecord2056] PRIMARY KEY CLUSTERED ( [PartitionId] ASC ) - WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) - ON [XFPS_DataRecord2056]([PartitionId]) -) -ON [XFPS_DataRecord2056]([PartitionId]); -GO - -DROP TABLE [BABEL-2515] -GO - --- reset to default -EXEC sp_babelfish_configure 'babelfishpg_tsql.escape_hatch_storage_on_partition', 'strict'; -GO diff --git a/test/JDBC/input/BABEL-UNSUPPORTED.sql b/test/JDBC/input/BABEL-UNSUPPORTED.sql index b9f31617277..8a3b8e4a1ec 100644 --- a/test/JDBC/input/BABEL-UNSUPPORTED.sql +++ b/test/JDBC/input/BABEL-UNSUPPORTED.sql @@ -251,20 +251,12 @@ GO -- escape hatch: storage_on_partition. -- 'strict' is default -CREATE TABLE t_unsupported_sop1(a int) ON partition(a); -GO - CREATE TABLE t_unsupported_sop2(a int) FILESTREAM_ON partition(a); GO SELECT set_config('babelfishpg_tsql.escape_hatch_storage_on_partition', 'ignore', 'false') GO -CREATE TABLE t_unsupported_sop1(a int) ON partition(a); -GO -DROP TABLE t_unsupported_sop1; -GO - CREATE TABLE t_unsupported_sop2(a int) FILESTREAM_ON partition(a); GO DROP TABLE t_unsupported_sop2 diff --git a/test/JDBC/input/PARTITION-vu-cleanup.mix b/test/JDBC/input/PARTITION-vu-cleanup.mix index 1a1503c2591..319199d8b32 100644 --- a/test/JDBC/input/PARTITION-vu-cleanup.mix +++ b/test/JDBC/input/PARTITION-vu-cleanup.mix @@ -13,6 +13,12 @@ GO DROP VIEW GetPartitionSchemesMetadataView GO +DROP VIEW GetPartitionedTableListFromSysTablesView +GO + +DROP VIEW GetPartitionedIndexListFromSysIndexesView +GO + DROP FUNCTION PartitionFunctionContainsDuplicateName GO @@ -25,6 +31,180 @@ GO DROP FUNCTION PartitionSchemeContainsDuplicateIDs GO +-------------------------------------------------- +--- DROP Partitioned Index +-------------------------------------------------- +DROP INDEX partition_vu_prepare_sqlvariant_index ON partition_vu_prepare_sqlvariant_table; +GO + +DROP INDEX partition_vu_prepare_uniqueidentifier_index ON partition_vu_prepare_uniqueidentifier_table; +GO + +DROP INDEX partition_vu_prepare_varbinary_index ON partition_vu_prepare_varbinary_table; +GO + +DROP INDEX partition_vu_prepare_binary_index ON partition_vu_prepare_binary_table; +GO + +DROP INDEX partition_vu_prepare_nchar_index ON partition_vu_prepare_nchar_table; +GO + +DROP INDEX partition_vu_prepare_nvarchar_index ON partition_vu_prepare_nvarchar_table; +GO + +DROP INDEX partition_vu_prepare_varchar_index ON partition_vu_prepare_varchar_table; +GO + +DROP INDEX partition_vu_prepare_char_index ON partition_vu_prepare_char_table; +GO + +DROP INDEX partition_vu_prepare_smalldatetime_index ON partition_vu_prepare_smalldatetime_table; +GO + +DROP INDEX partition_vu_prepare_datetime2_index ON partition_vu_prepare_datetime2_table; +GO + +DROP INDEX partition_vu_prepare_datetime_index ON partition_vu_prepare_datetime_table; +GO + +DROP INDEX partition_vu_prepare_date_index ON partition_vu_prepare_date_table; +GO + +DROP INDEX partition_vu_prepare_smallmoney_index ON partition_vu_prepare_smallmoney_table; +GO + +DROP INDEX partition_vu_prepare_money_index ON partition_vu_prepare_money_table; +GO + +DROP INDEX partition_vu_prepare_numeric_index ON partition_vu_prepare_numeric_table; +GO + +DROP INDEX partition_vu_prepare_decimal_index ON partition_vu_prepare_decimal_table; +GO + +DROP INDEX partition_vu_prepare_tinyint_index ON partition_vu_prepare_tinyint_table; +GO + +DROP INDEX partition_vu_prepare_smallint_index ON partition_vu_prepare_smallint_table; +GO + +DROP INDEX partition_vu_prepare_bigint_index ON partition_vu_prepare_bigint_table; +GO + +DROP INDEX partition_vu_prepare_int_index ON partition_vu_prepare_int_table; +GO + +DROP INDEX PARTITION_INDEXログインαιώνια ON PARTITION_TABLEログインαιώνια +GO + +DROP INDEX [PARTITION_INDEX 유니코드스키마👻 ] ON [PARTITION_TABLE 유니코드스키마👻 ] +GO + +SET QUOTED_IDENTIFIER ON; +GO + +DROP INDEX "PARTITION_INDEX 😎$@ #123 🌍rder " ON "PARTITION_TABLE 😎$@ #123 🌍rder " +GO + +SET QUOTED_IDENTIFIER OFF; +GO + +DROP INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +GO + +DROP INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO +-------------------------------------------------- +--- DROP Partitioned Table +-------------------------------------------------- +DROP TABLE partition_vu_prepare_sqlvariant_table; +GO + +DROP TABLE partition_vu_prepare_uniqueidentifier_table; +GO + +DROP TABLE partition_vu_prepare_varbinary_table; +GO + +DROP TABLE partition_vu_prepare_binary_table; +GO + +DROP TABLE partition_vu_prepare_nchar_table; +GO + +DROP TABLE partition_vu_prepare_nvarchar_table; +GO + +DROP TABLE partition_vu_prepare_varchar_table; +GO + +DROP TABLE partition_vu_prepare_char_table; +GO + +DROP TABLE partition_vu_prepare_smalldatetime_table; +GO + +DROP TABLE partition_vu_prepare_datetime2_table; +GO + +DROP TABLE partition_vu_prepare_datetime_table; +GO + +DROP TABLE partition_vu_prepare_date_table; +GO + +DROP TABLE partition_vu_prepare_smallmoney_table; +GO + +DROP TABLE partition_vu_prepare_money_table; +GO + +DROP TABLE partition_vu_prepare_numeric_table; +GO + +DROP TABLE partition_vu_prepare_decimal_table; +GO + +DROP TABLE partition_vu_prepare_tinyint_table; +GO + +DROP TABLE partition_vu_prepare_smallint_table; +GO + +DROP TABLE partition_vu_prepare_bigint_table; +GO + +DROP TABLE partition_vu_prepare_int_table; +GO + +DROP TABLE PartitionTableNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz +GO + +DROP TABLE PARTITION_TABLEログインαιώνια +GO + +DROP TABLE [PARTITION_TABLE 유니코드스키마👻 ] +GO + +SET QUOTED_IDENTIFIER ON; +GO + +DROP TABLE "PARTITION_TABLE 😎$@ #123 🌍rder " +GO + +SET QUOTED_IDENTIFIER OFF; +GO + +DROP TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +GO + +DROP TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO + +DROP SCHEMA PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +GO -------------------------------------------------- --- DROP Partition Scheme -------------------------------------------------- @@ -46,6 +226,12 @@ GO DROP PARTITION SCHEME NumericPartitionScheme GO +DROP PARTITION SCHEME MoneyPartitionScheme +GO + +DROP PARTITION SCHEME SmallMoneyPartitionScheme +GO + DROP PARTITION SCHEME DatePartitionScheme GO @@ -88,19 +274,22 @@ GO DROP PARTITION SCHEME PARTITION_SCHEMEログインαιώνια GO -DROP PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻] +DROP PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻 ] GO SET QUOTED_IDENTIFIER ON; GO -DROP PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder" +DROP PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder " Go SET QUOTED_IDENTIFIER OFF; GO --------------------------------------------------- +DROP PARTITION SCHEME PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO + +------------------------------------------- --- DROP Partition Function ------------------------------------------- DROP PARTITION FUNCTION IntPartitionFunction @@ -172,16 +361,26 @@ GO DROP PARTITION FUNCTION PARTITION_FUNCTIONログインαιώνια GO -DROP PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻] +DROP PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻 ] GO +DROP PARTITION FUNCTION PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +GO + +--------------------------- +--- DROP Procedures +--------------------------- + DROP PROCEDURE PartitionProcedureCreatePartitionFunction GO DROP PROCEDURE PartitionProcedureCreatePartitionScheme GO -DROP PROCEDURE PartitionProcedureCreatePartitionFunctionAndScheme +DROP PROCEDURE PartitionProcedureCreatePartitionTable +GO + +DROP PROCEDURE PartitionProcedureCreatePartitionFunctionSchemeAndTable GO DROP PROCEDURE PartitionProcedureDropPartitionFunction @@ -190,14 +389,17 @@ GO DROP PROCEDURE PartitionProcedureDropPartitionScheme GO -DROP PROCEDURE PartitionProcedureDropPartitionFunctionAndScheme +DROP PROCEDURE PartitionProcedureDropPartitionTable +GO + +DROP PROCEDURE PartitionProcedureDropPartitionFunctionSchemeAndTable GO SET QUOTED_IDENTIFIER ON; GO -DROP PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder" +DROP PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder " Go SET QUOTED_IDENTIFIER OFF; @@ -213,4 +415,15 @@ USE master go DROP DATABASE PartitionDb -go \ No newline at end of file +go + +-- validate that catalogs don't have stale entries +-- psql +SELECT count(*) FROM sys.babelfish_partition_function; +GO + +SELECT count(*) FROM sys.babelfish_partition_scheme +GO + +SELECT count(*) FROM sys.babelfish_partition_depend +GO \ No newline at end of file diff --git a/test/JDBC/input/PARTITION-vu-prepare.mix b/test/JDBC/input/PARTITION-vu-prepare.mix index 80b402156a3..2b0c5682875 100644 --- a/test/JDBC/input/PARTITION-vu-prepare.mix +++ b/test/JDBC/input/PARTITION-vu-prepare.mix @@ -138,6 +138,10 @@ GO -------------------------------------------------- --- Supported Datatypes for Partition Function -------------------------------------------------- +-- all datatypes should sort and store the values in ascending order by itself +-- and input values should be implicit casted into specified type + + -- using local variable in args declare @a int = 0; declare @b int = 500; @@ -146,9 +150,9 @@ CREATE PARTITION FUNCTION IntPartitionFunction (int) AS RANGE RIGHT FOR VALUES (@a, @b, @c); GO --- all datatypes should sort and store the values in ascending order by itself --- and input values should be implicit casted into specified type -CREATE PARTITION FUNCTION BigIntPartitionFunction (bigint) + +-- explicit schema can also be specified with paramater type +CREATE PARTITION FUNCTION BigIntPartitionFunction (sys.bigint) AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); GO @@ -156,7 +160,8 @@ CREATE PARTITION FUNCTION SmallIntPartitionFunction (smallint) AS RANGE RIGHT FOR VALUES (cast(32767 as bigint), -32768, 0); GO -CREATE PARTITION FUNCTION TinyIntPartitionFunction (tinyint) +-- explicit schema can also be specified with paramater type +CREATE PARTITION FUNCTION TinyIntPartitionFunction (sys.tinyint) AS RANGE RIGHT FOR VALUES (0, cast(255 as varchar), 128); GO @@ -237,6 +242,10 @@ CREATE PARTITION FUNCTION PartitionFunctionNameGreaterThan64AndLessThan128abcdef AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); GO +CREATE PARTITION FUNCTION PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder (bigint) +AS RANGE RIGHT FOR VALUES (0, 10000, 100, 1000); +GO + CREATE PARTITION FUNCTION PartitionFunctionHavingDifferentCollationInput (NVARCHAR(50)) AS RANGE RIGHT FOR VALUES ( @@ -252,17 +261,19 @@ GO -------------------------------------------------- -- without all option +-- filegroups are equal to partition that will generated by function CREATE PARTITION SCHEME IntPartitionScheme AS PARTITION IntPartitionFunction TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY]); GO --- with all option +-- filgroups are more than partition that will generated by function CREATE PARTITION SCHEME BigIntPartitionScheme AS PARTITION BigIntPartitionFunction -ALL TO ([PRIMARY]); +TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY]); GO +-- with all option CREATE PARTITION SCHEME SmallIntPartitionScheme AS PARTITION SmallIntPartitionFunction ALL TO ([PRIMARY]); @@ -283,6 +294,16 @@ PARTITION NumericPartitionFunction ALL TO ([PRIMARY]); GO +CREATE PARTITION SCHEME MoneyPartitionScheme AS +PARTITION MoneyPartitionFunction +ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME SmallMoneyPartitionScheme AS +PARTITION SmallMoneyPartitionFunction +ALL TO ([PRIMARY]); +GO + CREATE PARTITION SCHEME DatePartitionScheme AS PARTITION DatePartitionFunction ALL TO ([PRIMARY]); @@ -349,6 +370,39 @@ PARTITION PartitionFunctionNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuv ALL TO ([PRIMARY]); GO +CREATE PARTITION SCHEME PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder AS +PARTITION PartitionFunctionNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +ALL TO ([PRIMARY]); +GO + +CREATE SCHEMA PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +GO + +CREATE TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz ( + PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz BIGINT, + Value sys.varchar(50) +) ON PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz (PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + +CREATE INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz(Value) +ON PartitionSchemeNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz +(PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + +CREATE TABLE PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder ( + PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz BIGINT, + Value sys.varchar(50) +) ON PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +(PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + +CREATE INDEX PartitionIndexNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz +ON PartitionSchemaNameGreaterThan64abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.PartitionTableNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder(Value) +ON PartitionSchemeNameGreaterThan64AndLessThan128HavingEmoji😎$123🌍rder +(PartitionColumnNameGreaterThan128abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz); +GO + -------------------------------------------------- --- name identifiers test -------------------------------------------------- @@ -361,29 +415,62 @@ PARTITION PARTITION_FUNCTIONログインαιώνια ALL TO ([PRIMARY]); GO -CREATE PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻] (int) +CREATE TABLE PARTITION_TABLEログインαιώνια ( + PARTITION_COLUMNログインαιώνια INT, + Value sys.varchar(50) +) ON PARTITION_SCHEMEログインαιώνια(PARTITION_COLUMNログインαιώνια); +GO + +CREATE INDEX PARTITION_INDEXログインαιώνια +ON PARTITION_TABLEログインαιώνια(Value) +ON PARTITION_SCHEMEログインαιώνια(PARTITION_COLUMNログインαιώνια); +GO + +CREATE PARTITION FUNCTION [PARTITION_FUNCTION 유니코드스키마👻 ] (int) AS RANGE RIGHT FOR VALUES (0, 500, 1000); GO -CREATE PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻] AS -PARTITION [PARTITION_FUNCTION 유니코드스키마👻] +CREATE PARTITION SCHEME [PARTITION_SCHEME 유니코드스키마👻 ] AS +PARTITION [PARTITION_FUNCTION 유니코드스키마👻 ] ALL TO ([PRIMARY]); GO +CREATE TABLE [PARTITION_TABLE 유니코드스키마👻 ]( + [PARTITION_COLUMN 유니코드스키마👻 ] INT, + Value sys.varchar(50) +) ON [PARTITION_SCHEME 유니코드스키마👻 ]([PARTITION_COLUMN 유니코드스키마👻 ]); +GO + +CREATE INDEX [PARTITION_INDEX 유니코드스키마👻 ] +ON [PARTITION_TABLE 유니코드스키마👻 ](Value) +ON [PARTITION_SCHEME 유니코드스키마👻 ]([PARTITION_COLUMN 유니코드스키마👻 ]); +GO -- qouted identifer SET QUOTED_IDENTIFIER ON; GO -CREATE PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder" (int) +CREATE PARTITION FUNCTION "PARTITION_FUNCTION 😎$@ #123 🌍rder " (int) AS RANGE RIGHT FOR VALUES (0, 500, 1000); GO -CREATE PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder" AS -PARTITION "PARTITION_FUNCTION 😎$@ #123 🌍rder" +CREATE PARTITION SCHEME "PARTITION_SCHEME 😎$@ #123 🌍rder " AS +PARTITION "PARTITION_FUNCTION 😎$@ #123 🌍rder " ALL TO ([PRIMARY]); GO + +CREATE TABLE "PARTITION_TABLE 😎$@ #123 🌍rder " ( + "PARTITION_COLUMN 😎$@ #123 🌍rder " INT, + Value sys.varchar(50) +) ON "PARTITION_SCHEME 😎$@ #123 🌍rder " ("PARTITION_COLUMN 😎$@ #123 🌍rder "); +GO + +CREATE INDEX "PARTITION_INDEX 😎$@ #123 🌍rder " +ON "PARTITION_TABLE 😎$@ #123 🌍rder " (Value) +ON "PARTITION_SCHEME 😎$@ #123 🌍rder "("PARTITION_COLUMN 😎$@ #123 🌍rder "); +GO + SET QUOTED_IDENTIFIER OFF; Go @@ -406,11 +493,22 @@ PARTITION PartitionDb_PartitionFunction ALL TO ([PRIMARY]); GO +CREATE TABLE PartitionDb_PartitionTable ( + Id INT, + Value sys.varchar(50) +) ON PartitionDb_PartitionScheme(Id); +GO + +CREATE INDEX PartitionDb_PartitionIndex +ON PartitionDb_PartitionTable(Id) +ON PartitionDb_PartitionScheme (Id); +GO + USE MASTER go --------------------------------------------------------------- ---- CREATE/DROP Partition Function/Scheme inside Procedure +--- CREATE/DROP Partition Function/Scheme/Table inside Procedure --------------------------------------------------------------- CREATE PROCEDURE PartitionProcedureCreatePartitionFunction AS BEGIN @@ -427,14 +525,26 @@ ALL TO ([PRIMARY]) END; GO +CREATE PROCEDURE PartitionProcedureCreatePartitionTable AS +BEGIN +CREATE TABLE PartitionTableInsideProc1( + Id INT, + Value sys.varchar(50) +) ON PartitionSchemeInsideProc1(Id); +END; +GO -CREATE PROCEDURE PartitionProcedureCreatePartitionFunctionAndScheme AS +CREATE PROCEDURE PartitionProcedureCreatePartitionFunctionSchemeAndTable AS BEGIN CREATE PARTITION FUNCTION PartitionFunctionInsideProc2 (int) AS RANGE RIGHT FOR VALUES (500, 1000, 10000); CREATE PARTITION SCHEME PartitionSchemeInsideProc2 AS PARTITION PartitionFunctionInsideProc2 ALL TO ([PRIMARY]); +CREATE TABLE PartitionTableInsideProc2( + Id INT, + Value sys.varchar(50) +) ON PartitionSchemeInsideProc2(Id); END; Go @@ -450,9 +560,464 @@ DROP PARTITION SCHEME PartitionSchemeInsideProc1 END; GO -CREATE PROCEDURE PartitionProcedureDropPartitionFunctionAndScheme AS +CREATE PROCEDURE PartitionProcedureDropPartitionTable AS +BEGIN +DROP TABLE PartitionTableInsideProc1 +END; +GO + +CREATE PROCEDURE PartitionProcedureDropPartitionFunctionSchemeAndTable AS BEGIN +DROP TABLE PartitionTableInsideProc2; DROP PARTITION SCHEME PartitionSchemeInsideProc2; DROP PARTITION FUNCTION PartitionFunctionInsideProc2; END; Go + +USE master; +go +--------------------------------------------------------------------------- +--- CREATE PARTITIONED TABLES with PARTITION SCHEME for different datatypes +--------------------------------------------------------------------------- +-- int data type +CREATE TABLE partition_vu_prepare_int_table ( + Id INT UNIQUE, + Value sys.varchar(50) +) ON IntPartitionScheme(Id); +GO + +-- add constraint +ALTER TABLE partition_vu_prepare_int_table ADD CONSTRAINT check_value_not_null CHECK(value IS NOT NULL); +GO + +-- bigint data type +CREATE TABLE partition_vu_prepare_bigint_table ( + Id BIGINT, + Value sys.varchar(50) +) ON BigIntPartitionScheme--this is comment should get ignored +(Id); +GO + +-- smallint data type +CREATE TABLE partition_vu_prepare_smallint_table ( + Id SMALLINT, + Value sys.varchar(50) +) ON SmallIntPartitionScheme(Id); +GO + +-- tinyint data type +CREATE TABLE partition_vu_prepare_tinyint_table ( + Id TINYINT, + Value sys.varchar(50) +) ON TinyIntPartitionScheme(Id); +GO + +-- decimal data type +CREATE TABLE partition_vu_prepare_decimal_table ( + Id DECIMAL(10, 5), + Value sys.varchar(50) +) ON DecimalPartitionScheme(Id); +GO + +-- numeric data type +CREATE TABLE partition_vu_prepare_numeric_table ( + Id NUMERIC(5, 2), + Value sys.varchar(50) +) ON NumericPartitionScheme(Id); +GO + +-- money data type +CREATE TABLE partition_vu_prepare_money_table ( + Id MONEY, + Value sys.varchar(50) +) ON MoneyPartitionScheme(Id); +GO + +-- smallmoney data type +CREATE TABLE partition_vu_prepare_smallmoney_table ( + Id SMALLMONEY, + Value sys.varchar(50) +) ON SmallMoneyPartitionScheme(Id); +GO + +-- date data type +CREATE TABLE partition_vu_prepare_date_table ( + Id DATE, + Value sys.varchar(50) +) ON DatePartitionScheme(Id); +GO + +-- datetime data type +CREATE TABLE partition_vu_prepare_datetime_table ( + Id DATETIME, + Value sys.varchar(50) +) ON DateTimePartitionScheme(Id); +GO + +-- datetime2 data type +CREATE TABLE partition_vu_prepare_datetime2_table ( + Id DATETIME2(3), + Value sys.varchar(50) +) ON DateTime2PartitionScheme(Id); +GO + +-- smalldatetime data type +CREATE TABLE partition_vu_prepare_smalldatetime_table ( + Id SMALLDATETIME, + Value sys.varchar(50) +) ON SmallDateTimePartitionScheme(Id); +GO + +-- char data type +CREATE TABLE partition_vu_prepare_char_table ( + Id CHAR(5), + Value sys.varchar(50) +) ON CharPartitionScheme(Id); +GO + +-- varchar data type +CREATE TABLE partition_vu_prepare_varchar_table ( + Id VARCHAR(10), + Value sys.varchar(50) +) ON VarCharPartitionScheme(Id); +GO + +-- nvarchar data type +CREATE TABLE partition_vu_prepare_nvarchar_table ( + Id NVARCHAR(10), + Value sys.varchar(50) +) ON NVarCharPartitionScheme(Id); +GO + +-- nchar data type +CREATE TABLE partition_vu_prepare_nchar_table ( + Id NCHAR(5), + Value sys.varchar(50) +) ON NCharPartitionScheme(Id); +GO + +-- binary data type +CREATE TABLE partition_vu_prepare_binary_table ( + Id BINARY(4), + Value sys.varchar(50) +) ON BinaryPartitionScheme(Id); +GO + +-- varbinary data type +CREATE TABLE partition_vu_prepare_varbinary_table ( + Id VARBINARY(8), + Value sys.varchar(50) +) ON VarBinaryPartitionScheme(Id); +GO + +-- uniqueidentifier data type +CREATE TABLE partition_vu_prepare_uniqueidentifier_table ( + Id UNIQUEIDENTIFIER, + Value sys.varchar(50) +) ON UniqueIdentifierPartitionScheme(Id); +GO + +-- sql_variant data type +CREATE TABLE partition_vu_prepare_sqlvariant_table ( + Id SQL_VARIANT, + Value sys.varchar(50) +) ON SqlVariantPartitionScheme(Id); +GO + +-- identifier length greater than 64 +CREATE TABLE PartitionTableNameGreaterThan64AndLessThan128abcdefghijklmnopqrstuvwxyz ( + Id INT, + Value sys.varchar(50) +) ON IntPartitionScheme(Id); +GO + +CREATE VIEW GetPartitionedTableListFromSysTablesView +AS +( + SELECT + name + FROM + sys.tables + WHERE + name like '%partition_vu_prepare%' + ORDER BY + name +) +GO + +--------------------------------------------------------------------------- +--- CREATE ALIGNED PARTITIONED INDEX with PARTITION SCHEME +--------------------------------------------------------------------------- +-- using schema name +CREATE INDEX partition_vu_prepare_int_index +ON dbo.partition_vu_prepare_int_table(Value) +ON IntPartitionScheme (Id); +GO + +-- without explicit schema name +CREATE INDEX partition_vu_prepare_bigint_index +ON partition_vu_prepare_bigint_table(Id) +ON BigIntPartitionScheme (Id); +GO + +-- without partition scheme should also work +CREATE INDEX partition_vu_prepare_smallint_index +ON partition_vu_prepare_smallint_table--this is comment should get ignored +(Id) +GO + +CREATE INDEX partition_vu_prepare_tinyint_index +ON partition_vu_prepare_tinyint_table(Id) +ON TinyIntPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_decimal_index +ON partition_vu_prepare_decimal_table(Id) +ON DecimalPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_numeric_index +ON partition_vu_prepare_numeric_table(Id) +ON NumericPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_money_index +ON partition_vu_prepare_money_table(Id) +ON MoneyPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_smallmoney_index +ON partition_vu_prepare_smallmoney_table(Id) +ON SmallMoneyPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_date_index +ON partition_vu_prepare_date_table(Id) +ON DatePartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_datetime_index +ON partition_vu_prepare_datetime_table(Id) +ON DateTimePartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_datetime2_index +ON partition_vu_prepare_datetime2_table(Id) +ON DateTime2PartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_smalldatetime_index +ON partition_vu_prepare_smalldatetime_table(Id) +ON SmallDateTimePartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_char_index +ON partition_vu_prepare_char_table(Id) +ON CharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_varchar_index +ON partition_vu_prepare_varchar_table(Id) +ON VarCharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_nvarchar_index +ON partition_vu_prepare_nvarchar_table(Id) +ON NVarCharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_nchar_index +ON partition_vu_prepare_nchar_table(Id) +ON NCharPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_binary_index +ON partition_vu_prepare_binary_table(Id) +ON BinaryPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_varbinary_index +ON partition_vu_prepare_varbinary_table(Id) +ON VarBinaryPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_uniqueidentifier_index +ON partition_vu_prepare_uniqueidentifier_table(Id) +ON UniqueIdentifierPartitionScheme (Id); +GO + +CREATE INDEX partition_vu_prepare_sqlvariant_index +ON partition_vu_prepare_sqlvariant_table(Id) +ON SqlVariantPartitionScheme (Id); +GO + +CREATE VIEW GetPartitionedIndexListFromSysIndexesView +AS +( + SELECT + name + FROM + sys.indexes + WHERE + name like '%partition_vu_prepare%' + ORDER BY + name +) +GO + +--------------------------------------------------------------------------- +--- Insert data into partitioned tables +--------------------------------------------------------------------------- +-- Insert values into partition_vu_prepare_int_table +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (100, 'Value 100'); +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (10000, 'Value 10000'); +INSERT INTO partition_vu_prepare_int_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_bigint_table +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (100, 'Value 100'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (10000, 'Value 10000'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (1000000000, 'Value 1000000000'); +INSERT INTO partition_vu_prepare_bigint_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_smallint_table +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (-32768, 'Value -32768'); +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (32767, 'Value 32767'); +INSERT INTO partition_vu_prepare_smallint_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_tinyint_table +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (1, 'Value 1'); +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (128, 'Value 128'); +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (255, 'Value 255'); +INSERT INTO partition_vu_prepare_tinyint_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_decimal_table +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (100.0, 'Value 100.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (200.0, 'Value 200.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (300.0, 'Value 300.0'); +INSERT INTO partition_vu_prepare_decimal_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_numeric_table +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (10.0, 'Value 10.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (20.0, 'Value 20.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (30.0, 'Value 30.0'); +INSERT INTO partition_vu_prepare_numeric_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_money_table +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (2.56789, 'Value 2.56789'); +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (4.91, 'Value 4.91'); +INSERT INTO partition_vu_prepare_money_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_smallmoney_table +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (1.0, 'Value 1.0'); +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (2.56789, 'Value 2.56789'); +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (4.91, 'Value 4.91'); +INSERT INTO partition_vu_prepare_smallmoney_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_date_table +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES ('2022-01-01', 'Value 2022-01-01'); +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES ('2022-07-01', 'Value 2022-07-01'); +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES ('2023-01-01', 'Value 2023-01-01'); +INSERT INTO partition_vu_prepare_date_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_datetime_table +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES ('2019-01-01', 'Value 2019-01-01'); +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES ('2022-01-01', 'Value 2022-01-01'); +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES ('2022-07-01', 'Value 2022-07-01'); +INSERT INTO partition_vu_prepare_datetime_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_datetime2_table +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES ('2019-01-01 00:00:00.000', 'Value 2019-01-01 00:00:00.000'); +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES ('2022-01-01 00:00:00.000', 'Value 2022-01-01 00:00:00.000'); +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES ('2022-07-01 00:00:00.000', 'Value 2022-07-01 00:00:00.000'); +INSERT INTO partition_vu_prepare_datetime2_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_smalldatetime_table +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES ('2019-01-01', 'Value 2019-01-01'); +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES ('2022-01-01', 'Value 2022-01-01'); +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES ('2022-07-01', 'Value 2022-07-01'); +INSERT INTO partition_vu_prepare_smalldatetime_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_char_table +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('A', 'Value A'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('K', 'Value K'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('U', 'Value U'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES ('D', 'Value D'); +INSERT INTO partition_vu_prepare_char_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_varchar_table +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Apple', 'Value Apple'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Banana', 'Value Banana'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Mango', 'Value Mango'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Cherry', 'Value Cherry'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES ('Date', 'Value Date'); +INSERT INTO partition_vu_prepare_varchar_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_nvarchar_table +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Apple', N'Value Apple'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Banana', N'Value Banana'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Mango', N'Value Mango'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Cherry', N'Value Cherry'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (N'Date', N'Value Date'); +INSERT INTO partition_vu_prepare_nvarchar_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_nchar_table +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'A', N'Value A'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'K', N'Value K'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'U', N'Value U'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (N'B', N'Value B'); +INSERT INTO partition_vu_prepare_nchar_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- BABEL-4957 needs to fixed first otherwise dump/restore will fail +-- Insert values into partition_vu_prepare_binary_table +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0000, 'Value 0x0000'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0400, 'Value 0x0400'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0800, 'Value 0x0800'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (0x0C000, 'Value 0x0C000'); +-- INSERT INTO partition_vu_prepare_binary_table (Id, Value) VALUES (NULL, 'Value NULL'); +-- GO + +-- Insert values into partition_vu_prepare_varbinary_table +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0x0000000000000000, 'Value 0x0000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0x4000000000000000, 'Value 0x4000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0x8000000000000000, 'Value 0x8000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (0xC000000000000000, 'Value 0xC000000000000000'); +INSERT INTO partition_vu_prepare_varbinary_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_uniqueidentifier_table +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES ('00000000-0000-0000-0000-000000000000', 'Value 00000000-0000-0000-0000-000000000000'); +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES ('6F9619FF-8B86-D011-B42D-00C04FC964FF', 'Value 6F9619FF-8B86-D011-B42D-00C04FC964FF'); +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES ('FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', 'Value FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'); +INSERT INTO partition_vu_prepare_uniqueidentifier_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO + +-- Insert values into partition_vu_prepare_sqlvariant_table +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST('abc' AS char(5)), 'Value abc'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST(N'xyz' AS nchar(5)), N'Value xyz'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST('Apple' AS VARCHAR(10)), 'Value Apple'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST(N'Banana' AS NVARCHAR(10)), N'Value Banana'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (CAST('Some text' AS SQL_VARIANT), 'Value Some text'); +INSERT INTO partition_vu_prepare_sqlvariant_table (Id, Value) VALUES (NULL, 'Value NULL'); +GO \ No newline at end of file diff --git a/test/JDBC/input/PARTITION-vu-verify.mix b/test/JDBC/input/PARTITION-vu-verify.mix index f9897fd7d29..750218d7285 100644 --- a/test/JDBC/input/PARTITION-vu-verify.mix +++ b/test/JDBC/input/PARTITION-vu-verify.mix @@ -1,5 +1,7 @@ +-- parallel_query_expected + -------------------------------------------------- ---- CREATE PARTITION FUNCTION/SCHEME using procedure +--- CREATE PARTITION FUNCTION/SCHEME/TABLE using procedure -------------------------------------------------- EXEC PartitionProcedureCreatePartitionFunction GO @@ -7,11 +9,14 @@ GO EXEC PartitionProcedureCreatePartitionScheme GO -EXEC PartitionProcedureCreatePartitionFunctionAndScheme +EXEC PartitionProcedureCreatePartitionTable +GO + +EXEC PartitionProcedureCreatePartitionFunctionSchemeAndTable GO -------------------------------------------------- ---- CREATE PARTITION FUNCTION/SCHEME inside Function +--- CREATE PARTITION FUNCTION/SCHEME/TABLE inside Function -------------------------------------------------- CREATE FUNCTION TestFunctionCreatePartitionFunction() RETURNS INT @@ -52,6 +57,26 @@ BEGIN END; GO +CREATE FUNCTION TestFunctionCreatePartitionTable() +RETURNS INT +AS +BEGIN + CREATE TABLE TestPartitionTable ( + Id INT, + Value sys.varchar(20) + ) ON IntPartitionScheme(Id); +END; +GO + +CREATE FUNCTION TestFunctionDropPartitionTable() +RETURNS INT +AS +BEGIN + DROP TABLE partition_vu_prepare_int_table; + RETURN 1; +END; +GO + --------------------------------------------------------- --- CREATE PARTITION FUNCTION/SCHEME using 2-part name --------------------------------------------------------- @@ -228,6 +253,15 @@ CREATE PARTITION FUNCTION PartitionFunctionWithLeft (int) AS RANGE FOR VALUES (10, 1000, 10000); GO +-- NULL value is not supported in range values +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL); +GO + +CREATE PARTITION FUNCTION PartitionFunctionWithNULL (int) +AS RANGE RIGHT FOR VALUES (10, 1000, NULL, NULL); +GO + -------------------------------------------------- --- Duplicate Create of Partition Function/Scheme -------------------------------------------------- @@ -274,6 +308,12 @@ GO DROP PARTITION FUNCTION IntPartitionFunction GO +----------------------------------------------------------------------------------- +--- Drop of of Partition Scheme when there is dependent Table on it +----------------------------------------------------------------------------------- +DROP PARTITION SCHEME IntPartitionScheme +GO + ----------------------------------------------- --- Filegroup behaviour with Partition Scheme @@ -434,6 +474,11 @@ SELECT CURRENT_USER GO -- CREATE/DROP should throw permission error + +------------------------------------------------------------ +--- only db owner and logins which are member of sysadmin +--- are allowed to create/drop partition function and scheme +------------------------------------------------------------ CREATE PARTITION FUNCTION TestPartitionFunction (int) AS RANGE RIGHT FOR VALUES (500, 1000, 10000); Go @@ -449,7 +494,9 @@ go DROP PARTITION SCHEME IntPartitionScheme go --- but they can access the metadata +------------------------------------------ +--- all user can access the metadata +------------------------------------------ SELECT name, type, type_desc, fanout, boundary_value_on_right, is_system FROM @@ -464,6 +511,62 @@ SELECT sys.partition_functions pf on (ps.function_id = pf.function_id) go +------------------------------------------------------------ +--- all user can use the metadata of the partition scheme +--- to create table if they permission to create table +------------------------------------------------------------ + +-- grant create permission to user on schema so that it can create table +-- psql +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + + EXECUTE 'GRANT CREATE ON SCHEMA ' || quote_ident(schema_name) || ' TO partitiondb_partition_u1'; +END$$; +GO + +-- tsql user=partition_l1 password=12345678 +USE PartitionDb; +GO + +SELECT CURRENT_USER +GO + +CREATE TABLE PartitionDb_TestPartitionTable ( + Id INT, + Value sys.varchar(20) +) ON PartitionDb_PartitionScheme(Id); +GO + +DROP TABLE PartitionDb_TestPartitionTable +GO + +-- revoke create permission from user on schema +-- psql +DO $$ +DECLARE + schema_name TEXT; +BEGIN + IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' THEN + schema_name := 'partitiondb_dbo'; + ELSE + schema_name := 'dbo'; + END IF; + + EXECUTE 'REVOKE CREATE ON SCHEMA ' || quote_ident(schema_name) || ' FROM partitiondb_partition_u1'; +END$$; +GO + +----------------------------------------------------------------------------------- +--- DB owner should be able to create/drop partition function and scheme +---------------------------------------------------------------------------------- -- make the user a DB owner -- tsql USE PartitionDb; @@ -566,13 +669,747 @@ GO -------------------------------------------------- ---- DROP PARTITION FUNCTION/SCHEME using procedure +--- DROP PARTITION FUNCTION/SCHEME/TABLE using procedure -------------------------------------------------- +EXEC PartitionProcedureDropPartitionTable +GO + EXEC PartitionProcedureDropPartitionScheme GO EXEC PartitionProcedureDropPartitionFunction GO -EXEC PartitionProcedureDropPartitionFunctionAndScheme +EXEC PartitionProcedureDropPartitionFunctionSchemeAndTable +GO + +--------------------------------------------------------------------------- +--- PARTITIONED TABLES test +--------------------------------------------------------------------------- + +SELECT * FROM GetPartitionedTableListFromSysTablesView +GO + +--------------------------------------------------------------------------- +--- PARTITIONED INDEX test +--------------------------------------------------------------------------- +SELECT * FROM GetPartitionedIndexListFromSysIndexesView +GO + + +---------------------------------------------------------------------------------------------- +--- System views should list only metadata of Partitioned table(not of the partitions) +---------------------------------------------------------------------------------------------- +SELECT count(*) from sys.tables where name = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('partition_vu_prepare_int_table') +GO + +SELECT count(*) from sys.all_objects where name = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from information_schema.columns where TABLE_NAME = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from information_schema.tables where TABLE_NAME = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = 'partition_vu_prepare_int_table' +GO + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = 'partition_vu_prepare_int_table' +GO + +--------------------------------------------------------- +--- System views should not list metadata of Partitions +--------------------------------------------------------- +SELECT count(*) from sys.tables where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from sys.all_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO + +SELECT count(*) from sys.columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO + +SELECT count(*) from sys.indexes where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO + +SELECT count(*) from sys.index_columns where object_id = OBJECT_ID('363863941f079adaa9aa733200e57c9f_partition_0') +GO + +SELECT count(*) from sys.all_objects where name = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from sys.sp_tables_view where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from information_schema.columns where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from information_schema.tables where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from information_schema.table_constraints where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from information_schema.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + +SELECT count(*) from information_schema.key_column_usage where TABLE_NAME = '363863941f079adaa9aa733200e57c9f_partition_0' +GO + + +--------------------------------------------------------------------------- +--- Run analyze on each table and enable query plan +--------------------------------------------------------------------------- + +-- psql +ANALYZE master_dbo.partition_vu_prepare_int_table; +ANALYZE master_dbo.partition_vu_prepare_bigint_table; +ANALYZE master_dbo.partition_vu_prepare_smallint_table; +ANALYZE master_dbo.partition_vu_prepare_tinyint_table; +ANALYZE master_dbo.partition_vu_prepare_decimal_table; +ANALYZE master_dbo.partition_vu_prepare_numeric_table; +ANALYZE master_dbo.partition_vu_prepare_money_table; +ANALYZE master_dbo.partition_vu_prepare_smallmoney_table; +ANALYZE master_dbo.partition_vu_prepare_date_table; +ANALYZE master_dbo.partition_vu_prepare_datetime_table; +ANALYZE master_dbo.partition_vu_prepare_datetime2_table; +ANALYZE master_dbo.partition_vu_prepare_smalldatetime_table; +ANALYZE master_dbo.partition_vu_prepare_char_table; +ANALYZE master_dbo.partition_vu_prepare_varchar_table; +ANALYZE master_dbo.partition_vu_prepare_nvarchar_table; +ANALYZE master_dbo.partition_vu_prepare_nchar_table; +ANALYZE master_dbo.partition_vu_prepare_binary_table; +ANALYZE master_dbo.partition_vu_prepare_varbinary_table; +ANALYZE master_dbo.partition_vu_prepare_uniqueidentifier_table; +ANALYZE master_dbo.partition_vu_prepare_sqlvariant_table; +GO + +-- tsql +SELECT set_config('babelfishpg_tsql.explain_costs', 'off', false) +GO + +SET BABELFISH_SHOWPLAN_ALL ON +GO + +--------------------------------------------------------------------------- +--- Query plan of select on partitioned tables +--------------------------------------------------------------------------- + +SELECT * FROM partition_vu_prepare_int_table; +GO + +SELECT * FROM partition_vu_prepare_bigint_table; +GO + +SELECT * FROM partition_vu_prepare_smallint_table; +GO + +SELECT * FROM partition_vu_prepare_tinyint_table; +GO + +SELECT * FROM partition_vu_prepare_decimal_table; +GO + +SELECT * FROM partition_vu_prepare_numeric_table; +GO + +SELECT * FROM partition_vu_prepare_money_table; +GO + +SELECT * FROM partition_vu_prepare_smallmoney_table; +GO + +SELECT * FROM partition_vu_prepare_date_table; +GO + +SELECT * FROM partition_vu_prepare_datetime_table; +GO + +SELECT * FROM partition_vu_prepare_datetime2_table; +GO + +SELECT * FROM partition_vu_prepare_smalldatetime_table; +GO + +SELECT * FROM partition_vu_prepare_char_table; +GO + +SELECT * FROM partition_vu_prepare_varchar_table; +GO + +SELECT * FROM partition_vu_prepare_nvarchar_table; +GO + +SELECT * FROM partition_vu_prepare_nchar_table; +GO + +SELECT * FROM partition_vu_prepare_binary_table; +GO + +SELECT * FROM partition_vu_prepare_varbinary_table; +GO + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table; +GO + +SELECT * FROM partition_vu_prepare_sqlvariant_table; +GO + + +----------------------------------------------------------------------------------------- +--- Query plan of select on partitioned tables with predicate and enforced index scan +----------------------------------------------------------------------------------------- +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'off', false); +SELECT set_config('enable_bitmapscan', 'off', false); +GO + +SET BABELFISH_SHOWPLAN_ALL ON +GO + + +SELECT * FROM partition_vu_prepare_int_table WHERE Id >= 0 AND Id < 500; +GO + +SELECT * FROM partition_vu_prepare_bigint_table WHERE Id >= 0 AND Id < 100; +GO + +SELECT * FROM partition_vu_prepare_smallint_table WHERE Id >= -32768 AND Id < 0; +GO + +SELECT * FROM partition_vu_prepare_tinyint_table WHERE Id >= 0 AND Id < 128; +GO + +SELECT * FROM partition_vu_prepare_decimal_table WHERE Id >= 0.0 AND Id < 100.0; +GO + +SELECT * FROM partition_vu_prepare_numeric_table WHERE Id >= 0.0 AND Id < 10.0; +GO + +SELECT * FROM partition_vu_prepare_money_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO + +SELECT * FROM partition_vu_prepare_smallmoney_table WHERE Id >= 2.56789 AND Id < 3.56789; +GO + +SELECT * FROM partition_vu_prepare_date_table WHERE Id >= '2022-01-01' AND Id < '2022-07-01'; +GO + +SELECT * FROM partition_vu_prepare_datetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO + +SELECT * FROM partition_vu_prepare_datetime2_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO + +SELECT * FROM partition_vu_prepare_smalldatetime_table WHERE Id >= '2019-01-01' AND Id < '2022-01-01'; +GO + +SELECT * FROM partition_vu_prepare_char_table WHERE Id >= 'A' AND Id < 'B'; +GO + +SELECT * FROM partition_vu_prepare_varchar_table WHERE Id >= 'Apple' AND Id < 'Banana'; +GO + +SELECT * FROM partition_vu_prepare_nvarchar_table WHERE Id >= N'Apple' AND Id < N'Banana'; +GO + +SELECT * FROM partition_vu_prepare_nchar_table WHERE Id >= N'A' AND Id < N'B'; +GO + +SELECT * FROM partition_vu_prepare_binary_table WHERE Id >= 0x0000 AND Id < 0x0400; +GO + +SELECT * FROM partition_vu_prepare_varbinary_table WHERE Id >= 0x0000000000000000 AND Id < 0x4000000000000000; +GO + +SELECT * FROM partition_vu_prepare_uniqueidentifier_table WHERE Id >= '00000000-0000-0000-0000-000000000000' AND Id < '6F9619FF-8B86-D011-B42D-00C04FC964FF'; +GO + +SELECT * FROM partition_vu_prepare_sqlvariant_table WHERE Id >= CAST('abc' AS char(5)) AND Id < CAST('Apple' AS VARCHAR(10)); +GO + +SET BABELFISH_SHOWPLAN_ALL OFF +GO + +SELECT set_config('enable_seqscan', 'on', false); +SELECT set_config('enable_bitmapscan', 'on', false); +SELECT set_config('babelfishpg_tsql.explain_costs', 'on', false) +GO + + +------------------------------------------ +--- Blocked Operation For Partitioned Tables +------------------------------------------- +-- user should not be allowed to CREATE/ATTACH/DETACH partition +-- to babelfish partitioned table from psql endpoint + +-- psql +SET ROLE master_dbo; +GO + +-- Attempt to create new partition with random values +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +FOR VALUES FROM (0) TO (500); +GO + +-- Attempt to create new partition with DEFAULT +CREATE TABLE NonExistentTable PARTITION OF master_dbo.partition_vu_prepare_int_table +DEFAULT +GO + +-- Attempt to drop partition of babelfish partitioned table from psql endpoint +DROP TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO + + +-- Attempt to detach +-- explicit schema name specified +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +GO + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0"; +RESET search_path; +GO + +-- Attempt to detach using CONCURRENTLY option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +CONCURRENTLY; +GO + +-- Attempt to detach using FINALIZE option +ALTER TABLE master_dbo.partition_vu_prepare_int_table +DETACH PARTITION master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +FINALIZE; +GO + +-- Attempt to attach with Default value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable DEFAULT; +GO + +-- Attempt to attach with random value +ALTER TABLE master_dbo.partition_vu_prepare_int_table +ATTACH PARTITION NonExistentTable FOR VALUES FROM (10) TO (20); +GO + +-- user should not be allowed to modify partition +-- of babelfish partitioned table neither from psql nor tsql endpoint + +-- explicit schema name specified +ALTER TABLE master_dbo."363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +GO + +-- using search_path +SET search_path = public, master_dbo; +ALTER TABLE "363863941f079adaa9aa733200e57c9f_partition_0" +ADD CONSTRAINT xyz CHECK ( id > 10 and id < 20); +RESET search_path; +GO + +RESET ROLE; +GO + +-- Attempt to ADD storage parameter to babelfish partitioned table (not on the partitions) +SET babelfishpg_tsql.sql_dialect = "tsql"; +GO + +ALTER TABLE master_dbo.partition_vu_prepare_int_table SET (autovacuum_enabled = false); +GO + +RESET babelfishpg_tsql.sql_dialect; +GO + + +-- tsql +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO + + +ALTER TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO + +-- with explicity schema name +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD new_col int +GO + +ALTER TABLE dbo.[363863941f079adaa9aa733200e57c9f_partition_0] +ADD CONSTRAINT xyz DEFAULT 10 FOR id; +GO + +-- Attempt to drop partition of babelfish partitioned table from tsql endpoint +DROP TABLE [363863941f079adaa9aa733200e57c9f_partition_0] +GO + +-------------------------------------------------------------------- +--- Unsupported Option with CREATE TABLE with PARTITION SCHEME +-------------------------------------------------------------------- +-- Computed column as partitioning column is not yet supported in babelfish +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value +) +ON IntPartitionScheme(computed_col); +GO + +CREATE TABLE TestPartitionedTable +( + id INT, + value INT, + computed_col AS id + value PERSISTED +) +ON IntPartitionScheme(computed_col); +GO + +-- temporary table +CREATE TABLE #TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id); +GO + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--------------------------------------------------------------- + +-- Attempt to create with multiple columns as partitioning scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON IntPartitionScheme(id, value); +GO + +-- Attempt to create with a partition scheme that doesn't exist and column that doesn't exist in the table +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(NonExistentColumn); +GO + +-- Attempt to create with a partition scheme that doesn't exist +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON NonExistentPartitionScheme(id); +GO + +-- Attempt to use two part name with partition scheme +CREATE TABLE TestPartitionedTable +( + id INT, + value INT +) +ON master.IntPartitionScheme(id); +GO + +-- Attempt to create with a unique constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT UNIQUE +) +ON IntPartitionScheme(PartitionColumn); +GO + +-- Attempt to create with a primary key constraint on a non-partition column +CREATE TABLE TestPartitionedTable +( + Id INT, + PartitionColumn INT, + Col1 INT PRIMARY KEY +) +ON IntPartitionScheme(PartitionColumn); +GO + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE TABLE with PARTITION SCHEME +--- Attempt to create with an incompatible partition column data type +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable1 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON IntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable2 +( + Id INT, + PartitionColumn DATETIME +) +ON DatePartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable3 +( + Id INT, + PartitionColumn VARCHAR(10) +) +ON CharPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable4 +( + Id INT, + PartitionColumn VARBINARY(10) +) +ON BinaryPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable5 +( + Id INT, + PartitionColumn SMALLINT +) +ON BigIntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable6 +( + Id INT, + PartitionColumn DECIMAL(10, 2) +) +ON SmallIntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable7 +( + Id INT, + PartitionColumn DECIMAL(10, 5) +) +ON TinyIntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable8 +( + Id INT, + PartitionColumn BIGINT +) +ON DecimalPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable9 +( + Id INT, + PartitionColumn MONEY +) +ON NumericPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable10 +( + Id INT, + PartitionColumn INT +) +ON MoneyPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable11 +( + Id INT, + PartitionColumn DATETIME +) +ON SmallMoneyPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable12 +( + Id INT, + PartitionColumn DATETIME2(3) +) +ON DateTimePartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable13 +( + Id INT, + PartitionColumn SMALLDATETIME +) +ON DateTime2PartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable14 +( + Id INT, + PartitionColumn NVARCHAR(10) +) +ON SmallDateTimePartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable15 +( + Id INT, + PartitionColumn INT +) +ON NVarCharPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable16 +( + Id INT, + PartitionColumn NCHAR(5) +) +ON VarCharPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestPartitionedTable17 +( + Id INT, + PartitionColumn INT +) +ON NCharPartitionScheme(PartitionColumn); +GO + +-- using user defined type +CREATE TYPE PartitionUserDefinedType FROM SMALLINT; +GO + +CREATE TABLE TestPartitionedTable18 +( + Id INT, + PartitionColumn PartitionUserDefinedType +) +ON BigIntPartitionScheme(PartitionColumn); +GO + +DROP TYPE PartitionUserDefinedType +GO + +--------------------------------------------------------------- +--- Negative Scenarios for CREATE Index with PARTITION SCHEME +--------------------------------------------------------------- +CREATE TABLE TestPartitionedTable ( + PartitionColumn INT, + NonPartitionColumn INT +) ON IntPartitionScheme(PartitionColumn); +GO + +CREATE TABLE TestNonPartitionedTable ( + a INT, + b INT +) +GO + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonExistentColumn1) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonExistentColumn2); +GO + +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON NonExistentPartitionScheme (NonPartitionColumn); +GO + +-- scheme is different from the partition scheme used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON BigIntPartitionScheme (NonPartitionColumn); +GO + +-- column specified with partition scheme is different +-- from the partition column used in the table +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (NonPartitionColumn); +GO + +-- should work +CREATE INDEX TestPartitionIndex +ON TestPartitionedTable(NonPartitionColumn) +ON IntPartitionScheme (PartitionColumn); +GO + +DROP INDEX TestPartitionIndex ON TestPartitionedTable +GO + +-- usage of partition scheme on non-partitioned table (should fail) +CREATE INDEX TestPartitionIndex +ON TestNonPartitionedTable(a) +ON IntPartitionScheme (a); +GO + + +DROP TABLE TestPartitionedTable +GO + +DROP TABLE TestNonPartitionedTable +GO +------------------------------------------------------------------------------------------- +--- Rename Operation on Partitioned Tables should update name in babelfish_partition_depend +--- and it should also update the name of all the partitions +------------------------------------------------------------------------------------------- +-- psql +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; +GO + +-- tsql +-- trigger rename from TSQL endpoint +EXEC sp_rename 'partition_vu_prepare_int_table', 'partition_vu_prepare_int_table_renamed', 'OBJECT' +GO + +-- psql +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table_renamed'; +GO + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table_renamed')::regclass; +GO + +-- trigger rename from PSQL endpoint +ALTER TABLE master_dbo.partition_vu_prepare_int_table_renamed RENAME TO partition_vu_prepare_int_table; +GO + +-- we should get orginal here +SELECT sys.db_name(dbid) as db_name, partition_scheme_name, schema_name, table_name FROM sys.babelfish_partition_depend where table_name = 'partition_vu_prepare_int_table'; +GO + +SELECT inhrelid::regclass as partition_name from pg_inherits where inhparent = (select oid from pg_class where relname = 'partition_vu_prepare_int_table')::regclass; GO \ No newline at end of file diff --git a/test/dotnet/ExpectedOutput/insertBulk.out b/test/dotnet/ExpectedOutput/insertBulk.out index e3853821be5..e5c85449eca 100644 --- a/test/dotnet/ExpectedOutput/insertBulk.out +++ b/test/dotnet/ExpectedOutput/insertBulk.out @@ -442,3 +442,18 @@ hello#!#jello 1 #Q#drop table sourceTable #Q#drop table destinationTable +#Q#CREATE TABLE sourceTable(c1 int, c2 CHAR(1024)) +#Q#INSERT INTO sourceTable SELECT generate_series(1, 1000, 1), 'Foo' +#Q#CREATE PARTITION FUNCTION IntPartitionFunction (int) AS RANGE RIGHT FOR VALUES (0, 500, 1000) +#Q#CREATE PARTITION SCHEME IntPartitionScheme AS PARTITION IntPartitionFunction ALL TO ([PRIMARY]) +#Q#CREATE TABLE partitionedTable(c1 int, c2 CHAR(1024)) ON IntPartitionScheme(c1) +#Q#Select count(*) from sourceTable +#D#int +1000 +#Q#select count(*) from partitionedTable +#D#int +0 +#Q#DROP TABLE partitionedTable +#Q#DROP PARTITION SCHEME IntPartitionScheme +#Q#DROP PARTITION FUNCTION IntPartitionFunction +#Q#DROP TABLE sourceTable diff --git a/test/dotnet/input/InsertBulk/insertBulk.txt b/test/dotnet/input/InsertBulk/insertBulk.txt index b185778e64e..ea066080e5d 100644 --- a/test/dotnet/input/InsertBulk/insertBulk.txt +++ b/test/dotnet/input/InsertBulk/insertBulk.txt @@ -347,4 +347,18 @@ insertbulk#!#sourceTable#!#destinationTable Select count(*) from sourceTable select count(*) from destinationTable drop table sourceTable -drop table destinationTable \ No newline at end of file +drop table destinationTable + +# partitioned table +CREATE TABLE sourceTable(c1 int, c2 CHAR(1024)) +INSERT INTO sourceTable SELECT generate_series(1, 1000, 1), 'Foo' +CREATE PARTITION FUNCTION IntPartitionFunction (int) AS RANGE RIGHT FOR VALUES (0, 500, 1000) +CREATE PARTITION SCHEME IntPartitionScheme AS PARTITION IntPartitionFunction ALL TO ([PRIMARY]) +CREATE TABLE partitionedTable(c1 int, c2 CHAR(1024)) ON IntPartitionScheme(c1) +insertbulk#!#sourceTable#!#partitionedTable +Select count(*) from sourceTable +select count(*) from partitionedTable +DROP TABLE partitionedTable +DROP PARTITION SCHEME IntPartitionScheme +DROP PARTITION FUNCTION IntPartitionFunction +DROP TABLE sourceTable \ No newline at end of file diff --git a/test/python/expected/sql_validation_framework/expected_create.out b/test/python/expected/sql_validation_framework/expected_create.out index 073b85a951e..a14496dc9fe 100644 --- a/test/python/expected/sql_validation_framework/expected_create.out +++ b/test/python/expected/sql_validation_framework/expected_create.out @@ -70,9 +70,6 @@ Could not find tests for procedure sys.printarg Could not find tests for procedure sys.sp_cursor_list Could not find tests for procedure sys.sp_describe_cursor Could not find tests for table sys.babelfish_helpcollation -Could not find tests for table sys.babelfish_partition_depend -Could not find tests for table sys.babelfish_partition_function -Could not find tests for table sys.babelfish_partition_scheme Could not find tests for table sys.babelfish_syslanguages Could not find tests for table sys.service_settings Could not find tests for table sys.spt_datatype_info_table @@ -194,7 +191,6 @@ 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_partition_depend Could not find upgrade tests for table sys.babelfish_partition_function Could not find upgrade tests for table sys.babelfish_partition_scheme Could not find upgrade tests for table sys.babelfish_syslanguages From 1e57a7e72da842dda399dd102b8b66c989b82884 Mon Sep 17 00:00:00 2001 From: Rishabh Tanwar <33982749+rishabhtanwar29@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:24:19 +0530 Subject: [PATCH 12/15] Improve logic to extract identifier names (#2748) Previously, the logic to extract original identifier names from query string was not proper and could not handle the identifiers with special characters or object name being prefix of schema name. This logic was there to extract original table name and original function/procedure name from the query and due to this issue, we were storing wrong original names. Implemented helper function extract_multipart_identifier_name which improves the logic to extract original name from a multi-part identifier in a query string taking care of spaces or possibly quoted identifier. It internally uses extract_identifier function to extract individual parts of an identifier. Additional fixes: Fixed sp_rename_internal to properly handle rename of a table so that it also updates the underlying original table name (bbf_original_rel_name). Previously, sp_rename was using string_split() for the splitting which could not handle the quotes or special characters. Implemented helper SQL function babelfish_split_identifier which is mostly a wrapper over split_object_name C function to correctly split multi-part identifiers. Updated logic to fetch original table_name/column_name in sql views information_schema_tsql.columns_internal and information_schema_tsql.tables so that they don't assume that bbf_original_rel_name or bbf_original_name is always the first option in reloptions and attoptions list respectively, instead now the logic is to iterate over the whole list and search of the desired option. Task: BABEL-5089 Signed-off-by: Rishabh Tanwar ritanwar@amazon.com --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 2 +- .../sql/information_schema_tsql.sql | 44 ++- .../sql/sys_function_helpers.sql | 4 + .../babelfishpg_tsql--4.2.0--4.3.0.sql | 134 ++++++++- .../src/backend_parser/gram-tsql-rule.y | 2 +- contrib/babelfishpg_tsql/src/hooks.c | 97 +++--- contrib/babelfishpg_tsql/src/pl_handler.c | 6 +- contrib/babelfishpg_tsql/src/pltsql.h | 2 +- contrib/babelfishpg_tsql/src/pltsql_utils.c | 67 +++++ contrib/babelfishpg_tsql/src/procedures.c | 60 ++-- contrib/babelfishpg_tsql/src/schemacmds.c | 2 +- ...efore_16_4_or_15_8_or_14_13-vu-cleanup.out | 28 ++ ...efore_16_4_or_15_8_or_14_13-vu-prepare.out | 56 ++++ ...before_16_4_or_15_8_or_14_13-vu-verify.out | 125 ++++++++ test/JDBC/expected/ISC-Tables-vu-cleanup.out | 4 + test/JDBC/expected/ISC-Tables-vu-prepare.out | 19 +- test/JDBC/expected/ISC-Tables-vu-verify.out | 17 +- .../expected/Test-sp_rename-vu-cleanup.out | 3 + .../expected/Test-sp_rename-vu-prepare.out | 10 + .../expected/Test-sp_rename-vu-verify.out | 27 +- .../expected/Test_rename_db_single-db.out | 40 +-- ...efore_16_4_or_15_8_or_14_13-vu-cleanup.out | 58 ++++ ...fore_16_4_or_15_8_or_14_13-vu-prepare.out} | 15 + ...before_16_4_or_15_8_or_14_13-vu-verify.out | 283 ++++++++++++++++++ ... => babelfish_function_ext-vu-cleanup.out} | 12 + .../babelfish_function_ext-vu-prepare.out} | 17 +- ...t => babelfish_function_ext-vu-verify.out} | 4 + .../psql_logical_babelfish_db.out | 86 +++--- .../expected/psql_logical_babelfish_db.out | 86 +++--- ...efore_16_4_or_15_8_or_14_13-vu-cleanup.sql | 28 ++ ...efore_16_4_or_15_8_or_14_13-vu-prepare.sql | 56 ++++ ...before_16_4_or_15_8_or_14_13-vu-verify.sql | 52 ++++ test/JDBC/input/ISC-Tables-vu-cleanup.sql | 4 + test/JDBC/input/ISC-Tables-vu-prepare.sql | 19 +- test/JDBC/input/ISC-Tables-vu-verify.sql | 4 +- test/JDBC/input/Test_rename_db_single-db.sql | 32 +- ...efore_16_4_or_15_8_or_14_13-vu-cleanup.sql | 54 ++++ ...efore_16_4_or_15_8_or_14_13-vu-prepare.sql | 115 +++++++ ...before_16_4_or_15_8_or_14_13-vu-verify.sql | 141 +++++++++ ... => babelfish_function_ext-vu-cleanup.sql} | 12 + .../babelfish_function_ext-vu-prepare.sql | 115 +++++++ ...l => babelfish_function_ext-vu-verify.sql} | 0 test/JDBC/input/psql_logical_babelfish_db.mix | 16 +- .../Test-sp_rename-vu-cleanup.sql | 5 +- .../Test-sp_rename-vu-prepare.sql | 12 +- .../Test-sp_rename-vu-verify.sql | 10 + test/JDBC/jdbc_schedule | 7 + test/JDBC/upgrade/13_6/schedule | 2 +- test/JDBC/upgrade/13_7/schedule | 2 +- test/JDBC/upgrade/13_8/schedule | 2 +- test/JDBC/upgrade/13_9/schedule | 2 +- test/JDBC/upgrade/14_10/schedule | 2 +- test/JDBC/upgrade/14_11/schedule | 2 +- test/JDBC/upgrade/14_12/schedule | 2 +- test/JDBC/upgrade/14_3/schedule | 2 +- test/JDBC/upgrade/14_5/schedule | 2 +- test/JDBC/upgrade/14_6/schedule | 2 +- test/JDBC/upgrade/14_7/schedule | 2 +- test/JDBC/upgrade/14_8/schedule | 2 +- test/JDBC/upgrade/14_9/schedule | 2 +- test/JDBC/upgrade/15_1/schedule | 2 +- test/JDBC/upgrade/15_2/schedule | 2 +- test/JDBC/upgrade/15_3/schedule | 4 +- test/JDBC/upgrade/15_4/schedule | 4 +- test/JDBC/upgrade/15_5/schedule | 4 +- test/JDBC/upgrade/15_6/schedule | 4 +- test/JDBC/upgrade/15_7/schedule | 4 +- test/JDBC/upgrade/15_8/schedule | 2 +- test/JDBC/upgrade/16_1/schedule | 4 +- test/JDBC/upgrade/16_2/schedule | 4 +- test/JDBC/upgrade/16_3/schedule | 4 +- test/JDBC/upgrade/latest/schedule | 2 +- 72 files changed, 1766 insertions(+), 292 deletions(-) create mode 100644 test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.out create mode 100644 test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.out create mode 100644 test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.out create mode 100644 test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.out rename test/JDBC/expected/{BABEL-2877-vu-prepare.out => babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.out} (84%) create mode 100644 test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.out rename test/JDBC/expected/{BABEL-2877-vu-cleanup.out => babelfish_function_ext-vu-cleanup.out} (77%) rename test/JDBC/{input/BABEL-2877-vu-prepare.sql => expected/babelfish_function_ext-vu-prepare.out} (84%) rename test/JDBC/expected/{BABEL-2877-vu-verify.out => babelfish_function_ext-vu-verify.out} (95%) create mode 100644 test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.sql create mode 100644 test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.sql create mode 100644 test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.sql create mode 100644 test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.sql create mode 100644 test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.sql create mode 100644 test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.sql rename test/JDBC/input/{BABEL-2877-vu-cleanup.sql => babelfish_function_ext-vu-cleanup.sql} (75%) create mode 100644 test/JDBC/input/babelfish_function_ext-vu-prepare.sql rename test/JDBC/input/{BABEL-2877-vu-verify.sql => babelfish_function_ext-vu-verify.sql} (100%) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index 740eecf2602..344cf739009 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -3028,7 +3028,7 @@ AS $$ BEGIN SELECT (ROW_NUMBER() OVER (ORDER BY NULL)) as row, * INTO #sp_rename_temptable - FROM STRING_SPLIT(@input, '.') ORDER BY row DESC; + FROM sys.babelfish_split_identifier(@input) ORDER BY row DESC; SELECT (ROW_NUMBER() OVER (ORDER BY NULL)) as id, * INTO #sp_rename_temptable2 diff --git a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql index 0f200a79370..3144686869e 100644 --- a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql @@ -241,16 +241,28 @@ CREATE OR REPLACE VIEW information_schema_tsql.columns_internal AS SELECT c.oid AS "TABLE_OID", CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", - CAST(CASE - WHEN c.reloptions[1] LIKE 'bbf_original_rel_name=%' THEN substring(c.reloptions[1], 23) - ELSE c.relname - END AS sys.nvarchar(128)) AS "TABLE_NAME", - - CAST(CASE - WHEN a.attoptions[1] LIKE 'bbf_original_name=%' THEN substring(a.attoptions[1], 19) - ELSE a.attname - END AS sys.nvarchar(128)) AS "COLUMN_NAME", - + CAST( + COALESCE( + (SELECT string_agg( + CASE + WHEN option LIKE 'bbf_original_rel_name=%' THEN substring(option, 23 /* prefix length */) + ELSE NULL + END, ',') + FROM unnest(c.reloptions) AS option), + c.relname) + AS sys.nvarchar(128)) AS "TABLE_NAME", + + CAST( + COALESCE( + (SELECT string_agg( + CASE + WHEN option LIKE 'bbf_original_name=%' THEN substring(option, 19 /* prefix length */) + ELSE NULL + END, ',') + FROM unnest(a.attoptions) AS option), + a.attname) + AS sys.nvarchar(128)) AS "COLUMN_NAME", + CAST(a.attnum AS int) AS "ORDINAL_POSITION", CAST(CASE WHEN a.attgenerated = '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS sys.nvarchar(4000)) AS "COLUMN_DEFAULT", CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END @@ -449,9 +461,15 @@ CREATE VIEW information_schema_tsql.tables AS SELECT CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", CAST( - CASE WHEN c.reloptions[1] LIKE 'bbf_original_rel_name%' THEN substring(c.reloptions[1], 23) - ELSE c.relname END - AS sys._ci_sysname) AS "TABLE_NAME", + COALESCE( + (SELECT string_agg( + CASE + WHEN option LIKE 'bbf_original_rel_name=%' THEN substring(option, 23) + ELSE NULL + END, ',') + FROM unnest(c.reloptions) AS option), + c.relname) + AS sys._ci_sysname) AS "TABLE_NAME", CAST( CASE WHEN c.relkind IN ('r', 'p') THEN 'BASE TABLE' diff --git a/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql b/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql index 672d0ac192e..c5653f53aed 100644 --- a/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql +++ b/contrib/babelfishpg_tsql/sql/sys_function_helpers.sql @@ -10370,3 +10370,7 @@ CREATE OR REPLACE FUNCTION sys.bbf_get_immediate_base_type_of_UDT(OID) RETURNS OID AS 'babelfishpg_tsql', 'get_immediate_base_type_of_UDT' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.babelfish_split_identifier(IN identifier VARCHAR, OUT value VARCHAR) +RETURNS SETOF VARCHAR AS 'babelfishpg_tsql', 'split_identifier_internal' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 79fc47bbb7f..7c8e28e4b88 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -6159,16 +6159,28 @@ CREATE OR REPLACE VIEW information_schema_tsql.columns_internal AS SELECT c.oid AS "TABLE_OID", CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", - CAST(CASE - WHEN c.reloptions[1] LIKE 'bbf_original_rel_name=%' THEN substring(c.reloptions[1], 23) - ELSE c.relname - END AS sys.nvarchar(128)) AS "TABLE_NAME", - - CAST(CASE - WHEN a.attoptions[1] LIKE 'bbf_original_name=%' THEN substring(a.attoptions[1], 19) - ELSE a.attname - END AS sys.nvarchar(128)) AS "COLUMN_NAME", - + CAST( + COALESCE( + (SELECT string_agg( + CASE + WHEN option LIKE 'bbf_original_rel_name=%' THEN substring(option, 23 /* prefix length */) + ELSE NULL + END, ',') + FROM unnest(c.reloptions) AS option), + c.relname) + AS sys.nvarchar(128)) AS "TABLE_NAME", + + CAST( + COALESCE( + (SELECT string_agg( + CASE + WHEN option LIKE 'bbf_original_name=%' THEN substring(option, 19 /* prefix length */) + ELSE NULL + END, ',') + FROM unnest(a.attoptions) AS option), + a.attname) + AS sys.nvarchar(128)) AS "COLUMN_NAME", + CAST(a.attnum AS int) AS "ORDINAL_POSITION", CAST(CASE WHEN a.attgenerated = '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS sys.nvarchar(4000)) AS "COLUMN_DEFAULT", CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END @@ -6265,9 +6277,15 @@ CREATE OR REPLACE VIEW information_schema_tsql.tables AS SELECT CAST(nc.dbname AS sys.nvarchar(128)) AS "TABLE_CATALOG", CAST(ext.orig_name AS sys.nvarchar(128)) AS "TABLE_SCHEMA", CAST( - CASE WHEN c.reloptions[1] LIKE 'bbf_original_rel_name%' THEN substring(c.reloptions[1], 23) - ELSE c.relname END - AS sys._ci_sysname) AS "TABLE_NAME", + COALESCE( + (SELECT string_agg( + CASE + WHEN option LIKE 'bbf_original_rel_name=%' THEN substring(option, 23) + ELSE NULL + END, ',') + FROM unnest(c.reloptions) AS option), + c.relname) + AS sys._ci_sysname) AS "TABLE_NAME", CAST( CASE WHEN c.relkind IN ('r', 'p') THEN 'BASE TABLE' @@ -6464,6 +6482,96 @@ AND has_schema_privilege(t1.relnamespace, 'USAGE') AND has_table_privilege(t1.oid, 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER'); GRANT SELECT ON sys.sp_tables_view TO PUBLIC; +CREATE OR REPLACE FUNCTION sys.babelfish_split_identifier(IN identifier VARCHAR, OUT value VARCHAR) +RETURNS SETOF VARCHAR AS 'babelfishpg_tsql', 'split_identifier_internal' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE PROCEDURE sys.babelfish_sp_rename_word_parse( + IN "@input" sys.nvarchar(776), + IN "@objtype" sys.varchar(13), + INOUT "@subname" sys.nvarchar(776), + INOUT "@curr_relname" sys.nvarchar(776), + INOUT "@schemaname" sys.nvarchar(776), + INOUT "@dbname" sys.nvarchar(776) +) +AS $$ +BEGIN + SELECT (ROW_NUMBER() OVER (ORDER BY NULL)) as row, * + INTO #sp_rename_temptable + FROM sys.babelfish_split_identifier(@input) ORDER BY row DESC; + + SELECT (ROW_NUMBER() OVER (ORDER BY NULL)) as id, * + INTO #sp_rename_temptable2 + FROM #sp_rename_temptable; + + DECLARE @row_count INT; + SELECT @row_count = COUNT(*) FROM #sp_rename_temptable2; + + IF @objtype = 'COLUMN' + BEGIN + IF @row_count = 1 + BEGIN + THROW 33557097, N'Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong.', 1; + END + ELSE IF @row_count > 4 + BEGIN + THROW 33557097, N'No item by the given @objname could be found in the current database', 1; + END + ELSE + BEGIN + IF @row_count > 1 + BEGIN + SELECT @subname = value FROM #sp_rename_temptable2 WHERE id = 1; + SELECT @curr_relname = value FROM #sp_rename_temptable2 WHERE id = 2; + SET @schemaname = sys.schema_name(); + + END + IF @row_count > 2 + BEGIN + SELECT @schemaname = value FROM #sp_rename_temptable2 WHERE id = 3; + END + IF @row_count > 3 + BEGIN + SELECT @dbname = value FROM #sp_rename_temptable2 WHERE id = 4; + IF @dbname != sys.db_name() + BEGIN + THROW 33557097, N'No item by the given @objname could be found in the current database', 1; + END + END + END + END + ELSE + BEGIN + IF @row_count > 3 + BEGIN + THROW 33557097, N'No item by the given @objname could be found in the current database', 1; + END + ELSE + BEGIN + SET @curr_relname = NULL; + IF @row_count > 0 + BEGIN + SELECT @subname = value FROM #sp_rename_temptable2 WHERE id = 1; + SET @schemaname = sys.schema_name(); + END + IF @row_count > 1 + BEGIN + SELECT @schemaname = value FROM #sp_rename_temptable2 WHERE id = 2; + END + IF @row_count > 2 + BEGIN + SELECT @dbname = value FROM #sp_rename_temptable2 WHERE id = 3; + IF @dbname != sys.db_name() + BEGIN + THROW 33557097, N'No item by the given @objname could be found in the current database', 1; + END + END + END + END +END; +$$ +LANGUAGE 'pltsql'; + -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar); diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y index 8544c5f3e89..cfdf11893f8 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y @@ -2639,7 +2639,7 @@ tsql_untruncated_IDENT: * Extract the original, untruncated identifier from the input buffer. * Here, @1 represents the start location of the identifier token. */ - $$ = extract_identifier(yyextra->core_yy_extra.scanbuf + @1); + $$ = extract_identifier(yyextra->core_yy_extra.scanbuf + @1, NULL); } ; diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index af82ac40f80..a9bd0c41cfd 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -1448,7 +1448,7 @@ check_insert_row(List *icolumns, List *exprList, Oid relid) } char * -extract_identifier(const char *start) +extract_identifier(const char *start, int *last_pos) { /* * We will extract original identifier from source query string. 'start' @@ -1501,6 +1501,8 @@ extract_identifier(const char *start) original_name = palloc(i + 1); memcpy(original_name, start, i); original_name[i] = '\0'; + if (last_pos) + *last_pos = i; return original_name; } } @@ -1518,6 +1520,8 @@ extract_identifier(const char *start) if (!valid) { + if (last_pos) + *last_pos = i + 1; if (!found_escaped_in_dq) { /* no escaped character. copy whole string at once */ @@ -1563,6 +1567,8 @@ extract_identifier(const char *start) if (!valid) { + if (last_pos) + *last_pos = i + 1; if (!found_escaped_in_sq) { /* no escaped character. copy whole string at once */ @@ -1604,6 +1610,8 @@ extract_identifier(const char *start) * bracket */ memcpy(original_name, start + 1, i - 1); original_name[i - 1] = '\0'; + if (last_pos) + *last_pos = i + 1; return original_name; } } @@ -1614,6 +1622,42 @@ extract_identifier(const char *start) return NULL; } +/* + * extract_multipart_identifier_name + * Return name of a multipart SQL identifier, whose starting position + * is given as 'start'. This helper function basically returns the + * last part of the multipart identifier. + */ +static char * +extract_multipart_identifier_name(const char *start) +{ + int identifier_len = strlen(start); + int last_pos = 0; + char *name = extract_identifier(start, &last_pos); + + /* Loop until we find the last part of the identifier */ + while (last_pos < identifier_len) + { + int cur_pos = 0; + if (isspace(start[last_pos])) + { + last_pos++; + continue; + } + if (start[last_pos] != '.') + break; + + last_pos++; + while (isspace(start[last_pos])) + last_pos++; + pfree(name); + name = extract_identifier(start + last_pos, &cur_pos); + last_pos += cur_pos; + } + + return name; +} + extern const char *ATTOPTION_BBF_ORIGINAL_NAME; static void @@ -1633,7 +1677,7 @@ pltsql_post_transform_column_definition(ParseState *pstate, RangeVar *relation, * string. */ const char *column_name_start = pstate->p_sourcetext + column->location; - char *original_name = extract_identifier(column_name_start); + char *original_name = extract_identifier(column_name_start, NULL); if (original_name == NULL) ereport(ERROR, @@ -1673,8 +1717,7 @@ pltsql_post_transform_table_definition(ParseState *pstate, RangeVar *relation, c * string. */ char *table_name_start, - *original_name, - *temp; + *original_name; /* * Skip during restore since reloptions are also dumped using separate @@ -1688,24 +1731,7 @@ pltsql_post_transform_table_definition(ParseState *pstate, RangeVar *relation, c table_name_start = (char *) pstate->p_sourcetext + relation->location; - /* - * Could be the case that the fully qualified name is included, so just - * find the text after '.' in the identifier. We need to be careful as - * there can be '.' in the table name itself, so we will break the loop if - * current string matches with actual relname. - */ - temp = strpbrk(table_name_start, ". "); - while (temp && temp[0] != ' ' && - strncasecmp(relname, table_name_start, strlen(relname)) != 0 && - strncasecmp(relname, table_name_start + 1, strlen(relname)) != 0) /* match after skipping - * delimiter */ - { - temp += 1; - table_name_start = temp; - temp = strpbrk(table_name_start, ". "); - } - - original_name = extract_identifier(table_name_start); + original_name = extract_multipart_identifier_name(table_name_start); if (original_name == NULL) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), @@ -2048,7 +2074,7 @@ pre_transform_target_entry(ResTarget *res, ParseState *pstate, } /* To extract the identifier name from the query.*/ - original_name = extract_identifier(colname_start); + original_name = extract_identifier(colname_start, NULL); actual_alias_len = strlen(original_name); /* Maximum alias_len can be 63 after truncation. If alias_len is smaller than actual_alias_len, @@ -2730,8 +2756,8 @@ pltsql_report_proc_not_found_error(List *names, List *given_argnames, Oid *input errmsg("%s %s has no parameters and arguments were supplied.", obj_type, NameListToString(names))), parser_errposition(pstate, location)); } + ReleaseSysCache(tup); } - heap_freetuple(tup); } } @@ -3377,30 +3403,11 @@ pltsql_store_func_default_positions(ObjectAddress address, List *parameters, con * To get original function name, utilize location of original name * and query string. */ - char *func_name_start, - *temp; - const char *funcname = NameStr(form_proctup->proname); + char *func_name_start; func_name_start = (char *) queryString + origname_location; - /* - * Could be the case that the fully qualified name is included, so - * just find the text after '.' in the identifier. We need to be - * careful as there can be '.' in the function name itself, so we will - * break the loop if current string matches with actual funcname. - */ - temp = strpbrk(func_name_start, ". "); - while (temp && temp[0] != ' ' && - strncasecmp(funcname, func_name_start, strlen(funcname)) != 0 && - strncasecmp(funcname, func_name_start + 1, strlen(funcname)) != 0) /* match after skipping - * delimiter */ - { - temp += 1; - func_name_start = temp; - temp = strpbrk(func_name_start, ". "); - } - - original_name = extract_identifier(func_name_start); + original_name = extract_multipart_identifier_name(func_name_start); if (original_name == NULL) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 3f915f3406a..bf43cf4d6ea 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2595,7 +2595,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { int location = defel->location; - orig_loginname = extract_identifier(queryString + location); + orig_loginname = extract_identifier(queryString + location, NULL); login_options = lappend(login_options, defel); } else if (strcmp(defel->defname, "from_windows") == 0) @@ -2770,7 +2770,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { char *orig_user_name; - orig_user_name = extract_identifier(queryString + location); + orig_user_name = extract_identifier(queryString + location, NULL); user_options = lappend(user_options, makeDefElem("original_user_name", (Node *) makeString(orig_user_name), @@ -2825,7 +2825,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { char *orig_user_name; - orig_user_name = extract_identifier(queryString + location); + orig_user_name = extract_identifier(queryString + location, NULL); user_options = lappend(user_options, makeDefElem("original_user_name", (Node *) makeString(orig_user_name), diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 6cf1f772eb2..01c786f1adf 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -2107,7 +2107,7 @@ extern void pltsql_scanner_finish(void); extern int pltsql_yyparse(void); /* functions in hooks.c */ -extern char *extract_identifier(const char *start); +extern char *extract_identifier(const char *start, int *last_pos); /* functions in pltsql_utils.c */ extern char *gen_createfulltextindex_cmds(const char *table_name, const char *schema_name, const List *column_name, const char *index_name); diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index fa21a42f114..7e9fec3761b 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -6,6 +6,7 @@ #include "catalog/pg_type.h" #include "catalog/pg_trigger.h" #include "catalog/pg_constraint.h" +#include "funcapi.h" #include "parser/parser.h" /* only needed for GUC variables */ #include "parser/parse_type.h" #include "mb/pg_wchar.h" @@ -46,6 +47,7 @@ extern char *get_cur_db_name(void); extern char *construct_unique_index_name(char *index_name, char *relation_name); extern char *get_physical_schema_name(char *db_name, const char *schema_name); extern const char *get_dbo_schema_name(const char *dbname); +PG_FUNCTION_INFO_V1(split_identifier_internal); /* To cache oid of sys.varchar */ static Oid sys_varcharoid = InvalidOid; @@ -1574,6 +1576,71 @@ split_object_name(char *name) return res; } +/* + * Wrapper over split_object_name function above to expose it as a SQL function. + */ +Datum +split_identifier_internal(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + char **split_parts = NULL; + + if (SRF_IS_FIRSTCALL()) + { + int num_parts = 0; + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + if (!PG_ARGISNULL(0)) + { + char *input; + char **splited_object_name; + int i, j = 0; + + input = text_to_cstring(PG_GETARG_TEXT_P(0)); + splited_object_name = split_object_name(input); + + for (i = 0; i < 4; i++) + { + if (strlen(splited_object_name[i]) > 0) + num_parts++; + } + + if (num_parts > 0) + { + split_parts = (char **) palloc(num_parts * sizeof(char *)); + + for (i = 0; i < 4; i++) + { + if (i >= (4 - num_parts)) + split_parts[j++] = splited_object_name[i]; + else + pfree(splited_object_name[i]); + } + } + pfree(splited_object_name); + } + + funcctx->max_calls = num_parts; + funcctx->user_fctx = split_parts; + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + split_parts = (char **) funcctx->user_fctx; + + if (funcctx->call_cntr < funcctx->max_calls) + { + VarChar *val = (*common_utility_plugin_ptr->tsql_varchar_input) (split_parts[funcctx->call_cntr], + strlen(split_parts[funcctx->call_cntr]), + -1); + SRF_RETURN_NEXT(funcctx, PointerGetDatum(val)); + } + else + SRF_RETURN_DONE(funcctx); +} + /* * is_schema_from_db diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index b98d03e3117..b4908115e87 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -92,7 +92,6 @@ static List *gen_sp_droprolemember_subcmds(const char *user, const char *member) static List *gen_sp_rename_subcmds(const char *objname, const char *newname, const char *schemaname, ObjectType objtype, const char *curr_relname); static void update_bbf_server_options(char *servername, char *optname, char *optvalue, bool isInsert); static void clean_up_bbf_server_option(char *servername); -static void remove_delimited_identifer(char *str); static void rename_extended_property(ObjectType objtype, const char *var_schema_name, const char *var_major_name, @@ -3551,8 +3550,6 @@ sp_babelfish_volatility(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } -extern bool pltsql_quoted_identifier; - Datum sp_renamedb_internal(PG_FUNCTION_ARGS) { @@ -3716,16 +3713,6 @@ sp_rename_internal(PG_FUNCTION_ARGS) curr_relname[--len] = 0; } - /* remove delimited identifiers if quoted_identifier is on */ - if (pltsql_quoted_identifier) - { - remove_delimited_identifer(obj_name); - remove_delimited_identifer(schema_name); - if (curr_relname != NULL) { - remove_delimited_identifer(curr_relname); - } - } - /* check if inputs are empty after removing trailing spaces */ if (obj_name == NULL) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), @@ -3958,6 +3945,7 @@ rename_extended_property(ObjectType objtype, const char *var_schema_name, } } +extern const char *ATTOPTION_BBF_ORIGINAL_TABLE_NAME; extern const char *ATTOPTION_BBF_ORIGINAL_NAME; static List * @@ -3974,6 +3962,7 @@ gen_sp_rename_subcmds(const char *objname, const char *newname, const char *sche { case OBJECT_TABLE: appendStringInfo(&query, "ALTER TABLE dummy RENAME TO dummy; "); + appendStringInfo(&query, "ALTER TABLE dummy SET (dummy = 'dummy'); "); break; case OBJECT_VIEW: appendStringInfo(&query, "ALTER VIEW dummy RENAME TO dummy; "); @@ -4012,7 +4001,10 @@ gen_sp_rename_subcmds(const char *objname, const char *newname, const char *sche res = raw_parser(query.data, RAW_PARSE_DEFAULT); sql_dialect = old_dialect; - if ((objtype != OBJECT_COLUMN) && (objtype != OBJECT_TRIGGER) && (list_length(res) != 1)) + if ((objtype != OBJECT_TABLE) && + (objtype != OBJECT_COLUMN) && + (objtype != OBJECT_TRIGGER) && + (list_length(res) != 1)) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("Expected 1 statement but get %d statements after parsing", list_length(res)))); @@ -4030,6 +4022,29 @@ gen_sp_rename_subcmds(const char *objname, const char *newname, const char *sche renamestmt->newname = pstrdup(lowerstr(newname)); renamestmt->relation->schemaname = pstrdup(lowerstr(schemaname)); renamestmt->relation->relname = pstrdup(lowerstr(objname)); + + if (objtype == OBJECT_TABLE) + { + AlterTableStmt *altertablestmt; + AlterTableCmd *cmd; + ListCell *lc = NULL; + + rewrite_object_refs(stmt); + /* extra query nodes for modifying reloption */ + stmt = parsetree_nth_stmt(res, 1); + altertablestmt = (AlterTableStmt *) stmt; + if (!IsA(altertablestmt, AlterTableStmt)) + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("query is not a AlterTableStmt"))); + + altertablestmt->relation->schemaname = pstrdup(lowerstr(schemaname)); + altertablestmt->relation->relname = pstrdup(lowerstr(newname)); + altertablestmt->objtype = OBJECT_TABLE; + /* get data of the first node */ + lc = list_head(altertablestmt->cmds); + cmd = (AlterTableCmd *) lfirst(lc); + cmd->subtype = AT_SetRelOptions; + cmd->def = (Node *) list_make1(makeDefElem(pstrdup(ATTOPTION_BBF_ORIGINAL_TABLE_NAME), (Node *) makeString(pstrdup(newname)), -1)); + } } else if ((objtype == OBJECT_PROCEDURE) || (objtype == OBJECT_FUNCTION)) { @@ -4106,23 +4121,6 @@ gen_sp_rename_subcmds(const char *objname, const char *newname, const char *sche return res; } -static void -remove_delimited_identifer(char *str) -{ - size_t len = strlen(str); - if ((str[0] == '"' && str[len - 1] == '"') || (str[0] == '[' && str[len - 1] == ']')) - { - memmove(str, &str[1], len - 1); - str[len - 2] = '\0'; - } - if (isspace(str[0])) - ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong."))); - len = strlen(str); - while (isspace(str[len - 1])) - str[--len] = 0; -} - Datum sp_enum_oledb_providers_internal(PG_FUNCTION_ARGS) { diff --git a/contrib/babelfishpg_tsql/src/schemacmds.c b/contrib/babelfishpg_tsql/src/schemacmds.c index 5c95e5fdfdb..70d157ce1b6 100644 --- a/contrib/babelfishpg_tsql/src/schemacmds.c +++ b/contrib/babelfishpg_tsql/src/schemacmds.c @@ -39,7 +39,7 @@ add_ns_ext_info(CreateSchemaStmt *stmt, const char *queryString, const char *ori if (!orig_name) { if (stmt->location != -1 && queryString) - orig_name = extract_identifier(queryString + stmt->location); + orig_name = extract_identifier(queryString + stmt->location, NULL); else orig_name = ""; } diff --git a/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.out b/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.out new file mode 100644 index 00000000000..b2a1c38e3d1 --- /dev/null +++ b/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.out @@ -0,0 +1,28 @@ +DROP TABLE isc_tables_sc1.t2 +DROP TABLE [ISC_TABLES_TABLE_SCHEMA].[ISC_TABLES_TABLE] +DROP TABLE [ISC_TABLES SCHEMA . WITH .. DOTS].[ISC_TABLES TABLE . WITH .. DOTS2] +GO + +DROP TYPE isc_tables_sc1.isc_table_type2 +GO + +DROP SCHEMA isc_tables_sc1 +DROP SCHEMA [ISC_TABLES_TABLE_SCHEMA] +DROP SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] +GO + +DROP VIEW isc_tables_vu_prepare_v1 +GO + +DROP FUNCTION isc_tables_vu_prepare_f2 +DROP FUNCTION isc_tables_vu_prepare_f1 +GO + +DROP PROCEDURE isc_tables_vu_prepare_p1 +GO + +DROP TABLE isc_tables_vu_prepare_t1 +GO + +DROP TYPE isc_table_type1 +GO diff --git a/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.out b/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.out new file mode 100644 index 00000000000..806a0e3c9d7 --- /dev/null +++ b/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.out @@ -0,0 +1,56 @@ +CREATE TABLE isc_tables_vu_prepare_t1(a INT,b INT) +GO + +CREATE TYPE isc_table_type1 AS TABLE(a INT) +GO + +-- test different schema +CREATE SCHEMA isc_tables_sc1 +GO + +CREATE SCHEMA [ISC_TABLES_TABLE_SCHEMA] +GO + +CREATE SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] +GO + +CREATE TABLE isc_tables_sc1.t2(a INT,b INT) +GO + +-- Table name which is prefix of schema name +CREATE TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE] (a INT, b INT) +GO + +CREATE TABLE [ISC_TABLES SCHEMA . WITH .. DOTS] . [ISC_TABLES TABLE . WITH .. DOTS] (a INT, b INT) +GO + +CREATE TYPE isc_tables_sc1.isc_table_type2 AS TABLE(a INT) +GO + +--Dep Proc +CREATE PROCEDURE isc_tables_vu_prepare_p1 AS +SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'isc_tables_vu_prepare_t1' +SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1' +GO + +-- Dep Funcs +CREATE FUNCTION isc_tables_vu_prepare_f1() +RETURNS INT +AS +BEGIN + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%') +end +GO + +CREATE FUNCTION isc_tables_vu_prepare_f2() +RETURNS INT +AS +BEGIN + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%') +end +GO + +-- Dep View +CREATE VIEW isc_tables_vu_prepare_v1 AS + SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO diff --git a/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.out b/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.out new file mode 100644 index 00000000000..6e72ed8e0fa --- /dev/null +++ b/test/JDBC/expected/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.out @@ -0,0 +1,125 @@ +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#isc_tables table . with .. dots#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE_SCHEMA#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW +~~END~~ + + +-- Rename the existing tables to fix the originally stored incorrect bbf_original_rel_name +EXEC sp_rename 'ISC_TABLES_TABLE_SCHEMA.ISC_TABLES_TABLE', 'ISC_TABLES_TABLE2', 'OBJECT' +GO + +EXEC sp_rename '"ISC_TABLES SCHEMA . WITH .. DOTS"."ISC_TABLES TABLE . WITH .. DOTS"', 'ISC_TABLES TABLE . WITH .. DOTS2', 'OBJECT' +GO + +-- create a new table with name which is prefix of schema name to verify new behavior +CREATE TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE] (a INT, b INT) +GO + +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%' ORDER BY TABLE_NAME +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#ISC_TABLES TABLE . WITH .. DOTS2#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE2#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW +~~END~~ + +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#ISC_TABLES TABLE . WITH .. DOTS2#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE2#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW +~~END~~ + + +-- Table types should not be a result +-- Should not return any rows. +SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'isc_table_type1' +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +~~END~~ + + +SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = 'isc_tables_sc1' +SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = 'ISC_TABLES_SC1' +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#isc_tables_sc1#!#t2#!#BASE TABLE +~~END~~ + +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#isc_tables_sc1#!#t2#!#BASE TABLE +~~END~~ + + +-- Table types should not be a result +-- Should not return any rows. +SELECT * FROM information_schema.tables WHERE (TABLE_NAME = 'isc_table_type2' AND TABLE_SCHEMA = 'isc_tables_sc1') +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +~~END~~ + + +EXEC isc_tables_vu_prepare_p1 +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +~~END~~ + +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +~~END~~ + + +SELECT * FROM isc_tables_vu_prepare_f1() +SELECT * FROM isc_tables_vu_prepare_f2() +GO +~~START~~ +int +5 +~~END~~ + +~~START~~ +int +5 +~~END~~ + + +-- Drop and re-create isc_tables_vu_prepare_v1 as it might be dependent upon +-- the deprecated version of information_schema.tables view. +DROP VIEW isc_tables_vu_prepare_v1 +GO +CREATE VIEW isc_tables_vu_prepare_v1 AS + SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO + +SELECT * FROM isc_tables_vu_prepare_v1 +GO +~~START~~ +nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#ISC_TABLES TABLE . WITH .. DOTS2#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE2#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW +~~END~~ + + +DROP TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE2] +GO diff --git a/test/JDBC/expected/ISC-Tables-vu-cleanup.out b/test/JDBC/expected/ISC-Tables-vu-cleanup.out index ccadb1a4256..d648cef653b 100644 --- a/test/JDBC/expected/ISC-Tables-vu-cleanup.out +++ b/test/JDBC/expected/ISC-Tables-vu-cleanup.out @@ -1,10 +1,14 @@ DROP TABLE isc_tables_sc1.t2 +DROP TABLE [ISC_TABLES_TABLE_SCHEMA].[ISC_TABLES_TABLE] +DROP TABLE [ISC_TABLES SCHEMA . WITH .. DOTS].[ISC_TABLES TABLE . WITH .. DOTS] GO DROP TYPE isc_tables_sc1.isc_table_type2 GO DROP SCHEMA isc_tables_sc1 +DROP SCHEMA [ISC_TABLES_TABLE_SCHEMA] +DROP SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] GO DROP VIEW isc_tables_vu_prepare_v1 diff --git a/test/JDBC/expected/ISC-Tables-vu-prepare.out b/test/JDBC/expected/ISC-Tables-vu-prepare.out index 18f81a38128..806a0e3c9d7 100644 --- a/test/JDBC/expected/ISC-Tables-vu-prepare.out +++ b/test/JDBC/expected/ISC-Tables-vu-prepare.out @@ -8,9 +8,22 @@ GO CREATE SCHEMA isc_tables_sc1 GO +CREATE SCHEMA [ISC_TABLES_TABLE_SCHEMA] +GO + +CREATE SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] +GO + CREATE TABLE isc_tables_sc1.t2(a INT,b INT) GO +-- Table name which is prefix of schema name +CREATE TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE] (a INT, b INT) +GO + +CREATE TABLE [ISC_TABLES SCHEMA . WITH .. DOTS] . [ISC_TABLES TABLE . WITH .. DOTS] (a INT, b INT) +GO + CREATE TYPE isc_tables_sc1.isc_table_type2 AS TABLE(a INT) GO @@ -25,7 +38,7 @@ CREATE FUNCTION isc_tables_vu_prepare_f1() RETURNS INT AS BEGIN - RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME = 'isc_tables_vu_prepare_t1') + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%') end GO @@ -33,11 +46,11 @@ CREATE FUNCTION isc_tables_vu_prepare_f2() RETURNS INT AS BEGIN - RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1') + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%') end GO -- Dep View CREATE VIEW isc_tables_vu_prepare_v1 AS - SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1' + SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME GO diff --git a/test/JDBC/expected/ISC-Tables-vu-verify.out b/test/JDBC/expected/ISC-Tables-vu-verify.out index 549d72fae08..d050ff6b7f4 100644 --- a/test/JDBC/expected/ISC-Tables-vu-verify.out +++ b/test/JDBC/expected/ISC-Tables-vu-verify.out @@ -1,14 +1,20 @@ -SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'isc_tables_vu_prepare_t1' -SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1' +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%' ORDER BY TABLE_NAME +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#ISC_TABLES TABLE . WITH .. DOTS#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE#!#BASE TABLE master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW ~~END~~ ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#ISC_TABLES TABLE . WITH .. DOTS#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE#!#BASE TABLE master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW ~~END~~ @@ -62,12 +68,12 @@ SELECT * FROM isc_tables_vu_prepare_f2() GO ~~START~~ int -1 +4 ~~END~~ ~~START~~ int -1 +4 ~~END~~ @@ -75,6 +81,9 @@ SELECT * FROM isc_tables_vu_prepare_v1 GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar +master#!#ISC_TABLES SCHEMA . WITH .. DOTS#!#ISC_TABLES TABLE . WITH .. DOTS#!#BASE TABLE +master#!#ISC_TABLES_TABLE_SCHEMA#!#ISC_TABLES_TABLE#!#BASE TABLE master#!#dbo#!#isc_tables_vu_prepare_t1#!#BASE TABLE +master#!#dbo#!#isc_tables_vu_prepare_v1#!#VIEW ~~END~~ diff --git a/test/JDBC/expected/Test-sp_rename-vu-cleanup.out b/test/JDBC/expected/Test-sp_rename-vu-cleanup.out index 20379f7e2d5..6b0c9cd260e 100644 --- a/test/JDBC/expected/Test-sp_rename-vu-cleanup.out +++ b/test/JDBC/expected/Test-sp_rename-vu-cleanup.out @@ -67,3 +67,6 @@ GO DROP SCHEMA sp_rename_vu_schema1; GO + +DROP VIEW babelfish_split_identifier_view; +GO diff --git a/test/JDBC/expected/Test-sp_rename-vu-prepare.out b/test/JDBC/expected/Test-sp_rename-vu-prepare.out index 18717c0de14..09d689fc9ab 100644 --- a/test/JDBC/expected/Test-sp_rename-vu-prepare.out +++ b/test/JDBC/expected/Test-sp_rename-vu-prepare.out @@ -99,3 +99,13 @@ GO CREATE TYPE sp_rename_vu_schema1.sp_rename_vu_alias1 FROM VARCHAR(11) NOT NULL; GO + +-- Dependency test for function babelfish_split_identifier +-- Create a view which depends upon babelfish_split_identifier function only +-- if the function exists. +IF OBJECT_ID('sys.babelfish_split_identifier') IS NOT NULL +BEGIN + EXEC sp_executesql N' + CREATE VIEW babelfish_split_identifier_view AS SELECT * FROM sys.babelfish_split_identifier(''ABC.DEF.GHI'')'; +END +GO diff --git a/test/JDBC/expected/Test-sp_rename-vu-verify.out b/test/JDBC/expected/Test-sp_rename-vu-verify.out index be0cd468f5a..2f2b7909a95 100644 --- a/test/JDBC/expected/Test-sp_rename-vu-verify.out +++ b/test/JDBC/expected/Test-sp_rename-vu-verify.out @@ -300,7 +300,7 @@ GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar master#!#dbo#!#sp_rename_vu_table_delim#!#BASE TABLE -master#!#dbo#!#sp_rename_vu_table1_case_insensitive2#!#BASE TABLE +master#!#dbo#!#SP_RENAME_vu_TABLE1_case_insensitive2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_table2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_view1#!#VIEW master#!#sp_rename_vu_schema1#!#sp_rename_vu_table1#!#BASE TABLE @@ -318,7 +318,7 @@ GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar master#!#dbo#!#sp_rename_vu_table_delim#!#BASE TABLE -master#!#dbo#!#sp_rename_vu_table1_case_insensitive2#!#BASE TABLE +master#!#dbo#!#SP_RENAME_vu_TABLE1_case_insensitive2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_table2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_view1_case_insensitive1#!#VIEW master#!#sp_rename_vu_schema1#!#sp_rename_vu_table1#!#BASE TABLE @@ -356,7 +356,7 @@ GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar master#!#dbo#!#sp_rename_vu_table_delim#!#BASE TABLE -master#!#dbo#!#sp_rename_vu_table1_case_insensitive2#!#BASE TABLE +master#!#dbo#!#SP_RENAME_vu_TABLE1_case_insensitive2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_table2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_view1#!#VIEW master#!#sp_rename_vu_schema1#!#sp_rename_vu_table1#!#BASE TABLE @@ -531,7 +531,7 @@ GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar master#!#dbo#!#sp_rename_vu_table_delim#!#BASE TABLE -master#!#dbo#!#sp_rename_vu_table1_case_insensitive2#!#BASE TABLE +master#!#dbo#!#SP_RENAME_vu_TABLE1_case_insensitive2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_table2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_view1#!#VIEW master#!#sp_rename_vu_schema1#!#sp_rename_vu_table1#!#BASE TABLE @@ -563,7 +563,7 @@ GO ~~START~~ nvarchar#!#nvarchar#!#varchar#!#varchar master#!#dbo#!#sp_rename_vu_table_delim#!#BASE TABLE -master#!#dbo#!#sp_rename_vu_table1_case_insensitive2#!#BASE TABLE +master#!#dbo#!#SP_RENAME_vu_TABLE1_case_insensitive2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_table2#!#BASE TABLE master#!#dbo#!#sp_rename_vu_view1#!#VIEW master#!#sp_rename_vu_schema1#!#sp_rename_vu_table1#!#BASE TABLE @@ -826,3 +826,20 @@ GO ~~ERROR (Message: Feature not supported: renaming object type Statistics)~~ + +IF OBJECT_ID('babelfish_split_identifier_view') IS NULL +BEGIN + EXEC sp_executesql N' + CREATE VIEW babelfish_split_identifier_view AS SELECT * FROM sys.babelfish_split_identifier(''ABC.DEF.GHI'')'; +END +GO + +SELECT * FROM babelfish_split_identifier_view; +GO +~~START~~ +varchar +ABC +DEF +GHI +~~END~~ + diff --git a/test/JDBC/expected/Test_rename_db_single-db.out b/test/JDBC/expected/Test_rename_db_single-db.out index a17b66ff8a5..da14b309aad 100644 --- a/test/JDBC/expected/Test_rename_db_single-db.out +++ b/test/JDBC/expected/Test_rename_db_single-db.out @@ -13,10 +13,10 @@ Create login rename_db_login1 with password = '1234', default_database = rename_ go -- sanity checks for metadata stored in babelfish catalog -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go ~~START~~ varchar#!#text @@ -32,8 +32,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar -dbo#!##!#dbo#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 +dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 ~~END~~ @@ -61,10 +61,10 @@ use master; go -- should return updated rows -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go ~~START~~ varchar#!#text @@ -80,8 +80,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar -dbo#!##!#dbo#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 +dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 ~~END~~ @@ -109,10 +109,10 @@ use master; go -- should return updated rows -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go ~~START~~ varchar#!#text @@ -128,8 +128,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar -dbo#!##!#dbo#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 +dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 ~~END~~ @@ -157,10 +157,10 @@ use master; go -- should return updated rows -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go ~~START~~ varchar#!#text @@ -176,8 +176,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar -dbo#!##!#dbo#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 +dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 ~~END~~ diff --git a/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.out b/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.out new file mode 100644 index 00000000000..726983f8855 --- /dev/null +++ b/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.out @@ -0,0 +1,58 @@ +DROP VIEW babel_2877_vu_prepare_view1; +GO + +DROP VIEW babel_2877_vu_prepare_view2; +GO + +DROP VIEW babel_2877_vu_prepare_view3; +GO + +DROP FUNCTION IF EXISTS babel_2877_vu_prepare_func1; +GO + +DROP FUNCTION IF EXISTS babel_2877_vu_prepare_func2; +GO + +DROP FUNCTION IF EXISTS babel_2877_vu_prepare_func3; +GO + +DROP PROCEDURE IF EXISTS babel_2877_vu_prepare_proc1; +GO + +DROP PROCEDURE IF EXISTS babel_2877_vu_prepare_proc2; +GO + +DROP PROCEDURE IF EXISTS babel_2877_vu_prepare_proc3; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDON]; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON]; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF]; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF]; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema].[BABEL-2877-vu-prepare_FUNC]; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS].[BABEL-2877-vu-prepare Function . WITH .. DOTS2]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS]; +GO + +-- babelfish_function_ext entry should have been removed after dropping all these functions/procedure +SELECT * FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel_2877_vu_prepare%'; +GO +~~START~~ +varchar#!#varchar#!#nvarchar#!#text#!#text#!#bigint#!#bigint#!#datetime#!#datetime#!#ntext +~~END~~ + diff --git a/test/JDBC/expected/BABEL-2877-vu-prepare.out b/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.out similarity index 84% rename from test/JDBC/expected/BABEL-2877-vu-prepare.out rename to test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.out index aa91e6afde9..34f13e297af 100644 --- a/test/JDBC/expected/BABEL-2877-vu-prepare.out +++ b/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.out @@ -98,3 +98,18 @@ GO SET QUOTED_IDENTIFIER ON; GO + +CREATE SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema] +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS] +GO + +-- Function name which is prefix of schema name +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS] . [BABEL-2877-vu-prepare Function . WITH .. DOTS] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO diff --git a/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.out b/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.out new file mode 100644 index 00000000000..41cfe25c3ff --- /dev/null +++ b/test/JDBC/expected/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.out @@ -0,0 +1,283 @@ +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_func1' as regproc)); +GO +~~START~~ +text +CREATE OR REPLACE FUNCTION master_dbo.babel_2877_vu_prepare_func1("@a" integer, "@b" "varchar" DEFAULT 'abc'::"varchar", "@c" money, "@d" double precision DEFAULT 1.2) RETURNS "varchar" LANGUAGE pltsql STABLEAS '{"version_num": "1", "typmod_array": ["-1", "10", "-1", "-1", "100"], "original_probin": ""}', $function$BEGIN RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10));END$function$ +~~END~~ + + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_func2' as regproc)); +GO +~~START~~ +text +CREATE OR REPLACE FUNCTION master_dbo.babel_2877_vu_prepare_func2("@a" integer DEFAULT 10, "@b" "varchar" DEFAULT 'abc'::"varchar", "@c" money DEFAULT 5, "@d" double precision DEFAULT 1.2) RETURNS "varchar" LANGUAGE pltsql STABLEAS '{"version_num": "1", "typmod_array": ["-1", "10", "-1", "-1", "100"], "original_probin": ""}', $function$BEGIN RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10));END$function$ +~~END~~ + + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_func3' as regproc)); +GO +~~START~~ +text +CREATE OR REPLACE FUNCTION master_dbo.babel_2877_vu_prepare_func3("@a" integer, "@b" "varchar", "@c" money, "@d" double precision) RETURNS "varchar" LANGUAGE pltsql STABLEAS '{"version_num": "1", "typmod_array": ["-1", "10", "-1", "-1", "100"], "original_probin": ""}', $function$BEGIN RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10));END$function$ +~~END~~ + + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_proc1' as regproc)); +GO +~~START~~ +text +CREATE OR REPLACE PROCEDURE master_dbo.babel_2877_vu_prepare_proc1(IN "@a" integer, IN "@b" "varchar" DEFAULT 'abc'::"varchar", IN "@c" money DEFAULT 5, IN "@d" double precision) LANGUAGE pltsqlAS '{"version_num": "1", "typmod_array": ["-1", "10", "-1", "-1"], "original_probin": ""}', $procedure$BEGIN SELECT @a, @b, @c, @d;END$procedure$ +~~END~~ + + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_proc2' as regproc)); +GO +~~START~~ +text +CREATE OR REPLACE PROCEDURE master_dbo.babel_2877_vu_prepare_proc2(IN "@a" integer DEFAULT 10, IN "@b" "varchar" DEFAULT 'abc'::"varchar", IN "@c" money DEFAULT 5, IN "@d" double precision DEFAULT 1.2) LANGUAGE pltsqlAS '{"version_num": "1", "typmod_array": ["-1", "10", "-1", "-1"], "original_probin": ""}', $procedure$BEGIN SELECT @a, @b, @c, @d;END$procedure$ +~~END~~ + + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_proc3' as regproc)); +GO +~~START~~ +text +CREATE OR REPLACE PROCEDURE master_dbo.babel_2877_vu_prepare_proc3(IN "@a" integer, IN "@b" "varchar", IN "@c" money, IN "@d" double precision) LANGUAGE pltsqlAS '{"version_num": "1", "typmod_array": ["-1", "10", "-1", "-1"], "original_probin": ""}', $procedure$BEGIN SELECT @a, @b, @c, @d;END$procedure$ +~~END~~ + + +SELECT * FROM babel_2877_vu_prepare_func1(10); -- should fail, required argument @c not supplied +GO +~~ERROR (Code: 201)~~ + +~~ERROR (Message: function babel_2877_vu_prepare_func1 expects parameter "@c", which was not supplied.)~~ + + +SELECT * FROM babel_2877_vu_prepare_func1(10, 'abc', $5); +GO +~~START~~ +varchar +10abc5.00001.2 +~~END~~ + + +SELECT * FROM babel_2877_vu_prepare_func2(); +GO +~~START~~ +varchar +10abc5.00001.2 +~~END~~ + + +SELECT * FROM babel_2877_vu_prepare_func3(); -- should fail, all parameters are required +GO +~~ERROR (Code: 201)~~ + +~~ERROR (Message: function babel_2877_vu_prepare_func3 expects parameter "@a", which was not supplied.)~~ + + +SELECT * FROM babel_2877_vu_prepare_func3(10, 'abc', $5, 1.2); +GO +~~START~~ +varchar +10abc5.00001.2 +~~END~~ + + +SELECT * FROM babel_2877_vu_prepare_view1; +GO +~~START~~ +varchar +20def5.00001.2 +~~END~~ + + +SELECT * FROM babel_2877_vu_prepare_view2; +GO +~~START~~ +varchar +10abc5.00001.2 +~~END~~ + + +SELECT * FROM babel_2877_vu_prepare_view3; +GO +~~START~~ +varchar +20def10.00001.8 +~~END~~ + + +EXEC babel_2877_vu_prepare_proc1; -- should fail, required arguments @a and @d not supplied +GO +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure babel_2877_vu_prepare_proc1 expects parameter "@a", which was not supplied.)~~ + + +EXEC babel_2877_vu_prepare_proc1 10; -- should fail, required argument @d not supplied +GO +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure babel_2877_vu_prepare_proc1 expects parameter "@d", which was not supplied.)~~ + + +EXEC babel_2877_vu_prepare_proc1 @d=40; -- should fail, required argument @a not supplied +GO +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure babel_2877_vu_prepare_proc1 expects parameter "@a", which was not supplied.)~~ + + +EXEC babel_2877_vu_prepare_proc1 @a = 10, @d = 1.8; +GO +~~START~~ +int#!#varchar#!#money#!#float +10#!#abc#!#5.0000#!#1.8 +~~END~~ + + +EXEC babel_2877_vu_prepare_proc1 @a = 10, @b = 20, @c = 30, @d = 40; +GO +~~START~~ +int#!#varchar#!#money#!#float +10#!#20#!#30.0000#!#40.0 +~~END~~ + + +EXEC babel_2877_vu_prepare_proc2; +GO +~~START~~ +int#!#varchar#!#money#!#float +10#!#abc#!#5.0000#!#1.2 +~~END~~ + + +EXEC babel_2877_vu_prepare_proc2 @d = 1.5; +GO +~~START~~ +int#!#varchar#!#money#!#float +10#!#abc#!#5.0000#!#1.5 +~~END~~ + + +EXEC babel_2877_vu_prepare_proc3; -- should fail, all parameters are required +GO +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure babel_2877_vu_prepare_proc3 expects parameter "@a", which was not supplied.)~~ + + +EXEC babel_2877_vu_prepare_proc3 10, 'def', $10, 1.8; -- should fail, all parameters are required +GO +~~START~~ +int#!#varchar#!#money#!#float +10#!#def#!#10.0000#!#1.8 +~~END~~ + + +-- babelfish_function_ext table should have entry for all the above functions and procedures +SELECT nspname, + funcname, + funcsignature, + default_positions +FROM sys.babelfish_function_ext + WHERE funcname LIKE 'babel_2877_vu_prepare%' + AND funcname NOT LIKE '%ansi%' ORDER BY funcname; +GO +~~START~~ +varchar#!#varchar#!#text#!#text +master_babel-2877-vu-prepare schema . with .. dots#!#babel-2877-vu-prepare function . with .. dots#!#babel-2877-vu-prepare function . with .. dots(integer)#!# +master_babel-2877-vu-prepare_func_schema#!#babel-2877-vu-prepare_func#!#babel-2877-vu-prepare_func(integer)#!# +master_dbo#!#babel_2877_vu_prepare_func1#!#babel_2877_vu_prepare_func1(integer, "sys"."varchar", "sys"."money", double precision)#!#(1 3) +master_dbo#!#babel_2877_vu_prepare_func2#!#babel_2877_vu_prepare_func2(integer, "sys"."varchar", "sys"."money", double precision)#!#(0 1 2 3) +master_dbo#!#babel_2877_vu_prepare_func3#!#babel_2877_vu_prepare_func3(integer, "sys"."varchar", "sys"."money", double precision)#!# +master_dbo#!#babel_2877_vu_prepare_proc1#!#babel_2877_vu_prepare_proc1(integer, "sys"."varchar", "sys"."money", double precision)#!#(1 2) +master_dbo#!#babel_2877_vu_prepare_proc2#!#babel_2877_vu_prepare_proc2(integer, "sys"."varchar", "sys"."money", double precision)#!#(0 1 2 3) +master_dbo#!#babel_2877_vu_prepare_proc3#!#babel_2877_vu_prepare_proc3(integer, "sys"."varchar", "sys"."money", double precision)#!# +~~END~~ + + +SELECT orig_name, + CASE flag_validity & 1 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 1 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS ansi_null, + CASE flag_validity & 2 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 2 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS quoted_identifier +FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel-2877-vu-prepare%' ORDER BY funcname; +GO +~~START~~ +nvarchar#!#int#!#int +BABEL-2877-vu-prepare Schema . WITH .. DOTS#!#1#!#1 +BABEL-2877-vu-prepare_FUNC_Schema#!#1#!#1 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF#!#0#!#0 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON#!#0#!#1 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF#!#1#!#0 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDON#!#1#!#1 +~~END~~ + + +-- Rename the existing functions to fix the originally stored incorrect orig_name +EXEC sp_rename 'BABEL-2877-vu-prepare_FUNC_Schema.BABEL-2877-vu-prepare_FUNC', 'BABEL-2877-vu-prepare_FUNC2', 'OBJECT' +GO + +EXEC sp_rename '"BABEL-2877-vu-prepare Schema . WITH .. DOTS"."BABEL-2877-vu-prepare Function . WITH .. DOTS"', 'BABEL-2877-vu-prepare Function . WITH .. DOTS2', 'OBJECT' +GO + +-- create a new function with name which is prefix of schema name to verify new behavior +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SELECT orig_name, + CASE flag_validity & 1 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 1 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS ansi_null, + CASE flag_validity & 2 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 2 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS quoted_identifier +FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel-2877-vu-prepare%' ORDER BY funcname; +GO +~~START~~ +nvarchar#!#int#!#int +BABEL-2877-vu-prepare Function . WITH .. DOTS2#!#1#!#1 +BABEL-2877-vu-prepare_FUNC#!#1#!#1 +BABEL-2877-vu-prepare_FUNC2#!#1#!#1 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF#!#0#!#0 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON#!#0#!#1 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF#!#1#!#0 +BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDON#!#1#!#1 +~~END~~ + + +DROP FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC2] +GO diff --git a/test/JDBC/expected/BABEL-2877-vu-cleanup.out b/test/JDBC/expected/babelfish_function_ext-vu-cleanup.out similarity index 77% rename from test/JDBC/expected/BABEL-2877-vu-cleanup.out rename to test/JDBC/expected/babelfish_function_ext-vu-cleanup.out index 2b3ac2c3920..7518ce549de 100644 --- a/test/JDBC/expected/BABEL-2877-vu-cleanup.out +++ b/test/JDBC/expected/babelfish_function_ext-vu-cleanup.out @@ -37,6 +37,18 @@ GO DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF]; GO +DROP FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema].[BABEL-2877-vu-prepare_FUNC]; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS].[BABEL-2877-vu-prepare Function . WITH .. DOTS]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS]; +GO + -- babelfish_function_ext entry should have been removed after dropping all these functions/procedure SELECT * FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel_2877_vu_prepare%'; GO diff --git a/test/JDBC/input/BABEL-2877-vu-prepare.sql b/test/JDBC/expected/babelfish_function_ext-vu-prepare.out similarity index 84% rename from test/JDBC/input/BABEL-2877-vu-prepare.sql rename to test/JDBC/expected/babelfish_function_ext-vu-prepare.out index b740c68c1ec..34f13e297af 100644 --- a/test/JDBC/input/BABEL-2877-vu-prepare.sql +++ b/test/JDBC/expected/babelfish_function_ext-vu-prepare.out @@ -97,4 +97,19 @@ SET ANSI_NULLS ON; GO SET QUOTED_IDENTIFIER ON; -GO \ No newline at end of file +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema] +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS] +GO + +-- Function name which is prefix of schema name +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS] . [BABEL-2877-vu-prepare Function . WITH .. DOTS] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO diff --git a/test/JDBC/expected/BABEL-2877-vu-verify.out b/test/JDBC/expected/babelfish_function_ext-vu-verify.out similarity index 95% rename from test/JDBC/expected/BABEL-2877-vu-verify.out rename to test/JDBC/expected/babelfish_function_ext-vu-verify.out index de27044b493..301309e561d 100644 --- a/test/JDBC/expected/BABEL-2877-vu-verify.out +++ b/test/JDBC/expected/babelfish_function_ext-vu-verify.out @@ -187,6 +187,8 @@ FROM sys.babelfish_function_ext GO ~~START~~ varchar#!#varchar#!#text#!#text +master_babel-2877-vu-prepare schema . with .. dots#!#babel-2877-vu-prepare function . with .. dots#!#babel-2877-vu-prepare function . with .. dots(integer)#!# +master_babel-2877-vu-prepare_func_schema#!#babel-2877-vu-prepare_func#!#babel-2877-vu-prepare_func(integer)#!# master_dbo#!#babel_2877_vu_prepare_func1#!#babel_2877_vu_prepare_func1(integer, "sys"."varchar", "sys"."money", double precision)#!#(1 3) master_dbo#!#babel_2877_vu_prepare_func2#!#babel_2877_vu_prepare_func2(integer, "sys"."varchar", "sys"."money", double precision)#!#(0 1 2 3) master_dbo#!#babel_2877_vu_prepare_func3#!#babel_2877_vu_prepare_func3(integer, "sys"."varchar", "sys"."money", double precision)#!# @@ -221,6 +223,8 @@ FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel-2877-vu-prepare%' ORD GO ~~START~~ nvarchar#!#int#!#int +BABEL-2877-vu-prepare Function . WITH .. DOTS#!#1#!#1 +BABEL-2877-vu-prepare_FUNC#!#1#!#1 BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF#!#0#!#0 BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON#!#0#!#1 BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF#!#1#!#0 diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/psql_logical_babelfish_db.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/psql_logical_babelfish_db.out index 5c2c80407b5..5537cb8b498 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/psql_logical_babelfish_db.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/psql_logical_babelfish_db.out @@ -1,6 +1,6 @@ -- psql -- check whether we can query system views before setting the GUC. Should return zero rows -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" @@ -30,21 +30,21 @@ master -- query system views. Should return metadata of master database -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" -master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -54,7 +54,7 @@ set psql_logical_babelfish_db_name = 'invalid_db' go -- should return zero rows as the database set does not exist -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" @@ -63,21 +63,21 @@ go -- tsql -- should return data of master as the current database is master -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; 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#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -96,21 +96,21 @@ logical_database_db1 -- should return data of master as the current database is master -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; 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#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -119,21 +119,21 @@ use logical_database_db1 go -- should return data of logical_database_db1 as the current database is logical_database_db1 -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; 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 -logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -145,7 +145,7 @@ alter server role sysadmin add member logical_database_l1 go -- psql user=logical_database_l1 password=12345678 -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" @@ -156,21 +156,21 @@ go set psql_logical_babelfish_db_name = 'logical_database_db1' go -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" -logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ diff --git a/test/JDBC/expected/psql_logical_babelfish_db.out b/test/JDBC/expected/psql_logical_babelfish_db.out index 0a804f271d9..87497ca168e 100644 --- a/test/JDBC/expected/psql_logical_babelfish_db.out +++ b/test/JDBC/expected/psql_logical_babelfish_db.out @@ -1,6 +1,6 @@ -- psql -- check whether we can query system views before setting the GUC. Should return zero rows -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" @@ -30,21 +30,21 @@ master -- query system views. Should return metadata of master database -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" -master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -54,7 +54,7 @@ set psql_logical_babelfish_db_name = 'invalid_db' go -- should return zero rows as the database set does not exist -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" @@ -63,21 +63,21 @@ go -- tsql -- should return data of master as the current database is master -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; 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#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -96,21 +96,21 @@ logical_database_db1 -- should return data of master as the current database is master -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; 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#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +master#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# master#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -master#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# master#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -119,21 +119,21 @@ use logical_database_db1 go -- should return data of logical_database_db1 as the current database is logical_database_db1 -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; 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 -logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ @@ -145,7 +145,7 @@ alter server role sysadmin add member logical_database_l1 go -- psql user=logical_database_l1 password=12345678 -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" @@ -156,21 +156,21 @@ go set psql_logical_babelfish_db_name = 'logical_database_db1' go -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#varchar#!#"sys"."varchar"#!#int4#!#int4#!#int2#!#int2#!#int4#!#int2#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar"#!#"sys"."varchar" -logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#dbid#!#2#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#mode#!#4#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#name#!#1#!##!#YES#!#text#!#2147483647#!#2147483647#!##!##!##!##!##!##!##!##!##!#C#!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# +logical_database_db1#!#dbo#!#sysdatabases#!#sid#!#3#!##!#YES#!#varbinary#!#85#!#85#!##!##!##!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status#!#5#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#status2#!#6#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#crdate#!#7#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#reserved#!#8#!##!#YES#!#datetime#!##!##!##!##!##!#3#!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#category#!#9#!##!#YES#!#int#!##!##!#10#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#cmptlevel#!#10#!##!#YES#!#tinyint#!##!##!#3#!#10#!#0#!##!##!##!##!##!##!##!##!##!# -logical_database_db1#!#dbo#!#sysdatabases#!#filename#!#11#!##!#YES#!#nvarchar#!#260#!#520#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# logical_database_db1#!#dbo#!#sysdatabases#!#version#!#12#!##!#YES#!#smallint#!##!##!#5#!#10#!#0#!##!##!##!##!##!##!##!##!##!# ~~END~~ diff --git a/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.sql b/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.sql new file mode 100644 index 00000000000..b2a1c38e3d1 --- /dev/null +++ b/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup.sql @@ -0,0 +1,28 @@ +DROP TABLE isc_tables_sc1.t2 +DROP TABLE [ISC_TABLES_TABLE_SCHEMA].[ISC_TABLES_TABLE] +DROP TABLE [ISC_TABLES SCHEMA . WITH .. DOTS].[ISC_TABLES TABLE . WITH .. DOTS2] +GO + +DROP TYPE isc_tables_sc1.isc_table_type2 +GO + +DROP SCHEMA isc_tables_sc1 +DROP SCHEMA [ISC_TABLES_TABLE_SCHEMA] +DROP SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] +GO + +DROP VIEW isc_tables_vu_prepare_v1 +GO + +DROP FUNCTION isc_tables_vu_prepare_f2 +DROP FUNCTION isc_tables_vu_prepare_f1 +GO + +DROP PROCEDURE isc_tables_vu_prepare_p1 +GO + +DROP TABLE isc_tables_vu_prepare_t1 +GO + +DROP TYPE isc_table_type1 +GO diff --git a/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.sql b/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.sql new file mode 100644 index 00000000000..806a0e3c9d7 --- /dev/null +++ b/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare.sql @@ -0,0 +1,56 @@ +CREATE TABLE isc_tables_vu_prepare_t1(a INT,b INT) +GO + +CREATE TYPE isc_table_type1 AS TABLE(a INT) +GO + +-- test different schema +CREATE SCHEMA isc_tables_sc1 +GO + +CREATE SCHEMA [ISC_TABLES_TABLE_SCHEMA] +GO + +CREATE SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] +GO + +CREATE TABLE isc_tables_sc1.t2(a INT,b INT) +GO + +-- Table name which is prefix of schema name +CREATE TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE] (a INT, b INT) +GO + +CREATE TABLE [ISC_TABLES SCHEMA . WITH .. DOTS] . [ISC_TABLES TABLE . WITH .. DOTS] (a INT, b INT) +GO + +CREATE TYPE isc_tables_sc1.isc_table_type2 AS TABLE(a INT) +GO + +--Dep Proc +CREATE PROCEDURE isc_tables_vu_prepare_p1 AS +SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'isc_tables_vu_prepare_t1' +SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1' +GO + +-- Dep Funcs +CREATE FUNCTION isc_tables_vu_prepare_f1() +RETURNS INT +AS +BEGIN + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%') +end +GO + +CREATE FUNCTION isc_tables_vu_prepare_f2() +RETURNS INT +AS +BEGIN + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%') +end +GO + +-- Dep View +CREATE VIEW isc_tables_vu_prepare_v1 AS + SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO diff --git a/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.sql b/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.sql new file mode 100644 index 00000000000..b1bdcfc6fde --- /dev/null +++ b/test/JDBC/input/ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify.sql @@ -0,0 +1,52 @@ +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO + +-- Rename the existing tables to fix the originally stored incorrect bbf_original_rel_name +EXEC sp_rename 'ISC_TABLES_TABLE_SCHEMA.ISC_TABLES_TABLE', 'ISC_TABLES_TABLE2', 'OBJECT' +GO + +EXEC sp_rename '"ISC_TABLES SCHEMA . WITH .. DOTS"."ISC_TABLES TABLE . WITH .. DOTS"', 'ISC_TABLES TABLE . WITH .. DOTS2', 'OBJECT' +GO + +-- create a new table with name which is prefix of schema name to verify new behavior +CREATE TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE] (a INT, b INT) +GO + +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%' ORDER BY TABLE_NAME +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO + +-- Table types should not be a result +-- Should not return any rows. +SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'isc_table_type1' +GO + +SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = 'isc_tables_sc1' +SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = 'ISC_TABLES_SC1' +GO + +-- Table types should not be a result +-- Should not return any rows. +SELECT * FROM information_schema.tables WHERE (TABLE_NAME = 'isc_table_type2' AND TABLE_SCHEMA = 'isc_tables_sc1') +GO + +EXEC isc_tables_vu_prepare_p1 +GO + +SELECT * FROM isc_tables_vu_prepare_f1() +SELECT * FROM isc_tables_vu_prepare_f2() +GO + +-- Drop and re-create isc_tables_vu_prepare_v1 as it might be dependent upon +-- the deprecated version of information_schema.tables view. +DROP VIEW isc_tables_vu_prepare_v1 +GO +CREATE VIEW isc_tables_vu_prepare_v1 AS + SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME +GO + +SELECT * FROM isc_tables_vu_prepare_v1 +GO + +DROP TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE2] +GO diff --git a/test/JDBC/input/ISC-Tables-vu-cleanup.sql b/test/JDBC/input/ISC-Tables-vu-cleanup.sql index ccadb1a4256..d648cef653b 100644 --- a/test/JDBC/input/ISC-Tables-vu-cleanup.sql +++ b/test/JDBC/input/ISC-Tables-vu-cleanup.sql @@ -1,10 +1,14 @@ DROP TABLE isc_tables_sc1.t2 +DROP TABLE [ISC_TABLES_TABLE_SCHEMA].[ISC_TABLES_TABLE] +DROP TABLE [ISC_TABLES SCHEMA . WITH .. DOTS].[ISC_TABLES TABLE . WITH .. DOTS] GO DROP TYPE isc_tables_sc1.isc_table_type2 GO DROP SCHEMA isc_tables_sc1 +DROP SCHEMA [ISC_TABLES_TABLE_SCHEMA] +DROP SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] GO DROP VIEW isc_tables_vu_prepare_v1 diff --git a/test/JDBC/input/ISC-Tables-vu-prepare.sql b/test/JDBC/input/ISC-Tables-vu-prepare.sql index 18f81a38128..806a0e3c9d7 100644 --- a/test/JDBC/input/ISC-Tables-vu-prepare.sql +++ b/test/JDBC/input/ISC-Tables-vu-prepare.sql @@ -8,9 +8,22 @@ GO CREATE SCHEMA isc_tables_sc1 GO +CREATE SCHEMA [ISC_TABLES_TABLE_SCHEMA] +GO + +CREATE SCHEMA [ISC_TABLES SCHEMA . WITH .. DOTS] +GO + CREATE TABLE isc_tables_sc1.t2(a INT,b INT) GO +-- Table name which is prefix of schema name +CREATE TABLE [ISC_TABLES_TABLE_SCHEMA] . [ISC_TABLES_TABLE] (a INT, b INT) +GO + +CREATE TABLE [ISC_TABLES SCHEMA . WITH .. DOTS] . [ISC_TABLES TABLE . WITH .. DOTS] (a INT, b INT) +GO + CREATE TYPE isc_tables_sc1.isc_table_type2 AS TABLE(a INT) GO @@ -25,7 +38,7 @@ CREATE FUNCTION isc_tables_vu_prepare_f1() RETURNS INT AS BEGIN - RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME = 'isc_tables_vu_prepare_t1') + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%') end GO @@ -33,11 +46,11 @@ CREATE FUNCTION isc_tables_vu_prepare_f2() RETURNS INT AS BEGIN - RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1') + RETURN (SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%') end GO -- Dep View CREATE VIEW isc_tables_vu_prepare_v1 AS - SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1' + SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME GO diff --git a/test/JDBC/input/ISC-Tables-vu-verify.sql b/test/JDBC/input/ISC-Tables-vu-verify.sql index eba2754bd54..031d4746abe 100644 --- a/test/JDBC/input/ISC-Tables-vu-verify.sql +++ b/test/JDBC/input/ISC-Tables-vu-verify.sql @@ -1,5 +1,5 @@ -SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'isc_tables_vu_prepare_t1' -SELECT * FROM information_schema.tables WHERE TABLE_NAME = 'ISC_TABLES_VU_PREPARE_T1' +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'isc_tables%' ORDER BY TABLE_NAME +SELECT * FROM information_schema.tables WHERE TABLE_NAME LIKE 'ISC_TABLES%' ORDER BY TABLE_NAME GO -- Table types should not be a result diff --git a/test/JDBC/input/Test_rename_db_single-db.sql b/test/JDBC/input/Test_rename_db_single-db.sql index 5d9d6cea9a1..75766e8366e 100644 --- a/test/JDBC/input/Test_rename_db_single-db.sql +++ b/test/JDBC/input/Test_rename_db_single-db.sql @@ -13,10 +13,10 @@ Create login rename_db_login1 with password = '1234', default_database = rename_ go -- sanity checks for metadata stored in babelfish catalog -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go -- Test Alter Database @@ -32,10 +32,10 @@ use master; go -- should return updated rows -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go -- Test sp_renamedb @@ -51,10 +51,10 @@ use master; go -- should return updated rows -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go -- Test sp_rename @@ -70,10 +70,10 @@ use master; go -- should return updated rows -select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%'; -select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1'); -select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%'; -select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%'; +select owner, name from sys.babelfish_sysdatabases where name LIKE 'rename_db_database%' ORDER BY name; +select nspname, orig_name from sys.babelfish_namespace_ext where nspname IN ('dbo', 'guest', 'rename_db_schema1') ORDER BY nspname; +select rolname, login_name, orig_username, database_name from sys.babelfish_authid_user_ext where database_name LIKE 'rename_db_database%' ORDER BY rolname; +select rolname, default_database_name from sys.babelfish_authid_login_ext where default_database_name LIKE 'rename_db_database%' ORDER BY rolname; go -- cleanup diff --git a/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.sql b/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.sql new file mode 100644 index 00000000000..89eb8dc81b1 --- /dev/null +++ b/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup.sql @@ -0,0 +1,54 @@ +DROP VIEW babel_2877_vu_prepare_view1; +GO + +DROP VIEW babel_2877_vu_prepare_view2; +GO + +DROP VIEW babel_2877_vu_prepare_view3; +GO + +DROP FUNCTION IF EXISTS babel_2877_vu_prepare_func1; +GO + +DROP FUNCTION IF EXISTS babel_2877_vu_prepare_func2; +GO + +DROP FUNCTION IF EXISTS babel_2877_vu_prepare_func3; +GO + +DROP PROCEDURE IF EXISTS babel_2877_vu_prepare_proc1; +GO + +DROP PROCEDURE IF EXISTS babel_2877_vu_prepare_proc2; +GO + +DROP PROCEDURE IF EXISTS babel_2877_vu_prepare_proc3; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDON]; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON]; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF]; +GO + +DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF]; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema].[BABEL-2877-vu-prepare_FUNC]; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS].[BABEL-2877-vu-prepare Function . WITH .. DOTS2]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS]; +GO + +-- babelfish_function_ext entry should have been removed after dropping all these functions/procedure +SELECT * FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel_2877_vu_prepare%'; +GO \ No newline at end of file diff --git a/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.sql b/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.sql new file mode 100644 index 00000000000..34f13e297af --- /dev/null +++ b/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare.sql @@ -0,0 +1,115 @@ +-- Function +-- Defaults at different positions +CREATE FUNCTION babel_2877_vu_prepare_func1 (@a int, @b varchar(10) = 'abc', @c money, @d float = 1.2) +RETURNS varchar(100) AS +BEGIN + RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10)); +END +GO + +-- All parameters with defaults +CREATE FUNCTION babel_2877_vu_prepare_func2 (@a int = 10, @b varchar(10) = 'abc', @c money = $5, @d float = 1.2) +RETURNS varchar(100) AS +BEGIN + RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10)); +END +GO + +-- No defaults +CREATE FUNCTION babel_2877_vu_prepare_func3 (@a int, @b varchar(10), @c money, @d float) +RETURNS varchar(100) AS +BEGIN + RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10)); +END +GO + +-- Procedure +-- Defaults at different positions +CREATE PROCEDURE babel_2877_vu_prepare_proc1 (@a int, @b varchar(10) = 'abc', @c money = $5, @d float) +AS +BEGIN + SELECT @a, @b, @c, @d; +END +GO + +-- All parameters with defaults +CREATE PROCEDURE babel_2877_vu_prepare_proc2 (@a int = 10, @b varchar(10) = 'abc', @c money = $5, @d float = 1.2) +AS +BEGIN + SELECT @a, @b, @c, @d; +END +GO + +-- No defaults +CREATE PROCEDURE babel_2877_vu_prepare_proc3 (@a int, @b varchar(10), @c money, @d float) +AS +BEGIN + SELECT @a, @b, @c, @d; +END +GO + +-- Views +CREATE VIEW babel_2877_vu_prepare_view1 AS SELECT babel_2877_vu_prepare_func1(20, 'def', $5); +GO + +CREATE VIEW babel_2877_vu_prepare_view2 AS SELECT babel_2877_vu_prepare_func2(); +GO + +CREATE VIEW babel_2877_vu_prepare_view3 AS SELECT babel_2877_vu_prepare_func1(20, 'def', $10, 1.8); +GO + +-- CASE: Check for session properties like ANSI_NULLS and QUOTED_IDENTIFIER +-- ANSI_NULLS - Last bit from left in flag_values +-- QUOTED_IDENTIFIER - Second last bit from left in flag_values +SET ANSI_NULLS ON; +GO + +SET QUOTED_IDENTIFIER ON; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDON] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SET ANSI_NULLS OFF; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SET QUOTED_IDENTIFIER OFF; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SET ANSI_NULLS ON; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +-- reset session properties +SET ANSI_NULLS ON; +GO + +SET QUOTED_IDENTIFIER ON; +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema] +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS] +GO + +-- Function name which is prefix of schema name +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS] . [BABEL-2877-vu-prepare Function . WITH .. DOTS] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO diff --git a/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.sql b/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.sql new file mode 100644 index 00000000000..5d074621583 --- /dev/null +++ b/test/JDBC/input/babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify.sql @@ -0,0 +1,141 @@ +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_func1' as regproc)); +GO + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_func2' as regproc)); +GO + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_func3' as regproc)); +GO + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_proc1' as regproc)); +GO + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_proc2' as regproc)); +GO + +SELECT pg_get_functiondef(cast('babel_2877_vu_prepare_proc3' as regproc)); +GO + +SELECT * FROM babel_2877_vu_prepare_func1(10); -- should fail, required argument @c not supplied +GO + +SELECT * FROM babel_2877_vu_prepare_func1(10, 'abc', $5); +GO + +SELECT * FROM babel_2877_vu_prepare_func2(); +GO + +SELECT * FROM babel_2877_vu_prepare_func3(); -- should fail, all parameters are required +GO + +SELECT * FROM babel_2877_vu_prepare_func3(10, 'abc', $5, 1.2); +GO + +SELECT * FROM babel_2877_vu_prepare_view1; +GO + +SELECT * FROM babel_2877_vu_prepare_view2; +GO + +SELECT * FROM babel_2877_vu_prepare_view3; +GO + +EXEC babel_2877_vu_prepare_proc1; -- should fail, required arguments @a and @d not supplied +GO + +EXEC babel_2877_vu_prepare_proc1 10; -- should fail, required argument @d not supplied +GO + +EXEC babel_2877_vu_prepare_proc1 @d=40; -- should fail, required argument @a not supplied +GO + +EXEC babel_2877_vu_prepare_proc1 @a = 10, @d = 1.8; +GO + +EXEC babel_2877_vu_prepare_proc1 @a = 10, @b = 20, @c = 30, @d = 40; +GO + +EXEC babel_2877_vu_prepare_proc2; +GO + +EXEC babel_2877_vu_prepare_proc2 @d = 1.5; +GO + +EXEC babel_2877_vu_prepare_proc3; -- should fail, all parameters are required +GO + +EXEC babel_2877_vu_prepare_proc3 10, 'def', $10, 1.8; -- should fail, all parameters are required +GO + +-- babelfish_function_ext table should have entry for all the above functions and procedures +SELECT nspname, + funcname, + funcsignature, + default_positions +FROM sys.babelfish_function_ext + WHERE funcname LIKE 'babel_2877_vu_prepare%' + AND funcname NOT LIKE '%ansi%' ORDER BY funcname; +GO + +SELECT orig_name, + CASE flag_validity & 1 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 1 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS ansi_null, + CASE flag_validity & 2 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 2 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS quoted_identifier +FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel-2877-vu-prepare%' ORDER BY funcname; +GO + +-- Rename the existing functions to fix the originally stored incorrect orig_name +EXEC sp_rename 'BABEL-2877-vu-prepare_FUNC_Schema.BABEL-2877-vu-prepare_FUNC', 'BABEL-2877-vu-prepare_FUNC2', 'OBJECT' +GO + +EXEC sp_rename '"BABEL-2877-vu-prepare Schema . WITH .. DOTS"."BABEL-2877-vu-prepare Function . WITH .. DOTS"', 'BABEL-2877-vu-prepare Function . WITH .. DOTS2', 'OBJECT' +GO + +-- create a new function with name which is prefix of schema name to verify new behavior +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SELECT orig_name, + CASE flag_validity & 1 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 1 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS ansi_null, + CASE flag_validity & 2 + WHEN 0 + THEN NULL + ELSE + CASE flag_values & 2 + WHEN 0 + THEN 0 + ELSE 1 + END + END AS quoted_identifier +FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel-2877-vu-prepare%' ORDER BY funcname; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC2] +GO diff --git a/test/JDBC/input/BABEL-2877-vu-cleanup.sql b/test/JDBC/input/babelfish_function_ext-vu-cleanup.sql similarity index 75% rename from test/JDBC/input/BABEL-2877-vu-cleanup.sql rename to test/JDBC/input/babelfish_function_ext-vu-cleanup.sql index 55bbbf383e7..b99b446a9de 100644 --- a/test/JDBC/input/BABEL-2877-vu-cleanup.sql +++ b/test/JDBC/input/babelfish_function_ext-vu-cleanup.sql @@ -37,6 +37,18 @@ GO DROP FUNCTION IF EXISTS [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF]; GO +DROP FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema].[BABEL-2877-vu-prepare_FUNC]; +GO + +DROP FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS].[BABEL-2877-vu-prepare Function . WITH .. DOTS]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema]; +GO + +DROP SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS]; +GO + -- babelfish_function_ext entry should have been removed after dropping all these functions/procedure SELECT * FROM sys.babelfish_function_ext WHERE funcname LIKE 'babel_2877_vu_prepare%'; GO \ No newline at end of file diff --git a/test/JDBC/input/babelfish_function_ext-vu-prepare.sql b/test/JDBC/input/babelfish_function_ext-vu-prepare.sql new file mode 100644 index 00000000000..34f13e297af --- /dev/null +++ b/test/JDBC/input/babelfish_function_ext-vu-prepare.sql @@ -0,0 +1,115 @@ +-- Function +-- Defaults at different positions +CREATE FUNCTION babel_2877_vu_prepare_func1 (@a int, @b varchar(10) = 'abc', @c money, @d float = 1.2) +RETURNS varchar(100) AS +BEGIN + RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10)); +END +GO + +-- All parameters with defaults +CREATE FUNCTION babel_2877_vu_prepare_func2 (@a int = 10, @b varchar(10) = 'abc', @c money = $5, @d float = 1.2) +RETURNS varchar(100) AS +BEGIN + RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10)); +END +GO + +-- No defaults +CREATE FUNCTION babel_2877_vu_prepare_func3 (@a int, @b varchar(10), @c money, @d float) +RETURNS varchar(100) AS +BEGIN + RETURN CAST(@a AS varchar(10)) + @b + CAST(@c AS varchar(10)) + CAST(@d AS varchar(10)); +END +GO + +-- Procedure +-- Defaults at different positions +CREATE PROCEDURE babel_2877_vu_prepare_proc1 (@a int, @b varchar(10) = 'abc', @c money = $5, @d float) +AS +BEGIN + SELECT @a, @b, @c, @d; +END +GO + +-- All parameters with defaults +CREATE PROCEDURE babel_2877_vu_prepare_proc2 (@a int = 10, @b varchar(10) = 'abc', @c money = $5, @d float = 1.2) +AS +BEGIN + SELECT @a, @b, @c, @d; +END +GO + +-- No defaults +CREATE PROCEDURE babel_2877_vu_prepare_proc3 (@a int, @b varchar(10), @c money, @d float) +AS +BEGIN + SELECT @a, @b, @c, @d; +END +GO + +-- Views +CREATE VIEW babel_2877_vu_prepare_view1 AS SELECT babel_2877_vu_prepare_func1(20, 'def', $5); +GO + +CREATE VIEW babel_2877_vu_prepare_view2 AS SELECT babel_2877_vu_prepare_func2(); +GO + +CREATE VIEW babel_2877_vu_prepare_view3 AS SELECT babel_2877_vu_prepare_func1(20, 'def', $10, 1.8); +GO + +-- CASE: Check for session properties like ANSI_NULLS and QUOTED_IDENTIFIER +-- ANSI_NULLS - Last bit from left in flag_values +-- QUOTED_IDENTIFIER - Second last bit from left in flag_values +SET ANSI_NULLS ON; +GO + +SET QUOTED_IDENTIFIER ON; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDON] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SET ANSI_NULLS OFF; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDON] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SET QUOTED_IDENTIFIER OFF; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLOFF_QIDOFF] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +SET ANSI_NULLS ON; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_ANSI_NULLON_QIDOFF] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +-- reset session properties +SET ANSI_NULLS ON; +GO + +SET QUOTED_IDENTIFIER ON; +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare_FUNC_Schema] +GO + +CREATE SCHEMA [BABEL-2877-vu-prepare Schema . WITH .. DOTS] +GO + +-- Function name which is prefix of schema name +CREATE FUNCTION [BABEL-2877-vu-prepare_FUNC_Schema] . [BABEL-2877-vu-prepare_FUNC] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO + +CREATE FUNCTION [BABEL-2877-vu-prepare Schema . WITH .. DOTS] . [BABEL-2877-vu-prepare Function . WITH .. DOTS] (@a int) +RETURNS INT AS BEGIN RETURN 1; END; +GO diff --git a/test/JDBC/input/BABEL-2877-vu-verify.sql b/test/JDBC/input/babelfish_function_ext-vu-verify.sql similarity index 100% rename from test/JDBC/input/BABEL-2877-vu-verify.sql rename to test/JDBC/input/babelfish_function_ext-vu-verify.sql diff --git a/test/JDBC/input/psql_logical_babelfish_db.mix b/test/JDBC/input/psql_logical_babelfish_db.mix index 3d2035ad728..d11fdc5c831 100644 --- a/test/JDBC/input/psql_logical_babelfish_db.mix +++ b/test/JDBC/input/psql_logical_babelfish_db.mix @@ -1,6 +1,6 @@ -- psql -- check whether we can query system views before setting the GUC. Should return zero rows -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go -- GUC should be NULL as it is not set yet @@ -16,7 +16,7 @@ show psql_logical_babelfish_db_name; go -- query system views. Should return metadata of master database -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go -- set the GUC to an invalid database @@ -24,12 +24,12 @@ set psql_logical_babelfish_db_name = 'invalid_db' go -- should return zero rows as the database set does not exist -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go -- tsql -- should return data of master as the current database is master -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go create database logical_database_db1 @@ -41,14 +41,14 @@ select set_config('psql_logical_babelfish_db_name', 'logical_database_db1', fals go -- should return data of master as the current database is master -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go use logical_database_db1 go -- should return data of logical_database_db1 as the current database is logical_database_db1 -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go create login logical_database_l1 with password = '12345678' @@ -58,14 +58,14 @@ alter server role sysadmin add member logical_database_l1 go -- psql user=logical_database_l1 password=12345678 -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go -- any user can set the GUC set psql_logical_babelfish_db_name = 'logical_database_db1' go -select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases'; +select * from information_schema_tsql.columns where "TABLE_NAME"='sysdatabases' order by "COLUMN_NAME"; go -- psql diff --git a/test/JDBC/input/storedProcedures/Test-sp_rename-vu-cleanup.sql b/test/JDBC/input/storedProcedures/Test-sp_rename-vu-cleanup.sql index 795e51e371b..6b0c9cd260e 100644 --- a/test/JDBC/input/storedProcedures/Test-sp_rename-vu-cleanup.sql +++ b/test/JDBC/input/storedProcedures/Test-sp_rename-vu-cleanup.sql @@ -66,4 +66,7 @@ DROP TYPE sp_rename_vu_schema1.sp_rename_vu_tabletype1_schema1_new; GO DROP SCHEMA sp_rename_vu_schema1; -GO \ No newline at end of file +GO + +DROP VIEW babelfish_split_identifier_view; +GO diff --git a/test/JDBC/input/storedProcedures/Test-sp_rename-vu-prepare.sql b/test/JDBC/input/storedProcedures/Test-sp_rename-vu-prepare.sql index 91590694301..09d689fc9ab 100644 --- a/test/JDBC/input/storedProcedures/Test-sp_rename-vu-prepare.sql +++ b/test/JDBC/input/storedProcedures/Test-sp_rename-vu-prepare.sql @@ -98,4 +98,14 @@ CREATE TYPE sp_rename_vu_alias1 FROM VARCHAR(11) NOT NULL; GO CREATE TYPE sp_rename_vu_schema1.sp_rename_vu_alias1 FROM VARCHAR(11) NOT NULL; -GO \ No newline at end of file +GO + +-- Dependency test for function babelfish_split_identifier +-- Create a view which depends upon babelfish_split_identifier function only +-- if the function exists. +IF OBJECT_ID('sys.babelfish_split_identifier') IS NOT NULL +BEGIN + EXEC sp_executesql N' + CREATE VIEW babelfish_split_identifier_view AS SELECT * FROM sys.babelfish_split_identifier(''ABC.DEF.GHI'')'; +END +GO diff --git a/test/JDBC/input/storedProcedures/Test-sp_rename-vu-verify.sql b/test/JDBC/input/storedProcedures/Test-sp_rename-vu-verify.sql index 8541c8ff649..44c2fc27001 100644 --- a/test/JDBC/input/storedProcedures/Test-sp_rename-vu-verify.sql +++ b/test/JDBC/input/storedProcedures/Test-sp_rename-vu-verify.sql @@ -403,3 +403,13 @@ GO -- Statistics EXEC sp_rename 'sp_rename_vu_stat1', 'sp_rename_vu_stat2', 'STATISTICS'; GO + +IF OBJECT_ID('babelfish_split_identifier_view') IS NULL +BEGIN + EXEC sp_executesql N' + CREATE VIEW babelfish_split_identifier_view AS SELECT * FROM sys.babelfish_split_identifier(''ABC.DEF.GHI'')'; +END +GO + +SELECT * FROM babelfish_split_identifier_view; +GO diff --git a/test/JDBC/jdbc_schedule b/test/JDBC/jdbc_schedule index 7e23eb108f5..b6b7156c04b 100644 --- a/test/JDBC/jdbc_schedule +++ b/test/JDBC/jdbc_schedule @@ -330,3 +330,10 @@ ignore#!#BABEL-3513_before_15_8_or_16_4-vu-verify ignore#!#catalogs_dbo_sys_schema-upgrade-vu-prepare ignore#!#catalogs_dbo_sys_schema-upgrade-vu-verify ignore#!#catalogs_dbo_sys_schema-upgrade-vu-cleanup + +ignore#!#ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare +ignore#!#ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify +ignore#!#ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup +ignore#!#babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-prepare +ignore#!#babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-verify +ignore#!#babelfish_function_ext-before_16_4_or_15_8_or_14_13-vu-cleanup diff --git a/test/JDBC/upgrade/13_6/schedule b/test/JDBC/upgrade/13_6/schedule index 5871c317d48..cf475d8a827 100644 --- a/test/JDBC/upgrade/13_6/schedule +++ b/test/JDBC/upgrade/13_6/schedule @@ -163,7 +163,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_system_health_state diff --git a/test/JDBC/upgrade/13_7/schedule b/test/JDBC/upgrade/13_7/schedule index 1c4ddaf153e..eb5cae7c145 100644 --- a/test/JDBC/upgrade/13_7/schedule +++ b/test/JDBC/upgrade/13_7/schedule @@ -159,7 +159,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_system_health_state diff --git a/test/JDBC/upgrade/13_8/schedule b/test/JDBC/upgrade/13_8/schedule index 422e444d0d4..354a9a4be39 100644 --- a/test/JDBC/upgrade/13_8/schedule +++ b/test/JDBC/upgrade/13_8/schedule @@ -159,7 +159,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_system_health_state diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index a4e2812e781..2ba7093f258 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -160,7 +160,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_system_health_state diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index 6dfa08bb94f..d6e92203862 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -370,7 +370,7 @@ BABEL-3640 sys-sysindexes sys-system_objects ISC-Views -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Columns #ISC-Check-Constraints ISC-Table_Constraints diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 3af98943697..3b1a17d6b02 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -371,7 +371,7 @@ BABEL-3640 sys-sysindexes sys-system_objects ISC-Views -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Columns #ISC-Check-Constraints ISC-Table_Constraints diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index deb8b1f5906..79a999d5501 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -369,7 +369,7 @@ BABEL-3640 sys-sysindexes sys-system_objects ISC-Views -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Columns #ISC-Check-Constraints ISC-Table_Constraints diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 6a28ac8060a..d3eaad4c7f4 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -168,7 +168,7 @@ insteadof_nested_trigger_inside_proc insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_system_health_state diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index 8e2c880f955..b9fb6bb8bfa 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -167,7 +167,7 @@ insteadof_nested_trigger_inside_proc insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_configuration diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index bfdd647c650..863375a2997 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -194,7 +194,7 @@ insteadof_nested_trigger_inside_proc insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index e39dfeb7422..c4d8f318eb6 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -210,7 +210,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_configuration diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 1b56fb23c42..c1cc86c9c0f 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -208,7 +208,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_configuration diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index de665b221e8..16b079bd995 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -370,7 +370,7 @@ BABEL-3640 sys-sysindexes sys-system_objects ISC-Views -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Columns #ISC-Check-Constraints ISC-Table_Constraints diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 73a53866db8..11b4610aaed 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -192,7 +192,7 @@ insteadof_nested_trigger_with_dml insteadoftriggers_with_transaction ISC-Columns ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 is_srvrolemember msdb-dbo-fn_syspolicy_is_automation_enabled msdb-dbo-syspolicy_configuration diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 3d98fad0c55..cfed24a9ec8 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -211,7 +211,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index 498207cbc23..3546ae04aef 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -53,7 +53,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -222,7 +222,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index 1c889afba57..bfa4dd0bea0 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -53,7 +53,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -225,7 +225,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index cbf9c3dedeb..b1834f5d226 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -53,7 +53,7 @@ BABEL-2795 BABEL-2805 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -231,7 +231,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 919e1e84204..70fd96ac719 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -54,7 +54,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -237,7 +237,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 787237264a3..3afcc3f5b17 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -54,7 +54,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -238,7 +238,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 21da5b04e9e..aeb6e54b795 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -54,7 +54,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext BABEL-2884 BABEL-2917 BABEL-2944 diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index 16869e5de2a..b057877c5f7 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -54,7 +54,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -236,7 +236,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index 0f149508df5..b104eff58ec 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -54,7 +54,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -239,7 +239,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 6066507dcb3..6dde68bebd6 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -53,7 +53,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext-before_16_4_or_15_8_or_14_13 BABEL-2884 BABEL-2917 BABEL-2944 @@ -239,7 +239,7 @@ ISC-Columns isc-schemata-dep ISC-sequences ISC-Table_Constraints -ISC-Tables +ISC-Tables-before_16_4_or_15_8_or_14_13 ISC-Views is_srvrolemember jira-BABEL-3504-upgrade diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index efa230e4fc7..85a5b60e083 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -53,7 +53,7 @@ BABEL-2805 BABEL-2812 BABEL-2819 BABEL-2845 -BABEL-2877 +babelfish_function_ext BABEL-2884 BABEL-2917 BABEL-2944 From 60746325cfabc7e8ed6ddf2dd5f29354c75a2746 Mon Sep 17 00:00:00 2001 From: Kushaal Shroff <51415286+KushaalShroff@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:36:15 +0530 Subject: [PATCH 13/15] Support Halfvec and Sparsevec datatypes (#2703) This commit adds support to Babelfish for the newly added Halfvec and Sparsevec Datatypes introduced in PGVector 0.7. Added support for all its operators, utility functions and index methods as well. The tests added are fetched from the official Pgvector extension and converted to TSQL syntax and semantics. Tasks: BABEL-5058 Signed-off-by: Kushaal Shroff --- contrib/babelfishpg_common/src/typecode.c | 2 + contrib/babelfishpg_common/src/typecode.h | 2 +- .../src/backend/tds/tds_data_map.c | 2 + .../src/backend/tds/tdsresponse.c | 39 +- contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 | 11 + contrib/babelfishpg_tsql/antlr/TSqlParser.g4 | 23 +- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 2 + .../sql/information_schema_tsql.sql | 2 +- contrib/babelfishpg_tsql/sql/sys_views.sql | 2 + .../babelfishpg_tsql--4.2.0--4.3.0.sql | 177 ++ test/JDBC/expected/TestHalfvecDatatype.out | 1771 ++++++++++++++++ test/JDBC/expected/TestSparsevecDatatype.out | 1583 ++++++++++++++ test/JDBC/expected/babel_typecode.out | 2 + .../chinese_prc_ci_as/TestHalfvecDatatype.out | 1771 ++++++++++++++++ .../TestSparsevecDatatype.out | 1583 ++++++++++++++ .../parallel_query/TestHalfvecDatatype.out | 1823 +++++++++++++++++ .../parallel_query/TestSparsevecDatatype.out | 1611 +++++++++++++++ .../input/datatypes/TestHalfvecDatatype.mix | 683 ++++++ .../input/datatypes/TestSparsevecDatatype.mix | 634 ++++++ 19 files changed, 11712 insertions(+), 11 deletions(-) create mode 100644 test/JDBC/expected/TestHalfvecDatatype.out create mode 100644 test/JDBC/expected/TestSparsevecDatatype.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestHalfvecDatatype.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestSparsevecDatatype.out create mode 100644 test/JDBC/expected/parallel_query/TestHalfvecDatatype.out create mode 100644 test/JDBC/expected/parallel_query/TestSparsevecDatatype.out create mode 100644 test/JDBC/input/datatypes/TestHalfvecDatatype.mix create mode 100644 test/JDBC/input/datatypes/TestSparsevecDatatype.mix diff --git a/contrib/babelfishpg_common/src/typecode.c b/contrib/babelfishpg_common/src/typecode.c index df1e7934375..7c606884259 100644 --- a/contrib/babelfishpg_common/src/typecode.c +++ b/contrib/babelfishpg_common/src/typecode.c @@ -53,6 +53,8 @@ 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}, + {0, 1, "sparsevec", "sparsevec", 9, 34, 3}, + {0, 1, "halfvec", "halfvec", 9, 34, 3}, /* * Geospatial types cannot be stored in SQL variant so setting sqlvariant header size to 1 */ diff --git a/contrib/babelfishpg_common/src/typecode.h b/contrib/babelfishpg_common/src/typecode.h index b498923702c..ad26780d8dd 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 36 +#define TOTAL_TYPECODE_COUNT 38 struct Node; diff --git a/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c b/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c index 95470b96668..a377f4f3c76 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c @@ -189,6 +189,8 @@ TdsIoFunctionRawData TdsIoFunctionRawData_data[] = {"pg_catalog", "oid", TDS_TYPE_INTEGER, 4, 1, TDS_SEND_INTEGER, TDS_RECV_INVALID}, {"pg_catalog", "sql_identifier", TDS_TYPE_VARCHAR, -1, 1, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"sys", "vector", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_VARCHAR}, + {"sys", "halfvec", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_VARCHAR}, + {"sys", "sparsevec", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_VARCHAR}, {"pg_catalog", "name", TDS_TYPE_VARCHAR, -1, 1, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"pg_catalog", "character_data", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"pg_catalog", "bool", TDS_TYPE_BIT, 1, 1, TDS_SEND_BIT, TDS_RECV_INVALID}, diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c index eb00f630b3a..a6cd0721c42 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c @@ -129,6 +129,8 @@ static TdsColumnMetaData *colMetaData = NULL; static List *relMetaDataInfoList = NULL; static Oid sys_vector_oid = InvalidOid; +static Oid sys_sparsevec_oid = InvalidOid; +static Oid sys_halfvec_oid = InvalidOid; static Oid decimal_oid = InvalidOid; static void FillTabNameWithNumParts(StringInfo buf, uint8 numParts, TdsRelationMetaDataInfo relMetaDataInfo); @@ -138,7 +140,7 @@ static void ResetTdsEstateErrorData(void); static void SetAttributesForColmetada(TdsColumnMetaData *col); static int32 resolve_numeric_typmod_from_exp(Plan *plan, Node *expr); static int32 resolve_numeric_typmod_outer_var(Plan *plan, AttrNumber attno); -static bool is_sys_vector_datatype(Oid oid); +static bool is_this_a_vector_datatype(Oid oid); static inline void SendPendingDone(bool more) @@ -1106,8 +1108,8 @@ MakeEmptyParameterToken(char *name, int atttypid, int32 atttypmod, int attcollat temp->maxLen = 0xFFFF; break; case TDS_SEND_VARCHAR: - /* If this is vector datatype, we should adjust the typmod */ - if (is_sys_vector_datatype(col->pgTypeOid)) + /* If this is one of the vector datatypes we should adjust the typmod. */ + if (is_this_a_vector_datatype(col->pgTypeOid)) atttypmod = -1; SetColMetadataForCharTypeHelper(col, TDS_TYPE_VARCHAR, attcollation, (atttypmod == -1) ? @@ -1868,8 +1870,8 @@ PrepareRowDescription(TupleDesc typeinfo, PlannedStmt *plannedstmt, List *target att->attcollation, (atttypmod - 4) * 2); break; case TDS_SEND_VARCHAR: - /* If this is vector datatype, we should adjust the typmod */ - if (is_sys_vector_datatype(col->pgTypeOid)) + /* If this is one of the vector datatypes we should adjust the typmod. */ + if (is_this_a_vector_datatype(col->pgTypeOid)) atttypmod = -1; SetColMetadataForCharTypeHelper(col, TDS_TYPE_VARCHAR, @@ -3560,9 +3562,10 @@ SetAttributesForColmetada(TdsColumnMetaData *col) } static bool -is_sys_vector_datatype(Oid oid) +is_this_a_vector_datatype(Oid oid) { Oid nspoid; + if (sys_vector_oid == InvalidOid) { nspoid = get_namespace_oid("sys", true); @@ -3571,5 +3574,27 @@ is_sys_vector_datatype(Oid oid) sys_vector_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum("vector"), ObjectIdGetDatum(nspoid)); } - return sys_vector_oid == oid; + if (sys_vector_oid == oid) + return true; + + if (sys_halfvec_oid == InvalidOid) + { + nspoid = get_namespace_oid("sys", true); + if (nspoid == InvalidOid) + return false; + + sys_halfvec_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum("halfvec"), ObjectIdGetDatum(nspoid)); + } + if (sys_halfvec_oid == oid) + return true; + + if (sys_sparsevec_oid == InvalidOid) + { + nspoid = get_namespace_oid("sys", true); + if (nspoid == InvalidOid) + return false; + + sys_sparsevec_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum("sparsevec"), ObjectIdGetDatum(nspoid)); + } + return sys_sparsevec_oid == oid; } \ No newline at end of file diff --git a/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 b/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 index af910188c1d..b1cb8db529a 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 @@ -430,6 +430,10 @@ GROUPING_ID: G R O U P I N G UNDERLINE I D GROUP_MAX_REQUESTS: G R O U P UNDERLINE M A X UNDERLINE R E Q U E S T S; GUID: G U I D; HADR: H A D R; +HALFVEC_COSINE_OPS: H A L F V E C UNDERLINE C O S I N E UNDERLINE O P S; +HALFVEC_IP_OPS: H A L F V E C UNDERLINE I P UNDERLINE O P S; +HALFVEC_L1_OPS: H A L F V E C UNDERLINE L '1' UNDERLINE O P S; +HALFVEC_L2_OPS: H A L F V E C UNDERLINE L '2' UNDERLINE O P S; HASH: H A S H; HASHED: H A S H E D; HAVING: H A V I N G; @@ -924,6 +928,10 @@ SOFTNUMA: S O F T N U M A; SOME: S O M E; SOURCE: S O U R C E; SPARSE: S P A R S E; +SPARSEVEC_COSINE_OPS: S P A R S E V E C UNDERLINE C O S I N E UNDERLINE O P S; +SPARSEVEC_IP_OPS: S P A R S E V E C UNDERLINE I P UNDERLINE O P S; +SPARSEVEC_L1_OPS: S P A R S E V E C UNDERLINE L '1' UNDERLINE O P S; +SPARSEVEC_L2_OPS: S P A R S E V E C UNDERLINE L '2' UNDERLINE O P S; SPATIAL: S P A T I A L; SPATIAL_WINDOW_MAX_CELLS: S P A T I A L UNDERLINE W I N D O W UNDERLINE M A X UNDERLINE C E L L S; SPECIFICATION: S P E C I F I C A T I O N; @@ -1075,6 +1083,7 @@ VARP: V A R P; VARYING: V A R Y I N G; VECTOR_COSINE_OPS: V E C T O R UNDERLINE C O S I N E UNDERLINE O P S; VECTOR_IP_OPS: V E C T O R UNDERLINE I P UNDERLINE O P S; +VECTOR_L1_OPS: V E C T O R UNDERLINE L '1' UNDERLINE O P S; VECTOR_L2_OPS: V E C T O R UNDERLINE L '2' UNDERLINE O P S; VERBOSELOGGING: V E R B O S E L O G G I N G; VERSION: V E R S I O N; @@ -1182,6 +1191,8 @@ OR_ASSIGN: '|='; VECTOR_L2: '<->'; VECTOR_COSINE: '<=>'; VECTOR_IP: '<#>'; +VECTOR_L1: '<+>'; +VECTOR_CONCATENATE: '||'; DOT: '.'; UNDERLINE: '_'; diff --git a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 index 2aca758343b..ef14a0c3f9f 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 @@ -5215,7 +5215,22 @@ column_name_list_with_order /* We introduce specific index methods so as to avoid PG syntax leaks. */ column_name_list_with_order_for_vector - : simple_column_name (ASC | DESC)? (VECTOR_COSINE_OPS | VECTOR_IP_OPS | VECTOR_L2_OPS)? (COMMA simple_column_name (ASC | DESC)? (VECTOR_COSINE_OPS | VECTOR_IP_OPS | VECTOR_L2_OPS)?)* + : simple_column_name (ASC | DESC)? vector_index_ops? (COMMA simple_column_name (ASC | DESC)? vector_index_ops?)* + ; + +vector_index_ops + : VECTOR_COSINE_OPS + | VECTOR_IP_OPS + | VECTOR_L1_OPS + | VECTOR_L2_OPS + | HALFVEC_COSINE_OPS + | HALFVEC_IP_OPS + | HALFVEC_L1_OPS + | HALFVEC_L2_OPS + | SPARSEVEC_COSINE_OPS + | SPARSEVEC_IP_OPS + | SPARSEVEC_L1_OPS + | SPARSEVEC_L2_OPS ; //For some reason, sql server allows any number of prefixes: Here, h is the column: a.b.c.d.e.f.g.h @@ -5262,7 +5277,11 @@ comparison_operator ; vector_operator - : VECTOR_COSINE | VECTOR_IP | VECTOR_L2 + : VECTOR_COSINE + | VECTOR_IP + | VECTOR_L2 + | VECTOR_L1 + | VECTOR_CONCATENATE ; assignment_operator diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index 344cf739009..22581698b1f 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -640,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 'sparsevec' THEN tds_id = 167; -- Same as varchar + WHEN 'halfvec' THEN tds_id = 167; -- Same as varchar WHEN 'geometry' THEN tds_id = 240; WHEN 'geography' THEN tds_id = 240; ELSE tds_id = 0; diff --git a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql index 3144686869e..e3c68f35001 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', 'geometry', 'geography') + WHEN type IN ('xml', 'vector', 'halfvec', 'sparsevec', 'geometry', 'geography') THEN -1 WHEN type = 'sql_variant' THEN 0 diff --git a/contrib/babelfishpg_tsql/sql/sys_views.sql b/contrib/babelfishpg_tsql/sql/sys_views.sql index a21ef921b7f..84f76911def 100644 --- a/contrib/babelfishpg_tsql/sql/sys_views.sql +++ b/contrib/babelfishpg_tsql/sql/sys_views.sql @@ -360,6 +360,8 @@ BEGIN END IF; WHEN 'timestamp' THEN max_length = 8; WHEN 'vector' THEN max_length = -1; -- dummy as varchar max + WHEN 'halfvec' THEN max_length = -1; -- dummy as varchar max + WHEN 'sparsevec' THEN max_length = -1; -- dummy as varchar max ELSE max_length = typelen; END CASE; RETURN max_length; diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index 7c8e28e4b88..d689ebf4a16 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -328,6 +328,183 @@ WHERE ps.dbid = sys.db_id(); GRANT SELECT ON sys.partition_schemes TO PUBLIC; +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 'sparsevec' THEN tds_id = 167; -- Same as varchar + WHEN 'halfvec' 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_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', 'halfvec', 'sparsevec', 'geometry', 'geography') + THEN -1 + WHEN type = 'sql_variant' + THEN 0 + ELSE null + END$$; + +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 + WHEN 'halfvec' THEN max_length = -1; -- dummy as varchar max + WHEN 'sparsevec' 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 VIEW sys.database_principals AS SELECT CAST(Ext.orig_username AS SYS.SYSNAME) AS name, diff --git a/test/JDBC/expected/TestHalfvecDatatype.out b/test/JDBC/expected/TestHalfvecDatatype.out new file mode 100644 index 00000000000..c1b249ebf66 --- /dev/null +++ b/test/JDBC/expected/TestHalfvecDatatype.out @@ -0,0 +1,1771 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +SELECT CAST('[1,2,3]' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[-1,-2,-3]' as halfvec); +go +~~START~~ +varchar +[-1,-2,-3] +~~END~~ + + +SELECT CAST('[1.,2.,3.]' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST(' [ 1, 2 , 3 ] ' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1.23456]' as halfvec); +go +~~START~~ +varchar +[1.234375] +~~END~~ + + +SELECT CAST('[hello,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[hello,1]")~~ + + +SELECT CAST('[NaN,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in halfvec)~~ + + +SELECT CAST('[Infinity,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in halfvec)~~ + + +SELECT CAST('[-Infinity,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in halfvec)~~ + + +SELECT CAST('[65519,-65519]' as halfvec); +go +~~START~~ +varchar +[65504,-65504] +~~END~~ + + +SELECT CAST('[65520,-65520]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "65520" is out of range for type halfvec)~~ + + +SELECT CAST('[1e-8,-1e-8]' as halfvec); +go +~~START~~ +varchar +[0,-0] +~~END~~ + + +SELECT CAST('[4e38,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "4e38" is out of range for type halfvec)~~ + + +SELECT CAST('[1e-46,1]' as halfvec); +go +~~START~~ +varchar +[0,1] +~~END~~ + + +SELECT CAST('[1,2,3' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,2,3")~~ + + +SELECT CAST('[1,2,3]9' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,2,3]9")~~ + + +SELECT CAST('1,2,3' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "1,2,3")~~ + + +SELECT CAST('' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "")~~ + + +SELECT CAST('[' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[")~~ + + +SELECT CAST('[ ' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[ ")~~ + + +SELECT CAST('[,' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[,")~~ + + +SELECT CAST('[]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT CAST('[ ]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT CAST('[,]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[,]")~~ + + +SELECT CAST('[1,]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,]")~~ + + +SELECT CAST('[1a]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1a]")~~ + + +SELECT CAST('[1,,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,,3]")~~ + + +SELECT CAST('[1, ,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1, ,3]")~~ + + +SELECT CAST('[1,2,3]' as halfvec(3)); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1,2,3]' as halfvec(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +SELECT CAST('[1,2,3]' as halfvec(3, 2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid type modifier)~~ + + +SELECT CAST('[1,2,3]' as halfvec('a')); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 32)~~ + + +SELECT CAST('[1,2,3]' as halfvec(0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type halfvec must be at least 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec(16001)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type halfvec cannot exceed 16000)~~ + + +SELECT CAST('{"[1,2,3]"}' as halfvec(2)[]); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '[]' at line 1 and character position 39)~~ + + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[5,7,9] +~~END~~ + + +SELECT CAST('[65519]' as halfvec) + CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2]' as halfvec) + CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) - CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[-3,-3,-3] +~~END~~ + + +SELECT CAST('[-65519]' as halfvec) - CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2]' as halfvec) - CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) * CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[4,10,18] +~~END~~ + + +SELECT CAST('[65519]' as halfvec) * CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1e-7]' as halfvec) * CAST('[1e-7]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: underflow)~~ + + +SELECT CAST('[1,2]' as halfvec) * CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 3 and 2)~~ + + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '=' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '=' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '!' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '!' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +0 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[0,0,0]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[0,0,0]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[2,3,4]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT vector_dims(CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +3 +~~END~~ + + +SELECT ROUND(CAST(l2_norm(CAST('[1,1]' as halfvec)) as numeric), 5); +go +~~START~~ +numeric +1.00000 +~~END~~ + + +SELECT l2_norm(CAST('[3,4]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_norm(CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_norm(CAST('[0,0]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l2_norm(CAST('[2]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT l2_distance(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,1,1,1,1,1,1,4,5]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT CAST('[0,0]' as halfvec) <-> CAST('[3,4]' as halfvec); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +11.0 +~~END~~ + + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT inner_product(CAST('[65504]' as halfvec), CAST('[65504]' as halfvec)); +go +~~START~~ +float +4.290774016E9 +~~END~~ + + +SELECT inner_product(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +45.0 +~~END~~ + + +SELECT CAST('[1,2]' as halfvec) <#> CAST('[3,4]' as halfvec); +go +~~START~~ +float +-11.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[2,4]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[0,0]' as halfvec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1,1]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,0]' as halfvec), CAST('[0,2]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1,-1]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1.1,1.1]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1.1,-1.1]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[-1,-2,-3,-4,-5,-6,-7,-8,-9]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT CAST('[1,2]' as halfvec) <=> CAST('[2,4]' as halfvec); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[0,3,2,5,4,7,6,9,8]' as halfvec)); +go +~~START~~ +float +9.0 +~~END~~ + + +SELECT CAST('[0,0]' as halfvec) <+> CAST('[3,4]' as halfvec); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l2_normalize(CAST('[3,4]' as halfvec)); +go +~~START~~ +varchar +[0.60009766,0.7998047] +~~END~~ + + +SELECT l2_normalize(CAST('[3,0]' as halfvec)); +go +~~START~~ +varchar +[1,0] +~~END~~ + + +SELECT l2_normalize(CAST('[0,0.1]' as halfvec)); +go +~~START~~ +varchar +[0,1] +~~END~~ + + +SELECT l2_normalize(CAST('[0,0]' as halfvec)); +go +~~START~~ +varchar +[0,0] +~~END~~ + + +SELECT l2_normalize(CAST('[65504]' as halfvec)); +go +~~START~~ +varchar +[1] +~~END~~ + + +SELECT binary_quantize(CAST('[1,0,-1]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data type bit is not supported yet)~~ + + +SELECT binary_quantize(CAST('[0,0.1,-0.2,-0.3,0.4,0.5,0.6,-0.7,0.8,-0.9,1]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data type bit is not supported yet)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 3); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2); +go +~~START~~ +varchar +[3,4] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 3); +go +~~START~~ +varchar +[1] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 9); +go +~~START~~ +varchar +[3,4,5] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 0); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, -1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 2); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 2147483647, 10); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2147483647); +go +~~START~~ +varchar +[3,4,5] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -2147483644, 2147483647); +go +~~START~~ +varchar +[1,2] +~~END~~ + + +SELECT halfvec_avg(array_agg(CAST(n as halfvec))) FROM generate_series(1, 16002) n; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot cast type integer to halfvec)~~ + + +-- hnsw_halfvec +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l2_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM halfvec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM halfvec_table +Aggregate (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=0 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_ip_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <#> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_cosine_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- L1 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l1_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <+> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <+> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_l2_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM halfvec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM halfvec_table +Aggregate (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=0 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_ip_ops) WITH (lists = 1) WITH (lists = 1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'lists' at line 1 and character position 92)~~ + + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] + +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec) NULLS LAST +Sort (actual rows=5 loops=1) + Sort Key: ((val <#> '[3,3,3]'::halfvec)) + Sort Method: quicksort Memory: 25kB + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Sort (actual rows=5 loops=1) + Sort Key: ((halfvec_table.val <#> $0)) + Sort Method: quicksort Memory: 25kB + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_cosine_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'halfvec'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure halfvec_proc_1 @a halfvec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'halfvec_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#halfvec_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#halfvec_proc_1;1#!#@a#!#1#!##!#halfvec#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#halfvec_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure halfvec_proc_1; +go + +create table t(a halfvec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +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 +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#halfvec#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding halfvec(4) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: operator class "vector_l2_ops" does not accept data type halfvec)~~ + +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('[21,-2,0,2.5]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('[5, 10000, -9.75, 8]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('[-0.02,23,3.14,00]' as halfvec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-65519' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('[',a, ',', b, ',', c, ',', d, ']') as halfvec) FROM cte; +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +SELECT * FROM document_embeddings; +go +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +~~END~~ + +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '[3,1,2,4]'; +go +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +3#!#[-0.020004272,23,3.140625,0] +2#!#[5,10000,-9.75,8] +4#!#[200,80,-65504,-1] +~~END~~ + +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <=> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <#> '[3,1,2,0]') FROM document_embeddings; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '[3,20, 1,-2.5]' < 5; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +~~END~~ + +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +~~END~~ + + +SELECT AVG(embedding) FROM document_embeddings; +go +~~START~~ +varchar +[56.5,2526,-16376,2.375] +~~END~~ + + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go +~~START~~ +int#!#varchar +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +1#!#[21,-2,0,2.5] +~~END~~ + + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/TestSparsevecDatatype.out b/test/JDBC/expected/TestSparsevecDatatype.out new file mode 100644 index 00000000000..42b9df510d4 --- /dev/null +++ b/test/JDBC/expected/TestSparsevecDatatype.out @@ -0,0 +1,1583 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +SELECT CAST('{1:1.5,3:3.5}/5' as sparsevec); +go +~~START~~ +varchar +{1:1.5,3:3.5}/5 +~~END~~ + + +SELECT CAST('{1:-2,3:-4}/5' as sparsevec); +go +~~START~~ +varchar +{1:-2,3:-4}/5 +~~END~~ + + +SELECT CAST('{1:2.,3:4.}/5' as sparsevec); +go +~~START~~ +varchar +{1:2,3:4}/5 +~~END~~ + + +SELECT CAST(' { 1 : 1.5 , 3 : 3.5 } / 5 ' as sparsevec); +go +~~START~~ +varchar +{1:1.5,3:3.5}/5 +~~END~~ + + +SELECT CAST('{1:1.23456}/1' as sparsevec); +go +~~START~~ +varchar +{1:1.23456}/1 +~~END~~ + + +SELECT CAST('{1:hello,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:hello,2:1}/2")~~ + + +SELECT CAST('{1:NaN,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in sparsevec)~~ + + +SELECT CAST('{1:Infinity,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in sparsevec)~~ + + +SELECT CAST('{1:-Infinity,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in sparsevec)~~ + + +SELECT CAST('{1:1.5e38,2:-1.5e38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e+38,2:-1.5e+38}/2 +~~END~~ + + +SELECT CAST('{1:1.5e+38,2:-1.5e+38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e+38,2:-1.5e+38}/2 +~~END~~ + + +SELECT CAST('{1:1.5e-38,2:-1.5e-38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e-38,2:-1.5e-38}/2 +~~END~~ + + +SELECT CAST('{1:4e38,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "4e38" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:-4e38,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "-4e38" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:1e-46,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "1e-46" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:-1e-46,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "-1e-46" is out of range for type sparsevec)~~ + + +SELECT CAST('' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "")~~ + + +SELECT CAST('{' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{")~~ + + +SELECT CAST('{ ' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{ ")~~ + + +SELECT CAST('{:' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:")~~ + + +SELECT CAST('{,' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{,")~~ + + +SELECT CAST('{}' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{}")~~ + + +SELECT CAST('{}/'' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ''{}/'' at line 1 and character position 12)~~ + + +SELECT CAST('{}/1' as sparsevec); +go +~~START~~ +varchar +{}/1 +~~END~~ + + +SELECT CAST('{}/1a' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{}/1a")~~ + + +SELECT CAST('{ }/1' as sparsevec); +go +~~START~~ +varchar +{}/1 +~~END~~ + + +SELECT CAST('{:}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:}/1")~~ + + +SELECT CAST('{,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{,}/1")~~ + + +SELECT CAST('{1,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1,}/1")~~ + + +SELECT CAST('{:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:1}/1")~~ + + +SELECT CAST('{1:}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:}/1")~~ + + +SELECT CAST('{1a:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1a:1}/1")~~ + + +SELECT CAST('{1:1a}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:1a}/1")~~ + + +SELECT CAST('{1:1,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:1,}/1")~~ + + +SELECT CAST('{1:0,2:1,3:0}/3' as sparsevec); +go +~~START~~ +varchar +{2:1}/3 +~~END~~ + + +SELECT CAST('{2:1,1:1}/2' as sparsevec); +go +~~START~~ +varchar +{1:1,2:1}/2 +~~END~~ + + +SELECT CAST('{1:1,1:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec indices must not contain duplicates)~~ + + +SELECT CAST('{1:1,2:1,1:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec indices must not contain duplicates)~~ + + +SELECT CAST('{}/5' as sparsevec); +go +~~START~~ +varchar +{}/5 +~~END~~ + + +SELECT CAST('{}/-1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{}/1000000001' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/2147483648' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/-2147483649' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{}/9223372036854775808' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/-9223372036854775809' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{2147483647:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{2147483648:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{-2147483648:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{-2147483649:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{0:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{2:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{}/3' as sparsevec(3)); +go +~~START~~ +varchar +{}/3 +~~END~~ + + +SELECT CAST('{}/3' as sparsevec(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +SELECT CAST('{}/3' as sparsevec(3, 2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid type modifier)~~ + + +SELECT CAST('{}/3' as sparsevec('a')); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 31)~~ + + +SELECT CAST('{}/3' as sparsevec(0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type sparsevec must be at least 1)~~ + + +SELECT CAST('{}/3' as sparsevec(1000000001)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type sparsevec cannot exceed 1000000000)~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +0 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{}/3' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2}/2' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:3,3:4}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:2,2:3}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT ROUND(l2_norm(CAST('{1:1,2:1}/2' as sparsevec)), 5); +go +~~START~~ +numeric +1.41421 +~~END~~ + + +SELECT l2_norm(CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_norm(CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_norm(CAST('{1:3e37,2:4e37}/2' as sparsevec)); +go +~~START~~ +float +5.000000042966943E37 +~~END~~ + + +SELECT l2_norm(CAST('{}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l2_norm(CAST('{1:2}/1' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{1:3}/2' as sparsevec), CAST('{2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{2:4}/2' as sparsevec), CAST('{1:3}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{1:3,2:4}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT CAST('{}/2' as sparsevec) <-> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go +~~START~~ +float +10.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT inner_product(CAST('{1:1,3:3}/4' as sparsevec), CAST('{2:2,4:4}/4' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{2:2,4:4}/4' as sparsevec), CAST('{1:1,3:3}/4' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go +~~START~~ +float +18.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{}/2' as sparsevec), CAST('{1:1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go +~~START~~ +float +18.0 +~~END~~ + + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <#> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +-11.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1,2:1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1,2:-1}/2' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:2}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{2:2}/2' as sparsevec), CAST('{1:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1.1,2:1.1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1.1,2:-1.1}/2' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('{}/1' as sparsevec), CAST('{}/1' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <=> CAST('{1:2,2:4}/2' as sparsevec); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT l1_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:-3e38}/1' as sparsevec)); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7}/8' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/8' as sparsevec)); +go +~~START~~ +float +36.0 +~~END~~ + + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7,9:9}/9' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/9' as sparsevec)); +go +~~START~~ +float +45.0 +~~END~~ + + +SELECT CAST('{}/2' as sparsevec) <+> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +varchar +{1:0.6,2:0.8}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3}/2' as sparsevec)); +go +~~START~~ +varchar +{1:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{2:0.1}/2' as sparsevec)); +go +~~START~~ +varchar +{2:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{}/2' as sparsevec)); +go +~~START~~ +varchar +{}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +varchar +{1:1}/1 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3e38,2:1e-37}/2' as sparsevec)); +go +~~START~~ +varchar +{1:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{2:3e37,4:3e-37,6:4e37,8:4e-37}/9' as sparsevec)); +go +~~START~~ +varchar +{2:0.6,6:0.8}/9 +~~END~~ + + + +-- L2 +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <-> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM sparsevec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM sparsevec_table +Aggregate (actual rows=1 loops=1) + -> Seq Scan on sparsevec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE sparsevec_table; +go + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=0 loops=1) + Order By: (val <-> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_ip_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:4}/3 +{1:1,2:2,3:3}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <#> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_cosine_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:1,3:1}/3 +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> '{}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- L1 +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l1_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <+> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <+> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- non-zero elements +CREATE TABLE sparsevec_table (val sparsevec(1001)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST(array_fill(1, ARRAY[1001]) AS sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 46)~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +TRUNCATE TABLE sparsevec_table; +go + +DROP TABLE sparsevec_table; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'sparsevec'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure sparsevec_proc_1 @a sparsevec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'sparsevec_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@a#!#1#!##!#sparsevec#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure sparsevec_proc_1; +go + +create table t(a sparsevec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +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 +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#sparsevec#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding sparsevec(5) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: operator class "vector_l2_ops" does not accept data type sparsevec)~~ + +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('{1:5,2:1}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('{1:5, 2:10000, 3:-9.75, 4:8}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('{1:-0.02,2:23,4:3.14,5:00}/5' as sparsevec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-305' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('{1:',a, ',3:', b, ',4:', c, ',5:', d, '}/5') as sparsevec) FROM cte; +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +SELECT * FROM document_embeddings; +go +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +~~END~~ + +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '{1:1,2:2,3:4}/5'; +go +~~START~~ +int#!#varchar +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +1#!#{1:5,2:1}/5 +~~END~~ + +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <=> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <#> '{1:1,2:2,3:4}/5') FROM document_embeddings; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '{1:1,2:2,4:4}/5' < 5; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +~~END~~ + +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +~~END~~ + + +SELECT AVG(embedding) FROM document_embeddings; +go +~~ERROR (Code: 206)~~ + +~~ERROR (Message: The function avg is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.)~~ + + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go +~~ERROR (Code: 206)~~ + +~~ERROR (Message: The function avg is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.)~~ + + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/babel_typecode.out b/test/JDBC/expected/babel_typecode.out index 9bd049143a1..275df8bed10 100644 --- a/test/JDBC/expected/babel_typecode.out +++ b/test/JDBC/expected/babel_typecode.out @@ -37,6 +37,8 @@ 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#!#sparsevec#!#sparsevec#!#9#!#34#!#3 +sys#!#halfvec#!#halfvec#!#9#!#34#!#3 sys#!#geometry#!#geometry#!#5#!#34#!#1 sys#!#geography#!#geography#!#5#!#35#!#1 ~~END~~ diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestHalfvecDatatype.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestHalfvecDatatype.out new file mode 100644 index 00000000000..a56df52f315 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestHalfvecDatatype.out @@ -0,0 +1,1771 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +SELECT CAST('[1,2,3]' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[-1,-2,-3]' as halfvec); +go +~~START~~ +varchar +[-1,-2,-3] +~~END~~ + + +SELECT CAST('[1.,2.,3.]' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST(' [ 1, 2 , 3 ] ' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1.23456]' as halfvec); +go +~~START~~ +varchar +[1.234375] +~~END~~ + + +SELECT CAST('[hello,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[hello,1]")~~ + + +SELECT CAST('[NaN,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in halfvec)~~ + + +SELECT CAST('[Infinity,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in halfvec)~~ + + +SELECT CAST('[-Infinity,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in halfvec)~~ + + +SELECT CAST('[65519,-65519]' as halfvec); +go +~~START~~ +varchar +[65504,-65504] +~~END~~ + + +SELECT CAST('[65520,-65520]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "65520" is out of range for type halfvec)~~ + + +SELECT CAST('[1e-8,-1e-8]' as halfvec); +go +~~START~~ +varchar +[0,-0] +~~END~~ + + +SELECT CAST('[4e38,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "4e38" is out of range for type halfvec)~~ + + +SELECT CAST('[1e-46,1]' as halfvec); +go +~~START~~ +varchar +[0,1] +~~END~~ + + +SELECT CAST('[1,2,3' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,2,3")~~ + + +SELECT CAST('[1,2,3]9' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,2,3]9")~~ + + +SELECT CAST('1,2,3' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "1,2,3")~~ + + +SELECT CAST('' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "")~~ + + +SELECT CAST('[' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[")~~ + + +SELECT CAST('[ ' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[ ")~~ + + +SELECT CAST('[,' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[,")~~ + + +SELECT CAST('[]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT CAST('[ ]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT CAST('[,]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[,]")~~ + + +SELECT CAST('[1,]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,]")~~ + + +SELECT CAST('[1a]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1a]")~~ + + +SELECT CAST('[1,,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,,3]")~~ + + +SELECT CAST('[1, ,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1, ,3]")~~ + + +SELECT CAST('[1,2,3]' as halfvec(3)); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1,2,3]' as halfvec(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +SELECT CAST('[1,2,3]' as halfvec(3, 2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid type modifier)~~ + + +SELECT CAST('[1,2,3]' as halfvec('a')); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 32)~~ + + +SELECT CAST('[1,2,3]' as halfvec(0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type halfvec must be at least 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec(16001)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type halfvec cannot exceed 16000)~~ + + +SELECT CAST('{"[1,2,3]"}' as halfvec(2)[]); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '[]' at line 1 and character position 39)~~ + + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[5,7,9] +~~END~~ + + +SELECT CAST('[65519]' as halfvec) + CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2]' as halfvec) + CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) - CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[-3,-3,-3] +~~END~~ + + +SELECT CAST('[-65519]' as halfvec) - CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2]' as halfvec) - CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) * CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[4,10,18] +~~END~~ + + +SELECT CAST('[65519]' as halfvec) * CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1e-7]' as halfvec) * CAST('[1e-7]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: underflow)~~ + + +SELECT CAST('[1,2]' as halfvec) * CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 3 and 2)~~ + + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '=' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '=' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '!' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '!' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +0 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[0,0,0]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[0,0,0]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[2,3,4]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT vector_dims(CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +3 +~~END~~ + + +SELECT ROUND(CAST(l2_norm(CAST('[1,1]' as halfvec)) as numeric), 5); +go +~~START~~ +numeric +1.00000 +~~END~~ + + +SELECT l2_norm(CAST('[3,4]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_norm(CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_norm(CAST('[0,0]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l2_norm(CAST('[2]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT l2_distance(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,1,1,1,1,1,1,4,5]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT CAST('[0,0]' as halfvec) <-> CAST('[3,4]' as halfvec); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +11.0 +~~END~~ + + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT inner_product(CAST('[65504]' as halfvec), CAST('[65504]' as halfvec)); +go +~~START~~ +float +4.290774016E9 +~~END~~ + + +SELECT inner_product(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +45.0 +~~END~~ + + +SELECT CAST('[1,2]' as halfvec) <#> CAST('[3,4]' as halfvec); +go +~~START~~ +float +-11.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[2,4]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[0,0]' as halfvec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1,1]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,0]' as halfvec), CAST('[0,2]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1,-1]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1.1,1.1]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1.1,-1.1]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[-1,-2,-3,-4,-5,-6,-7,-8,-9]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT CAST('[1,2]' as halfvec) <=> CAST('[2,4]' as halfvec); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[0,3,2,5,4,7,6,9,8]' as halfvec)); +go +~~START~~ +float +9.0 +~~END~~ + + +SELECT CAST('[0,0]' as halfvec) <+> CAST('[3,4]' as halfvec); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l2_normalize(CAST('[3,4]' as halfvec)); +go +~~START~~ +varchar +[0.60009766,0.7998047] +~~END~~ + + +SELECT l2_normalize(CAST('[3,0]' as halfvec)); +go +~~START~~ +varchar +[1,0] +~~END~~ + + +SELECT l2_normalize(CAST('[0,0.1]' as halfvec)); +go +~~START~~ +varchar +[0,1] +~~END~~ + + +SELECT l2_normalize(CAST('[0,0]' as halfvec)); +go +~~START~~ +varchar +[0,0] +~~END~~ + + +SELECT l2_normalize(CAST('[65504]' as halfvec)); +go +~~START~~ +varchar +[1] +~~END~~ + + +SELECT binary_quantize(CAST('[1,0,-1]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data type bit is not supported yet)~~ + + +SELECT binary_quantize(CAST('[0,0.1,-0.2,-0.3,0.4,0.5,0.6,-0.7,0.8,-0.9,1]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data type bit is not supported yet)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 3); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2); +go +~~START~~ +varchar +[3,4] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 3); +go +~~START~~ +varchar +[1] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 9); +go +~~START~~ +varchar +[3,4,5] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 0); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, -1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 2); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 2147483647, 10); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2147483647); +go +~~START~~ +varchar +[3,4,5] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -2147483644, 2147483647); +go +~~START~~ +varchar +[1,2] +~~END~~ + + +SELECT halfvec_avg(array_agg(CAST(n as halfvec))) FROM generate_series(1, 16002) n; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot cast type integer to halfvec)~~ + + +-- hnsw_halfvec +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l2_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM halfvec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM halfvec_table +Aggregate (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=0 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_ip_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <#> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_cosine_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- L1 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l1_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <+> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <+> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_l2_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM halfvec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM halfvec_table +Aggregate (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=0 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_ip_ops) WITH (lists = 1) WITH (lists = 1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'lists' at line 1 and character position 92)~~ + + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] + +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec) NULLS LAST +Sort (actual rows=5 loops=1) + Sort Key: ((val <#> '[3,3,3]'::halfvec)) + Sort Method: quicksort Memory: 25kB + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Sort (actual rows=5 loops=1) + Sort Key: ((halfvec_table.val <#> $0)) + Sort Method: quicksort Memory: 25kB + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_cosine_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec) NULLS LAST +Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'halfvec'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure halfvec_proc_1 @a halfvec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'halfvec_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#halfvec_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#halfvec_proc_1;1#!#@a#!#1#!##!#halfvec#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#halfvec_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure halfvec_proc_1; +go + +create table t(a halfvec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +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 +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#halfvec#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding halfvec(4) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: operator class "vector_l2_ops" does not accept data type halfvec)~~ + +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('[21,-2,0,2.5]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('[5, 10000, -9.75, 8]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('[-0.02,23,3.14,00]' as halfvec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-65519' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('[',a, ',', b, ',', c, ',', d, ']') as halfvec) FROM cte; +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +SELECT * FROM document_embeddings; +go +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +~~END~~ + +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '[3,1,2,4]'; +go +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +3#!#[-0.020004272,23,3.140625,0] +2#!#[5,10000,-9.75,8] +4#!#[200,80,-65504,-1] +~~END~~ + +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <=> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <#> '[3,1,2,0]') FROM document_embeddings; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '[3,20, 1,-2.5]' < 5; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +~~END~~ + +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +~~END~~ + + +SELECT AVG(embedding) FROM document_embeddings; +go +~~START~~ +varchar +[56.5,2526,-16376,2.375] +~~END~~ + + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go +~~START~~ +int#!#varchar +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +1#!#[21,-2,0,2.5] +~~END~~ + + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestSparsevecDatatype.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestSparsevecDatatype.out new file mode 100644 index 00000000000..aa069df9fdc --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestSparsevecDatatype.out @@ -0,0 +1,1583 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +SELECT CAST('{1:1.5,3:3.5}/5' as sparsevec); +go +~~START~~ +varchar +{1:1.5,3:3.5}/5 +~~END~~ + + +SELECT CAST('{1:-2,3:-4}/5' as sparsevec); +go +~~START~~ +varchar +{1:-2,3:-4}/5 +~~END~~ + + +SELECT CAST('{1:2.,3:4.}/5' as sparsevec); +go +~~START~~ +varchar +{1:2,3:4}/5 +~~END~~ + + +SELECT CAST(' { 1 : 1.5 , 3 : 3.5 } / 5 ' as sparsevec); +go +~~START~~ +varchar +{1:1.5,3:3.5}/5 +~~END~~ + + +SELECT CAST('{1:1.23456}/1' as sparsevec); +go +~~START~~ +varchar +{1:1.23456}/1 +~~END~~ + + +SELECT CAST('{1:hello,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:hello,2:1}/2")~~ + + +SELECT CAST('{1:NaN,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in sparsevec)~~ + + +SELECT CAST('{1:Infinity,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in sparsevec)~~ + + +SELECT CAST('{1:-Infinity,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in sparsevec)~~ + + +SELECT CAST('{1:1.5e38,2:-1.5e38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e+38,2:-1.5e+38}/2 +~~END~~ + + +SELECT CAST('{1:1.5e+38,2:-1.5e+38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e+38,2:-1.5e+38}/2 +~~END~~ + + +SELECT CAST('{1:1.5e-38,2:-1.5e-38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e-38,2:-1.5e-38}/2 +~~END~~ + + +SELECT CAST('{1:4e38,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "4e38" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:-4e38,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "-4e38" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:1e-46,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "1e-46" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:-1e-46,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "-1e-46" is out of range for type sparsevec)~~ + + +SELECT CAST('' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "")~~ + + +SELECT CAST('{' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{")~~ + + +SELECT CAST('{ ' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{ ")~~ + + +SELECT CAST('{:' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:")~~ + + +SELECT CAST('{,' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{,")~~ + + +SELECT CAST('{}' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{}")~~ + + +SELECT CAST('{}/'' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ''{}/'' at line 1 and character position 12)~~ + + +SELECT CAST('{}/1' as sparsevec); +go +~~START~~ +varchar +{}/1 +~~END~~ + + +SELECT CAST('{}/1a' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{}/1a")~~ + + +SELECT CAST('{ }/1' as sparsevec); +go +~~START~~ +varchar +{}/1 +~~END~~ + + +SELECT CAST('{:}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:}/1")~~ + + +SELECT CAST('{,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{,}/1")~~ + + +SELECT CAST('{1,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1,}/1")~~ + + +SELECT CAST('{:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:1}/1")~~ + + +SELECT CAST('{1:}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:}/1")~~ + + +SELECT CAST('{1a:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1a:1}/1")~~ + + +SELECT CAST('{1:1a}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:1a}/1")~~ + + +SELECT CAST('{1:1,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:1,}/1")~~ + + +SELECT CAST('{1:0,2:1,3:0}/3' as sparsevec); +go +~~START~~ +varchar +{2:1}/3 +~~END~~ + + +SELECT CAST('{2:1,1:1}/2' as sparsevec); +go +~~START~~ +varchar +{1:1,2:1}/2 +~~END~~ + + +SELECT CAST('{1:1,1:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec indices must not contain duplicates)~~ + + +SELECT CAST('{1:1,2:1,1:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec indices must not contain duplicates)~~ + + +SELECT CAST('{}/5' as sparsevec); +go +~~START~~ +varchar +{}/5 +~~END~~ + + +SELECT CAST('{}/-1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{}/1000000001' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/2147483648' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/-2147483649' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{}/9223372036854775808' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/-9223372036854775809' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{2147483647:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{2147483648:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{-2147483648:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{-2147483649:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{0:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{2:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{}/3' as sparsevec(3)); +go +~~START~~ +varchar +{}/3 +~~END~~ + + +SELECT CAST('{}/3' as sparsevec(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +SELECT CAST('{}/3' as sparsevec(3, 2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid type modifier)~~ + + +SELECT CAST('{}/3' as sparsevec('a')); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 31)~~ + + +SELECT CAST('{}/3' as sparsevec(0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type sparsevec must be at least 1)~~ + + +SELECT CAST('{}/3' as sparsevec(1000000001)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type sparsevec cannot exceed 1000000000)~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +0 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{}/3' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2}/2' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:3,3:4}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:2,2:3}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT ROUND(l2_norm(CAST('{1:1,2:1}/2' as sparsevec)), 5); +go +~~START~~ +numeric +1.41421 +~~END~~ + + +SELECT l2_norm(CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_norm(CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_norm(CAST('{1:3e37,2:4e37}/2' as sparsevec)); +go +~~START~~ +float +5.000000042966943E37 +~~END~~ + + +SELECT l2_norm(CAST('{}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l2_norm(CAST('{1:2}/1' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{1:3}/2' as sparsevec), CAST('{2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{2:4}/2' as sparsevec), CAST('{1:3}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{1:3,2:4}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT CAST('{}/2' as sparsevec) <-> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go +~~START~~ +float +10.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT inner_product(CAST('{1:1,3:3}/4' as sparsevec), CAST('{2:2,4:4}/4' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{2:2,4:4}/4' as sparsevec), CAST('{1:1,3:3}/4' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go +~~START~~ +float +18.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{}/2' as sparsevec), CAST('{1:1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go +~~START~~ +float +18.0 +~~END~~ + + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <#> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +-11.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1,2:1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1,2:-1}/2' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:2}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{2:2}/2' as sparsevec), CAST('{1:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1.1,2:1.1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1.1,2:-1.1}/2' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('{}/1' as sparsevec), CAST('{}/1' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <=> CAST('{1:2,2:4}/2' as sparsevec); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT l1_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:-3e38}/1' as sparsevec)); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7}/8' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/8' as sparsevec)); +go +~~START~~ +float +36.0 +~~END~~ + + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7,9:9}/9' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/9' as sparsevec)); +go +~~START~~ +float +45.0 +~~END~~ + + +SELECT CAST('{}/2' as sparsevec) <+> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +varchar +{1:0.6,2:0.8}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3}/2' as sparsevec)); +go +~~START~~ +varchar +{1:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{2:0.1}/2' as sparsevec)); +go +~~START~~ +varchar +{2:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{}/2' as sparsevec)); +go +~~START~~ +varchar +{}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +varchar +{1:1}/1 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3e38,2:1e-37}/2' as sparsevec)); +go +~~START~~ +varchar +{1:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{2:3e37,4:3e-37,6:4e37,8:4e-37}/9' as sparsevec)); +go +~~START~~ +varchar +{2:0.6,6:0.8}/9 +~~END~~ + + + +-- L2 +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <-> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM sparsevec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM sparsevec_table +Aggregate (actual rows=1 loops=1) + -> Seq Scan on sparsevec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE sparsevec_table; +go + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=0 loops=1) + Order By: (val <-> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_ip_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:4}/3 +{1:1,2:2,3:3}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <#> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_cosine_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:1,3:1}/3 +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> '{}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- L1 +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l1_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <+> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <+> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- non-zero elements +CREATE TABLE sparsevec_table (val sparsevec(1001)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST(array_fill(1, ARRAY[1001]) AS sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 46)~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +TRUNCATE TABLE sparsevec_table; +go + +DROP TABLE sparsevec_table; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'sparsevec'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure sparsevec_proc_1 @a sparsevec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'sparsevec_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@a#!#1#!##!#sparsevec#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure sparsevec_proc_1; +go + +create table t(a sparsevec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +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 +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#sparsevec#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding sparsevec(5) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: operator class "vector_l2_ops" does not accept data type sparsevec)~~ + +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('{1:5,2:1}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('{1:5, 2:10000, 3:-9.75, 4:8}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('{1:-0.02,2:23,4:3.14,5:00}/5' as sparsevec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-305' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('{1:',a, ',3:', b, ',4:', c, ',5:', d, '}/5') as sparsevec) FROM cte; +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +SELECT * FROM document_embeddings; +go +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +~~END~~ + +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '{1:1,2:2,3:4}/5'; +go +~~START~~ +int#!#varchar +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +1#!#{1:5,2:1}/5 +~~END~~ + +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <=> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <#> '{1:1,2:2,3:4}/5') FROM document_embeddings; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '{1:1,2:2,4:4}/5' < 5; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +~~END~~ + +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +~~END~~ + + +SELECT AVG(embedding) FROM document_embeddings; +go +~~ERROR (Code: 206)~~ + +~~ERROR (Message: The function avg is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.)~~ + + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go +~~ERROR (Code: 206)~~ + +~~ERROR (Message: The function avg is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.)~~ + + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/parallel_query/TestHalfvecDatatype.out b/test/JDBC/expected/parallel_query/TestHalfvecDatatype.out new file mode 100644 index 00000000000..5825cfeabc1 --- /dev/null +++ b/test/JDBC/expected/parallel_query/TestHalfvecDatatype.out @@ -0,0 +1,1823 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +SELECT CAST('[1,2,3]' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[-1,-2,-3]' as halfvec); +go +~~START~~ +varchar +[-1,-2,-3] +~~END~~ + + +SELECT CAST('[1.,2.,3.]' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST(' [ 1, 2 , 3 ] ' as halfvec); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1.23456]' as halfvec); +go +~~START~~ +varchar +[1.234375] +~~END~~ + + +SELECT CAST('[hello,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[hello,1]")~~ + + +SELECT CAST('[NaN,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in halfvec)~~ + + +SELECT CAST('[Infinity,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in halfvec)~~ + + +SELECT CAST('[-Infinity,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in halfvec)~~ + + +SELECT CAST('[65519,-65519]' as halfvec); +go +~~START~~ +varchar +[65504,-65504] +~~END~~ + + +SELECT CAST('[65520,-65520]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "65520" is out of range for type halfvec)~~ + + +SELECT CAST('[1e-8,-1e-8]' as halfvec); +go +~~START~~ +varchar +[0,-0] +~~END~~ + + +SELECT CAST('[4e38,1]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "4e38" is out of range for type halfvec)~~ + + +SELECT CAST('[1e-46,1]' as halfvec); +go +~~START~~ +varchar +[0,1] +~~END~~ + + +SELECT CAST('[1,2,3' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,2,3")~~ + + +SELECT CAST('[1,2,3]9' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,2,3]9")~~ + + +SELECT CAST('1,2,3' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "1,2,3")~~ + + +SELECT CAST('' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "")~~ + + +SELECT CAST('[' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[")~~ + + +SELECT CAST('[ ' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[ ")~~ + + +SELECT CAST('[,' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[,")~~ + + +SELECT CAST('[]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT CAST('[ ]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT CAST('[,]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[,]")~~ + + +SELECT CAST('[1,]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,]")~~ + + +SELECT CAST('[1a]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1a]")~~ + + +SELECT CAST('[1,,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1,,3]")~~ + + +SELECT CAST('[1, ,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type halfvec: "[1, ,3]")~~ + + +SELECT CAST('[1,2,3]' as halfvec(3)); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1,2,3]' as halfvec(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +SELECT CAST('[1,2,3]' as halfvec(3, 2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid type modifier)~~ + + +SELECT CAST('[1,2,3]' as halfvec('a')); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 32)~~ + + +SELECT CAST('[1,2,3]' as halfvec(0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type halfvec must be at least 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec(16001)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type halfvec cannot exceed 16000)~~ + + +SELECT CAST('{"[1,2,3]"}' as halfvec(2)[]); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '[]' at line 1 and character position 39)~~ + + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[5,7,9] +~~END~~ + + +SELECT CAST('[65519]' as halfvec) + CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2]' as halfvec) + CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) - CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[-3,-3,-3] +~~END~~ + + +SELECT CAST('[-65519]' as halfvec) - CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2]' as halfvec) - CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) * CAST('[4,5,6]' as halfvec); +go +~~START~~ +varchar +[4,10,18] +~~END~~ + + +SELECT CAST('[65519]' as halfvec) * CAST('[65519]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1e-7]' as halfvec) * CAST('[1e-7]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: underflow)~~ + + +SELECT CAST('[1,2]' as halfvec) * CAST('[3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 3 and 2)~~ + + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '<' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '=' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '=' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '!' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '!' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2,3]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2]' as halfvec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '>' at line 1 and character position 34)~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +0 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[0,0,0]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[0,0,0]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[2,3,4]' as halfvec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT halfvec_cmp(CAST('[2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT vector_dims(CAST('[1,2,3]' as halfvec)); +go +~~START~~ +int +3 +~~END~~ + + +SELECT ROUND(CAST(l2_norm(CAST('[1,1]' as halfvec)) as numeric), 5); +go +~~START~~ +numeric +1.00000 +~~END~~ + + +SELECT l2_norm(CAST('[3,4]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_norm(CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_norm(CAST('[0,0]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l2_norm(CAST('[2]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT l2_distance(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,1,1,1,1,1,1,4,5]' as halfvec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT CAST('[0,0]' as halfvec) <-> CAST('[3,4]' as halfvec); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +11.0 +~~END~~ + + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT inner_product(CAST('[65504]' as halfvec), CAST('[65504]' as halfvec)); +go +~~START~~ +float +4.290774016E9 +~~END~~ + + +SELECT inner_product(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +45.0 +~~END~~ + + +SELECT CAST('[1,2]' as halfvec) <#> CAST('[3,4]' as halfvec); +go +~~START~~ +float +-11.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[2,4]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[0,0]' as halfvec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1,1]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,0]' as halfvec), CAST('[0,2]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1,-1]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1.1,1.1]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1.1,-1.1]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[-1,-2,-3,-4,-5,-6,-7,-8,-9]' as halfvec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT CAST('[1,2]' as halfvec) <=> CAST('[2,4]' as halfvec); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different halfvec dimensions 2 and 1)~~ + + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[0,3,2,5,4,7,6,9,8]' as halfvec)); +go +~~START~~ +float +9.0 +~~END~~ + + +SELECT CAST('[0,0]' as halfvec) <+> CAST('[3,4]' as halfvec); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l2_normalize(CAST('[3,4]' as halfvec)); +go +~~START~~ +varchar +[0.60009766,0.7998047] +~~END~~ + + +SELECT l2_normalize(CAST('[3,0]' as halfvec)); +go +~~START~~ +varchar +[1,0] +~~END~~ + + +SELECT l2_normalize(CAST('[0,0.1]' as halfvec)); +go +~~START~~ +varchar +[0,1] +~~END~~ + + +SELECT l2_normalize(CAST('[0,0]' as halfvec)); +go +~~START~~ +varchar +[0,0] +~~END~~ + + +SELECT l2_normalize(CAST('[65504]' as halfvec)); +go +~~START~~ +varchar +[1] +~~END~~ + + +SELECT binary_quantize(CAST('[1,0,-1]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data type bit is not supported yet)~~ + + +SELECT binary_quantize(CAST('[0,0.1,-0.2,-0.3,0.4,0.5,0.6,-0.7,0.8,-0.9,1]' as halfvec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data type bit is not supported yet)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 3); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2); +go +~~START~~ +varchar +[3,4] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 3); +go +~~START~~ +varchar +[1] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 9); +go +~~START~~ +varchar +[3,4,5] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 0); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, -1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 2); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 2147483647, 10); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: halfvec must have at least 1 dimension)~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2147483647); +go +~~START~~ +varchar +[3,4,5] +~~END~~ + + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -2147483644, 2147483647); +go +~~START~~ +varchar +[1,2] +~~END~~ + + +SELECT halfvec_avg(array_agg(CAST(n as halfvec))) FROM generate_series(1, 16002) n; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: cannot cast type integer to halfvec)~~ + + +-- hnsw_halfvec +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l2_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM halfvec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM halfvec_table +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=0 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_ip_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <#> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_cosine_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=3 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec) NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- L1 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l1_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <+> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <+> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_l2_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM halfvec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM halfvec_table +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=0 loops=1) + Order By: (val <-> '[3,3,3]'::halfvec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_ip_ops) WITH (lists = 1) WITH (lists = 1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'lists' at line 1 and character position 92)~~ + + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] + +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=5 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Sort (actual rows=5 loops=1) + Sort Key: ((val <#> '[3,3,3]'::halfvec)) + Worker 0: Sort Method: quicksort Memory: 25kB + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Sort (actual rows=5 loops=1) + Sort Key: ((halfvec_table.val <#> $0)) + Sort Method: quicksort Memory: 25kB + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Seq Scan on halfvec_table (actual rows=5 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_cosine_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec) NULLS LAST +Gather (actual rows=3 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec) NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::halfvec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxhalfvec_table7f9bec28bc8902d45d905788d7aa59a1 on halfvec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go +~~START~~ +text +on +~~END~~ + + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'halfvec'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure halfvec_proc_1 @a halfvec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'halfvec_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#halfvec_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#halfvec_proc_1;1#!#@a#!#1#!##!#halfvec#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#halfvec_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure halfvec_proc_1; +go + +create table t(a halfvec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +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 +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#halfvec#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding halfvec(4) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: operator class "vector_l2_ops" does not accept data type halfvec)~~ + +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('[21,-2,0,2.5]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('[5, 10000, -9.75, 8]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('[-0.02,23,3.14,00]' as halfvec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-65519' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('[',a, ',', b, ',', c, ',', d, ']') as halfvec) FROM cte; +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +SELECT * FROM document_embeddings; +go +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +~~END~~ + +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '[3,1,2,4]'; +go +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +3#!#[-0.020004272,23,3.140625,0] +2#!#[5,10000,-9.75,8] +4#!#[200,80,-65504,-1] +~~END~~ + +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <=> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <#> '[3,1,2,0]') FROM document_embeddings; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '[3,20, 1,-2.5]' < 5; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +~~END~~ + +~~START~~ +int#!#varchar +1#!#[21,-2,0,2.5] +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +~~END~~ + + +SELECT AVG(embedding) FROM document_embeddings; +go +~~START~~ +varchar +[56.5,2526,-16376,2.375] +~~END~~ + + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go +~~START~~ +int#!#varchar +2#!#[5,10000,-9.75,8] +3#!#[-0.020004272,23,3.140625,0] +4#!#[200,80,-65504,-1] +1#!#[21,-2,0,2.5] +~~END~~ + + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/parallel_query/TestSparsevecDatatype.out b/test/JDBC/expected/parallel_query/TestSparsevecDatatype.out new file mode 100644 index 00000000000..b4e480d7a3f --- /dev/null +++ b/test/JDBC/expected/parallel_query/TestSparsevecDatatype.out @@ -0,0 +1,1611 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +SELECT CAST('{1:1.5,3:3.5}/5' as sparsevec); +go +~~START~~ +varchar +{1:1.5,3:3.5}/5 +~~END~~ + + +SELECT CAST('{1:-2,3:-4}/5' as sparsevec); +go +~~START~~ +varchar +{1:-2,3:-4}/5 +~~END~~ + + +SELECT CAST('{1:2.,3:4.}/5' as sparsevec); +go +~~START~~ +varchar +{1:2,3:4}/5 +~~END~~ + + +SELECT CAST(' { 1 : 1.5 , 3 : 3.5 } / 5 ' as sparsevec); +go +~~START~~ +varchar +{1:1.5,3:3.5}/5 +~~END~~ + + +SELECT CAST('{1:1.23456}/1' as sparsevec); +go +~~START~~ +varchar +{1:1.23456}/1 +~~END~~ + + +SELECT CAST('{1:hello,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:hello,2:1}/2")~~ + + +SELECT CAST('{1:NaN,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in sparsevec)~~ + + +SELECT CAST('{1:Infinity,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in sparsevec)~~ + + +SELECT CAST('{1:-Infinity,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in sparsevec)~~ + + +SELECT CAST('{1:1.5e38,2:-1.5e38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e+38,2:-1.5e+38}/2 +~~END~~ + + +SELECT CAST('{1:1.5e+38,2:-1.5e+38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e+38,2:-1.5e+38}/2 +~~END~~ + + +SELECT CAST('{1:1.5e-38,2:-1.5e-38}/2' as sparsevec); +go +~~START~~ +varchar +{1:1.5e-38,2:-1.5e-38}/2 +~~END~~ + + +SELECT CAST('{1:4e38,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "4e38" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:-4e38,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "-4e38" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:1e-46,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "1e-46" is out of range for type sparsevec)~~ + + +SELECT CAST('{1:-1e-46,2:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: "-1e-46" is out of range for type sparsevec)~~ + + +SELECT CAST('' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "")~~ + + +SELECT CAST('{' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{")~~ + + +SELECT CAST('{ ' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{ ")~~ + + +SELECT CAST('{:' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:")~~ + + +SELECT CAST('{,' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{,")~~ + + +SELECT CAST('{}' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{}")~~ + + +SELECT CAST('{}/'' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ''{}/'' at line 1 and character position 12)~~ + + +SELECT CAST('{}/1' as sparsevec); +go +~~START~~ +varchar +{}/1 +~~END~~ + + +SELECT CAST('{}/1a' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{}/1a")~~ + + +SELECT CAST('{ }/1' as sparsevec); +go +~~START~~ +varchar +{}/1 +~~END~~ + + +SELECT CAST('{:}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:}/1")~~ + + +SELECT CAST('{,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{,}/1")~~ + + +SELECT CAST('{1,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1,}/1")~~ + + +SELECT CAST('{:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{:1}/1")~~ + + +SELECT CAST('{1:}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:}/1")~~ + + +SELECT CAST('{1a:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1a:1}/1")~~ + + +SELECT CAST('{1:1a}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:1a}/1")~~ + + +SELECT CAST('{1:1,}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type sparsevec: "{1:1,}/1")~~ + + +SELECT CAST('{1:0,2:1,3:0}/3' as sparsevec); +go +~~START~~ +varchar +{2:1}/3 +~~END~~ + + +SELECT CAST('{2:1,1:1}/2' as sparsevec); +go +~~START~~ +varchar +{1:1,2:1}/2 +~~END~~ + + +SELECT CAST('{1:1,1:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec indices must not contain duplicates)~~ + + +SELECT CAST('{1:1,2:1,1:1}/2' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec indices must not contain duplicates)~~ + + +SELECT CAST('{}/5' as sparsevec); +go +~~START~~ +varchar +{}/5 +~~END~~ + + +SELECT CAST('{}/-1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{}/1000000001' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/2147483648' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/-2147483649' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{}/9223372036854775808' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec cannot have more than 1000000000 dimensions)~~ + + +SELECT CAST('{}/-9223372036854775809' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec must have at least 1 dimension)~~ + + +SELECT CAST('{2147483647:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{2147483648:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{-2147483648:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{-2147483649:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{0:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{2:1}/1' as sparsevec); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sparsevec index out of bounds)~~ + + +SELECT CAST('{}/3' as sparsevec(3)); +go +~~START~~ +varchar +{}/3 +~~END~~ + + +SELECT CAST('{}/3' as sparsevec(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +SELECT CAST('{}/3' as sparsevec(3, 2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid type modifier)~~ + + +SELECT CAST('{}/3' as sparsevec('a')); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 31)~~ + + +SELECT CAST('{}/3' as sparsevec(0)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type sparsevec must be at least 1)~~ + + +SELECT CAST('{}/3' as sparsevec(1000000001)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: dimensions for type sparsevec cannot exceed 1000000000)~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +0 +~~END~~ + + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +0 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{}/3' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2}/2' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:3,3:4}/3' as sparsevec)); +go +~~START~~ +int +-1 +~~END~~ + + +SELECT sparsevec_cmp(CAST('{1:2,2:3}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go +~~START~~ +int +1 +~~END~~ + + +SELECT ROUND(l2_norm(CAST('{1:1,2:1}/2' as sparsevec)), 5); +go +~~START~~ +numeric +1.41421 +~~END~~ + + +SELECT l2_norm(CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_norm(CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_norm(CAST('{1:3e37,2:4e37}/2' as sparsevec)); +go +~~START~~ +float +5.000000042966943E37 +~~END~~ + + +SELECT l2_norm(CAST('{}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l2_norm(CAST('{1:2}/1' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{1:3}/2' as sparsevec), CAST('{2:4}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{2:4}/2' as sparsevec), CAST('{1:3}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{1:3,2:4}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT CAST('{}/2' as sparsevec) <-> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go +~~START~~ +float +10.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT inner_product(CAST('{1:1,3:3}/4' as sparsevec), CAST('{2:2,4:4}/4' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{2:2,4:4}/4' as sparsevec), CAST('{1:1,3:3}/4' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go +~~START~~ +float +18.0 +~~END~~ + + +SELECT inner_product(CAST('{1:1}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{}/2' as sparsevec), CAST('{1:1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT inner_product(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go +~~START~~ +float +18.0 +~~END~~ + + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <#> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +-11.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1,2:1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1,2:-1}/2' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:2}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{2:2}/2' as sparsevec), CAST('{1:2}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1.1,2:1.1}/2' as sparsevec)); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1.1,2:-1.1}/2' as sparsevec)); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance(CAST('{}/1' as sparsevec), CAST('{}/1' as sparsevec)); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <=> CAST('{1:2,2:4}/2' as sparsevec); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different sparsevec dimensions 2 and 1)~~ + + +SELECT l1_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:-3e38}/1' as sparsevec)); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7}/8' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/8' as sparsevec)); +go +~~START~~ +float +36.0 +~~END~~ + + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7,9:9}/9' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/9' as sparsevec)); +go +~~START~~ +float +45.0 +~~END~~ + + +SELECT CAST('{}/2' as sparsevec) <+> CAST('{1:3,2:4}/2' as sparsevec); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3,2:4}/2' as sparsevec)); +go +~~START~~ +varchar +{1:0.6,2:0.8}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3}/2' as sparsevec)); +go +~~START~~ +varchar +{1:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{2:0.1}/2' as sparsevec)); +go +~~START~~ +varchar +{2:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{}/2' as sparsevec)); +go +~~START~~ +varchar +{}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3e38}/1' as sparsevec)); +go +~~START~~ +varchar +{1:1}/1 +~~END~~ + + +SELECT l2_normalize(CAST('{1:3e38,2:1e-37}/2' as sparsevec)); +go +~~START~~ +varchar +{1:1}/2 +~~END~~ + + +SELECT l2_normalize(CAST('{2:3e37,4:3e-37,6:4e37,8:4e-37}/9' as sparsevec)); +go +~~START~~ +varchar +{2:0.6,6:0.8}/9 +~~END~~ + + + +-- L2 +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <-> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SELECT COUNT(*) FROM sparsevec_table; +go +~~START~~ +int +5 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM sparsevec_table +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Seq Scan on sparsevec_table (actual rows=5 loops=1) +~~END~~ + + +TRUNCATE TABLE sparsevec_table; +go + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=0 loops=1) + Order By: (val <-> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- inner product +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_ip_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:4}/3 +{1:1,2:2,3:3}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <#> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- cosine +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_cosine_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:1,3:1}/3 +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Gather (actual rows=3 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec)) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec) NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> '{}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- L1 +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l1_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go +~~START~~ +varchar +{1:1,2:2,3:3}/3 +{1:1,2:2,3:4}/3 +{1:1,2:1,3:1}/3 +{}/3 +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec) NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <+> '{1:3,2:3,3:3}/3'::sparsevec) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxsparsevec_table7f9bec28bc8902d45d905788d7aa59a1 on sparsevec_table (actual rows=4 loops=1) + Order By: (val <+> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go +~~START~~ +text +on +~~END~~ + + + +-- non-zero elements +CREATE TABLE sparsevec_table (val sparsevec(1001)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST(array_fill(1, ARRAY[1001]) AS sparsevec)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '(' at line 1 and character position 46)~~ + + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +TRUNCATE TABLE sparsevec_table; +go + +DROP TABLE sparsevec_table; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'sparsevec'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure sparsevec_proc_1 @a sparsevec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'sparsevec_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@a#!#1#!##!#sparsevec#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#sparsevec_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure sparsevec_proc_1; +go + +create table t(a sparsevec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +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 +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#sparsevec#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding sparsevec(5) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: operator class "vector_l2_ops" does not accept data type sparsevec)~~ + +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('{1:5,2:1}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('{1:5, 2:10000, 3:-9.75, 4:8}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('{1:-0.02,2:23,4:3.14,5:00}/5' as sparsevec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-305' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('{1:',a, ',3:', b, ',4:', c, ',5:', d, '}/5') as sparsevec) FROM cte; +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +SELECT * FROM document_embeddings; +go +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +~~END~~ + +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '{1:1,2:2,3:4}/5'; +go +~~START~~ +int#!#varchar +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +1#!#{1:5,2:1}/5 +~~END~~ + +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <=> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <#> '{1:1,2:2,3:4}/5') FROM document_embeddings; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + +~~START~~ +int +4 +~~END~~ + + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '{1:1,2:2,4:4}/5' < 5; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +4#!#{1:200,3:80,4:-305,5:-1}/5 +~~END~~ + +~~START~~ +int#!#varchar +1#!#{1:5,2:1}/5 +2#!#{1:5,2:10000,3:-9.75,4:8}/5 +3#!#{1:-0.02,2:23,4:3.14}/5 +~~END~~ + + +SELECT AVG(embedding) FROM document_embeddings; +go +~~ERROR (Code: 206)~~ + +~~ERROR (Message: The function avg is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.)~~ + + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go +~~ERROR (Code: 206)~~ + +~~ERROR (Message: The function avg is found but cannot be used. Possibly due to datatype mismatch and implicit casting is not allowed.)~~ + + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/input/datatypes/TestHalfvecDatatype.mix b/test/JDBC/input/datatypes/TestHalfvecDatatype.mix new file mode 100644 index 00000000000..938ecf58f0c --- /dev/null +++ b/test/JDBC/input/datatypes/TestHalfvecDatatype.mix @@ -0,0 +1,683 @@ +-- parallel_query_expected +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go + +SELECT CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[-1,-2,-3]' as halfvec); +go + +SELECT CAST('[1.,2.,3.]' as halfvec); +go + +SELECT CAST(' [ 1, 2 , 3 ] ' as halfvec); +go + +SELECT CAST('[1.23456]' as halfvec); +go + +SELECT CAST('[hello,1]' as halfvec); +go + +SELECT CAST('[NaN,1]' as halfvec); +go + +SELECT CAST('[Infinity,1]' as halfvec); +go + +SELECT CAST('[-Infinity,1]' as halfvec); +go + +SELECT CAST('[65519,-65519]' as halfvec); +go + +SELECT CAST('[65520,-65520]' as halfvec); +go + +SELECT CAST('[1e-8,-1e-8]' as halfvec); +go + +SELECT CAST('[4e38,1]' as halfvec); +go + +SELECT CAST('[1e-46,1]' as halfvec); +go + +SELECT CAST('[1,2,3' as halfvec); +go + +SELECT CAST('[1,2,3]9' as halfvec); +go + +SELECT CAST('1,2,3' as halfvec); +go + +SELECT CAST('' as halfvec); +go + +SELECT CAST('[' as halfvec); +go + +SELECT CAST('[ ' as halfvec); +go + +SELECT CAST('[,' as halfvec); +go + +SELECT CAST('[]' as halfvec); +go + +SELECT CAST('[ ]' as halfvec); +go + +SELECT CAST('[,]' as halfvec); +go + +SELECT CAST('[1,]' as halfvec); +go + +SELECT CAST('[1a]' as halfvec); +go + +SELECT CAST('[1,,3]' as halfvec); +go + +SELECT CAST('[1, ,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec(3)); +go + +SELECT CAST('[1,2,3]' as halfvec(2)); +go + +SELECT CAST('[1,2,3]' as halfvec(3, 2)); +go + +SELECT CAST('[1,2,3]' as halfvec('a')); +go + +SELECT CAST('[1,2,3]' as halfvec(0)); +go + +SELECT CAST('[1,2,3]' as halfvec(16001)); +go + +SELECT CAST('{"[1,2,3]"}' as halfvec(2)[]); +go + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5,6]' as halfvec); +go + +SELECT CAST('[65519]' as halfvec) + CAST('[65519]' as halfvec); +go + +SELECT CAST('[1,2]' as halfvec) + CAST('[3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) - CAST('[4,5,6]' as halfvec); +go + +SELECT CAST('[-65519]' as halfvec) - CAST('[65519]' as halfvec); +go + +SELECT CAST('[1,2]' as halfvec) - CAST('[3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) * CAST('[4,5,6]' as halfvec); +go + +SELECT CAST('[65519]' as halfvec) * CAST('[65519]' as halfvec); +go + +SELECT CAST('[1e-7]' as halfvec) * CAST('[1e-7]' as halfvec); +go + +SELECT CAST('[1,2]' as halfvec) * CAST('[3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) + CAST('[4,5]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) < CAST('[1,2]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) <= CAST('[1,2]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) = CAST('[1,2]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) != CAST('[1,2]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) >= CAST('[1,2]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2,3]' as halfvec); +go + +SELECT CAST('[1,2,3]' as halfvec) > CAST('[1,2]' as halfvec); +go + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[0,0,0]' as halfvec)); +go + +SELECT halfvec_cmp(CAST('[0,0,0]' as halfvec), CAST('[1,2,3]' as halfvec)); +go + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[1,2,3]' as halfvec)); +go + +SELECT halfvec_cmp(CAST('[1,2,3]' as halfvec), CAST('[1,2]' as halfvec)); +go + +SELECT halfvec_cmp(CAST('[1,2]' as halfvec), CAST('[2,3,4]' as halfvec)); +go + +SELECT halfvec_cmp(CAST('[2,3]' as halfvec), CAST('[1,2,3]' as halfvec)); +go + +SELECT vector_dims(CAST('[1,2,3]' as halfvec)); +go + +SELECT ROUND(CAST(l2_norm(CAST('[1,1]' as halfvec)) as numeric), 5); +go + +SELECT l2_norm(CAST('[3,4]' as halfvec)); +go + +SELECT l2_norm(CAST('[0,1]' as halfvec)); +go + +SELECT l2_norm(CAST('[0,0]' as halfvec)); +go + +SELECT l2_norm(CAST('[2]' as halfvec)); +go + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go + +SELECT l2_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go + +SELECT l2_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go + +SELECT l2_distance(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,1,1,1,1,1,1,4,5]' as halfvec)); +go + +SELECT CAST('[0,0]' as halfvec) <-> CAST('[3,4]' as halfvec); +go + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3,4]' as halfvec)); +go + +SELECT inner_product(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go + +SELECT inner_product(CAST('[65504]' as halfvec), CAST('[65504]' as halfvec)); +go + +SELECT inner_product(CAST('[1,1,1,1,1,1,1,1,1]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go + +SELECT CAST('[1,2]' as halfvec) <#> CAST('[3,4]' as halfvec); +go + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[2,4]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[0,0]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1,1]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,0]' as halfvec), CAST('[0,2]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1,-1]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[1.1,1.1]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,1]' as halfvec), CAST('[-1.1,-1.1]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go + +SELECT cosine_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[-1,-2,-3,-4,-5,-6,-7,-8,-9]' as halfvec)); +go + +SELECT CAST('[1,2]' as halfvec) <=> CAST('[2,4]' as halfvec); +go + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[3,4]' as halfvec)); +go + +SELECT l1_distance(CAST('[0,0]' as halfvec), CAST('[0,1]' as halfvec)); +go + +SELECT l1_distance(CAST('[1,2]' as halfvec), CAST('[3]' as halfvec)); +go + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[1,2,3,4,5,6,7,8,9]' as halfvec)); +go + +SELECT l1_distance(CAST('[1,2,3,4,5,6,7,8,9]' as halfvec), CAST('[0,3,2,5,4,7,6,9,8]' as halfvec)); +go + +SELECT CAST('[0,0]' as halfvec) <+> CAST('[3,4]' as halfvec); +go + +SELECT l2_normalize(CAST('[3,4]' as halfvec)); +go + +SELECT l2_normalize(CAST('[3,0]' as halfvec)); +go + +SELECT l2_normalize(CAST('[0,0.1]' as halfvec)); +go + +SELECT l2_normalize(CAST('[0,0]' as halfvec)); +go + +SELECT l2_normalize(CAST('[65504]' as halfvec)); +go + +SELECT binary_quantize(CAST('[1,0,-1]' as halfvec)); +go + +SELECT binary_quantize(CAST('[0,0.1,-0.2,-0.3,0.4,0.5,0.6,-0.7,0.8,-0.9,1]' as halfvec)); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 3); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 3); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 9); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 1, 0); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, -1); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -1, 2); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 2147483647, 10); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), 3, 2147483647); +go + +SELECT subvector(CAST('[1,2,3,4,5]' as halfvec), -2147483644, 2147483647); +go + +SELECT halfvec_avg(array_agg(CAST(n as halfvec))) FROM generate_series(1, 16002) n; +go + +-- hnsw_halfvec +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l2_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go + +SELECT COUNT(*) FROM halfvec_table; +go + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +-- inner product + +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_ip_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +-- cosine + +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_cosine_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +-- L1 + +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING hnsw (val halfvec_l1_ops); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <+> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <+> (SELECT CAST(NULL as halfvec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +-- ivfflat +-- l2 +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_l2_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <-> (SELECT CAST(NULL as halfvec))) t2; +go + +SELECT COUNT(*) FROM halfvec_table; +go + +TRUNCATE TABLE halfvec_table; +go + +SELECT * FROM halfvec_table ORDER BY val <-> CAST('[3,3,3]' AS halfvec); +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +-- inner product + +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_ip_ops) WITH (lists = 1) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <#> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <#> (SELECT CAST(NULL as halfvec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +-- cosine + +CREATE TABLE halfvec_table (val halfvec(3)); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[0,0,0]' AS halfvec)), (CAST('[1,2,3]' AS halfvec)), (CAST('[1,1,1]' AS halfvec)), (NULL); +go + +CREATE INDEX idx ON halfvec_table USING ivfflat (val halfvec_cosine_ops) WITH (lists = 1); +go + +INSERT INTO halfvec_table (val) VALUES (CAST('[1,2,4]' AS halfvec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM halfvec_table ORDER BY val <=> CAST('[3,3,3]' AS halfvec); +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> CAST('[0,0,0]' AS halfvec)) t2; +go + +SELECT COUNT(*) FROM (SELECT * FROM halfvec_table ORDER BY val <=> (SELECT CAST(NULL as halfvec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE halfvec_table; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'halfvec'; +go + +create procedure halfvec_proc_1 @a halfvec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'halfvec_proc_1' +go + +drop procedure halfvec_proc_1; +go + +create table t(a halfvec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +go +select count(*) from sys.columns where object_id = sys.object_id('t') +go +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding halfvec(4) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('[21,-2,0,2.5]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('[5, 10000, -9.75, 8]' as halfvec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('[-0.02,23,3.14,00]' as halfvec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-65519' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('[',a, ',', b, ',', c, ',', d, ']') as halfvec) FROM cte; +go +SELECT * FROM document_embeddings; +go +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '[3,1,2,4]'; +go +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <=> '[3,1,2,0]') FROM document_embeddings; +SELECT count(embedding <#> '[3,1,2,0]') FROM document_embeddings; +go + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '[3,20, 1,-2.5]' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '[3,20, 1,-2.5]' < 5; +go + +SELECT AVG(embedding) FROM document_embeddings; +go + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go \ No newline at end of file diff --git a/test/JDBC/input/datatypes/TestSparsevecDatatype.mix b/test/JDBC/input/datatypes/TestSparsevecDatatype.mix new file mode 100644 index 00000000000..af1238e9df0 --- /dev/null +++ b/test/JDBC/input/datatypes/TestSparsevecDatatype.mix @@ -0,0 +1,634 @@ +-- parallel_query_expected +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go + +SELECT CAST('{1:1.5,3:3.5}/5' as sparsevec); +go + +SELECT CAST('{1:-2,3:-4}/5' as sparsevec); +go + +SELECT CAST('{1:2.,3:4.}/5' as sparsevec); +go + +SELECT CAST(' { 1 : 1.5 , 3 : 3.5 } / 5 ' as sparsevec); +go + +SELECT CAST('{1:1.23456}/1' as sparsevec); +go + +SELECT CAST('{1:hello,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:NaN,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:Infinity,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:-Infinity,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:1.5e38,2:-1.5e38}/2' as sparsevec); +go + +SELECT CAST('{1:1.5e+38,2:-1.5e+38}/2' as sparsevec); +go + +SELECT CAST('{1:1.5e-38,2:-1.5e-38}/2' as sparsevec); +go + +SELECT CAST('{1:4e38,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:-4e38,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:1e-46,2:1}/2' as sparsevec); +go + +SELECT CAST('{1:-1e-46,2:1}/2' as sparsevec); +go + +SELECT CAST('' as sparsevec); +go + +SELECT CAST('{' as sparsevec); +go + +SELECT CAST('{ ' as sparsevec); +go + +SELECT CAST('{:' as sparsevec); +go + +SELECT CAST('{,' as sparsevec); +go + +SELECT CAST('{}' as sparsevec); +go + +SELECT CAST('{}/'' as sparsevec); +go + +SELECT CAST('{}/1' as sparsevec); +go + +SELECT CAST('{}/1a' as sparsevec); +go + +SELECT CAST('{ }/1' as sparsevec); +go + +SELECT CAST('{:}/1' as sparsevec); +go + +SELECT CAST('{,}/1' as sparsevec); +go + +SELECT CAST('{1,}/1' as sparsevec); +go + +SELECT CAST('{:1}/1' as sparsevec); +go + +SELECT CAST('{1:}/1' as sparsevec); +go + +SELECT CAST('{1a:1}/1' as sparsevec); +go + +SELECT CAST('{1:1a}/1' as sparsevec); +go + +SELECT CAST('{1:1,}/1' as sparsevec); +go + +SELECT CAST('{1:0,2:1,3:0}/3' as sparsevec); +go + +SELECT CAST('{2:1,1:1}/2' as sparsevec); +go + +SELECT CAST('{1:1,1:1}/2' as sparsevec); +go + +SELECT CAST('{1:1,2:1,1:1}/2' as sparsevec); +go + +SELECT CAST('{}/5' as sparsevec); +go + +SELECT CAST('{}/-1' as sparsevec); +go + +SELECT CAST('{}/1000000001' as sparsevec); +go + +SELECT CAST('{}/2147483648' as sparsevec); +go + +SELECT CAST('{}/-2147483649' as sparsevec); +go + +SELECT CAST('{}/9223372036854775808' as sparsevec); +go + +SELECT CAST('{}/-9223372036854775809' as sparsevec); +go + +SELECT CAST('{2147483647:1}/1' as sparsevec); +go + +SELECT CAST('{2147483648:1}/1' as sparsevec); +go + +SELECT CAST('{-2147483648:1}/1' as sparsevec); +go + +SELECT CAST('{-2147483649:1}/1' as sparsevec); +go + +SELECT CAST('{0:1}/1' as sparsevec); +go + +SELECT CAST('{2:1}/1' as sparsevec); +go + +SELECT CAST('{}/3' as sparsevec(3)); +go + +SELECT CAST('{}/3' as sparsevec(2)); +go + +SELECT CAST('{}/3' as sparsevec(3, 2)); +go + +SELECT CAST('{}/3' as sparsevec('a')); +go + +SELECT CAST('{}/3' as sparsevec(0)); +go + +SELECT CAST('{}/3' as sparsevec(1000000001)); +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) < CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) <= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) = CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) != CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) >= CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2,3:3}/3' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT CASE WHEN CAST('{1:1,2:2,3:3}/3' as sparsevec) > CAST('{1:1,2:2}/2' as sparsevec) THEN 1 ELSE 0 END; +go + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{}/3' as sparsevec)); +go + +SELECT sparsevec_cmp(CAST('{}/3' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go + +SELECT sparsevec_cmp(CAST('{1:1,2:2,3:3}/3' as sparsevec), CAST('{1:1,2:2}/2' as sparsevec)); +go + +SELECT sparsevec_cmp(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:3,3:4}/3' as sparsevec)); +go + +SELECT sparsevec_cmp(CAST('{1:2,2:3}/2' as sparsevec), CAST('{1:1,2:2,3:3}/3' as sparsevec)); +go + +SELECT ROUND(l2_norm(CAST('{1:1,2:1}/2' as sparsevec)), 5); +go + +SELECT l2_norm(CAST('{1:3,2:4}/2' as sparsevec)); +go + +SELECT l2_norm(CAST('{2:1}/2' as sparsevec)); +go + +SELECT l2_norm(CAST('{1:3e37,2:4e37}/2' as sparsevec)); +go + +SELECT l2_norm(CAST('{}/2' as sparsevec)); +go + +SELECT l2_norm(CAST('{1:2}/1' as sparsevec)); +go + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go + +SELECT l2_distance(CAST('{1:3}/2' as sparsevec), CAST('{2:4}/2' as sparsevec)); +go + +SELECT l2_distance(CAST('{2:4}/2' as sparsevec), CAST('{1:3}/2' as sparsevec)); +go + +SELECT l2_distance(CAST('{1:3,2:4}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go + +SELECT l2_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go + +SELECT CAST('{}/2' as sparsevec) <-> CAST('{1:3,2:4}/2' as sparsevec); +go + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go + +SELECT inner_product(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go + +SELECT inner_product(CAST('{1:1,3:3}/4' as sparsevec), CAST('{2:2,4:4}/4' as sparsevec)); +go + +SELECT inner_product(CAST('{2:2,4:4}/4' as sparsevec), CAST('{1:1,3:3}/4' as sparsevec)); +go + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go + +SELECT inner_product(CAST('{1:1}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go + +SELECT inner_product(CAST('{}/2' as sparsevec), CAST('{1:1}/2' as sparsevec)); +go + +SELECT inner_product(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go + +SELECT inner_product(CAST('{1:1,3:3,5:5}/5' as sparsevec), CAST('{2:4,3:6,4:8}/5' as sparsevec)); +go + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <#> CAST('{1:3,2:4}/2' as sparsevec); +go + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:2,2:4}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1,2:1}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1,2:-1}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:2}/2' as sparsevec), CAST('{2:2}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{2:2}/2' as sparsevec), CAST('{1:2}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:1.1,2:1.1}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:1,2:1}/2' as sparsevec), CAST('{1:-1.1,2:-1.1}/2' as sparsevec)); +go + +SELECT cosine_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:3e38}/1' as sparsevec)); +go + +SELECT cosine_distance(CAST('{}/1' as sparsevec), CAST('{}/1' as sparsevec)); +go + +SELECT CAST('{1:1,2:2}/2' as sparsevec) <=> CAST('{1:2,2:4}/2' as sparsevec); +go + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{1:3,2:4}/2' as sparsevec)); +go + +SELECT l1_distance(CAST('{}/2' as sparsevec), CAST('{2:1}/2' as sparsevec)); +go + +SELECT l1_distance(CAST('{1:1,2:2}/2' as sparsevec), CAST('{1:3}/1' as sparsevec)); +go + +SELECT l1_distance(CAST('{1:3e38}/1' as sparsevec), CAST('{1:-3e38}/1' as sparsevec)); +go + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7}/8' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/8' as sparsevec)); +go + +SELECT l1_distance(CAST('{1:1,3:3,5:5,7:7,9:9}/9' as sparsevec), CAST('{2:2,4:4,6:6,8:8}/9' as sparsevec)); +go + +SELECT CAST('{}/2' as sparsevec) <+> CAST('{1:3,2:4}/2' as sparsevec); +go + +SELECT l2_normalize(CAST('{1:3,2:4}/2' as sparsevec)); +go + +SELECT l2_normalize(CAST('{1:3}/2' as sparsevec)); +go + +SELECT l2_normalize(CAST('{2:0.1}/2' as sparsevec)); +go + +SELECT l2_normalize(CAST('{}/2' as sparsevec)); +go + +SELECT l2_normalize(CAST('{1:3e38}/1' as sparsevec)); +go + +SELECT l2_normalize(CAST('{1:3e38,2:1e-37}/2' as sparsevec)); +go + +SELECT l2_normalize(CAST('{2:3e37,4:3e-37,6:4e37,8:4e-37}/9' as sparsevec)); +go + +-- L2 + +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <-> (SELECT CAST(NULL as sparsevec))) t2; +go + +SELECT COUNT(*) FROM sparsevec_table; +go + +TRUNCATE TABLE sparsevec_table; +go + +SELECT * FROM sparsevec_table ORDER BY val <-> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go + +-- inner product + +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_ip_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM sparsevec_table ORDER BY val <#> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <#> (SELECT CAST(NULL as sparsevec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go + +-- cosine + +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_cosine_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> CAST('{}/3' AS sparsevec)) t2; +go + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <=> (SELECT CAST(NULL as sparsevec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go + +-- L1 + +CREATE TABLE sparsevec_table (val sparsevec(3)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{}/3' AS sparsevec)), (CAST('{1:1,2:2,3:3}/3' AS sparsevec)), (CAST('{1:1,2:1,3:1}/3' AS sparsevec)), (NULL); +go + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l1_ops); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST('{1:1,2:2,3:4}/3' AS sparsevec)); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM sparsevec_table ORDER BY val <+> CAST('{1:3,2:3,3:3}/3' AS sparsevec); +go + +SELECT COUNT(*) FROM (SELECT * FROM sparsevec_table ORDER BY val <+> (SELECT CAST(NULL as sparsevec))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE sparsevec_table; +go + +-- non-zero elements + +CREATE TABLE sparsevec_table (val sparsevec(1001)); +go + +INSERT INTO sparsevec_table (val) VALUES (CAST(array_fill(1, ARRAY[1001]) AS sparsevec)); +go + +CREATE INDEX idx ON sparsevec_table USING hnsw (val sparsevec_l2_ops); +go + +TRUNCATE TABLE sparsevec_table; +go + +DROP TABLE sparsevec_table; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'sparsevec'; +go + +create procedure sparsevec_proc_1 @a sparsevec, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'sparsevec_proc_1' +go + +drop procedure sparsevec_proc_1; +go + +create table t(a sparsevec(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +go +select count(*) from sys.columns where object_id = sys.object_id('t') +go +drop table t; +go + +-- Testing with different typmod +CREATE TABLE document_embeddings ( + id int PRIMARY KEY, + embedding sparsevec(5) NOT NULL +); +go +CREATE INDEX document_embeddings_embedding_idx ON document_embeddings USING hnsw (embedding vector_l2_ops); +go +INSERT INTO document_embeddings(id, embedding) VALUES(1, CAST('{1:5,2:1}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(2, CAST('{1:5, 2:10000, 3:-9.75, 4:8}/5' as sparsevec)); +INSERT INTO document_embeddings(id, embedding) VALUES(3, CAST('{1:-0.02,2:23,4:3.14,5:00}/5' as sparsevec)); +WITH cte AS ( + SELECT CAST(2e2 AS real) a, 80 b, CAST('-305' AS real) c, -1 d +) +INSERT INTO document_embeddings(id, embedding) SELECT 4, CAST(CONCAT('{1:',a, ',3:', b, ',4:', c, ',5:', d, '}/5') as sparsevec) FROM cte; +go +SELECT * FROM document_embeddings; +go +SELECT TOP 5 * FROM document_embeddings ORDER BY embedding <=> '{1:1,2:2,3:4}/5'; +go +-- extending PG syntax to have generic vector expression support +SELECT count(embedding <-> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <=> '{1:1,2:2,3:4}/5') FROM document_embeddings; +SELECT count(embedding <#> '{1:1,2:2,3:4}/5') FROM document_embeddings; +go + +-- WHERE clause expressions +SELECT * FROM document_embeddings WHERE embedding <-> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <=> '{1:1,2:2,4:4}/5' < 5; +SELECT * FROM document_embeddings WHERE embedding <#> '{1:1,2:2,4:4}/5' < 5; +go + +SELECT AVG(embedding) FROM document_embeddings; +go + +SELECT id, AVG(embedding) FROM document_embeddings GROUP BY id; +go + +Drop table document_embeddings +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) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go \ No newline at end of file From f9f908828c6b618da6b461b7d3c453bf76a40fd3 Mon Sep 17 00:00:00 2001 From: Rohit bhagat <65351720+rohit01010@users.noreply.github.com> Date: Fri, 26 Jul 2024 08:58:30 +0530 Subject: [PATCH 14/15] Added support for WITHIN GROUP clause for STRING_AGG (#2767) Currently we do not support WITHIN GROUP clause for STRING_AGG function. This PR adds the support for WITHIN GROUP clause for STRING_AGG function with the following syntax: STRING_AGG (expression, separator) WITHIN GROUP (ORDER BY [ ASC | DESC ]) This support is added by rewriting the above query as following PostgreSQL compatible query in ANTLR Parser STRING_AGG (expression, separator ORDER BY [ ASC | DESC ]) This query rewriting is skipped when parsing Function/Procedure/Trigger 's body during creation of Function/Procedure/Trigger since body of these object is stored with language as 'pltsql'. Although the query rewriting will occur during it's execution. Task: BABEL-1878 Signed-off-by: Rohit Bhagat --- contrib/babelfishpg_tsql/src/tsqlIface.cpp | 57 ++ .../string_agg-vu-verify.out | 696 ++++++++++++++++++ .../japanese_ci_as/string_agg-vu-verify.out | 696 ++++++++++++++++++ test/JDBC/expected/string_agg-vu-cleanup.out | 44 ++ test/JDBC/expected/string_agg-vu-prepare.out | 133 ++++ test/JDBC/expected/string_agg-vu-verify.out | 696 ++++++++++++++++++ .../input/functions/string_agg-vu-cleanup.sql | 44 ++ .../input/functions/string_agg-vu-prepare.sql | 123 ++++ .../input/functions/string_agg-vu-verify.sql | 238 ++++++ test/JDBC/upgrade/latest/schedule | 1 + 10 files changed, 2728 insertions(+) create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/string_agg-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/string_agg-vu-verify.out create mode 100644 test/JDBC/expected/string_agg-vu-cleanup.out create mode 100644 test/JDBC/expected/string_agg-vu-prepare.out create mode 100644 test/JDBC/expected/string_agg-vu-verify.out create mode 100644 test/JDBC/input/functions/string_agg-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_agg-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_agg-vu-verify.sql diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index 2eeea8071c3..ecdb3c5e49d 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -213,6 +213,7 @@ 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); +static void rewrite_string_agg_query(TSqlParser::STRING_AGGContext *ctx); static bool setSysSchema = false; static void rewrite_function_trim_to_sys_trim(TSqlParser::TRIMContext *ctx); @@ -843,6 +844,8 @@ class tsqlCommonMutator : public TSqlParserBaseListener public: explicit tsqlCommonMutator() = default; bool in_create_or_alter_function = false; + bool in_create_or_alter_procedure = false; + bool in_create_or_alter_trigger = false; void enterCreate_or_alter_function(TSqlParser::Create_or_alter_functionContext *ctx) override { in_create_or_alter_function = true; @@ -852,6 +855,22 @@ class tsqlCommonMutator : public TSqlParserBaseListener in_create_or_alter_function = false; } + void enterCreate_or_alter_procedure(TSqlParser::Create_or_alter_procedureContext *ctx) override { + in_create_or_alter_procedure = true; + } + + void exitCreate_or_alter_procedure(TSqlParser::Create_or_alter_procedureContext *ctx) override { + in_create_or_alter_procedure = false; + } + + void enterCreate_or_alter_trigger(TSqlParser::Create_or_alter_triggerContext *ctx) override { + in_create_or_alter_trigger = true; + } + + void exitCreate_or_alter_trigger(TSqlParser::Create_or_alter_triggerContext *ctx) override { + in_create_or_alter_trigger = false; + } + void enterTransaction_statement(TSqlParser::Transaction_statementContext *ctx) override { if (in_create_or_alter_function && ctx->COMMIT()){ throw PGErrorWrapperException(ERROR, ERRCODE_FEATURE_NOT_SUPPORTED, "Invalid use of a side-effecting operator 'COMMIT TRANSACTION' within a function.", 0, 0); @@ -1202,6 +1221,19 @@ class tsqlCommonMutator : public TSqlParserBaseListener rewritten_query_fragment.emplace(std::make_pair(linked_srv->start->getStartIndex(), std::make_pair(linked_srv_name, str))); } } + + void exitSTRING_AGG(TSqlParser::STRING_AGGContext *ctx) override + { + /* + * For User Defined Function/Procedure/Trigger the language of the body of Function/Procedure/Trigger is set as 'pltsql' + * hence we cannot rewrite the STRING_AGG query into PG syntax during creation of this objects, + * hence skipped the rewriting of STRING_AGG query for Function/Procedure/Trigger. + * Also, Function's/Procedure's/Trigger's body gets compiled during its execution so the rewriting of + * STRING_AGG query will happen during execution. + */ + if (!(in_create_or_alter_function || in_create_or_alter_procedure || in_create_or_alter_trigger)) + rewrite_string_agg_query(ctx); + } }; //////////////////////////////////////////////////////////////////////////////// @@ -4871,6 +4903,9 @@ makeReturnQueryStmt(TSqlParser::Select_statement_standaloneContext *ctx, bool it result->lineno =getLineNo(ctx); auto *expr = makeTsqlExpr(ctx, false); + PLtsql_expr_query_mutator mutator(expr, ctx); + add_rewritten_query_fragment_to_mutator(&mutator); + mutator.run(); result->query = expr; if (itvf) { @@ -8272,6 +8307,28 @@ rewrite_column_name_with_omitted_schema_name(T ctx, GetCtxFunc getSchema, Get return ""; } +/* + * In this function we Rewrite the Query for STRING_AGG function as follows + * Query: STRING_AGG '(' expr=expression ',' separator=expression ')' WITHIN GROUP '(' order_by_clause ')' + * will be rewritten to + * Query: STRING_AGG '(' expr=expression ',' separator=expression order_by_clause ')' + */ +static void +rewrite_string_agg_query(TSqlParser::STRING_AGGContext *ctx) +{ + if (ctx->WITHIN() && ctx->order_by_clause()) + { + rewritten_query_fragment.emplace(std::make_pair(ctx->RR_BRACKET()[0]->getSymbol()->getStartIndex(), std::make_pair(::getFullText(ctx->RR_BRACKET()[0]), std::string(" ") + ::getFullText(ctx->order_by_clause()) + ::getFullText(ctx->RR_BRACKET()[0])))); + + /* remove block (WITHIN GROUP LR_BRACKET order_by_clause RR_BRACKET) */ + rewritten_query_fragment.emplace(std::make_pair(ctx->WITHIN()->getSymbol()->getStartIndex(), std::make_pair(::getFullText(ctx->WITHIN()), ""))); + rewritten_query_fragment.emplace(std::make_pair(ctx->GROUP()->getSymbol()->getStartIndex(), std::make_pair(::getFullText(ctx->GROUP()), ""))); + rewritten_query_fragment.emplace(std::make_pair(ctx->LR_BRACKET()[1]->getSymbol()->getStartIndex(), std::make_pair(::getFullText(ctx->LR_BRACKET()[1]), ""))); + rewritten_query_fragment.emplace(std::make_pair(ctx->order_by_clause()->start->getStartIndex(), std::make_pair(::getFullText(ctx->order_by_clause()), ""))); + rewritten_query_fragment.emplace(std::make_pair(ctx->RR_BRACKET()[1]->getSymbol()->getStartIndex(), std::make_pair(::getFullText(ctx->RR_BRACKET()[1]), ""))); + } +} + /* * In this function we Rewrite the Query for Trim function as follows * TRIM '(' expression from expression ')' -> sys.TRIM '(' expression , expression ')' diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/string_agg-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/string_agg-vu-verify.out new file mode 100644 index 00000000000..2cefc8d5fb7 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/string_agg-vu-verify.out @@ -0,0 +1,696 @@ +-- expression as column +SELECT STRING_AGG(a,'-') FROM string_agg_t +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +c-a-d-h +b-g-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-g-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-h-d +g-b-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-g-e +~~END~~ + + +-- expression as expression of multiple columns +SELECT STRING_AGG(a+b,'-') FROM string_agg_t +GO +~~START~~ +text +cx-by-gu-az-ev-dw-ht +~~END~~ + + +SELECT STRING_AGG(a+b,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cx-az-dw-ht +by-gu-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +ev-gu-by +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +ev-gu-by +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-ht-dw +gu-by-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev +~~END~~ + + +-- expression as function +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t +GO +~~START~~ +text +cx-by-gu-az-ev-dw-ht-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cx-az-dw-ht +by-gu-ev-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-ev-gu-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-ev-gu-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-ht-dw +s-gu-by-ev +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +s-by-gu-ev +~~END~~ + + +-- Delimeter as a function +SELECT STRING_AGG(a, char(10)) FROM string_agg_t +GO +~~START~~ +text +cbgaedh +~~END~~ + + +SELECT STRING_AGG(a, char(10)) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cadh +bge +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +bge +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +achd +gbe +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +bge +~~END~~ + + +-- order by clause on string column +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-e-g +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +g-e-b +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-ev-gu +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +gu-ev-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-ev-gu-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-gu-ev-by +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +beg +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +geb +~~END~~ + + +-- Batch statements +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + +~~START~~ +text +hdca +egb +~~END~~ + +~~START~~ +text +acdh +bge +~~END~~ + +~~START~~ +text +achd +gbe +~~END~~ + +~~START~~ +text +acdh +bge +~~END~~ + + +-- expression as column with multibyte characters +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t +GO +~~START~~ +text +?-莫-?-尔-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-尔 +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-尔 +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-尔 +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +尔-? +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +尔-? +?-莫-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +尔-? +莫-?-莫 +~~END~~ + + +-- casting result to NVARCHAR to verify the output +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t +GO +~~START~~ +nvarchar +😎-莫-😇-尔-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +😇-莫-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +莫-😇-莫 +~~END~~ + + +-- expression as column with chinese characters +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as +GO +~~START~~ +text +莫-尔-拉-比-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +比-莫 +斯-拉-尔 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +比-莫 +斯-拉-尔 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +拉-尔-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +-- expression from a column of a subquery +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +b-g-e-d-h +a-c-d-h +~~END~~ + + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 ASC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id ASC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +b-g-e-d-h +a-c-d-h +~~END~~ + + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 DESC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id DESC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +h-d-e-g-b +h-d-c-a +~~END~~ + + +-- Dependent objects +SELECT * FROM string_agg_dep_v1 +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +EXEC string_agg_dep_p1 +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +SELECT dbo.string_agg_dep_f1() +GO +~~START~~ +nvarchar +c-b-g-a-e-d-h +~~END~~ + + +SELECT * FROM string_agg_dep_v2 +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +EXEC string_agg_dep_p2 +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +SELECT * FROM dbo.string_agg_dep_f2() +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +SELECT * FROM string_agg_dep_v3 +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +EXEC string_agg_dep_p3 +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT * FROM dbo.string_agg_dep_f3() +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +-- dependent object trigger +INSERT INTO string_agg_school_details (classID, rollID, studentName) +VALUES (2, 3, 'StudentF'); +GO +~~START~~ +int#!#text +1#!#StudentA, StudentB, StudentC +2#!#StudentD, StudentE, StudentF +~~END~~ + +~~ROW COUNT: 1~~ + + +UPDATE string_agg_school_details +SET studentName = 'StudentG' +WHERE classID = 2 AND rollID = 3; +GO +~~START~~ +int#!#text +1#!#StudentA, StudentB, StudentC +2#!#StudentD, StudentE, StudentG +~~END~~ + +~~ROW COUNT: 1~~ + + +DELETE FROM string_agg_school_details +WHERE classID = 1 AND rollID = 2; +GO +~~START~~ +int#!#text +1#!#StudentA, StudentC +2#!#StudentD, StudentE, StudentG +~~END~~ + +~~ROW COUNT: 1~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/string_agg-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/string_agg-vu-verify.out new file mode 100644 index 00000000000..fe20c1e4b6e --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/string_agg-vu-verify.out @@ -0,0 +1,696 @@ +-- expression as column +SELECT STRING_AGG(a,'-') FROM string_agg_t +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +c-a-d-h +b-g-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-g-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-h-d +g-b-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-g-e +~~END~~ + + +-- expression as expression of multiple columns +SELECT STRING_AGG(a+b,'-') FROM string_agg_t +GO +~~START~~ +text +cx-by-gu-az-ev-dw-ht +~~END~~ + + +SELECT STRING_AGG(a+b,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cx-az-dw-ht +by-gu-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +ev-gu-by +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +ev-gu-by +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-ht-dw +gu-by-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev +~~END~~ + + +-- expression as function +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t +GO +~~START~~ +text +cx-by-gu-az-ev-dw-ht-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cx-az-dw-ht +by-gu-ev-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-ev-gu-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-ev-gu-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-ht-dw +s-gu-by-ev +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +s-by-gu-ev +~~END~~ + + +-- Delimeter as a function +SELECT STRING_AGG(a, char(10)) FROM string_agg_t +GO +~~START~~ +text +cbgaedh +~~END~~ + + +SELECT STRING_AGG(a, char(10)) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cadh +bge +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +bge +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +achd +gbe +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +bge +~~END~~ + + +-- order by clause on string column +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-e-g +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +g-e-b +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-ev-gu +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +gu-ev-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-ev-gu-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-gu-ev-by +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +beg +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +geb +~~END~~ + + +-- Batch statements +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + +~~START~~ +text +hdca +egb +~~END~~ + +~~START~~ +text +acdh +bge +~~END~~ + +~~START~~ +text +achd +gbe +~~END~~ + +~~START~~ +text +acdh +bge +~~END~~ + + +-- expression as column with multibyte characters +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t +GO +~~START~~ +text +?-莫-?-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +莫-?-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-莫-莫 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +莫-?-莫 +~~END~~ + + +-- casting result to NVARCHAR to verify the output +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t +GO +~~START~~ +nvarchar +😎-莫-😇-尔-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +😇-莫-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +莫-😇-莫 +~~END~~ + + +-- expression as column with chinese characters +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as +GO +~~START~~ +text +莫-尔-拉-比-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +比-莫 +斯-拉-尔 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +比-莫 +斯-拉-尔 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +拉-尔-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +-- expression from a column of a subquery +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +b-g-e-d-h +a-c-d-h +~~END~~ + + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 ASC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id ASC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +b-g-e-d-h +a-c-d-h +~~END~~ + + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 DESC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id DESC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +h-d-e-g-b +h-d-c-a +~~END~~ + + +-- Dependent objects +SELECT * FROM string_agg_dep_v1 +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +EXEC string_agg_dep_p1 +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +SELECT dbo.string_agg_dep_f1() +GO +~~START~~ +nvarchar +c-b-g-a-e-d-h +~~END~~ + + +SELECT * FROM string_agg_dep_v2 +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +EXEC string_agg_dep_p2 +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +SELECT * FROM dbo.string_agg_dep_f2() +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +SELECT * FROM string_agg_dep_v3 +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +EXEC string_agg_dep_p3 +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT * FROM dbo.string_agg_dep_f3() +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +-- dependent object trigger +INSERT INTO string_agg_school_details (classID, rollID, studentName) +VALUES (2, 3, 'StudentF'); +GO +~~START~~ +int#!#text +1#!#StudentA, StudentB, StudentC +2#!#StudentD, StudentE, StudentF +~~END~~ + +~~ROW COUNT: 1~~ + + +UPDATE string_agg_school_details +SET studentName = 'StudentG' +WHERE classID = 2 AND rollID = 3; +GO +~~START~~ +int#!#text +1#!#StudentA, StudentB, StudentC +2#!#StudentD, StudentE, StudentG +~~END~~ + +~~ROW COUNT: 1~~ + + +DELETE FROM string_agg_school_details +WHERE classID = 1 AND rollID = 2; +GO +~~START~~ +int#!#text +1#!#StudentA, StudentC +2#!#StudentD, StudentE, StudentG +~~END~~ + +~~ROW COUNT: 1~~ + diff --git a/test/JDBC/expected/string_agg-vu-cleanup.out b/test/JDBC/expected/string_agg-vu-cleanup.out new file mode 100644 index 00000000000..de3bb6c6e39 --- /dev/null +++ b/test/JDBC/expected/string_agg-vu-cleanup.out @@ -0,0 +1,44 @@ +DROP TRIGGER string_agg_tr_concat_student_names +GO + +DROP TABLE string_agg_school_details +GO + +DROP VIEW string_agg_dep_v3 +GO + +DROP PROCEDURE string_agg_dep_p3 +GO + +DROP FUNCTION string_agg_dep_f3 +GO + +DROP VIEW string_agg_dep_v2 +GO + +DROP PROCEDURE string_agg_dep_p2 +GO + +DROP FUNCTION string_agg_dep_f2 +GO + +DROP VIEW string_agg_dep_v1 +GO + +DROP PROCEDURE string_agg_dep_p1 +GO + +DROP FUNCTION string_agg_dep_f1 +GO + +DROP TABLE string_agg_multibyte_t +GO + +DROP TABLE string_agg_chinese_prc_ci_as +GO + +DROP TABLE string_agg_t2 +GO + +DROP TABLE string_agg_t +GO diff --git a/test/JDBC/expected/string_agg-vu-prepare.out b/test/JDBC/expected/string_agg-vu-prepare.out new file mode 100644 index 00000000000..b6b589e2884 --- /dev/null +++ b/test/JDBC/expected/string_agg-vu-prepare.out @@ -0,0 +1,133 @@ +CREATE TABLE string_agg_t (id int, a varchar(10), b varchar(10), g int, sbid int) +go + +INSERT INTO string_agg_t values +(3,'c','x',1,4), +(2,'b','y',2,6), +(2,'g','u',2,5), +(1,'a','z',1,7), +(5,'e','v',2,1), +(4,'d','w',1,3), +(4,'h','t',1,2), +(NULL,NULL,'s',2,NULL) +go +~~ROW COUNT: 8~~ + + +CREATE TABLE string_agg_t2 (id int, a varchar(10), g1 int, g2 int) +go + +INSERT INTO string_agg_t2 values +(1,'b',2,1), +(2,'g',2,1), +(3,'e',2,1), +(1,'a',1,2), +(2,'c',1,2), +(3,'d',1,2), +(4,'h',1,2), +(1,'d',3,1), +(2,'h',3,1) +go +~~ROW COUNT: 9~~ + + +CREATE TABLE string_agg_multibyte_t (id int, a nvarchar(10), g int, sbid int) +go +INSERT INTO string_agg_multibyte_t VALUES +(3,N'😎',1,4), +(2,N'莫',2,6), +(2,N'😇',2,5), +(1,N'尔',1,7), +(5,N'莫',2,1) +GO +~~ROW COUNT: 5~~ + + +CREATE TABLE string_agg_chinese_prc_ci_as(id int, a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS, g int, sbid int) +GO +INSERT INTO string_agg_chinese_prc_ci_as VALUES +(1,N'莫',1,5), +(2,N'尔',2,4), +(2,N'拉',2,3), +(3,N'比',1,2), +(5,N'斯',2,1) +GO +~~ROW COUNT: 5~~ + + +CREATE VIEW string_agg_dep_v1 AS + SELECT STRING_AGG (a, '-') as result FROM string_agg_t +GO + +CREATE PROCEDURE string_agg_dep_p1 AS + SELECT STRING_AGG (a, '-') FROM string_agg_t +GO + +CREATE FUNCTION string_agg_dep_f1() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT STRING_AGG (a, '-') FROM string_agg_t) +END +GO + +CREATE VIEW string_agg_dep_v2 AS + SELECT STRING_AGG (a, '-') as result FROM string_agg_t GROUP BY g +GO + +CREATE PROCEDURE string_agg_dep_p2 AS + SELECT STRING_AGG (a, '-') FROM string_agg_t GROUP BY g +GO + +CREATE FUNCTION string_agg_dep_f2() +RETURNS TABLE +AS +RETURN (SELECT STRING_AGG (a, '-') as result FROM string_agg_t GROUP BY g) +GO + +CREATE VIEW string_agg_dep_v3 AS + SELECT STRING_AGG (a, '-') WITHIN GROUP (ORDER BY sbid) as result FROM string_agg_t GROUP BY g +GO + +CREATE PROCEDURE string_agg_dep_p3 AS + SELECT STRING_AGG (a, '-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g +GO + +CREATE FUNCTION string_agg_dep_f3() +RETURNS TABLE +AS +RETURN (SELECT STRING_AGG (a, '-') WITHIN GROUP (ORDER BY sbid) as result FROM string_agg_t GROUP BY g) +GO + +-- Create a table to test the trigger +CREATE TABLE string_agg_school_details ( + classID INT, + rollID INT, + studentName VARCHAR(50) +); +GO + +INSERT INTO string_agg_school_details (classID, rollID, studentName) +VALUES + (1, 2, 'StudentB'), + (1, 1, 'StudentA'), + (1, 3, 'StudentC'), + (2, 2, 'StudentE'), + (2, 1, 'StudentD') +GO +~~ROW COUNT: 5~~ + + +-- Create a trigger to display classID, list of student names seperated by ', ' +CREATE TRIGGER string_agg_tr_concat_student_names +ON string_agg_school_details +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SELECT classID, STRING_AGG(studentName, ', ') + WITHIN GROUP (ORDER BY rollID) + FROM string_agg_school_details + GROUP BY classID + ORDER BY classID; +END; +GO diff --git a/test/JDBC/expected/string_agg-vu-verify.out b/test/JDBC/expected/string_agg-vu-verify.out new file mode 100644 index 00000000000..a7ab6809426 --- /dev/null +++ b/test/JDBC/expected/string_agg-vu-verify.out @@ -0,0 +1,696 @@ +-- expression as column +SELECT STRING_AGG(a,'-') FROM string_agg_t +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +c-a-d-h +b-g-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-g-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-h-d +g-b-e +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-g-e +~~END~~ + + +-- expression as expression of multiple columns +SELECT STRING_AGG(a+b,'-') FROM string_agg_t +GO +~~START~~ +text +cx-by-gu-az-ev-dw-ht +~~END~~ + + +SELECT STRING_AGG(a+b,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cx-az-dw-ht +by-gu-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +ev-gu-by +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +ev-gu-by +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-ht-dw +gu-by-ev +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev +~~END~~ + + +-- expression as function +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t +GO +~~START~~ +text +cx-by-gu-az-ev-dw-ht-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cx-az-dw-ht +by-gu-ev-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-ev-gu-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-ev-gu-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-gu-ev-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-ht-dw +s-gu-by-ev +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +s-by-gu-ev +~~END~~ + + +-- Delimeter as a function +SELECT STRING_AGG(a, char(10)) FROM string_agg_t +GO +~~START~~ +text +cbgaedh +~~END~~ + + +SELECT STRING_AGG(a, char(10)) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +cadh +bge +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +bge +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +achd +gbe +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +bge +~~END~~ + + +-- order by clause on string column +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +a-c-d-h +b-e-g +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +h-d-c-a +g-e-b +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-ev-gu +~~END~~ + + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +gu-ev-by +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +az-cx-dw-ht +by-ev-gu-s +~~END~~ + + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +ht-dw-cx-az +s-gu-ev-by +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +acdh +beg +~~END~~ + + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +geb +~~END~~ + + +-- Batch statements +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO +~~START~~ +text +hdca +egb +~~END~~ + +~~START~~ +text +hdca +egb +~~END~~ + +~~START~~ +text +acdh +bge +~~END~~ + +~~START~~ +text +achd +gbe +~~END~~ + +~~START~~ +text +acdh +bge +~~END~~ + + +-- expression as column with multibyte characters +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t +GO +~~START~~ +text +?-?-?-?-? +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-?-? +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-?-? +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-?-? +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-?-? +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-?-? +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +text +?-? +?-?-? +~~END~~ + + +-- casting result to NVARCHAR to verify the output +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t +GO +~~START~~ +nvarchar +😎-莫-😇-尔-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +😎-尔 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +莫-😇-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +😇-莫-莫 +~~END~~ + + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO +~~START~~ +nvarchar +尔-😎 +莫-😇-莫 +~~END~~ + + +-- expression as column with chinese characters +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as +GO +~~START~~ +text +莫-尔-拉-比-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +比-莫 +斯-拉-尔 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +比-莫 +斯-拉-尔 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +拉-尔-斯 +~~END~~ + + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO +~~START~~ +text +莫-比 +尔-拉-斯 +~~END~~ + + +-- expression from a column of a subquery +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +b-g-e-d-h +a-c-d-h +~~END~~ + + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 ASC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id ASC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +b-g-e-d-h +a-c-d-h +~~END~~ + + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 DESC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id DESC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO +~~START~~ +text +h-d-e-g-b +h-d-c-a +~~END~~ + + +-- Dependent objects +SELECT * FROM string_agg_dep_v1 +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +EXEC string_agg_dep_p1 +GO +~~START~~ +text +c-b-g-a-e-d-h +~~END~~ + + +SELECT dbo.string_agg_dep_f1() +GO +~~START~~ +nvarchar +c-b-g-a-e-d-h +~~END~~ + + +SELECT * FROM string_agg_dep_v2 +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +EXEC string_agg_dep_p2 +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +SELECT * FROM dbo.string_agg_dep_f2() +GO +~~START~~ +text +b-g-e +c-a-d-h +~~END~~ + + +SELECT * FROM string_agg_dep_v3 +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +EXEC string_agg_dep_p3 +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +SELECT * FROM dbo.string_agg_dep_f3() +GO +~~START~~ +text +h-d-c-a +e-g-b +~~END~~ + + +-- dependent object trigger +INSERT INTO string_agg_school_details (classID, rollID, studentName) +VALUES (2, 3, 'StudentF'); +GO +~~START~~ +int#!#text +1#!#StudentA, StudentB, StudentC +2#!#StudentD, StudentE, StudentF +~~END~~ + +~~ROW COUNT: 1~~ + + +UPDATE string_agg_school_details +SET studentName = 'StudentG' +WHERE classID = 2 AND rollID = 3; +GO +~~START~~ +int#!#text +1#!#StudentA, StudentB, StudentC +2#!#StudentD, StudentE, StudentG +~~END~~ + +~~ROW COUNT: 1~~ + + +DELETE FROM string_agg_school_details +WHERE classID = 1 AND rollID = 2; +GO +~~START~~ +int#!#text +1#!#StudentA, StudentC +2#!#StudentD, StudentE, StudentG +~~END~~ + +~~ROW COUNT: 1~~ + diff --git a/test/JDBC/input/functions/string_agg-vu-cleanup.sql b/test/JDBC/input/functions/string_agg-vu-cleanup.sql new file mode 100644 index 00000000000..ea5e706c59f --- /dev/null +++ b/test/JDBC/input/functions/string_agg-vu-cleanup.sql @@ -0,0 +1,44 @@ +DROP TRIGGER string_agg_tr_concat_student_names +GO + +DROP TABLE string_agg_school_details +GO + +DROP VIEW string_agg_dep_v3 +GO + +DROP PROCEDURE string_agg_dep_p3 +GO + +DROP FUNCTION string_agg_dep_f3 +GO + +DROP VIEW string_agg_dep_v2 +GO + +DROP PROCEDURE string_agg_dep_p2 +GO + +DROP FUNCTION string_agg_dep_f2 +GO + +DROP VIEW string_agg_dep_v1 +GO + +DROP PROCEDURE string_agg_dep_p1 +GO + +DROP FUNCTION string_agg_dep_f1 +GO + +DROP TABLE string_agg_multibyte_t +GO + +DROP TABLE string_agg_chinese_prc_ci_as +GO + +DROP TABLE string_agg_t2 +GO + +DROP TABLE string_agg_t +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_agg-vu-prepare.sql b/test/JDBC/input/functions/string_agg-vu-prepare.sql new file mode 100644 index 00000000000..6c498e9edb1 --- /dev/null +++ b/test/JDBC/input/functions/string_agg-vu-prepare.sql @@ -0,0 +1,123 @@ +CREATE TABLE string_agg_t (id int, a varchar(10), b varchar(10), g int, sbid int) +go + +INSERT INTO string_agg_t values +(3,'c','x',1,4), +(2,'b','y',2,6), +(2,'g','u',2,5), +(1,'a','z',1,7), +(5,'e','v',2,1), +(4,'d','w',1,3), +(4,'h','t',1,2), +(NULL,NULL,'s',2,NULL) +go + +CREATE TABLE string_agg_t2 (id int, a varchar(10), g1 int, g2 int) +go + +INSERT INTO string_agg_t2 values +(1,'b',2,1), +(2,'g',2,1), +(3,'e',2,1), +(1,'a',1,2), +(2,'c',1,2), +(3,'d',1,2), +(4,'h',1,2), +(1,'d',3,1), +(2,'h',3,1) +go + +CREATE TABLE string_agg_multibyte_t (id int, a nvarchar(10), g int, sbid int) +go +INSERT INTO string_agg_multibyte_t VALUES +(3,N'😎',1,4), +(2,N'莫',2,6), +(2,N'😇',2,5), +(1,N'尔',1,7), +(5,N'莫',2,1) +GO + +CREATE TABLE string_agg_chinese_prc_ci_as(id int, a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS, g int, sbid int) +GO +INSERT INTO string_agg_chinese_prc_ci_as VALUES +(1,N'莫',1,5), +(2,N'尔',2,4), +(2,N'拉',2,3), +(3,N'比',1,2), +(5,N'斯',2,1) +GO + +CREATE VIEW string_agg_dep_v1 AS + SELECT STRING_AGG (a, '-') as result FROM string_agg_t +GO + +CREATE PROCEDURE string_agg_dep_p1 AS + SELECT STRING_AGG (a, '-') FROM string_agg_t +GO + +CREATE FUNCTION string_agg_dep_f1() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT STRING_AGG (a, '-') FROM string_agg_t) +END +GO + +CREATE VIEW string_agg_dep_v2 AS + SELECT STRING_AGG (a, '-') as result FROM string_agg_t GROUP BY g +GO + +CREATE PROCEDURE string_agg_dep_p2 AS + SELECT STRING_AGG (a, '-') FROM string_agg_t GROUP BY g +GO + +CREATE FUNCTION string_agg_dep_f2() +RETURNS TABLE +AS +RETURN (SELECT STRING_AGG (a, '-') as result FROM string_agg_t GROUP BY g) +GO + +CREATE VIEW string_agg_dep_v3 AS + SELECT STRING_AGG (a, '-') WITHIN GROUP (ORDER BY sbid) as result FROM string_agg_t GROUP BY g +GO + +CREATE PROCEDURE string_agg_dep_p3 AS + SELECT STRING_AGG (a, '-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g +GO + +CREATE FUNCTION string_agg_dep_f3() +RETURNS TABLE +AS +RETURN (SELECT STRING_AGG (a, '-') WITHIN GROUP (ORDER BY sbid) as result FROM string_agg_t GROUP BY g) +GO + +-- Create a table to test the trigger +CREATE TABLE string_agg_school_details ( + classID INT, + rollID INT, + studentName VARCHAR(50) +); +GO + +INSERT INTO string_agg_school_details (classID, rollID, studentName) +VALUES + (1, 2, 'StudentB'), + (1, 1, 'StudentA'), + (1, 3, 'StudentC'), + (2, 2, 'StudentE'), + (2, 1, 'StudentD') +GO + +-- Create a trigger to display classID, list of student names seperated by ', ' +CREATE TRIGGER string_agg_tr_concat_student_names +ON string_agg_school_details +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SELECT classID, STRING_AGG(studentName, ', ') + WITHIN GROUP (ORDER BY rollID) + FROM string_agg_school_details + GROUP BY classID + ORDER BY classID; +END; +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_agg-vu-verify.sql b/test/JDBC/input/functions/string_agg-vu-verify.sql new file mode 100644 index 00000000000..43da3af3ef2 --- /dev/null +++ b/test/JDBC/input/functions/string_agg-vu-verify.sql @@ -0,0 +1,238 @@ +-- expression as column +SELECT STRING_AGG(a,'-') FROM string_agg_t +GO + +SELECT STRING_AGG(a,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +-- expression as expression of multiple columns +SELECT STRING_AGG(a+b,'-') FROM string_agg_t +GO + +SELECT STRING_AGG(a+b,'-') FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +-- expression as function +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t +GO + +SELECT STRING_AGG(concat(a,b),'-') FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +-- Delimeter as a function +SELECT STRING_AGG(a, char(10)) FROM string_agg_t +GO + +SELECT STRING_AGG(a, char(10)) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +-- order by clause on string column +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a+b,'-') WITHIN GROUP (ORDER BY a+b DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(concat(a,b),'-') WITHIN GROUP (ORDER BY concat(a,b) DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a ASC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY a DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +-- Batch statements +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_t GROUP BY g ORDER BY g +SELECT STRING_AGG(a, char(10)) WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_t GROUP BY g ORDER BY g +GO + +-- expression as column with multibyte characters +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t +GO + +SELECT STRING_AGG(a,'-') FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +-- casting result to NVARCHAR to verify the output +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t +GO + +SELECT CAST(STRING_AGG(a,'-') AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +SELECT CAST(STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) AS sys.NVARCHAR(100)) FROM string_agg_multibyte_t GROUP BY g ORDER BY g +GO + +-- expression as column with chinese characters +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as +GO + +SELECT STRING_AGG(a,'-') FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid ASC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO + +SELECT STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id, sbid DESC) FROM string_agg_chinese_prc_ci_as GROUP BY g ORDER BY g +GO + +-- expression from a column of a subquery +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 ASC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id ASC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO + +SELECT STRING_AGG(sbq.b,'-') WITHIN GROUP (ORDER BY g1 DESC) FROM (SELECT g1, g2, STRING_AGG(a,'-') WITHIN GROUP (ORDER BY id DESC) as 'b' FROM string_agg_t2 GROUP BY g1, g2) as sbq GROUP BY g2 ORDER BY g2 +GO + +-- Dependent objects +SELECT * FROM string_agg_dep_v1 +GO + +EXEC string_agg_dep_p1 +GO + +SELECT dbo.string_agg_dep_f1() +GO + +SELECT * FROM string_agg_dep_v2 +GO + +EXEC string_agg_dep_p2 +GO + +SELECT * FROM dbo.string_agg_dep_f2() +GO + +SELECT * FROM string_agg_dep_v3 +GO + +EXEC string_agg_dep_p3 +GO + +SELECT * FROM dbo.string_agg_dep_f3() +GO + +-- dependent object trigger +INSERT INTO string_agg_school_details (classID, rollID, studentName) +VALUES (2, 3, 'StudentF'); +GO + +UPDATE string_agg_school_details +SET studentName = 'StudentG' +WHERE classID = 2 AND rollID = 3; +GO + +DELETE FROM string_agg_school_details +WHERE classID = 1 AND rollID = 2; +GO diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 85a5b60e083..1f35f0ef139 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -549,3 +549,4 @@ BABEL-3401 BABEL-3820 PARTITION BABEL-5071 +string_agg From 39062e760658054bdcac7381ab31bfb22e517293 Mon Sep 17 00:00:00 2001 From: Rohit bhagat <65351720+rohit01010@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:57:01 +0530 Subject: [PATCH 15/15] Added wrapper functions for REVERSE() function to fix issue with input containing multi-byte characters. (#2786) Currently for string function REVERSE() we are directly using corresponding PG function whose input and output datatype is TEXT. This leads to incorrect output for input containing multi-byte characters with nchar and nvarchar datatype. This PR will fix this issue by adding wrapper functions with correct input and return datatype for REVERSE() function. Task: BABEL-4839 Signed-off-by: Rohit Bhagat --- .../babelfishpg_tsql/sql/sys_functions.sql | 78 ++- .../babelfishpg_tsql--4.2.0--4.3.0.sql | 75 +++ .../expected/BABEL-1994-CHAR-vu-verify.out | 2 +- test/JDBC/expected/BABEL-1994-CHAR.out | 2 +- .../expected/BABEL-1994-VARCHAR-vu-verify.out | 2 +- test/JDBC/expected/BABEL-1994-VARCHAR.out | 2 +- .../expected/four-part-names-vu-verify.out | 2 +- .../reverse-before-15_8-or-16_4-vu-verify.out | 602 ++++++++++++++++++ .../chinese_prc_ci_as/reverse-vu-verify.out | 602 ++++++++++++++++++ .../reverse-before-15_8-or-16_4-vu-verify.out | 602 ++++++++++++++++++ .../japanese_ci_as/reverse-vu-verify.out | 602 ++++++++++++++++++ .../JDBC/expected/pg_stat_statements_tsql.out | 2 +- ...reverse-before-15_8-or-16_4-vu-cleanup.out | 80 +++ ...reverse-before-15_8-or-16_4-vu-prepare.out | 156 +++++ .../reverse-before-15_8-or-16_4-vu-verify.out | 602 ++++++++++++++++++ test/JDBC/expected/reverse-vu-cleanup.out | 80 +++ test/JDBC/expected/reverse-vu-prepare.out | 156 +++++ test/JDBC/expected/reverse-vu-verify.out | 602 ++++++++++++++++++ ...reverse-before-15_8-or-16_4-vu-cleanup.sql | 80 +++ ...reverse-before-15_8-or-16_4-vu-prepare.sql | 126 ++++ .../reverse-before-15_8-or-16_4-vu-verify.sql | 262 ++++++++ .../string_functions/reverse-vu-cleanup.sql | 80 +++ .../string_functions/reverse-vu-prepare.sql | 126 ++++ .../string_functions/reverse-vu-verify.sql | 262 ++++++++ test/JDBC/jdbc_schedule | 4 + test/JDBC/upgrade/13_4/schedule | 1 + test/JDBC/upgrade/13_5/schedule | 1 + test/JDBC/upgrade/13_6/schedule | 1 + test/JDBC/upgrade/13_7/schedule | 1 + test/JDBC/upgrade/13_8/schedule | 1 + test/JDBC/upgrade/13_9/schedule | 1 + test/JDBC/upgrade/14_10/schedule | 1 + test/JDBC/upgrade/14_11/schedule | 1 + test/JDBC/upgrade/14_12/schedule | 1 + test/JDBC/upgrade/14_13/schedule | 1 + test/JDBC/upgrade/14_3/schedule | 1 + test/JDBC/upgrade/14_5/schedule | 1 + test/JDBC/upgrade/14_6/schedule | 1 + test/JDBC/upgrade/14_7/schedule | 1 + test/JDBC/upgrade/14_8/schedule | 1 + test/JDBC/upgrade/14_9/schedule | 1 + test/JDBC/upgrade/15_1/schedule | 1 + test/JDBC/upgrade/15_2/schedule | 1 + test/JDBC/upgrade/15_3/schedule | 1 + test/JDBC/upgrade/15_4/schedule | 1 + test/JDBC/upgrade/15_5/schedule | 1 + test/JDBC/upgrade/15_6/schedule | 1 + test/JDBC/upgrade/15_7/schedule | 1 + test/JDBC/upgrade/15_8/schedule | 1 + test/JDBC/upgrade/16_1/schedule | 1 + test/JDBC/upgrade/16_2/schedule | 1 + test/JDBC/upgrade/16_3/schedule | 1 + test/JDBC/upgrade/latest/schedule | 1 + 53 files changed, 5210 insertions(+), 7 deletions(-) create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-vu-verify.out create mode 100644 test/JDBC/expected/reverse-before-15_8-or-16_4-vu-cleanup.out create mode 100644 test/JDBC/expected/reverse-before-15_8-or-16_4-vu-prepare.out create mode 100644 test/JDBC/expected/reverse-before-15_8-or-16_4-vu-verify.out create mode 100644 test/JDBC/expected/reverse-vu-cleanup.out create mode 100644 test/JDBC/expected/reverse-vu-prepare.out create mode 100644 test/JDBC/expected/reverse-vu-verify.out create mode 100644 test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-verify.sql create mode 100644 test/JDBC/input/functions/string_functions/reverse-vu-cleanup.sql create mode 100644 test/JDBC/input/functions/string_functions/reverse-vu-prepare.sql create mode 100644 test/JDBC/input/functions/string_functions/reverse-vu-verify.sql diff --git a/contrib/babelfishpg_tsql/sql/sys_functions.sql b/contrib/babelfishpg_tsql/sql/sys_functions.sql index e96476a55b3..e54d82a884b 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -4867,4 +4867,80 @@ LANGUAGE plpgsql STABLE; CREATE OR REPLACE FUNCTION sys.bbf_pivot() RETURNS setof record AS 'babelfishpg_tsql', 'bbf_pivot' -LANGUAGE C STABLE; \ No newline at end of file +LANGUAGE C STABLE; + +-- wrapper functions for reverse +CREATE OR REPLACE FUNCTION sys.reverse(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_arg_typeid oid; + string_basetype oid; +BEGIN + string_arg_typeid := pg_typeof(string)::oid; + string_arg_datatype := sys.translate_pg_type_to_tsql(string_arg_typeid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(string_arg_typeid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for reverse function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of reverse function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.reverse(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.reverse(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.reverse(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that reverse with text input +-- will use following definition instead of PG reverse +CREATE OR REPLACE FUNCTION sys.reverse(string TEXT) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that reverse with ntext input +-- will use following definition instead of PG reverse +CREATE OR REPLACE FUNCTION sys.reverse(string NTEXT) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; \ No newline at end of file diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql index d689ebf4a16..c1f723e8ff6 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.2.0--4.3.0.sql @@ -5475,6 +5475,81 @@ RETURNS OID AS 'babelfishpg_tsql', 'get_immediate_base_type_of_UDT' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +-- wrapper functions for reverse +CREATE OR REPLACE FUNCTION sys.reverse(string ANYELEMENT) +RETURNS sys.VARCHAR +AS +$BODY$ +DECLARE + string_arg_datatype text; + string_arg_typeid oid; + string_basetype oid; +BEGIN + string_arg_typeid := pg_typeof(string)::oid; + string_arg_datatype := sys.translate_pg_type_to_tsql(string_arg_typeid); + IF string_arg_datatype IS NULL THEN + -- for User Defined Datatype, use immediate base type to check for argument datatype validation + string_basetype := sys.bbf_get_immediate_base_type_of_UDT(string_arg_typeid); + string_arg_datatype := sys.translate_pg_type_to_tsql(string_basetype); + END IF; + + -- restricting arguments with invalid datatypes for reverse function + IF string_arg_datatype IN ('image', 'sql_variant', 'xml', 'geometry', 'geography') THEN + RAISE EXCEPTION 'Argument data type % is invalid for argument 1 of reverse function.', string_arg_datatype; + END IF; + + IF string IS NULL THEN + RETURN NULL; + END IF; + + RETURN PG_CATALOG.reverse(string::sys.varchar); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.reverse(string sys.NCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.reverse(string sys.NVARCHAR) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +-- Adding following definition will make sure that reverse with text input +-- will use following definition instead of PG reverse +CREATE OR REPLACE FUNCTION sys.reverse(string TEXT) +RETURNS sys.VARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; + +-- Adding following definition will make sure that reverse with ntext input +-- will use following definition instead of PG reverse +CREATE OR REPLACE FUNCTION sys.reverse(string NTEXT) +RETURNS sys.NVARCHAR +AS +$BODY$ +BEGIN + RETURN PG_CATALOG.reverse(string); +END; +$BODY$ +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; create or replace view sys.tables as with tt_internal as MATERIALIZED diff --git a/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out b/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out index dd9391646a7..7f79afa8366 100644 --- a/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out +++ b/test/JDBC/expected/BABEL-1994-CHAR-vu-verify.out @@ -160,7 +160,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#varchar +int#!#varchar#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ diff --git a/test/JDBC/expected/BABEL-1994-CHAR.out b/test/JDBC/expected/BABEL-1994-CHAR.out index d3a4ed2a963..5e040c94c1b 100644 --- a/test/JDBC/expected/BABEL-1994-CHAR.out +++ b/test/JDBC/expected/BABEL-1994-CHAR.out @@ -191,7 +191,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#varchar +int#!#varchar#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ diff --git a/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out b/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out index f1861abcbec..3c1c10aed32 100644 --- a/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out +++ b/test/JDBC/expected/BABEL-1994-VARCHAR-vu-verify.out @@ -165,7 +165,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#varchar +int#!#varchar#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ diff --git a/test/JDBC/expected/BABEL-1994-VARCHAR.out b/test/JDBC/expected/BABEL-1994-VARCHAR.out index 4c3597c7a2f..412e478bb8f 100644 --- a/test/JDBC/expected/BABEL-1994-VARCHAR.out +++ b/test/JDBC/expected/BABEL-1994-VARCHAR.out @@ -189,7 +189,7 @@ select ; go ~~START~~ -int#!#text#!#nvarchar#!#bigint#!#varchar +int#!#varchar#!#nvarchar#!#bigint#!#varchar 97#!# a#!#[a[]] b ]#!#1#!#a ~~END~~ diff --git a/test/JDBC/expected/four-part-names-vu-verify.out b/test/JDBC/expected/four-part-names-vu-verify.out index 679cb963a11..7573c252abe 100644 --- a/test/JDBC/expected/four-part-names-vu-verify.out +++ b/test/JDBC/expected/four-part-names-vu-verify.out @@ -68,7 +68,7 @@ PRIMARY#!#1#!#FG#!#ROWS_FILEGROUP#!#1#!#0 SELECT a*2, REVERSE(b) FROM bbf_fpn_server...fpn_table GO ~~START~~ -int#!#text +int#!#varchar 2#!#eno 4#!#owt 6#!#eerht diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..a71a9d05654 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,602 @@ +-- NULL +SELECT reverse(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- empty string +SELECT reverse('') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + 斯莫拉·尔比 +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar + 斯莫拉·尔比 +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + 斯莫拉·尔比 +~~END~~ + + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +斯莫拉·尔比 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +EXEC babel_4839_reverse_dep_proc +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_itvf_func() +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO +~~START~~ +text + ??ihgfed?cba + 斯莫拉·尔比 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO +~~START~~ +text + ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO +~~START~~ +text +ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO +~~START~~ +text +0202463626160202x0 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +fedcba +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +12-21-6102 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:00:00 12-21-6102 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:34:21 31-21-5591 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.50:01:21 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:01+ 4321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +654321 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +54321 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +65321 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +532 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +SELECT reverse(a) from babel_4839_reverse_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +>ydob/<>/tiurf<>ydob< +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +)2 1(TNIOP +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-vu-verify.out new file mode 100644 index 00000000000..99256865d9d --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/reverse-vu-verify.out @@ -0,0 +1,602 @@ +-- NULL +SELECT reverse(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- empty string +SELECT reverse('') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + 斯莫拉·尔比 +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar + 斯莫拉·尔比 +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + 斯莫拉·尔比 +~~END~~ + + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +斯莫拉·尔比 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +EXEC babel_4839_reverse_dep_proc +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_itvf_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO +~~START~~ +varchar + ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO +~~START~~ +varchar +ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO +~~START~~ +varchar + dcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +fedcba +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +12-21-6102 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:00:00 12-21-6102 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:34:21 31-21-5591 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.50:01:21 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:01+ 4321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +654321 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +54321 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +65321 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +532 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +SELECT reverse(a) from babel_4839_reverse_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +>ydob/<>/tiurf<>ydob< +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +)2 1(TNIOP +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..3aba6abbf8c --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,602 @@ +-- NULL +SELECT reverse(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- empty string +SELECT reverse('') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + 斯莫拉??比 +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar + 斯莫拉??比 +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +斯莫拉??比 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + 斯莫拉??比 +~~END~~ + + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +斯莫拉·尔比 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +EXEC babel_4839_reverse_dep_proc +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_itvf_func() +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO +~~START~~ +text + ??ihgfed?cba + 斯莫拉??比 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO +~~START~~ +text + ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO +~~START~~ +text +ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO +~~START~~ +text +0202463626160202x0 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +fedcba +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +12-21-6102 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:00:00 12-21-6102 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:34:21 31-21-5591 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.50:01:21 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:01+ 4321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +654321 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +54321 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +65321 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +532 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +SELECT reverse(a) from babel_4839_reverse_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +>ydob/<>/tiurf<>ydob< +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +)2 1(TNIOP +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-vu-verify.out new file mode 100644 index 00000000000..855705d732a --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/reverse-vu-verify.out @@ -0,0 +1,602 @@ +-- NULL +SELECT reverse(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- empty string +SELECT reverse('') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + 斯莫拉??比 +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar + 斯莫拉??比 +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +斯莫拉??比 +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + 斯莫拉??比 +~~END~~ + + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +斯莫拉·尔比 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +EXEC babel_4839_reverse_dep_proc +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_itvf_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO +~~START~~ +varchar + ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO +~~START~~ +varchar +ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO +~~START~~ +varchar + dcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +fedcba +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +12-21-6102 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:00:00 12-21-6102 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:34:21 31-21-5591 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.50:01:21 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:01+ 4321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +654321 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +54321 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +65321 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +532 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +SELECT reverse(a) from babel_4839_reverse_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +>ydob/<>/tiurf<>ydob< +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +)2 1(TNIOP +~~END~~ + diff --git a/test/JDBC/expected/pg_stat_statements_tsql.out b/test/JDBC/expected/pg_stat_statements_tsql.out index 7103f9d35a6..7c55141a593 100644 --- a/test/JDBC/expected/pg_stat_statements_tsql.out +++ b/test/JDBC/expected/pg_stat_statements_tsql.out @@ -539,7 +539,7 @@ int SELECT REVERSE(name) FROM pgss_cust go ~~START~~ -text +varchar CBA ZYX NML diff --git a/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-cleanup.out b/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-cleanup.out new file mode 100644 index 00000000000..b48d463a0ea --- /dev/null +++ b/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4839_reverse_itvf_func +GO + +DROP FUNCTION babel_4839_reverse_dep_func +GO + +DROP PROCEDURE babel_4839_reverse_dep_proc +GO + +DROP VIEW babel_4839_reverse_dep_view +GO + +DROP TABLE babel_4839_reverse_UDT +GO + +DROP VIEW babel_4839_reverse_dep_view_1 +GO + +DROP VIEW babel_4839_reverse_dep_view_2 +GO + +DROP VIEW babel_4839_reverse_dep_view_3 +GO + +DROP VIEW babel_4839_reverse_dep_view_4 +GO + +DROP VIEW babel_4839_reverse_dep_view_5 +GO + +DROP VIEW babel_4839_reverse_dep_view_6 +GO + +DROP VIEW babel_4839_reverse_dep_view_7 +GO + +DROP TYPE dbo.babel_4839_reverse_varUDT +GO + +DROP TYPE dbo.babel_4839_reverse_imageUDT +GO + +DROP TABLE babel_4839_reverse_text +GO + +DROP TABLE babel_4839_reverse_image +GO + +DROP TABLE babel_4839_reverse_arabic_ci_ai +GO + +DROP TABLE babel_4839_reverse_arabic_cs_as +GO + +DROP TABLE babel_4839_reverse_arabic_ci_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_ai +GO + +DROP TABLE babel_4839_reverse_chinese_prc_cs_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_as +GO + +DROP TABLE babel_4839_reverse_t5 +GO + +DROP TABLE babel_4839_reverse_t4 +GO + +DROP TABLE babel_4839_reverse_t3 +GO + +DROP TABLE babel_4839_reverse_t2 +GO + +DROP TABLE babel_4839_reverse_t1 +GO diff --git a/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-prepare.out new file mode 100644 index 00000000000..e9835fceab6 --- /dev/null +++ b/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4839_reverse_t1(a NCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4839_reverse_t1 VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t2 VALUES(N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t3(a CHAR(50)) +GO +INSERT INTO babel_4839_reverse_t3 VALUES('abcdefghi') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t4 VALUES('abcdefghi') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4839_reverse_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4839_reverse_arabic_ci_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4839_reverse_arabic_cs_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4839_reverse_arabic_ci_ai VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_image(a IMAGE) +GO +INSERT INTO babel_4839_reverse_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4839_reverse_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4839_reverse_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4839_reverse_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4839_reverse_UDT(a dbo.babel_4839_reverse_imageUDT, b dbo.babel_4839_reverse_varUDT) +GO +INSERT INTO babel_4839_reverse_UDT VALUES(CAST('abcdef' as dbo.babel_4839_reverse_imageUDT), CAST('abcdef' as dbo.babel_4839_reverse_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4839_reverse_dep_view AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE PROCEDURE babel_4839_reverse_dep_proc AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE FUNCTION babel_4839_reverse_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 reverse(a) from babel_4839_reverse_t2) +END +GO + +CREATE VIEW babel_4839_reverse_dep_view_1 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t1 +GO + +CREATE VIEW babel_4839_reverse_dep_view_2 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t2 +GO + +CREATE VIEW babel_4839_reverse_dep_view_3 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t3 +GO + +CREATE VIEW babel_4839_reverse_dep_view_4 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t4 +GO + +CREATE VIEW babel_4839_reverse_dep_view_5 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t5 +GO + +CREATE VIEW babel_4839_reverse_dep_view_6 AS + SELECT reverse(a) as result FROM babel_4839_reverse_text +GO + +CREATE VIEW babel_4839_reverse_dep_view_7 AS + SELECT reverse(b) as result FROM babel_4839_reverse_text +GO + +CREATE FUNCTION babel_4839_reverse_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT reverse(a) as result from babel_4839_reverse_t2) +GO diff --git a/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-verify.out new file mode 100644 index 00000000000..e9ab22a8618 --- /dev/null +++ b/test/JDBC/expected/reverse-before-15_8-or-16_4-vu-verify.out @@ -0,0 +1,602 @@ +-- NULL +SELECT reverse(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- empty string +SELECT reverse('') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ???·?? +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar + ???·?? +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +???·?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ???·?? +~~END~~ + + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +斯莫拉·尔比 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +EXEC babel_4839_reverse_dep_proc +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_itvf_func() +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO +~~START~~ +text + ??ihgfed?cba + ???·?? +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO +~~START~~ +text + ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO +~~START~~ +text +ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO +~~START~~ +text +0202463626160202x0 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO +~~START~~ +text +??ihgfed?cba +~~END~~ + + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +fedcba +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +12-21-6102 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:00:00 12-21-6102 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:34:21 31-21-5591 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.50:01:21 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:01+ 4321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +654321 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +54321 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +65321 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +532 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +SELECT reverse(a) from babel_4839_reverse_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +>ydob/<>/tiurf<>ydob< +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +)2 1(TNIOP +~~END~~ + diff --git a/test/JDBC/expected/reverse-vu-cleanup.out b/test/JDBC/expected/reverse-vu-cleanup.out new file mode 100644 index 00000000000..b48d463a0ea --- /dev/null +++ b/test/JDBC/expected/reverse-vu-cleanup.out @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4839_reverse_itvf_func +GO + +DROP FUNCTION babel_4839_reverse_dep_func +GO + +DROP PROCEDURE babel_4839_reverse_dep_proc +GO + +DROP VIEW babel_4839_reverse_dep_view +GO + +DROP TABLE babel_4839_reverse_UDT +GO + +DROP VIEW babel_4839_reverse_dep_view_1 +GO + +DROP VIEW babel_4839_reverse_dep_view_2 +GO + +DROP VIEW babel_4839_reverse_dep_view_3 +GO + +DROP VIEW babel_4839_reverse_dep_view_4 +GO + +DROP VIEW babel_4839_reverse_dep_view_5 +GO + +DROP VIEW babel_4839_reverse_dep_view_6 +GO + +DROP VIEW babel_4839_reverse_dep_view_7 +GO + +DROP TYPE dbo.babel_4839_reverse_varUDT +GO + +DROP TYPE dbo.babel_4839_reverse_imageUDT +GO + +DROP TABLE babel_4839_reverse_text +GO + +DROP TABLE babel_4839_reverse_image +GO + +DROP TABLE babel_4839_reverse_arabic_ci_ai +GO + +DROP TABLE babel_4839_reverse_arabic_cs_as +GO + +DROP TABLE babel_4839_reverse_arabic_ci_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_ai +GO + +DROP TABLE babel_4839_reverse_chinese_prc_cs_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_as +GO + +DROP TABLE babel_4839_reverse_t5 +GO + +DROP TABLE babel_4839_reverse_t4 +GO + +DROP TABLE babel_4839_reverse_t3 +GO + +DROP TABLE babel_4839_reverse_t2 +GO + +DROP TABLE babel_4839_reverse_t1 +GO diff --git a/test/JDBC/expected/reverse-vu-prepare.out b/test/JDBC/expected/reverse-vu-prepare.out new file mode 100644 index 00000000000..e9835fceab6 --- /dev/null +++ b/test/JDBC/expected/reverse-vu-prepare.out @@ -0,0 +1,156 @@ +CREATE TABLE babel_4839_reverse_t1(a NCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4839_reverse_t1 VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t2 VALUES(N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t3(a CHAR(50)) +GO +INSERT INTO babel_4839_reverse_t3 VALUES('abcdefghi') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t4 VALUES('abcdefghi') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4839_reverse_t5 VALUES(0x2020616263642020) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4839_reverse_arabic_ci_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4839_reverse_arabic_cs_as VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4839_reverse_arabic_ci_ai VALUES(N'الله مع المتقين') +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_image(a IMAGE) +GO +INSERT INTO babel_4839_reverse_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO +~~ROW COUNT: 1~~ + + +CREATE TABLE babel_4839_reverse_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4839_reverse_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO +~~ROW COUNT: 1~~ + + +CREATE TYPE dbo.babel_4839_reverse_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4839_reverse_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4839_reverse_UDT(a dbo.babel_4839_reverse_imageUDT, b dbo.babel_4839_reverse_varUDT) +GO +INSERT INTO babel_4839_reverse_UDT VALUES(CAST('abcdef' as dbo.babel_4839_reverse_imageUDT), CAST('abcdef' as dbo.babel_4839_reverse_varUDT)) +GO +~~ROW COUNT: 1~~ + + +CREATE VIEW babel_4839_reverse_dep_view AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE PROCEDURE babel_4839_reverse_dep_proc AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE FUNCTION babel_4839_reverse_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 reverse(a) from babel_4839_reverse_t2) +END +GO + +CREATE VIEW babel_4839_reverse_dep_view_1 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t1 +GO + +CREATE VIEW babel_4839_reverse_dep_view_2 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t2 +GO + +CREATE VIEW babel_4839_reverse_dep_view_3 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t3 +GO + +CREATE VIEW babel_4839_reverse_dep_view_4 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t4 +GO + +CREATE VIEW babel_4839_reverse_dep_view_5 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t5 +GO + +CREATE VIEW babel_4839_reverse_dep_view_6 AS + SELECT reverse(a) as result FROM babel_4839_reverse_text +GO + +CREATE VIEW babel_4839_reverse_dep_view_7 AS + SELECT reverse(b) as result FROM babel_4839_reverse_text +GO + +CREATE FUNCTION babel_4839_reverse_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT reverse(a) as result from babel_4839_reverse_t2) +GO diff --git a/test/JDBC/expected/reverse-vu-verify.out b/test/JDBC/expected/reverse-vu-verify.out new file mode 100644 index 00000000000..3687359bdb7 --- /dev/null +++ b/test/JDBC/expected/reverse-vu-verify.out @@ -0,0 +1,602 @@ +-- NULL +SELECT reverse(NULL) +GO +~~START~~ +varchar + +~~END~~ + + +-- empty string +SELECT reverse('') +GO +~~START~~ +varchar + +~~END~~ + + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar + ???·?? +~~END~~ + + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar + ???·?? +~~END~~ + + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +varchar +???·?? +~~END~~ + + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO +~~START~~ +varchar +斯莫拉·尔比 +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO +~~START~~ +varchar +نيقتملا عم هللا +~~END~~ + + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ??ihgfed?cba +~~END~~ + + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar + ???·?? +~~END~~ + + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO +~~START~~ +nvarchar +斯莫拉·尔比 +~~END~~ + + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO +~~START~~ +varchar +hgfedcba +~~END~~ + + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +EXEC babel_4839_reverse_dep_proc +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_itvf_func() +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO +~~START~~ +nvarchar + 🙂🙂ihgfed🙂cba + 斯莫拉·尔比 +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO +~~START~~ +varchar + ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO +~~START~~ +varchar +ihgfedcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO +~~START~~ +varchar + dcba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO +~~START~~ +varchar +fedcba +~~END~~ + + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +12-21-6102 +~~END~~ + + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:00:00 12-21-6102 +~~END~~ + + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:34:21 31-21-5591 +~~END~~ + + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.50:01:21 +~~END~~ + + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +00:01+ 4321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +7321.73:54:21 32-01-8691 +~~END~~ + + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +654321 +~~END~~ + + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +54321 +~~END~~ + + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1.54321 +~~END~~ + + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +87654321 +~~END~~ + + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +65321 +~~END~~ + + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +532 +~~END~~ + + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +0000.65321 +~~END~~ + + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO +~~START~~ +varchar +1 +~~END~~ + + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +SELECT reverse(a) from babel_4839_reverse_image; +GO +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type image is invalid for argument 1 of reverse function.)~~ + + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO +~~START~~ +varchar +??ihgfed?cba +~~END~~ + + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO +~~START~~ +nvarchar +🙂🙂ihgfed🙂cba +~~END~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type sql_variant is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type xml is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geometry is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Argument data type geography is invalid for argument 1 of reverse function.)~~ + + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +FF469CF40C00-D24B-110D-68B8-FF9169F6 +~~END~~ + + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +>ydob/<>/tiurf<>ydob< +~~END~~ + + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO +~~START~~ +varchar +)2 1(TNIOP +~~END~~ + diff --git a/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 00000000000..f285ad662a0 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4839_reverse_itvf_func +GO + +DROP FUNCTION babel_4839_reverse_dep_func +GO + +DROP PROCEDURE babel_4839_reverse_dep_proc +GO + +DROP VIEW babel_4839_reverse_dep_view +GO + +DROP TABLE babel_4839_reverse_UDT +GO + +DROP VIEW babel_4839_reverse_dep_view_1 +GO + +DROP VIEW babel_4839_reverse_dep_view_2 +GO + +DROP VIEW babel_4839_reverse_dep_view_3 +GO + +DROP VIEW babel_4839_reverse_dep_view_4 +GO + +DROP VIEW babel_4839_reverse_dep_view_5 +GO + +DROP VIEW babel_4839_reverse_dep_view_6 +GO + +DROP VIEW babel_4839_reverse_dep_view_7 +GO + +DROP TYPE dbo.babel_4839_reverse_varUDT +GO + +DROP TYPE dbo.babel_4839_reverse_imageUDT +GO + +DROP TABLE babel_4839_reverse_text +GO + +DROP TABLE babel_4839_reverse_image +GO + +DROP TABLE babel_4839_reverse_arabic_ci_ai +GO + +DROP TABLE babel_4839_reverse_arabic_cs_as +GO + +DROP TABLE babel_4839_reverse_arabic_ci_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_ai +GO + +DROP TABLE babel_4839_reverse_chinese_prc_cs_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_as +GO + +DROP TABLE babel_4839_reverse_t5 +GO + +DROP TABLE babel_4839_reverse_t4 +GO + +DROP TABLE babel_4839_reverse_t3 +GO + +DROP TABLE babel_4839_reverse_t2 +GO + +DROP TABLE babel_4839_reverse_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 00000000000..b1cba9cffa9 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4839_reverse_t1(a NCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4839_reverse_t1 VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t2 VALUES(N'abc🙂defghi🙂🙂') +GO + +CREATE TABLE babel_4839_reverse_t3(a CHAR(50)) +GO +INSERT INTO babel_4839_reverse_t3 VALUES('abcdefghi') +GO + +CREATE TABLE babel_4839_reverse_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t4 VALUES('abcdefghi') +GO + +CREATE TABLE babel_4839_reverse_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4839_reverse_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4839_reverse_arabic_ci_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4839_reverse_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4839_reverse_arabic_cs_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4839_reverse_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4839_reverse_arabic_ci_ai VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4839_reverse_image(a IMAGE) +GO +INSERT INTO babel_4839_reverse_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4839_reverse_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4839_reverse_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO + +CREATE TYPE dbo.babel_4839_reverse_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4839_reverse_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4839_reverse_UDT(a dbo.babel_4839_reverse_imageUDT, b dbo.babel_4839_reverse_varUDT) +GO +INSERT INTO babel_4839_reverse_UDT VALUES(CAST('abcdef' as dbo.babel_4839_reverse_imageUDT), CAST('abcdef' as dbo.babel_4839_reverse_varUDT)) +GO + +CREATE VIEW babel_4839_reverse_dep_view AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE PROCEDURE babel_4839_reverse_dep_proc AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE FUNCTION babel_4839_reverse_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 reverse(a) from babel_4839_reverse_t2) +END +GO + +CREATE VIEW babel_4839_reverse_dep_view_1 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t1 +GO + +CREATE VIEW babel_4839_reverse_dep_view_2 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t2 +GO + +CREATE VIEW babel_4839_reverse_dep_view_3 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t3 +GO + +CREATE VIEW babel_4839_reverse_dep_view_4 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t4 +GO + +CREATE VIEW babel_4839_reverse_dep_view_5 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t5 +GO + +CREATE VIEW babel_4839_reverse_dep_view_6 AS + SELECT reverse(a) as result FROM babel_4839_reverse_text +GO + +CREATE VIEW babel_4839_reverse_dep_view_7 AS + SELECT reverse(b) as result FROM babel_4839_reverse_text +GO + +CREATE FUNCTION babel_4839_reverse_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT reverse(a) as result from babel_4839_reverse_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-verify.sql new file mode 100644 index 00000000000..57acb62db07 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/reverse-before-15_8-or-16_4-vu-verify.sql @@ -0,0 +1,262 @@ +-- NULL +SELECT reverse(NULL) +GO + +-- empty string +SELECT reverse('') +GO + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO + +EXEC babel_4839_reverse_dep_proc +GO + +SELECT * FROM babel_4839_reverse_dep_func() +GO + +SELECT * FROM babel_4839_reverse_itvf_func() +GO + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO + +SELECT reverse(a) from babel_4839_reverse_image; +GO + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/input/functions/string_functions/reverse-vu-cleanup.sql b/test/JDBC/input/functions/string_functions/reverse-vu-cleanup.sql new file mode 100644 index 00000000000..f285ad662a0 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/reverse-vu-cleanup.sql @@ -0,0 +1,80 @@ +DROP FUNCTION babel_4839_reverse_itvf_func +GO + +DROP FUNCTION babel_4839_reverse_dep_func +GO + +DROP PROCEDURE babel_4839_reverse_dep_proc +GO + +DROP VIEW babel_4839_reverse_dep_view +GO + +DROP TABLE babel_4839_reverse_UDT +GO + +DROP VIEW babel_4839_reverse_dep_view_1 +GO + +DROP VIEW babel_4839_reverse_dep_view_2 +GO + +DROP VIEW babel_4839_reverse_dep_view_3 +GO + +DROP VIEW babel_4839_reverse_dep_view_4 +GO + +DROP VIEW babel_4839_reverse_dep_view_5 +GO + +DROP VIEW babel_4839_reverse_dep_view_6 +GO + +DROP VIEW babel_4839_reverse_dep_view_7 +GO + +DROP TYPE dbo.babel_4839_reverse_varUDT +GO + +DROP TYPE dbo.babel_4839_reverse_imageUDT +GO + +DROP TABLE babel_4839_reverse_text +GO + +DROP TABLE babel_4839_reverse_image +GO + +DROP TABLE babel_4839_reverse_arabic_ci_ai +GO + +DROP TABLE babel_4839_reverse_arabic_cs_as +GO + +DROP TABLE babel_4839_reverse_arabic_ci_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_ai +GO + +DROP TABLE babel_4839_reverse_chinese_prc_cs_as +GO + +DROP TABLE babel_4839_reverse_chinese_prc_ci_as +GO + +DROP TABLE babel_4839_reverse_t5 +GO + +DROP TABLE babel_4839_reverse_t4 +GO + +DROP TABLE babel_4839_reverse_t3 +GO + +DROP TABLE babel_4839_reverse_t2 +GO + +DROP TABLE babel_4839_reverse_t1 +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/reverse-vu-prepare.sql b/test/JDBC/input/functions/string_functions/reverse-vu-prepare.sql new file mode 100644 index 00000000000..b1cba9cffa9 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/reverse-vu-prepare.sql @@ -0,0 +1,126 @@ +CREATE TABLE babel_4839_reverse_t1(a NCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t1 VALUES(N'abc🙂defghi🙂🙂') +INSERT INTO babel_4839_reverse_t1 VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_t2(a NVARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t2 VALUES(N'abc🙂defghi🙂🙂') +GO + +CREATE TABLE babel_4839_reverse_t3(a CHAR(50)) +GO +INSERT INTO babel_4839_reverse_t3 VALUES('abcdefghi') +GO + +CREATE TABLE babel_4839_reverse_t4(a VARCHAR(50)) +GO +INSERT INTO babel_4839_reverse_t4 VALUES('abcdefghi') +GO + +CREATE TABLE babel_4839_reverse_t5(a VARBINARY(50)) +GO +INSERT INTO babel_4839_reverse_t5 VALUES(0x2020616263642020) +GO + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_as(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_chinese_prc_cs_as(a VARCHAR(50) COLLATE CHINESE_PRC_CS_AS) +GO +INSERT INTO babel_4839_reverse_chinese_prc_cs_as VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_chinese_prc_ci_ai(a VARCHAR(50) COLLATE CHINESE_PRC_CI_AI) +GO +INSERT INTO babel_4839_reverse_chinese_prc_ci_ai VALUES(N'比尔·拉莫斯') +GO + +CREATE TABLE babel_4839_reverse_arabic_ci_as(a VARCHAR(50) COLLATE ARABIC_CI_AS) +GO +INSERT INTO babel_4839_reverse_arabic_ci_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4839_reverse_arabic_cs_as(a VARCHAR(50) COLLATE ARABIC_CS_AS) +GO +INSERT INTO babel_4839_reverse_arabic_cs_as VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4839_reverse_arabic_ci_ai(a VARCHAR(50) COLLATE ARABIC_CI_AI) +GO +INSERT INTO babel_4839_reverse_arabic_ci_ai VALUES(N'الله مع المتقين') +GO + +CREATE TABLE babel_4839_reverse_image(a IMAGE) +GO +INSERT INTO babel_4839_reverse_image values(CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS image)) +GO + +CREATE TABLE babel_4839_reverse_text(a TEXT, b NTEXT) +GO +INSERT INTO babel_4839_reverse_text VALUES (N'abc🙂defghi🙂🙂', N'abc🙂defghi🙂🙂') +GO + +CREATE TYPE dbo.babel_4839_reverse_imageUDT FROM image; +GO + +CREATE TYPE dbo.babel_4839_reverse_varUDT FROM varchar(50); +GO + +CREATE TABLE babel_4839_reverse_UDT(a dbo.babel_4839_reverse_imageUDT, b dbo.babel_4839_reverse_varUDT) +GO +INSERT INTO babel_4839_reverse_UDT VALUES(CAST('abcdef' as dbo.babel_4839_reverse_imageUDT), CAST('abcdef' as dbo.babel_4839_reverse_varUDT)) +GO + +CREATE VIEW babel_4839_reverse_dep_view AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE PROCEDURE babel_4839_reverse_dep_proc AS + SELECT reverse(a) as result from babel_4839_reverse_t2 +GO + +CREATE FUNCTION babel_4839_reverse_dep_func() +RETURNS NVARCHAR(50) +AS +BEGIN +RETURN (SELECT TOP 1 reverse(a) from babel_4839_reverse_t2) +END +GO + +CREATE VIEW babel_4839_reverse_dep_view_1 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t1 +GO + +CREATE VIEW babel_4839_reverse_dep_view_2 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t2 +GO + +CREATE VIEW babel_4839_reverse_dep_view_3 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t3 +GO + +CREATE VIEW babel_4839_reverse_dep_view_4 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t4 +GO + +CREATE VIEW babel_4839_reverse_dep_view_5 AS + SELECT reverse(a) as result FROM babel_4839_reverse_t5 +GO + +CREATE VIEW babel_4839_reverse_dep_view_6 AS + SELECT reverse(a) as result FROM babel_4839_reverse_text +GO + +CREATE VIEW babel_4839_reverse_dep_view_7 AS + SELECT reverse(b) as result FROM babel_4839_reverse_text +GO + +CREATE FUNCTION babel_4839_reverse_itvf_func() +RETURNS TABLE +AS +RETURN (SELECT reverse(a) as result from babel_4839_reverse_t2) +GO \ No newline at end of file diff --git a/test/JDBC/input/functions/string_functions/reverse-vu-verify.sql b/test/JDBC/input/functions/string_functions/reverse-vu-verify.sql new file mode 100644 index 00000000000..57acb62db07 --- /dev/null +++ b/test/JDBC/input/functions/string_functions/reverse-vu-verify.sql @@ -0,0 +1,262 @@ +-- NULL +SELECT reverse(NULL) +GO + +-- empty string +SELECT reverse('') +GO + +-- input type char +DECLARE @inputString CHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +DECLARE @inputString CHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO + +-- input type varchar +DECLARE @inputString VARCHAR(25) = 'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +DECLARE @inputString VARCHAR(25) = '比尔·拉莫斯' +SELECT reverse(@inputString) COLLATE CHINESE_PRC_CI_AS +GO + +-- with table column of type varchar with collation chinese_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_as +GO + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AS FROM babel_4839_reverse_chinese_prc_ci_as +GO + +-- with table column of type varchar with collation chinese_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_cs_as +GO + +SELECT reverse(a) COLLATE CHINESE_PRC_CS_AS FROM babel_4839_reverse_chinese_prc_cs_as +GO + +-- with table column of type varchar with collation chinese_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_chinese_prc_ci_ai +GO + +SELECT reverse(a) COLLATE CHINESE_PRC_CI_AI FROM babel_4839_reverse_chinese_prc_ci_ai +GO + +-- with table column of type varchar with collation arabic_prc_ci_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_as +GO + +SELECT reverse(a) COLLATE ARABIC_CI_AS FROM babel_4839_reverse_arabic_ci_as +GO + +-- with table column of type varchar with collation arabic_prc_cs_as +SELECT reverse(a) FROM babel_4839_reverse_arabic_cs_as +GO + +SELECT reverse(a) COLLATE ARABIC_CS_AS FROM babel_4839_reverse_arabic_cs_as +GO + +-- with table column of type varchar with collation arabic_prc_ci_ai +SELECT reverse(a) FROM babel_4839_reverse_arabic_ci_ai +GO + +SELECT reverse(a) COLLATE ARABIC_CI_AI FROM babel_4839_reverse_arabic_ci_ai +GO + +-- input type nchar +DECLARE @inputString NCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString NCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +-- with table column of type nchar +SELECT reverse(a) FROM babel_4839_reverse_t1 +GO + +-- input type nvarchar +DECLARE @inputString NVARCHAR(25) = N'abc🙂defghi🙂🙂' +SELECT reverse(@inputString) +GO + +DECLARE @inputString NVARCHAR(25) = N'比尔·拉莫斯' +SELECT reverse(@inputString) +GO + +-- input type binary +DECLARE @inputString BINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO + +-- input type varbinary +DECLARE @inputString VARBINARY(10) = 0x6162636465666768 +SELECT reverse(@inputString) +GO + +-- dependent objects +SELECT * FROM babel_4839_reverse_dep_view +GO + +EXEC babel_4839_reverse_dep_proc +GO + +SELECT * FROM babel_4839_reverse_dep_func() +GO + +SELECT * FROM babel_4839_reverse_itvf_func() +GO + +SELECT * FROM babel_4839_reverse_dep_view_1 +GO + +SELECT * FROM babel_4839_reverse_dep_view_2 +GO + +SELECT * FROM babel_4839_reverse_dep_view_3 +GO + +SELECT * FROM babel_4839_reverse_dep_view_4 +GO + +SELECT * FROM babel_4839_reverse_dep_view_5 +GO + +SELECT * FROM babel_4839_reverse_dep_view_6 +GO + +SELECT * FROM babel_4839_reverse_dep_view_7 +GO + +-- input type UDT +-- -- in table babel_4839_reverse_UDT, col 'a' has basetype image and col 'b' has basetype varchar +SELECT reverse(a) FROM babel_4839_reverse_UDT +GO + +SELECT reverse(b) FROM babel_4839_reverse_UDT +GO + +-- other different datatypes, datatypes that are not implicitly coercible to varchar/nvarchar should throw error +DECLARE @inputString date = '2016-12-21'; +SELECT reverse(@inputString) +GO + +DECLARE @date date = '12-21-16'; +DECLARE @inputString datetime = @date; +SELECT reverse(@inputString) +GO + +DECLARE @inputString smalldatetime = '1955-12-13 12:43:10'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString time(4) = '12:10:05.1237'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString datetimeoffset(4) = '1968-10-23 12:45:37.1234 +10:0'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString datetime2(4) = '1968-10-23 12:45:37.1237'; +SELECT reverse(@inputString) +GO + +DECLARE @inputString decimal = 123456; +SELECT reverse(@inputString) +GO + +DECLARE @inputString numeric = 12345.12; +SELECT reverse(@inputString) +GO + +DECLARE @inputString float = 12345.1; +SELECT reverse(@inputString) +GO + +DECLARE @inputString real = 12345.1; +SELECT reverse(@inputString) +GO + +DECLARE @inputString bigint = 12345678; +SELECT reverse(@inputString) +GO + +DECLARE @inputString int = 12345678; +SELECT reverse(@inputString) +GO + +DECLARE @inputString smallint = 12356; +SELECT reverse(@inputString) +GO + +DECLARE @inputString tinyint = 235; +SELECT reverse(@inputString) +GO + +DECLARE @inputString money = 12356; +SELECT reverse(@inputString) +GO + +DECLARE @inputString smallmoney = 12356; +SELECT reverse(@inputString) +GO + +DECLARE @inputString bit = 1; +SELECT reverse(@inputString) +GO + +DECLARE @inputString uniqueidentifier = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier) +SELECT reverse(@inputString) +GO + +SELECT reverse(a) from babel_4839_reverse_image; +GO + +-- input datatype text +SELECT reverse(a) FROM babel_4839_reverse_text +GO + +-- input datatype ntext +SELECT reverse(b) FROM babel_4839_reverse_text +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(@inputString) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(@inputString) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(@inputString) +GO + +DECLARE @inputString geography = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +SELECT reverse(@inputString) +GO + +DECLARE @inputString sql_variant = CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS sql_variant) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString xml = CAST ('' AS xml) +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO + +DECLARE @inputString geometry = geometry::STGeomFromText('POINT (1 2)', 0); +SELECT reverse(CAST(@inputString AS VARCHAR(50))) +GO diff --git a/test/JDBC/jdbc_schedule b/test/JDBC/jdbc_schedule index b6b7156c04b..f5d48501de4 100644 --- a/test/JDBC/jdbc_schedule +++ b/test/JDBC/jdbc_schedule @@ -331,6 +331,10 @@ ignore#!#catalogs_dbo_sys_schema-upgrade-vu-prepare ignore#!#catalogs_dbo_sys_schema-upgrade-vu-verify ignore#!#catalogs_dbo_sys_schema-upgrade-vu-cleanup +# These tests are meant for upgrade scenario prior to 15_8 or 16_4 release +ignore#!#reverse-before-15_8-or-16_4-vu-prepare +ignore#!#reverse-before-15_8-or-16_4-vu-verify +ignore#!#reverse-before-15_8-or-16_4-vu-cleanup ignore#!#ISC-Tables-before_16_4_or_15_8_or_14_13-vu-prepare ignore#!#ISC-Tables-before_16_4_or_15_8_or_14_13-vu-verify ignore#!#ISC-Tables-before_16_4_or_15_8_or_14_13-vu-cleanup diff --git a/test/JDBC/upgrade/13_4/schedule b/test/JDBC/upgrade/13_4/schedule index 6bca6f66c75..cbef4e18a56 100644 --- a/test/JDBC/upgrade/13_4/schedule +++ b/test/JDBC/upgrade/13_4/schedule @@ -240,3 +240,4 @@ left-before-15_8-or-16_4 right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/13_5/schedule b/test/JDBC/upgrade/13_5/schedule index a8fe82a0554..0363737d1c3 100644 --- a/test/JDBC/upgrade/13_5/schedule +++ b/test/JDBC/upgrade/13_5/schedule @@ -293,3 +293,4 @@ left-before-15_8-or-16_4 right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/13_6/schedule b/test/JDBC/upgrade/13_6/schedule index cf475d8a827..1327b4c93a4 100644 --- a/test/JDBC/upgrade/13_6/schedule +++ b/test/JDBC/upgrade/13_6/schedule @@ -349,3 +349,4 @@ right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/13_7/schedule b/test/JDBC/upgrade/13_7/schedule index eb5cae7c145..2d9d57cdac5 100644 --- a/test/JDBC/upgrade/13_7/schedule +++ b/test/JDBC/upgrade/13_7/schedule @@ -342,3 +342,4 @@ left-before-15_8-or-16_4 right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/13_8/schedule b/test/JDBC/upgrade/13_8/schedule index 354a9a4be39..f1b742802ae 100644 --- a/test/JDBC/upgrade/13_8/schedule +++ b/test/JDBC/upgrade/13_8/schedule @@ -342,3 +342,4 @@ left-before-15_8-or-16_4 right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 BABEL-4869 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index 2ba7093f258..6c82b785f66 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -347,3 +347,4 @@ right-before-15_8-or-16_4 BABEL-4863-before-16_3-or-15_7-or-14_12 babel_726-before-14_12-or-15_7-or-16_3 BABEL-4869 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index d6e92203862..014ade173d4 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -449,3 +449,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 3b1a17d6b02..187eebca630 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -447,3 +447,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index 79a999d5501..f7fd039767a 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -448,3 +448,4 @@ babel_4328_datetime2 babel_4328_datetimeoffset babel_726 BABEL-3401 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index 882322de179..098e190be63 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -448,3 +448,4 @@ babel_4328_datetime2 babel_4328_datetimeoffset babel_726 BABEL-3401 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index d3eaad4c7f4..4d4a5a1f67c 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -370,3 +370,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index b9fb6bb8bfa..9c9d0e97312 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -382,3 +382,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index 863375a2997..031a0a0d08c 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -419,3 +419,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index c4d8f318eb6..de6becd4edb 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -440,3 +440,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index c1cc86c9c0f..8c89be1338a 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -442,3 +442,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 16b079bd995..ba7a2b9f688 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -445,3 +445,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 11b4610aaed..0fd44c49848 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -418,3 +418,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index cfed24a9ec8..7223bf9ab77 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -453,3 +453,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index 3546ae04aef..8ad992a719d 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -472,3 +472,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index bfa4dd0bea0..af758020a8c 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -484,3 +484,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index b1834f5d226..8479e645f20 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -515,3 +515,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 70fd96ac719..6361d10a4a1 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -531,3 +531,4 @@ BABEL-4869 babel_4328_datetime-before-16_3 babel_4328_datetime2-before-16_3 babel_4328_datetimeoffset-before-16_3 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 3afcc3f5b17..3f5150dbc86 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -533,6 +533,7 @@ test_like_for_AI babel_726 BABEL-4869 BABEL-4815 +reverse-before-15_8-or-16_4 BABEL-3401 babel_4328_datetime babel_4328_datetime2 diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index aeb6e54b795..e1f37c6fb05 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -528,3 +528,4 @@ ltrim rtrim left right +reverse diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index b057877c5f7..68fb6f537b8 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -524,3 +524,4 @@ ltrim-before-15_8-or-16_4 rtrim-before-15_8-or-16_4 left-before-15_8-or-16_4 right-before-15_8-or-16_4 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index b104eff58ec..a62a8d7712d 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -539,3 +539,4 @@ ltrim-before-15_8-or-16_4 rtrim-before-15_8-or-16_4 left-before-15_8-or-16_4 right-before-15_8-or-16_4 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 6dde68bebd6..1d73345a938 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -541,3 +541,4 @@ ltrim-before-15_8-or-16_4 rtrim-before-15_8-or-16_4 left-before-15_8-or-16_4 right-before-15_8-or-16_4 +reverse-before-15_8-or-16_4 diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 1f35f0ef139..fc50d4eba70 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -550,3 +550,4 @@ BABEL-3820 PARTITION BABEL-5071 string_agg +reverse