provide ILIKE support

This introduces support for ILIKE and NOT ILIKE. ILIKE is the
case-insensitive variant of LIKE. Systems such as Postgres, Redshift,
and Snowflake provide this variant.[1][2][3]

[1] https://www.postgresql.org/docs/7.3/functions-matching.html
[2] https://docs.aws.amazon.com/redshift/latest/dg/r_patternmatching_condition_like.html
[3] https://docs.snowflake.com/en/sql-reference/functions/ilike.html
This commit is contained in:
Max Countryman 2021-03-20 08:54:19 -07:00
parent 1e87ab8e22
commit a9e6f77d62
5 changed files with 62 additions and 1 deletions

View file

@ -839,9 +839,12 @@ impl<'a> Parser<'a> {
Keyword::AND => Some(BinaryOperator::And),
Keyword::OR => Some(BinaryOperator::Or),
Keyword::LIKE => Some(BinaryOperator::Like),
Keyword::ILIKE => Some(BinaryOperator::ILike),
Keyword::NOT => {
if self.parse_keyword(Keyword::LIKE) {
Some(BinaryOperator::NotLike)
} else if self.parse_keyword(Keyword::ILIKE) {
Some(BinaryOperator::NotILike)
} else {
None
}
@ -975,12 +978,14 @@ impl<'a> Parser<'a> {
Token::Word(w) if w.keyword == Keyword::IN => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::BETWEEN => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::LIKE => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(Self::BETWEEN_PREC),
_ => Ok(0),
},
Token::Word(w) if w.keyword == Keyword::IS => Ok(17),
Token::Word(w) if w.keyword == Keyword::IN => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::BETWEEN => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::LIKE => Ok(Self::BETWEEN_PREC),
Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(Self::BETWEEN_PREC),
Token::Eq
| Token::Lt
| Token::LtEq
@ -1472,7 +1477,7 @@ impl<'a> Parser<'a> {
) -> Result<Statement, ParserError> {
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let table_name = self.parse_object_name()?;
let like = if self.parse_keyword(Keyword::LIKE) {
let like = if self.parse_keyword(Keyword::LIKE) || self.parse_keyword(Keyword::ILIKE) {
self.parse_object_name().ok()
} else {
None
@ -2497,6 +2502,10 @@ impl<'a> Parser<'a> {
Ok(Some(ShowStatementFilter::Like(
self.parse_literal_string()?,
)))
} else if self.parse_keyword(Keyword::ILIKE) {
Ok(Some(ShowStatementFilter::ILike(
self.parse_literal_string()?,
)))
} else if self.parse_keyword(Keyword::WHERE) {
Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
} else {