Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update logic for LIKE operator for Case Insensitive collation #3439

Open
wants to merge 35 commits into
base: BABEL_5_X_DEV
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
780e8e0
Update logic for LIKE operator for Case Insensitive collation
ahmed-shameem Jan 30, 2025
05b7ac9
Fix collate clause for prefix match
ahmed-shameem Jan 30, 2025
27c1368
Update expected output
ahmed-shameem Jan 30, 2025
fe87cdc
Update expected output
ahmed-shameem Jan 30, 2025
411fb23
Correct transformation logic and handle the case for CollateExpr
ahmed-shameem Feb 3, 2025
ad9f928
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Feb 3, 2025
6dc495e
Update opcollid for exact pattern match
ahmed-shameem Feb 3, 2025
df91bea
Update logic by adding extra COLLATE on top for leftop and use the ol…
ahmed-shameem Feb 4, 2025
8a70738
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Feb 11, 2025
35af9eb
Update logic for LIKE for CI collations in general
ahmed-shameem Feb 11, 2025
ff0ec83
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Feb 17, 2025
999c4be
Check BABEL-5155
ahmed-shameem Feb 17, 2025
5946b87
Revert "Check BABEL-5155"
ahmed-shameem Feb 17, 2025
a464b3c
Refractor code
ahmed-shameem Feb 17, 2025
7a792a6
Add tests
ahmed-shameem Feb 17, 2025
ebc4093
Update upgrade schedule file
ahmed-shameem Feb 17, 2025
dbaac5e
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Feb 25, 2025
385d124
Address review comments
ahmed-shameem Feb 25, 2025
a708dc1
Fix test failures
ahmed-shameem Feb 25, 2025
5670e31
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Feb 28, 2025
acc0ff0
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Mar 5, 2025
1ad0877
Add ASSERT condition for operand typeids
ahmed-shameem Mar 5, 2025
50be1d2
Add ASSERT condition for operand typeids
ahmed-shameem Mar 5, 2025
b2655ae
Update schedule files
ahmed-shameem Mar 6, 2025
9da1a04
Update schedule files
ahmed-shameem Mar 6, 2025
1eafe0f
Fix few test failures
ahmed-shameem Mar 6, 2025
44077f6
Fix few test failures
ahmed-shameem Mar 6, 2025
2c4767d
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Mar 6, 2025
d71408a
Fix few test failures
ahmed-shameem Mar 6, 2025
37b04aa
Merge remote-tracking branch 'upstream/BABEL_5_X_DEV' into update-lik…
ahmed-shameem Mar 7, 2025
d45b12d
Fix test failures
ahmed-shameem Mar 7, 2025
5309c0b
Rerun tests
ahmed-shameem Mar 7, 2025
624ade0
Rerun tests
ahmed-shameem Mar 7, 2025
f8fae83
Rerun tests
ahmed-shameem Mar 7, 2025
cb06d31
Rerun tests
ahmed-shameem Mar 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 54 additions & 11 deletions contrib/babelfishpg_tsql/src/collation.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@ transform_funcexpr(Node *node)
return node;
}

static CollateExpr*
create_collate_expr(Node *arg, Oid collid)
{
CollateExpr *expr = makeNode(CollateExpr);
expr->arg = (Expr *) arg;
expr->collOid = collid;
return expr;
}

/*
* If the node is OpExpr and the colaltion is ci_as, then
* transform the LIKE OpExpr to ILIKE OpExpr:
Expand All @@ -321,7 +330,7 @@ transform_funcexpr(Node *node)
static Node *
transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like_entry, coll_info_t coll_info_of_inputcollid)
{
Node *leftop = (Node *) linitial(op->args);
Node *leftop = copyObject(linitial(op->args));
Node *rightop = (Node *) lsecond(op->args);
Oid ltypeId = exprType(leftop);
Oid rtypeId = exprType(rightop);
Expand All @@ -332,6 +341,7 @@ transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like
Operator optup;
Pattern_Prefix_Status pstatus;
int collidx_of_cs_as;
CollateExpr *new_leftop = makeNode(CollateExpr);

tsql_get_database_or_server_collation_oid_internal(true);

Expand Down Expand Up @@ -388,18 +398,28 @@ transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like
if (IsA(leftop, Const) || !IsA(rightop, Const) ||
((Const *) rightop)->constisnull)
{
/* update the collation of left and right node*/
linitial(op->args) = (Node *) create_collate_expr(linitial(op->args), op->inputcollid);
lsecond(op->args) = (Node *) create_collate_expr(lsecond(op->args), op->inputcollid);
return node;
}

patt = (Const *) rightop;
patt->constcollid = op->inputcollid;

/* extract pattern */
pstatus = pattern_fixed_prefix_wrapper(patt, 1, coll_info_of_inputcollid.oid,
&prefix, NULL);

/* update the collation for the prefix as well */
prefix->constcollid = coll_info_of_inputcollid.oid;

/* If there is no constant prefix then there's nothing more to do */
if (pstatus == Pattern_Prefix_None)
{
/* update the collation of left and right node*/
linitial(op->args) = (Node *) create_collate_expr(linitial(op->args), op->inputcollid);
lsecond(op->args) = (Node *) create_collate_expr(lsecond(op->args), op->inputcollid);
return node;
Comment on lines +417 to 420
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you plz point me the example/test cases for this?

}

Expand All @@ -409,7 +429,7 @@ transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like
if (pstatus == Pattern_Prefix_Exact)
{
op_str = like_entry.is_not_match ? "<>" : "=";
optup = compatible_oper(NULL, list_make1(makeString(op_str)), ltypeId, ltypeId,
optup = compatible_oper(NULL, list_make1(makeString(op_str)), ltypeId, rtypeId,
true, -1);
if (optup == (Operator) NULL)
return node;
Expand All @@ -428,11 +448,18 @@ transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like
Node *constant_suffix;
Const *highest_sort_key;

/* Always create a CollateExpr on top to match with op->inputcollid */
new_leftop->arg = linitial(op->args);
new_leftop->collOid = op->inputcollid;
linitial(op->args) = (Node*) new_leftop;

/* construct leftop >= pattern */
optup = compatible_oper(NULL, list_make1(makeString(">=")), ltypeId, ltypeId,
optup = compatible_oper(NULL, list_make1(makeString(">=")), ltypeId, rtypeId,
true, -1);
if (optup == (Operator) NULL)
return node;

/* Use the original node to create the operator */
greater_equal = make_op_with_func(oprid(optup), BOOLOID, false,
(Expr *) leftop, (Expr *) prefix,
InvalidOid, coll_info_of_inputcollid.oid, oprfuncid(optup));
Expand All @@ -447,14 +474,15 @@ transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like
return node;
concat_expr = make_op_with_func(oprid(optup), rtypeId, false,
(Expr *) prefix, (Expr *) highest_sort_key,
InvalidOid, coll_info_of_inputcollid.oid, oprfuncid(optup));
coll_info_of_inputcollid.oid, coll_info_of_inputcollid.oid, oprfuncid(optup));
ReleaseSysCache(optup);
/* construct leftop < pattern */
optup = compatible_oper(NULL, list_make1(makeString("<")), ltypeId, ltypeId,
optup = compatible_oper(NULL, list_make1(makeString("<")), ltypeId, rtypeId,
true, -1);
if (optup == (Operator) NULL)
return node;

/* Use the original node to create the operator */
less_equal = make_op_with_func(oprid(optup), BOOLOID, false,
(Expr *) leftop, (Expr *) concat_expr,
InvalidOid, coll_info_of_inputcollid.oid, oprfuncid(optup));
Expand Down Expand Up @@ -751,7 +779,7 @@ Datum remove_accents_internal(PG_FUNCTION_ARGS)
}

static Node *
convert_node_to_funcexpr_for_like(Node *node)
convert_node_to_funcexpr_for_like(Node *node, Oid colloid_of_cs_as)
{
FuncExpr *newFuncExpr = makeNode(FuncExpr);
Node *new_node;
Expand Down Expand Up @@ -784,6 +812,7 @@ convert_node_to_funcexpr_for_like(Node *node)
if (con->constisnull)
return new_node;
con->constvalue = DirectFunctionCall1(remove_accents_internal, con->constvalue);
con->constcollid = colloid_of_cs_as;
return (Node *) con;
}
else
Expand Down Expand Up @@ -846,20 +875,34 @@ convert_node_to_funcexpr_for_like(Node *node)


static Node *
transform_likenode_for_AI(Node *node, OpExpr *op)
transform_likenode_for_AI(Node *node, OpExpr *op, coll_info_t coll_info_of_inputcollid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where do we need coll_info_of_inputcollid?

{
Node *leftop = (Node *) linitial(op->args);
Node *rightop = (Node *) lsecond(op->args);
Oid colloid_of_cs_as;

/* Find the CS_AS collation corresponding to the CS_AI collation */
int collidx_of_cs_as =
tsql_find_cs_as_collation_internal(
tsql_find_collation_internal(coll_info_of_inputcollid.collname));

if (NOT_FOUND == collidx_of_cs_as)
{
elog(DEBUG2, "No corresponding CS_AS collation found for collation \"%s\"", coll_info_of_inputcollid.collname);
return node;
}

colloid_of_cs_as = tsql_get_oid_from_collidx(collidx_of_cs_as);

linitial(op->args) = coerce_to_target_type(NULL,
convert_node_to_funcexpr_for_like(leftop),
convert_node_to_funcexpr_for_like(leftop, colloid_of_cs_as),
get_sys_varcharoid(),
exprType(leftop), -1,
COERCION_EXPLICIT,
COERCE_EXPLICIT_CAST,
-1);
lsecond(op->args) = coerce_to_target_type(NULL,
convert_node_to_funcexpr_for_like(rightop),
convert_node_to_funcexpr_for_like(rightop, colloid_of_cs_as),
get_sys_varcharoid(),
exprType(rightop), -1,
COERCION_EXPLICIT,
Expand Down Expand Up @@ -906,7 +949,7 @@ transform_from_cs_ai_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like

op->inputcollid = tsql_get_oid_from_collidx(collidx_of_cs_as);

return transform_likenode_for_AI(node, op);
return transform_likenode_for_AI(node, op, coll_info_of_inputcollid);
}

/*
Expand Down Expand Up @@ -996,7 +1039,7 @@ transform_likenode(Node *node)
coll_info_of_inputcollid.collateflags == 0x000f /* CI_AI */ )
{
if (supported_collation_for_db_and_like(coll_info_of_inputcollid.code_page))
return transform_from_ci_as_for_likenode(transform_likenode_for_AI(node, op), op, like_entry, coll_info_of_inputcollid);
return transform_from_ci_as_for_likenode(transform_likenode_for_AI(node, op, coll_info_of_inputcollid), op, like_entry, coll_info_of_inputcollid);
else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
Expand Down
77 changes: 77 additions & 0 deletions test/JDBC/expected/BABEL-5608-vu-cleanup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@



-- Fix me: will be fixed with BABEL-5155
-- -- CASE 1: T_Const LIKE T_CollateExpr(T_Const)
-- DROP TABLE BABEL_5608_vu_prepare_t1;
-- GO
-- -- CASE 2: T_CollateExpr(T_Const) LIKE T_Const
-- DROP TABLE BABEL_5608_vu_prepare_t2;
-- GO
-- -- CASE 3: T_CollateExpr(T_Const) LIKE T_CollateExpr(T_Const)
-- DROP TABLE BABEL_5608_vu_prepare_t3;
-- GO
-- CASE 4: T_ReLabelType (T_Var) LIKE T_Const
DROP TABLE BABEL_5608_vu_prepare_t4_1;
GO

DROP TABLE BABEL_5608_vu_prepare_t4_2;
GO

-- CASE 5: T_ReLabelType(T_Var) LIKE T_CollateExpr(T_Const)
DROP TABLE BABEL_5608_vu_prepare_t5_1;
GO

DROP TABLE BABEL_5608_vu_prepare_t5_2;
GO

-- CASE 6: T_ReLabelType(T_Var) LIKE T_ReLabelType(T_Var)
DROP TABLE BABEL_5608_vu_prepare_t6;
GO

-- CASE 7: T_CollateExpr(T_ReLabel(T_Var)) LIKE T_Const
DROP TABLE BABEL_5608_vu_prepare_t7_1;
GO

DROP TABLE BABEL_5608_vu_prepare_t7_2;
GO

-- CASE 8: T_CollateExpr(T_ReLabel(T_Var)) LIKE T_CollateExpr(T_Const)
DROP TABLE BABEL_5608_vu_prepare_t8_1;
GO

DROP TABLE BABEL_5608_vu_prepare_t8_2;
GO

-- CASE 9: T_FuncExpr LIKE T_CollateExpr(T_Const) AND COMBINATIONS
DROP TABLE BABEL_5608_vu_prepare_t9_1;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_2;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_3;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_4;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_5;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_6;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_7;
GO

DROP TABLE BABEL_5608_vu_prepare_t9_8;
GO

-- CASE 10: ESCAPE WITH LIKE
DROP TABLE BABEL_5608_vu_prepare_t10;
GO

-- CASE 11: T_CoerceViaIO
DROP TABLE BABEL_5608_vu_prepare_t11;
GO
Loading
Loading