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

Lexer - Solving ambiguity on function keywords #385

Merged
merged 1 commit into from
Jan 6, 2023

Conversation

iifawzi
Copy link
Contributor

@iifawzi iifawzi commented Aug 19, 2022

Fixing: #327 and #378
Signed-off-by: iifawzi iifawzie@gmail.com

@codecov
Copy link

codecov bot commented Aug 19, 2022

Codecov Report

Base: 95.64% // Head: 95.66% // Increases project coverage by +0.02% 🎉

Coverage data is based on head (395c533) compared to base (8fddb4b).
Patch coverage: 100.00% of modified lines in pull request are covered.

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #385      +/-   ##
============================================
+ Coverage     95.64%   95.66%   +0.02%     
- Complexity     2144     2156      +12     
============================================
  Files            67       67              
  Lines          4548     4569      +21     
============================================
+ Hits           4350     4371      +21     
  Misses          198      198              
Impacted Files Coverage Δ
src/Lexer.php 99.73% <100.00%> (+0.01%) ⬆️
src/TokensList.php 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@iifawzi

This comment was marked as resolved.

@williamdes williamdes marked this pull request as draft October 25, 2022 11:06
@williamdes
Copy link
Member

Note: When this gets merged please hard reset your master branch to phpmyadmin/sql-parser#master and use specific branch names for your PRs ;)

@iifawzi
Copy link
Contributor Author

iifawzi commented Nov 17, 2022

Yes, i've mistakenly used the master branch here, I will make sure to do this after this get merged

@iifawzi iifawzi changed the title Fixing parser not recognizing single chars aliases or tables Solving ambiguity on function keywords Nov 19, 2022
@iifawzi iifawzi changed the title Solving ambiguity on function keywords Lexer - Solving ambiguity on function keywords Nov 19, 2022
src/Lexer.php Outdated
Comment on lines 389 to 454
/**
* Resolves the ambiguity when dealing with the functions keywords.
*
* In SQL statements, the function keywords might be used as table names or columns names.
* To solve this ambiguity, the solution is to find the next token, excluding whitespaces and
* comments, right after the function keyword position. The function keyword is for sure used
* as column name or table name if the next token found is any of:
*
* - "FROM" (the FROM keyword like in "SELECT Country x, AverageSalary avg FROM...");
* - "WHERE" (the WHERE keyword like in "DELETE FROM emp x WHERE x.salary = 20");
* - "SET" (the SET keyword like in "UPDATE Country x, City y set x.Name=x.Name");
* - "," (a comma separator like 'x,' in "UPDATE Country x, City y set x.Name=x.Name");
* - "." (a dot separator like in "x.asset_id FROM (SELECT evt.asset_id FROM evt)".
* - "NULL" (when used as a table alias like in "avg.col FROM (SELECT ev.col FROM ev) avg").
*
* This method will change the flag of the function keyword tokens when any of those
* condition above is true. Otherwise, the
* default flag (function keyword) will be kept.
*
* @return void
*/
private function solveAmbiguityOnFunctionKeywords()
{
$iBak = $this->list->idx;
$keywordFunction = Token::TYPE_KEYWORD | Token::FLAG_KEYWORD_FUNCTION;
while (($keywordToken = $this->list->getNextOfTypeAndFlag(Token::TYPE_KEYWORD, $keywordFunction)) !== null) {
$next = $this->list->getNext();
if (
($next->type !== Token::TYPE_KEYWORD || ! in_array($next->value, ['FROM', 'SET', 'WHERE'], true))
&& ($next->type !== Token::TYPE_OPERATOR || ! in_array($next->value, ['.', ','], true))
&& ($next->value !== null)
) {
continue;
}

$keywordToken->type = Token::TYPE_NONE;
$keywordToken->flags = Token::TYPE_NONE;
$keywordToken->keyword = $keywordToken->value;
}

$this->list->idx = $iBak;
}
Copy link
Contributor Author

@iifawzi iifawzi Nov 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that I'm not missing any other cases. This way the keywords that represent functions names can be used freely as aliases or table names if the lexer detected that they're not being used as functions

Copy link
Contributor Author

@iifawzi iifawzi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes

@iifawzi iifawzi marked this pull request as ready for review November 19, 2022 12:57
src/Lexer.php Outdated Show resolved Hide resolved
src/TokensList.php Outdated Show resolved Hide resolved
src/Lexer.php Outdated Show resolved Hide resolved
@williamdes
Copy link
Member

Can you squash your commits on the next push ?

Signed-off-by: iifawzi <iifawzie@gmail.com>
Copy link
Member

@williamdes williamdes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really nice, I think we should wait for the parser to be released before merging this into it. I consider this one as potentially risky, not sure why.
But anyway we can agree this is not emergency and can wait for the next window to go in ?

@iifawzi
Copy link
Contributor Author

iifawzi commented Nov 21, 2022

Since it affects the lexer, I agree that it's potentially risky. But still, the risks that this might introduce are minimal since we're only changing the token type in very specific cases, and otherwise it's kept as it's.

Anyway, this's not an emergency yes, it can for sure wait for the next release.

@williamdes williamdes added this to the 5.7.0 milestone Nov 21, 2022
@williamdes williamdes self-assigned this Jan 6, 2023
williamdes added a commit that referenced this pull request Jan 6, 2023
Pull-request: #385

Signed-off-by: William Desportes <williamdes@wdes.fr>
@williamdes williamdes merged commit 78735dd into phpmyadmin:master Jan 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants