Skip to content

Commit

Permalink
Support for T-SQL variable/parameter names like @@var and @var# (babe…
Browse files Browse the repository at this point in the history
…lfish-for-postgresql#3073)

Valid names of user-defined T-SQL variables and/or parameters are @@Myvar, @Myvar#, @#myvar, etc. and indeed we see customer T-SQL applications using such names.
Until now, such names have raised errors in the backend because we can only handle variable/parameter names with one leading @ and without # characters.
This fix adds support by enclosing such variable names in square bracket delimiters; when using double quotes as delimiters (as is currently done in most places for regular-named variables), a query like select @@v will produce the string '@@v' instead of the value of variable @@v.
The fix is partly done through ANTLR rewriting and partly at execution time elsewhere in the babelfish_tsql codeline. Things are complicated by the fact that the ANTLR rewriting logic is very fragmented, as well as that for some variables reference contexts inside the body of a procedure or trigger, rewriting must be postponed until the body is executed. This means there are multiple code paths where these variable names must be intercepted.
This fix also addresses variable names in some contexts (like a cursor variable) that previously could not be longer than 63 characters.
This fix also solves the previous issue that a variable could be declared with a name matching an internal sys function, but was resolved as the intern function instead of the variable, i.e. DECLARE @@rand INT=123 SELECT @@rand would return a random number instead of 123.

Issues Resolved: 
BABEL-2481 Parameter declarations containing # characters not handled correctly
BABEL-476 Support local variables/parameters with multiple '@' characters
BABEL-5384 User-defined @@variable should not be mapped to sys function

Signed-off-by: Rob Verschoor [email protected]
  • Loading branch information
robverschoor authored and ritanwar committed Nov 25, 2024
1 parent 4870eec commit 86f693b
Show file tree
Hide file tree
Showing 21 changed files with 6,849 additions and 126 deletions.
37 changes: 21 additions & 16 deletions contrib/babelfishpg_tsql/antlr/TSqlParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ raiseerror_statement
;

raiseerror_msg
: DECIMAL | char_string | LOCAL_ID
: DECIMAL | char_string | local_id
;

raiseerror_option
Expand Down Expand Up @@ -2004,7 +2004,7 @@ func_body_return_select_body
;

func_body_returns_table
: RETURNS LOCAL_ID table_type_definition
: RETURNS local_id table_type_definition
(WITH function_option (COMMA function_option)*)?
AS?
BEGIN sql_clauses* SEMI? END
Expand All @@ -2031,7 +2031,7 @@ atomic_func_body

// CREATE PROC p @p INT NULL --> this appears to be accepted syntax for non-native compiled procs, though formally not allowed
procedure_param
: LOCAL_ID AS? data_type VARYING? (NOT? NULL_P)? (EQUAL default_val=expression)? param_option=(OUT | OUTPUT | READONLY)?
: local_id AS? data_type VARYING? (NOT? NULL_P)? (EQUAL default_val=expression)? param_option=(OUT | OUTPUT | READONLY)?
;

// drop_procedure_param can be used in a DROP FUNCTION or DROP PROCEDURE command
Expand Down Expand Up @@ -2640,7 +2640,7 @@ predict_function

// https://msdn.microsoft.com/en-us/library/ms188927.aspx
declare_statement
: DECLARE LOCAL_ID AS? table_type_definition SEMI?
: DECLARE local_id AS? table_type_definition SEMI?
| DECLARE loc+=declare_local (COMMA loc+=declare_local)* SEMI?
;

Expand Down Expand Up @@ -2842,7 +2842,7 @@ execute_statement_arg
;

execute_statement_arg_named
: name=LOCAL_ID EQUAL value=execute_parameter
: name=local_id EQUAL value=execute_parameter
;

execute_statement_arg_unnamed
Expand All @@ -2851,13 +2851,13 @@ execute_statement_arg_unnamed

execute_parameter
: constant
| LOCAL_ID (OUTPUT | OUT)?
| local_id (OUTPUT | OUT)?
| id
| DEFAULT
;

execute_var_string
: LOCAL_ID
: local_id
| char_string
;

Expand Down Expand Up @@ -3098,21 +3098,21 @@ set_statement
// https://msdn.microsoft.com/en-us/library/ms174377.aspx
transaction_statement
// https://msdn.microsoft.com/en-us/library/ms188386.aspx
: BEGIN DISTRIBUTED (TRAN | TRANSACTION) (id | LOCAL_ID)? SEMI?
: BEGIN DISTRIBUTED (TRAN | TRANSACTION) (id | local_id)? SEMI?
// https://msdn.microsoft.com/en-us/library/ms188929.aspx
| BEGIN (TRAN | TRANSACTION) ((id | LOCAL_ID) (WITH MARK char_string)?)? SEMI?
| BEGIN (TRAN | TRANSACTION) ((id | local_id) (WITH MARK char_string)?)? SEMI?
// https://msdn.microsoft.com/en-us/library/ms190295.aspx
| COMMIT (TRAN | TRANSACTION) (id | LOCAL_ID)? (WITH LR_BRACKET DELAYED_DURABILITY EQUAL (OFF | ON) RR_BRACKET )? SEMI?
| COMMIT (TRAN | TRANSACTION) (id | local_id)? (WITH LR_BRACKET DELAYED_DURABILITY EQUAL (OFF | ON) RR_BRACKET )? SEMI?
// https://msdn.microsoft.com/en-us/library/ms178628.aspx
| COMMIT WORK? SEMI?
| COMMIT id
| ROLLBACK id
// https://msdn.microsoft.com/en-us/library/ms181299.aspx
| ROLLBACK (TRAN | TRANSACTION) (id | LOCAL_ID)? SEMI?
| ROLLBACK (TRAN | TRANSACTION) (id | local_id)? SEMI?
// https://msdn.microsoft.com/en-us/library/ms174973.aspx
| ROLLBACK WORK? SEMI?
// https://msdn.microsoft.com/en-us/library/ms188378.aspx
| SAVE (TRAN | TRANSACTION) (id | LOCAL_ID)? SEMI?
| SAVE (TRAN | TRANSACTION) (id | local_id)? SEMI?
;

// https://msdn.microsoft.com/en-us/library/ms188366.aspx
Expand All @@ -3135,7 +3135,7 @@ shutdown_statement
;

dbcc_statement
: DBCC CHECKIDENT ( LR_BRACKET table_name_string ( (COMMA NORESEED) | (COMMA RESEED (COMMA MINUS? new_value=(DECIMAL | FLOAT))?) )? RR_BRACKET ) (WITH dbcc_options)? SEMI?
: DBCC CHECKIDENT ( LR_BRACKET dbcc_table_name ( (COMMA NORESEED) | (COMMA RESEED (COMMA MINUS? checkident_new_value)?) )? RR_BRACKET ) (WITH dbcc_options)? SEMI?
| DBCC name=dbcc_command ( LR_BRACKET expression_list RR_BRACKET )? (WITH dbcc_options)? SEMI?
//These are dbcc commands with strange syntax that doesn't fit the regular dbcc syntax
| DBCC SHRINKLOG ( LR_BRACKET SIZE EQUAL (constant_expression| id | DEFAULT) (KB | MB | GB | TB)? RR_BRACKET )? (WITH dbcc_options)? SEMI?
Expand Down Expand Up @@ -3175,12 +3175,17 @@ dbcc_options
: ID (COMMA ID)?
;


table_name_string
dbcc_table_name
: table = id
| char_string
| local_id
;

checkident_new_value
: DECIMAL
| FLOAT
| local_id
;

execute_as_clause
: (EXECUTE|EXEC) AS (CALLER | SELF | OWNER | char_string)
Expand Down Expand Up @@ -3459,7 +3464,7 @@ set_offsets_keyword

constant_LOCAL_ID
: constant
| LOCAL_ID
| local_id
;

// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/expressions-transact-sql
Expand Down
10 changes: 9 additions & 1 deletion contrib/babelfishpg_tsql/src/pl_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,16 @@ do_compile(FunctionCallInfo fcinfo,
*/
if (function->is_mstvf)
{
/*
* For a user-defined @@var or @var# name,
* delimit with square brackets
*/
char *typname_fmt = "%s.\"%s\"";
if (!is_tsql_atatuservar(argdtype->typname))
typname_fmt = pstrdup("%s.%s");

tbl_dno = argvariable->dno;
tbl_typ = psprintf("%s.%s",
tbl_typ = psprintf(typname_fmt,
get_namespace_name(
get_rel_namespace(get_typ_typrelid(argtypeid))),
argdtype->typname);
Expand Down
Loading

0 comments on commit 86f693b

Please sign in to comment.