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

Add WITH support #334

Merged
merged 1 commit into from
May 16, 2021
Merged

Add WITH support #334

merged 1 commit into from
May 16, 2021

Conversation

soyuka
Copy link
Contributor

@soyuka soyuka commented Mar 11, 2021

Fixes: #165
Fixes: #331

@codecov
Copy link

codecov bot commented Mar 11, 2021

Codecov Report

Merging #334 (602217e) into master (8d8336d) will increase coverage by 0.08%.
The diff coverage is 100.00%.

❗ Current head 602217e differs from pull request most recent head 4216402. Consider uploading reports for the commit 4216402 to get more accurate results
Impacted file tree graph

@@             Coverage Diff              @@
##             master     #334      +/-   ##
============================================
+ Coverage     95.45%   95.53%   +0.08%     
- Complexity     1969     2009      +40     
============================================
  Files            65       67       +2     
  Lines          4203     4303     +100     
============================================
+ Hits           4012     4111      +99     
- Misses          191      192       +1     
Impacted Files Coverage Δ Complexity Δ
src/Parser.php 100.00% <ø> (ø) 32.00 <0.00> (+1.00)
src/Components/OptionsArray.php 100.00% <100.00%> (ø) 61.00 <0.00> (+1.00)
src/Components/WithKeyword.php 100.00% <100.00%> (ø) 6.00 <6.00> (?)
src/Statements/WithStatement.php 100.00% <100.00%> (ø) 24.00 <24.00> (?)
src/TokensList.php 100.00% <100.00%> (+2.04%) 27.00 <0.00> (ø)
src/Statement.php 100.00% <0.00%> (ø) 82.00% <0.00%> (+2.00%)
src/Components/Array2d.php 100.00% <0.00%> (ø) 15.00% <0.00%> (ø%)
src/Components/ArrayObj.php 100.00% <0.00%> (ø) 26.00% <0.00%> (ø%)
src/Tools/TestGenerator.php 0.00% <0.00%> (ø) 24.00% <0.00%> (ø%)
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8d8336d...4216402. Read the comment docs.

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.

Parfait !

@williamdes williamdes added this to the 5.4.3 milestone Mar 11, 2021
@soyuka soyuka force-pushed the feat/with branch 2 times, most recently from 91d2de5 to 77ffd9d Compare March 11, 2021 19:39
src/Components/WithKeyword.php Outdated Show resolved Hide resolved
src/Components/WithKeyword.php Show resolved Hide resolved
src/Statements/WithStatement.php Outdated Show resolved Hide resolved
src/Statements/WithStatement.php Show resolved Hide resolved
src/Statements/WithStatement.php Show resolved Hide resolved
src/Statements/WithStatement.php Outdated Show resolved Hide resolved
@Surfoo
Copy link

Surfoo commented May 10, 2021

Hello,
When do you think it will be merged?

@williamdes williamdes force-pushed the feat/with branch 2 times, most recently from 2bee1c8 to a22dc44 Compare May 10, 2021 20:10
@williamdes
Copy link
Member

Hello,
When do you think it will be merged?

Hi @phpmyadmin/developers
Could someone with some expertise on the sql-parser review this PR please ?

src/Components/WithKeyword.php Show resolved Hide resolved
public static function build($component, array $options = [])
{
if (! $component instanceof WithKeyword) {
throw new RuntimeException('Can not build a component that is not a WithKeyword');

Choose a reason for hiding this comment

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

What about LogicException ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

LogicException are more often used outside of running code, at compile time, here as we would hit that during the "runtime" it's more appropriate. See also https://stackoverflow.com/questions/5586404/logicexception-vs-runtimeexception.

I hesitated here, and I even wanted to pick an exception of the package but ParseException wasn't a good fit.

}

$this->count = count($tokens);
$this->count = $count === -1 ? count($tokens) : $count;

Choose a reason for hiding this comment

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

You change the behavior, are you sure ? 😃

Before $this->count was equal to 0 as we return earlier

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, there was a bug in the parser actually. count here should always be the value of the array's length.


$str .= ' AS (';

foreach ($component->statement->statements as $statement) {

Choose a reason for hiding this comment

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

maybe check that statement->statements is an iterable, on line 45 you just check that it's isset

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As component->statement should be typed to Parser and that Parser has a public $statements = []; we're fine :).

src/Components/WithKeyword.php Show resolved Hide resolved
src/Statements/WithStatement.php Show resolved Hide resolved
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.

Thank you for the new reviews !!

Did you manually test the binaries in ./bin/ ?

@soyuka
Copy link
Contributor Author

soyuka commented May 12, 2021

20210512_10h01m39s_grim

bin/lint-query outputs nothing, error code 0

bin/tokenize-query works as well

@williamdes
Copy link
Member

Thank you :)
I will merge this pull-request this week-end or monday to get a chance to have a team member review it

Copy link
Member

@devenbansod devenbansod left a comment

Choose a reason for hiding this comment

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

Thanks for working on this @soyuka! LGTM 👍 💯

@williamdes williamdes removed the request for review from MauricioFauth May 16, 2021 13:07
@williamdes williamdes self-assigned this May 16, 2021
@williamdes williamdes merged commit 1b330ca into phpmyadmin:master May 16, 2021
williamdes added a commit that referenced this pull request May 16, 2021
Pull-request: #334
Signed-off-by: William Desportes <[email protected]>
@iifawzi
Copy link
Contributor

iifawzi commented Dec 4, 2021

Hi, while working on other issues related to the WITH statements, I walked through this implementation and I noticed that it's parsing the statement based on this definition https://dev.mysql.com/doc/refman/8.0/en/with.html

    WITH [RECURSIVE]
        cte_name [(col_name [, col_name] ...)] AS (subquery)
        [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

I'm wondering, shouldn't we also parse the part that follows the WITH statements? which will always be either SELECT (mostly), UPDATE or DELETE, instead of depending on other statements to parse them? this would help in not duplicating the code as well as throwing an appropriate errors. I think we would only need to parse the tokens remained after the WITH tokens based on the statement type (select, update, or delete). And imo it makes sense because the WITH statements wouldn't work without them.

For now, the parser will not throw any error for such queries:

WITH cte (col1, col2) AS ( SELECT 1, 2 UNION ALL SELECT 3, 4 ) FROM cte;

As i'm currently working on making the InsertStatement aware of the WITH support, I'd also need to parse the tokens remained after the WITH statement, in order to the insertStatement to behave correctly. The same should be done if I wanted to make other statements aware of it too. So why not handling it in the WithStatement from the first place? #353

What do you think? I might be missing something though.

@williamdes
Copy link
Member

It seems to make sense to handle this in WithStatement and not in another statement
Would it be difficult to implement?
The version will be released at the end of the week by the way

@iifawzi
Copy link
Contributor

iifawzi commented Dec 5, 2021

Cool, I don't think it would be that difficult to implement, I will work on it. Hopefully I can manage to finish it along with the other issues related to it, before the end of the week.

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.

Add support for WITH clause (enhancement for syntax highlighter) WITH keyword
7 participants