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 37 commits into
base: BABEL_5_X_DEV
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 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
1e1005a
Address review comments
ahmed-shameem Mar 10, 2025
255efa5
Address review comments
ahmed-shameem Mar 12, 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
71 changes: 59 additions & 12 deletions contrib/babelfishpg_tsql/src/collation.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,16 @@ 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;
expr->location = -1;
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 +331,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,13 +342,13 @@ 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 *prefix_collate;

tsql_get_database_or_server_collation_oid_internal(true);

if (!OidIsValid(database_or_server_collation_oid))
return node;


/*
* Find the CS_AS collation corresponding to the CI_AS collation
* Change the collation of the ILIKE op to the CS_AS collation
Expand Down Expand Up @@ -388,6 +398,9 @@ 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);
Copy link
Contributor

Choose a reason for hiding this comment

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

[Question] Will we need this only when leftop is a Const node? The above if condition will let us in when leftop is not Const and rightop is not Const. IsA(leftop, Const) || !IsA(rightop, Const)

lsecond(op->args) = (IsA(rightop, Const) && ((Const *) rightop)->constisnull) ? lsecond(op->args) : (Node *) create_collate_expr(lsecond(op->args), op->inputcollid);
return node;
}

Expand All @@ -400,23 +413,45 @@ transform_from_ci_as_for_likenode(Node *node, OpExpr *op, like_ilike_info_t like
/* 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 +416 to 419
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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added one such case, please look at case 14

}

/*
* We need to do this because the dump considers rightop as Const with COLLATE being added
* whereas during restore, that is considered as CollateExpr while building new expression tree
* which is adding extra parenthesis on rightop when we invoke pg_get_constraintdef() from PG
* We update the righop to equivalent CollateExpr to pick correct collation
* We are clearing collation or else we observe multiple redundant COLLATE
* clause in pg_get_constraintdef(), which will result in error during upgrade/restore
* We also set InvalidOid for highest_sort_key during creation for the same reason,
* later we enclose it withing CollateExpr
*/
prefix->constcollid = ((Const *) rightop)->constcollid = InvalidOid;

prefix_collate = create_collate_expr((Node* ) prefix, coll_info_of_inputcollid.oid);

Assert(ltypeId == rtypeId);

/*
* If we found an exact-match pattern, generate an "=" indexqual.
*/
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;

ret = (Node *) (make_op_with_func(oprid(optup), BOOLOID, false,
(Expr *) leftop, (Expr *) prefix,
InvalidOid, coll_info_of_inputcollid.oid, oprfuncid(optup)));
(Expr *) leftop,
(Expr *) prefix_collate,
InvalidOid,
coll_info_of_inputcollid.oid,
oprfuncid(optup)));

ReleaseSysCache(optup);
}
Expand All @@ -428,33 +463,45 @@ 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 */
linitial(op->args) = (Node*) create_collate_expr(linitial(op->args), op->inputcollid);
lsecond(op->args) = (Node *) create_collate_expr(lsecond(op->args), op->inputcollid);

/* 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));
(Expr *) leftop,
(Expr *) prefix_collate,
InvalidOid,
coll_info_of_inputcollid.oid,
oprfuncid(optup));
ReleaseSysCache(optup);
/* construct pattern||E'\uFFFF' */
highest_sort_key = makeConst(TEXTOID, -1, coll_info_of_inputcollid.oid, -1,
highest_sort_key = makeConst(TEXTOID, -1, InvalidOid, -1,
PointerGetDatum(cstring_to_text(SORT_KEY_STR)), false, false);

optup = compatible_oper(NULL, list_make1(makeString("||")), rtypeId, rtypeId,
true, -1);
if (optup == (Operator) NULL)
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));
(Expr *) prefix_collate,
(Expr *) create_collate_expr((Node* ) highest_sort_key, coll_info_of_inputcollid.oid),
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
Loading
Loading