Skip to content

LIKE ... ESCAPE ... produces incorrect PSI children in binary expression tree #666

Closed
@griffio

Description

@griffio

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 )

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions