Description
Failing ANSI SQL
SELECT *
FROM itemDownload
WHERE url LIKE :urlLike ESCAPE :escape AND itemId = :itemId AND channelId = :channelId;
SELECT *
FROM itemDownload
WHERE url LIKE :urlLike AND itemId = :itemId AND channelId = :channelId;
Description
Relates to sqlite ESCAPE gets wrong inferred type
Current PSI nodes:
0 = {SqlColumnExprImpl} "SqlColumnExprImpl(COLUMN_EXPR)
1 = {SqlBinaryLikeOperatorImpl} "SqlBinaryLikeOperatorImpl(BINARY_LIKE_OPERATOR)
2 = {SqlBindExprImpl} "SqlBindExprImpl(BIND_EXPR)
3 = {SqlBinaryAndExprImpl} "SqlBinaryAndExprImpl(BINARY_AND_EXPR) <-- BIND_EXPR :escape is child of this node
The desired tree would be
SqlBinaryAndExprImpl(BINARY_AND_EXPR)
├── SqlBinaryLikeExprImpl(BINARY_LIKE_EXPR)
│ ├── SqlColumnExprImpl(COLUMN_EXPR) "url"
│ ├── SqlBindExprImpl(BIND_EXPR) ":urlLike"
│ └── SqlBindExprImpl(BIND_EXPR) ":escape" (optional ESCAPE clause)
└── SqlBinaryAndExprImpl(BINARY_AND_EXPR)
├── SqlBinaryEqualityExprImpl(BINARY_EQUALITY_EXPR)
│ ├── SqlColumnExprImpl(COLUMN_EXPR) "itemId"
│ └── SqlBindExprImpl(BIND_EXPR) ":itemId"
└── SqlBinaryEqualityExprImpl(BINARY_EQUALITY_EXPR)
├── SqlColumnExprImpl(COLUMN_EXPR) "channelId"
└── SqlBindExprImpl(BIND_EXPR) ":channelId"
Proposed fix in sql.bnf
grammar
LIKE expr ESCAPE expr
is unusual as is similar to a function call LIKE(a, [ b ]) with optional argument of type TEXT
Create a new expr that can be assigned TEXT type in SqlDelight since there is no way to infer it
like_arguments_expr ::= ESCAPE expr. <-- cannot have expr [ ESCAPE expr ] as expr always causes a parser loop.
binary_like_expr ::= expr binary_like_operator expr [ like_arguments_expr ] {
mixin = "com.alecstrong.sql.psi.core.psi.mixins.BinaryLikeExprMixin"
}
Move the precedence of binary_like_expr before bind_expr so that binary_like_expr nodes are children nodes of binary_and
expr ::= ( other_expr
...
| binary_and_expr
...
| bind_expr
| like_arguments_expr
| binary_like_expr )