-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-30724][SQL] Support 'LIKE ANY' and 'LIKE ALL' operators #27477
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
Changes from 2 commits
4548b0f
5475675
de7c398
caea82a
88ca4c2
1c3d98c
2b59cb0
0656b05
cf4666f
f9af131
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1387,14 +1387,23 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging | |
| case SqlBaseParser.IN => | ||
| invertIfNotDefined(In(e, ctx.expression.asScala.map(expression))) | ||
| case SqlBaseParser.LIKE => | ||
| val escapeChar = Option(ctx.escapeChar).map(string).map { str => | ||
| if (str.length != 1) { | ||
| throw new ParseException("Invalid escape string." + | ||
| "Escape string must contains only one character.", ctx) | ||
| } | ||
| str | ||
| }.getOrElse('\\') | ||
| invertIfNotDefined(Like(e, expression(ctx.pattern), Literal(escapeChar))) | ||
| Option(ctx.quantifier).map(_.getType) match { | ||
| case Some(SqlBaseParser.ANY) if !ctx.expression.isEmpty => | ||
|
||
| ctx.expression.asScala.map(expression).map(p => invertIfNotDefined(new Like(e, p))) | ||
| .reduceLeft(Or) | ||
| case Some(SqlBaseParser.ALL) if !ctx.expression.isEmpty => | ||
wangyum marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ctx.expression.asScala.map(expression).map(p => invertIfNotDefined(new Like(e, p))) | ||
| .reduceLeft(And) | ||
| case _ => | ||
| val escapeChar = Option(ctx.escapeChar).map(string).map { str => | ||
| if (str.length != 1) { | ||
| throw new ParseException("Invalid escape string." + | ||
| "Escape string must contains only one character.", ctx) | ||
|
||
| } | ||
| str | ||
| }.getOrElse('\\') | ||
| invertIfNotDefined(Like(e, expression(ctx.pattern), Literal(escapeChar))) | ||
| } | ||
| case SqlBaseParser.RLIKE => | ||
| invertIfNotDefined(RLike(e, expression(ctx.pattern))) | ||
| case SqlBaseParser.NULL if ctx.NOT != null => | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| CREATE OR REPLACE TEMPORARY VIEW like_all_table AS SELECT * FROM (VALUES | ||
| ('google', '%oo%'), | ||
| ('facebook', '%oo%'), | ||
| ('linkedin', '%in')) | ||
| as t1(company, pat); | ||
|
|
||
| select company from like_all_table where company like all ('%oo%','%go%') ; | ||
|
|
||
| select company from like_all_table where company like all ('microsoft','%yoo%') ; | ||
|
|
||
| select | ||
| company, | ||
| CASE | ||
| WHEN company like all ('%oo%','%go%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS is_available, | ||
| CASE | ||
| WHEN company like all ('%oo%','go%') OR company like all ('%in','ms%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS mix | ||
| From like_all_table ; | ||
|
|
||
| --Mix test with constant pattern and column value | ||
| select company from like_all_table where company like all ('%oo%',pat) ; | ||
|
|
||
| -- not like all test | ||
|
|
||
| select company from like_all_table where company not like all ('%oo%','%in','fa%') ; | ||
| select company from like_all_table where company not like all ('microsoft','%yoo%') ; | ||
|
|
||
| -- null test | ||
|
|
||
| select company from like_all_table where company like all ('%oo%',null) ; | ||
|
|
||
| select company from like_all_table where company not like all ('%oo%',null) ; | ||
|
|
||
| select company from like_all_table where company not like all (null,null) ; | ||
|
|
||
| select company from like_all_table where company not like all (null,null) ; | ||
wangyum marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| CREATE OR REPLACE TEMPORARY VIEW like_any_table AS SELECT * FROM (VALUES | ||
| ('google', '%oo%'), | ||
| ('facebook', '%oo%'), | ||
| ('linkedin', '%in')) | ||
| as t1(company, pat); | ||
|
|
||
| select company from like_any_table where company like any ('%oo%','%in','fa%') ; | ||
|
|
||
| select company from like_any_table where company like any ('microsoft','%yoo%') ; | ||
|
|
||
| select | ||
| company, | ||
| CASE | ||
| WHEN company like any ('%oo%','%in','fa%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS is_available, | ||
| CASE | ||
| WHEN company like any ('%oo%','fa%') OR company like any ('%in','ms%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS mix | ||
| From like_any_table; | ||
|
|
||
| --Mix test with constant pattern and column value | ||
wangyum marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| select company from like_any_table where company like any ('%zz%',pat) ; | ||
|
|
||
| -- not like any test | ||
|
|
||
| select company from like_any_table where company not like any ('%oo%','%in','fa%') ; | ||
| select company from like_any_table where company not like any ('microsoft','%yoo%') ; | ||
|
|
||
| -- null test | ||
|
|
||
| select company from like_any_table where company like any ('%oo%',null) ; | ||
|
|
||
| select company from like_any_table where company not like any ('%oo%',null) ; | ||
|
|
||
| select company from like_any_table where company like any (null,null) ; | ||
|
|
||
| select company from like_any_table where company not like any (null,null) ; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| -- Automatically generated by SQLQueryTestSuite | ||
| -- Number of queries: 11 | ||
|
|
||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note: I've checked that the output is the same with PostgreSQL output: https://gist.github.com/maropu/fa4bd6491e21751d6bbc44c545390b0c |
||
| -- !query | ||
| CREATE OR REPLACE TEMPORARY VIEW like_all_table AS SELECT * FROM (VALUES | ||
| ('google', '%oo%'), | ||
| ('facebook', '%oo%'), | ||
| ('linkedin', '%in')) | ||
| as t1(company, pat) | ||
| -- !query schema | ||
| struct<> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company like all ('%oo%','%go%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company like all ('microsoft','%yoo%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select | ||
| company, | ||
| CASE | ||
| WHEN company like all ('%oo%','%go%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS is_available, | ||
| CASE | ||
| WHEN company like all ('%oo%','go%') OR company like all ('%in','ms%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS mix | ||
| From like_all_table | ||
| -- !query schema | ||
| struct<company:string,is_available:string,mix:string> | ||
| -- !query output | ||
| facebook N N | ||
| google Y Y | ||
| linkedin N N | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company like all ('%oo%',pat) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company not like all ('%oo%','%in','fa%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company not like all ('microsoft','%yoo%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company like all ('%oo%',null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company not like all ('%oo%',null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company not like all (null,null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_all_table where company not like all (null,null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| -- Automatically generated by SQLQueryTestSuite | ||
| -- Number of queries: 11 | ||
|
|
||
|
|
||
| -- !query | ||
| CREATE OR REPLACE TEMPORARY VIEW like_any_table AS SELECT * FROM (VALUES | ||
| ('google', '%oo%'), | ||
| ('facebook', '%oo%'), | ||
| ('linkedin', '%in')) | ||
| as t1(company, pat) | ||
| -- !query schema | ||
| struct<> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company like any ('%oo%','%in','fa%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company like any ('microsoft','%yoo%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select | ||
| company, | ||
| CASE | ||
| WHEN company like any ('%oo%','%in','fa%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS is_available, | ||
| CASE | ||
| WHEN company like any ('%oo%','fa%') OR company like any ('%in','ms%') THEN 'Y' | ||
| ELSE 'N' | ||
| END AS mix | ||
| From like_any_table | ||
| -- !query schema | ||
| struct<company:string,is_available:string,mix:string> | ||
| -- !query output | ||
| facebook Y Y | ||
| google Y Y | ||
| linkedin Y Y | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company like any ('%zz%',pat) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company not like any ('%oo%','%in','fa%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company not like any ('microsoft','%yoo%') | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company like any ('%oo%',null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company not like any ('%oo%',null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company like any (null,null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
||
|
|
||
|
|
||
| -- !query | ||
| select company from like_any_table where company not like any (null,null) | ||
| -- !query schema | ||
| struct<company:string> | ||
| -- !query output | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we don't need to support
ESCAPE. Did I understand correctly?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.

https://docs.teradata.com/reader/756LNiPSFdY~4JcCCcR5Cw/4~AyrPNmDN0Xk4SALLo6aQ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it~