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

[MySQL (Oracle)] Cannot parse user variable in EXPLAIN INTO #4420

Open
OnMYLai opened this issue Feb 21, 2025 · 5 comments
Open

[MySQL (Oracle)] Cannot parse user variable in EXPLAIN INTO #4420

OnMYLai opened this issue Feb 21, 2025 · 5 comments

Comments

@OnMYLai
Copy link

OnMYLai commented Feb 21, 2025

My SQL, copying from MySQL doc with changes of the select sql to sth in my db:
EXPLAIN FORMAT=JSON INTO @myselect SELECT a FROM ab1;
Parsing return error msg line 1:25 mismatched input '@myselect' expecting '@', and unable to parse the 'myselect' as an ID.

the rule for the INTO part:
explainInto
: INTO_SYMBOL AT_SIGN_SYMBOL textOrIdentifier
;
maybe need to recognize AT_TEXT_SUFFIX?

@mike-lischke
Copy link
Member

Good find @OnMYLai!

@OnMYLai
Copy link
Author

OnMYLai commented Feb 28, 2025

Found another similar issue on NTILE call:

SELECT a, NTILE(2) OVER w AS 'ntile2' FROM ab1 WINDOW w as (ORDER BY a);

This runs fine and parses fine;

SET @var = 2;
SELECT a, NTILE(@var) OVER w AS 'ntile2' FROM ab1 WINDOW w as (ORDER BY a);

This can run, but parsing returns line 2:15 no viable alternative at input '('.

MySQL doc saids it is ok to use user-defined variables in NTILE call.

Related rules:

windowFunctionCall
    : ...
    | NTILE_SYMBOL (
        OPEN_PAR_SYMBOL stableInteger CLOSE_PAR_SYMBOL
        | {this.isServerVersionLt80024()}? simpleExprWithParentheses
    ) windowingClause
    ...
    ;

stableInteger
    : int64Literal
    | paramOrVar
    ;

paramOrVar
    : PARAM_MARKER
    | identifier
    | AT_SIGN_SYMBOL textOrIdentifier
    ;

P.S. I kept the server version used in parser as default 80200, if it was less than 80024 then the simpleExprWithParenthese will kick in and capture the @var without issue.

@OnMYLai
Copy link
Author

OnMYLai commented Feb 28, 2025

Same issue MAYBE on TABLESAMPLE clause as well:

tablesampleClause
    : {this.isServerVersionGe80200()}? TABLESAMPLE_SYMBOL samplingMethod OPEN_PAR_SYMBOL samplingPercentage CLOSE_PAR_SYMBOL
    ;

samplingPercentage
    : ulonglongNumber
    | AT_SIGN_SYMBOL textOrIdentifier
    | PARAM_MARKER
    ;

I use MAYBE becoz

  1. it is Heatwave SQL and I don't have the env to test and
  2. the doc has so little info on that it doesnt even state if an user variable can be used there.

Anyway my testing SQL:

SELECT COUNT(*) FROM LINEITEM TABLESAMPLE SYSTEM (@var);

got me error line 1:50 no viable alternative at input 'SELECT COUNT(*) FROM LINEITEM TABLESAMPLE SYSTEM (@var'

@mike-lischke
Copy link
Member

mike-lischke commented Feb 28, 2025

The best option we have for this kind of problem is to compare the ANTLR grammar with the yacc grammar of the MySQL server. That's the ultimate source of truth. If the ANTLR grammar misses something it needs to be adjusted, otherwise that syntax is not allowed.

According to that it is not allowed to use a user variable in the table sample clause. I see, that AT_SIGN_SYMBOL textOrIdentifier stands for a user variable, but we are missing that AT_TEXT_SUFFIX.

@mike-lischke
Copy link
Member

mike-lischke commented Feb 28, 2025

We already have a rule userVariable. Can you replace all the occurrences of AT_SIGN_SYMBOL textOrIdentifier by that? There's also one place (roleOrPrivilege) which uses the correct alts, which can also be changed to use this userVariable rule.

If it works just file a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants