Skip to content

Commit

Permalink
Fixed definition of parsename, session_context and sp_set_session_con…
Browse files Browse the repository at this point in the history
…text (#2152)

Following is the current definition of PARSENAME, session_context and sp_set_session_context

-- parsename
CREATE OR REPLACE FUNCTION sys.parsename(object_name sys.VARCHAR, object_piece int)
RETURNS sys.SYSNAME
AS 'babelfishpg_tsql', 'parsename'
LANGUAGE C IMMUTABLE STRICT; 

-- session_context
CREATE OR REPLACE FUNCTION sys.session_context ("@key" sys.sysname)
RETURNS sys.SQL_VARIANT 
AS 'babelfishpg_tsql', 'session_context' 
LANGUAGE C;
GRANT EXECUTE ON FUNCTION sys.session_context TO PUBLIC;

-- sp_set_session_context
CREATE OR REPLACE PROCEDURE sys.sp_set_session_context ("@key" sys.sysname, 
    "@value" sys.SQL_VARIANT, "@read_only" sys.bit = 0)
AS 'babelfishpg_tsql', 'sp_set_session_context'
LANGUAGE C;
GRANT EXECUTE ON PROCEDURE sys.sp_set_session_context TO PUBLIC;

But the correct definitions should be as follows, in these definitions sys.NVARCHAR should be used instead of sys.VARCHAR and sys.NVARCHAR(128) instead of sys.SYSNAME. This commit fixes such issues. 

--parsename
CREATE OR REPLACE FUNCTION sys.parsename(object_name sys.NVARCHAR(128), object_piece int)
RETURNS sys.NVARCHAR(128)
AS 'babelfishpg_tsql', 'parsename'
LANGUAGE C IMMUTABLE STRICT;

-- session_context
CREATE OR REPLACE FUNCTION sys.session_context ("@key" sys.NVARCHAR(128))
RETURNS sys.SQL_VARIANT 
AS 'babelfishpg_tsql', 'session_context'
LANGUAGE C;
GRANT EXECUTE ON FUNCTION sys.session_context TO PUBLIC;

-- sp_set_session_context
CREATE OR REPLACE PROCEDURE sys.sp_set_session_context ("@key" sys.NVARCHAR(128), 
    "@value" sys.SQL_VARIANT, "@read_only" sys.bit = 0)
AS 'babelfishpg_tsql', 'sp_set_session_context'
LANGUAGE C;
GRANT EXECUTE ON PROCEDURE sys.sp_set_session_context TO PUBLIC;

Task: BABEL-4583
Signed-off-by: Rohit Bhagat <[email protected]>
  • Loading branch information
rohit01010 authored Dec 20, 2023
1 parent dff6a8f commit 37c2532
Show file tree
Hide file tree
Showing 36 changed files with 1,191 additions and 99 deletions.
1 change: 1 addition & 0 deletions contrib/babelfishpg_common/src/babelfishpg_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ get_common_utility_plugin(void)
common_utility_plugin_var.TdsGetVariantBaseType = &TdsGetVariantBaseType;
common_utility_plugin_var.lookup_tsql_datatype_oid = &lookup_tsql_datatype_oid;
common_utility_plugin_var.GetUTF8CodePoint = &GetUTF8CodePoint;
common_utility_plugin_var.TsqlUTF8LengthInUTF16 = &TsqlUTF8LengthInUTF16;
}
return &common_utility_plugin_var;
}
2 changes: 1 addition & 1 deletion contrib/babelfishpg_common/src/babelfishpg_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,5 @@ typedef struct common_utility_plugin
bool *isBaseDate, int *variantHeaderLen);
Oid (*lookup_tsql_datatype_oid) (const char *typestr);
int32_t (*GetUTF8CodePoint) (const unsigned char *in, int len, int *consumed_p);

int (*TsqlUTF8LengthInUTF16) (const void *vin, int len);
} common_utility_plugin;
1 change: 1 addition & 0 deletions contrib/babelfishpg_common/src/varchar.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
extern int32_t GetUTF8CodePoint(const unsigned char *in, int len, int *consumed_p);
extern void *tsql_varchar_input(const char *s, size_t len, int32 atttypmod);
extern void *tsql_bpchar_input(const char *s, size_t len, int32 atttypmod);
extern int TsqlUTF8LengthInUTF16(const void *vin, int len);

#endif
8 changes: 5 additions & 3 deletions contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2537,14 +2537,16 @@ LANGUAGE 'pltsql';
GRANT EXECUTE ON PROCEDURE sys.sp_helpdbfixedrole TO PUBLIC;


CREATE OR REPLACE PROCEDURE sys.sp_set_session_context ("@key" sys.sysname,
CREATE OR REPLACE PROCEDURE sys.sp_set_session_context ("@key" sys.NVARCHAR(128),
"@value" sys.SQL_VARIANT, "@read_only" sys.bit = 0)
AS 'babelfishpg_tsql', 'sp_set_session_context'
LANGUAGE C;
GRANT EXECUTE ON PROCEDURE sys.sp_set_session_context TO PUBLIC;

CREATE OR REPLACE FUNCTION sys.session_context ("@key" sys.sysname)
RETURNS sys.SQL_VARIANT AS 'babelfishpg_tsql', 'session_context' LANGUAGE C;
CREATE OR REPLACE FUNCTION sys.session_context ("@key" sys.NVARCHAR(128))
RETURNS sys.SQL_VARIANT
AS 'babelfishpg_tsql', 'session_context'
LANGUAGE C;
GRANT EXECUTE ON FUNCTION sys.session_context TO PUBLIC;

-- SYSLOGINS
Expand Down
4 changes: 2 additions & 2 deletions contrib/babelfishpg_tsql/sql/sys_functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,8 @@ RETURNS INTEGER AS
'babelfishpg_tsql', 'object_id'
LANGUAGE C STABLE;

CREATE OR REPLACE FUNCTION sys.parsename(object_name sys.VARCHAR, object_piece int)
RETURNS sys.SYSNAME
CREATE OR REPLACE FUNCTION sys.parsename(object_name sys.NVARCHAR, object_piece int)
RETURNS sys.NVARCHAR(128)
AS 'babelfishpg_tsql', 'parsename'
LANGUAGE C IMMUTABLE STRICT;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
\echo Use "ALTER EXTENSION ""babelfishpg_tsql"" UPDATE TO '3.4.0'" to load this file. \quit
\echo Use "ALTER EXTENSION ""babelfishpg_tsql"" UPDATE TO '3.5.0'" to load this file. \quit

-- add 'sys' to search path for the convenience
SELECT set_config('search_path', 'sys, '||current_setting('search_path'), false);
Expand Down Expand Up @@ -58,6 +58,108 @@ WHERE t5.contype = 'p'
AND CAST(t4."ORDINAL_POSITION" AS smallint) = t5.conkey[seq]
AND ext.dbid = sys.db_id();

-- Rename functions for dependencies
DO $$
DECLARE
exception_message text;
BEGIN
-- Rename parsename for dependencies
ALTER FUNCTION sys.parsename(sys.VARCHAR, INT) RENAME TO parsename_deprecated_in_3_5_0;

EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

DO $$
DECLARE
exception_message text;
BEGIN
-- Rename sp_set_session_context for dependencies
ALTER PROCEDURE sys.sp_set_session_context(sys.SYSNAME, sys.SQL_VARIANT, sys.BIT) RENAME TO sp_set_session_context_deprecated_in_3_5_0;

EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

DO $$
DECLARE
exception_message text;
BEGIN
-- Rename session_context for dependencies
ALTER FUNCTION sys.session_context(sys.SYSNAME) RENAME TO session_context_deprecated_in_3_5_0;

EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

CREATE OR REPLACE FUNCTION sys.parsename(object_name sys.NVARCHAR, object_piece int)
RETURNS sys.NVARCHAR(128)
AS 'babelfishpg_tsql', 'parsename'
LANGUAGE C IMMUTABLE STRICT;

CREATE OR REPLACE PROCEDURE sys.sp_set_session_context ("@key" sys.NVARCHAR(128),
"@value" sys.SQL_VARIANT, "@read_only" sys.bit = 0)
AS 'babelfishpg_tsql', 'sp_set_session_context'
LANGUAGE C;
GRANT EXECUTE ON PROCEDURE sys.sp_set_session_context TO PUBLIC;

CREATE OR REPLACE FUNCTION sys.session_context ("@key" sys.NVARCHAR(128))
RETURNS sys.SQL_VARIANT
AS 'babelfishpg_tsql', 'session_context'
LANGUAGE C;
GRANT EXECUTE ON FUNCTION sys.session_context TO PUBLIC;

-- === DROP deprecated functions (if exists)
DO $$
DECLARE
exception_message text;
BEGIN
-- === DROP parsename_deprecated_in_3_5_0
CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'parsename_deprecated_in_3_5_0');

EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

DO $$
DECLARE
exception_message text;
BEGIN
-- === DROP sp_set_session_context_deprecated_in_3_5_0
CALL sys.babelfish_drop_deprecated_object('procedure', 'sys', 'sp_set_session_context_deprecated_in_3_5_0');

EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

DO $$
DECLARE
exception_message text;
BEGIN
-- === DROP session_context_deprecated_in_3_5_0
CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'session_context_deprecated_in_3_5_0');

EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT;
RAISE WARNING '%', exception_message;
END;
$$;

-- Drops the temporary procedure used by the upgrade script.
-- Please have this be one of the last statements executed in this upgrade script.
Expand Down
7 changes: 7 additions & 0 deletions contrib/babelfishpg_tsql/src/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ sp_set_session_context(PG_FUNCTION_ARGS)
VarChar *key_arg;
SessionCxtEntry *result_entry;
char *key;
int encoded_key_bytelen;
bool found;
MemoryContext oldContext;
int i;
Expand All @@ -294,6 +295,12 @@ sp_set_session_context(PG_FUNCTION_ARGS)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("The parameters supplied for the procedure \"sp_set_session_context\" are not valid.")));

encoded_key_bytelen = ((*common_utility_plugin_ptr->TsqlUTF8LengthInUTF16)(VARDATA_ANY(key_arg), VARSIZE_ANY_EXHDR(key_arg))) * 2; /* Each UTF16 character is 2 bytes */

if (encoded_key_bytelen > 256)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("Cannot set key '%s' in the session context. The size of the key cannot exceed 256 bytes.", key)));

/* Strip Whitespace */
i = strlen(key);
while (i > 0 && isspace((unsigned char) key[i - 1]))
Expand Down
16 changes: 4 additions & 12 deletions test/JDBC/expected/Test-sp_set_session_context-vu-verify.out
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,9 @@ declare @key nvarchar(4000) = cast (REPLICATE('a', 129) as nvarchar(4000));
EXEC sp_set_session_context @key, '129 chars';
SELECT sys.session_context(@key)
go
~~ERROR (Code: 8152)~~

~~ERROR (Message: value too long for type character varying(128))~~

~~ERROR (Code: 8152)~~
~~ERROR (Code: 33557097)~~

~~ERROR (Message: value too long for type character varying(128))~~
~~ERROR (Message: Cannot set key 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' in the session context. The size of the key cannot exceed 256 bytes.)~~


declare @key nvarchar(4000) = cast (REPLICATE('あ', 128) as nvarchar(4000));
Expand All @@ -237,13 +233,9 @@ declare @key nvarchar(4000) = cast (REPLICATE('あ', 129) as nvarchar(4000));
EXEC sp_set_session_context @key, 1;
select session_context(@key);
go
~~ERROR (Code: 8152)~~

~~ERROR (Message: value too long for type character varying(128))~~

~~ERROR (Code: 8152)~~
~~ERROR (Code: 33557097)~~

~~ERROR (Message: value too long for type character varying(128))~~
~~ERROR (Message: Cannot set key 'あああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ' in the session context. The size of the key cannot exceed 256 bytes.)~~


EXEC sp_set_session_context 'a ', 'trailing spaces'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
DROP VIEW IF EXISTS parsename_EmployeeDatabaseView1_before_14_11_or_15_6;
GO

DROP PROCEDURE IF EXISTS parsename_GetEmployeeDatabaseName1_before_14_11_or_15_6;
GO

DROP VIEW IF EXISTS parsename_EmployeeDatabaseView2_before_14_11_or_15_6;
GO

DROP PROCEDURE IF EXISTS parsename_GetEmployeeDatabaseName2_before_14_11_or_15_6;
GO

DROP VIEW IF EXISTS parsename_EmployeeDatabaseView3_before_14_11_or_15_6;
GO

DROP PROCEDURE IF EXISTS parsename_GetEmployeeDatabaseName3_before_14_11_or_15_6;
GO

DROP TABLE IF EXISTS parsename_Employee_before_14_11_or_15_6;
GO
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
CREATE TABLE parsename_Employee_before_14_11_or_15_6 (
EmployeeID INT PRIMARY KEY,
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
HireDate DATETIME,
Salary MONEY
);
GO


-- Insert some sample data
INSERT INTO parsename_Employee_before_14_11_or_15_6(EmployeeID, FirstName, LastName, HireDate, Salary)
VALUES (1, 'John', 'Doe', '2020-01-01', 50000),
(2, 'Jane', 'Smith', '2020-02-01', 60000),
(3, 'Bob', 'Johnson', '2020-03-01', 70000);
GO
~~ROW COUNT: 3~~


CREATE VIEW parsename_EmployeeDatabaseView1_before_14_11_or_15_6
AS
SELECT PARSENAME('tempdb.dbo.Employee', 3) AS [Database Name]
GO

CREATE PROCEDURE parsename_GetEmployeeDatabaseName1_before_14_11_or_15_6
AS
BEGIN
SELECT PARSENAME('tempdb.dbo.Employee', 3) AS [Database Name]
END
GO

CREATE VIEW parsename_EmployeeDatabaseView2_before_14_11_or_15_6
AS
SELECT PARSENAME('tempdb.dbo.Employee', 2) AS [Schema Name]
GO

CREATE PROCEDURE parsename_GetEmployeeDatabaseName2_before_14_11_or_15_6
AS
BEGIN
SELECT PARSENAME('tempdb.dbo.Employee', 2) AS [Schema Name]
END
GO

CREATE VIEW parsename_EmployeeDatabaseView3_before_14_11_or_15_6
AS
SELECT PARSENAME('tempdb.dbo.Employee', 1) AS [Table Name]
GO

CREATE PROCEDURE parsename_GetEmployeeDatabaseName3_before_14_11_or_15_6
AS
BEGIN
SELECT PARSENAME('tempdb.dbo.Employee_parsename', 1) AS [Table Name]
END
GO
Loading

0 comments on commit 37c2532

Please sign in to comment.