Skip to content

Commit

Permalink
Handle comparison operators containing whitespace (#2203)
Browse files Browse the repository at this point in the history
2-character comparison operators may contain whitespace (e.g. ! =, < >, but Babelfish does not currently support this.
Also, Babelfish does not support the !< and !> operators.
This fix addresses both issues by rewriting the ANTLR input stream.

Signed-off-by: Rob Verschoor [email protected]
Issues Resolved

BABEL-3379 Babelfish doesn't strip out white space for comparison operators
BABEL-4114 Support comparison operators !< and !>
  • Loading branch information
robverschoor authored and shardgupta committed Jan 9, 2024
1 parent 740e035 commit 6ac3a8b
Show file tree
Hide file tree
Showing 8 changed files with 508 additions and 3 deletions.
41 changes: 38 additions & 3 deletions contrib/babelfishpg_tsql/src/tsqlIface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2489,7 +2489,42 @@ class tsqlMutator : public TSqlParserBaseListener
std::string result = Trees::getNodeText(t, this->ruleNames);
return result;
}


void enterComparison_operator(TSqlParser::Comparison_operatorContext *ctx) override
{
// Handle multiple cases:
// - 2-char comparison operators containing whitespace, i.e. '! =', '< >', etc.
// - operators !< and !> (which may also contains whitespace), convert to >= and <=
std::string str = getFullText(ctx);
std::string operator_final = "";
int fill = 0;

if (str.length() > 2)
{
// This operator contains whitespace, remove it
for(size_t i = 0; i < str.length(); i++)
{
if (!isspace(str[i]))
operator_final += str[i];
}
fill = str.length() - operator_final.length();
}

// Handle !> and !< operators by converting to <= and >=
if (pg_strncasecmp(str.c_str(), "!<", 2) == 0) operator_final = ">=";
else if (pg_strncasecmp(operator_final.c_str(), "!<", 2) == 0) operator_final = ">=";
else if (pg_strncasecmp(str.c_str(), "!>", 2) == 0) operator_final = "<=";
else if (pg_strncasecmp(operator_final.c_str(), "!>", 2) == 0) operator_final = "<=";

// Fill with spaces until original length
operator_final.append(fill, ' ');

if (operator_final.length() > 0)
{
stream.setText(ctx->start->getStartIndex(), operator_final.c_str());
}
}

// Tree listener overrides
void enterEveryRule(ParserRuleContext *ctx) override
{
Expand All @@ -2507,8 +2542,8 @@ class tsqlMutator : public TSqlParserBaseListener
std::cout << "-leaving (tsqlMutator)" << (void *) ctx << "[" << desc << "]" << std::endl;
}

void enterFunc_proc_name_server_database_schema(TSqlParser::Func_proc_name_server_database_schemaContext *ctx) override
{
void enterFunc_proc_name_server_database_schema(TSqlParser::Func_proc_name_server_database_schemaContext *ctx) override
{
// We are looking at a function name; it may be a function call, or a
// DROP function statement, or some other reference.
//
Expand Down
8 changes: 8 additions & 0 deletions test/JDBC/expected/operator_whitespace-vu-cleanup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
drop procedure p1_operator_whitespace
go

drop view v1_operator_whitespace
go

drop table t1_operator_whitespace
go
31 changes: 31 additions & 0 deletions test/JDBC/expected/operator_whitespace-vu-prepare.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
create table t1_operator_whitespace(a int)
go

create view v1_operator_whitespace as
select c1=1, c2=a from t1_operator_whitespace where a = case when a! >2 then a else 0 end
go


create procedure p1_operator_whitespace
as
select a as p1 from t1_operator_whitespace where a ! = 2
select a as p2 from t1_operator_whitespace where a ! =2
select a as q3 from t1_operator_whitespace where a !


= 2
select a as p4 from t1_operator_whitespace where a < >2
select a as p5 from t1_operator_whitespace where a < = 2
select a as p6 from t1_operator_whitespace where a > =2
select a as p7 from t1_operator_whitespace where a!<2
select a as p8 from t1_operator_whitespace where a !< 2
select a as p9 from t1_operator_whitespace where a ! < 2
select a as p10 from t1_operator_whitespace where a! <2
select a as p11 from t1_operator_whitespace where a !> 2
select a as p12 from t1_operator_whitespace where a!>2
select a as p13 from t1_operator_whitespace where a ! > 2
select a as p14 from t1_operator_whitespace where a! >2
select a as q15 from t1_operator_whitespace where a = case when a! >2 then a else 0 end
EXECUTE('select a as p16 from t1_operator_whitespace where a ! = 2')
EXECUTE('select a as p17 from t1_operator_whitespace where a ! < 2')
go
Loading

0 comments on commit 6ac3a8b

Please sign in to comment.