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

Support parsing MySQL CALL sql #30974

Closed
zhuruixuan opened this issue Apr 19, 2024 · 8 comments
Closed

Support parsing MySQL CALL sql #30974

zhuruixuan opened this issue Apr 19, 2024 · 8 comments

Comments

@zhuruixuan
Copy link
Collaborator

Background

Hi community.
The ShardingSphere SQL parser engine helps users to parse SQL to create the AST (Abstract Syntax Tree) and visit the AST to get SQLStatement (Java Object). Currently, we are planning to enhance the support for MySQL SQL parsing in ShardingSphere.

More details:
https://shardingsphere.apache.org/document/current/en/reference/sharding/parse/

Issue Background Explanation

The current issue involves using a custom web scraping script to fetch SQL cases from the official website of a corresponding database. These SQL cases are then passed to ShardingSphere's parsing engine for analysis. For SQL cases that fail to be parsed successfully, every 3 to 5 SQL cases are grouped together as an issue.

  1. Since SQL cases are obtained through web scraping, it cannot be guaranteed that all SQL cases are correct. Please follow the following process to handle this pull request (PR).
  2. Some SQL cases may have already been fixed in other PRs. For cases that can already be executed successfully, simply leave a comment to ignore them.
  3. If a SQL case can be executed successfully without any code changes, there is no need to add a corresponding test assert file.

Task

This issue is to support more MySQL sql parsing, as follows:

CALL sys.ps_setup_enable_consumer('history_long');

link

CALL sys.ps_setup_reset_to_default(TRUE);

link

CALL mysql.sp_set_firewall_group_mode(group, mode);

link

CALL sp_migrate_firewall_user_to_group('fwuser@localhost', 'mygroup);

link

Overall Procedure

If you intend to participate in fixing this issue, please feel free to leave a comment below the issue. Community members will assign the issue accordingly.

For example, you can leave a comment like this: "Hi, please assign this issue to me. Thank you!"

Once you have claimed the issue, please review the syntax of the SQL on the official website of the corresponding database. Execute the SQL on the respective database to ensure the correctness of the SQL syntax.

You can check the corresponding source of each SQL case on the official database website by clicking on the link provided below each case.

Next, execute the problematic SQL cases mentioned above in the database (you can quickly start the corresponding database using the Docker image for that database, and then connect to it using
a client you are familiar with), to ensure that the SQL syntax itself is correct.

Fixing ANTLR Grammar Parsing Issue

Once you have confirmed the correctness of the SQL syntax, you can validate and fix the grammar parsing issue in ShardingSphere.

If you are using IntelliJ IDEA, you will need to install the ANTLR plugin before proceeding.

If it is an ANTLR parsing error message, try to repair the .g4 file by comparing it with the official database syntax until the SQL can be correctly parsed by ANTLR.

When there is no error message in the ANTLR Preview window, it means that ANTLR can correctly parse the SQL.

Visitor problem fix

After ANTLR parses SQL into an abstract syntax tree, ShardingSphere will access the abstract syntax tree through Visitor and extract the required information.
If you need to extract Segments, you need to first execute:

mvn -T 2C clean install -DskipTests

Under the shardingsphere-parser module to compile the entire parser module.
Then rewrite the corresponding visit method in SQLStatementVisitorr as needed to extract the corresponding Segment.

Add assertion test file

After the above SQL parsing problem is repaired, the corresponding Test needs to be added.
The steps are as follows:

  1. Add the corresponding sql-case in the sql/supported directory.
  2. Add case assertions in the case directory of the shardingsphere-test-it-parser module.
  3. Run org.apache.shardingsphere.test.it.sql.parser.internal.InternalSQLParserIT
    After SQL Parser IT runs successfully, you can submit a PR.

Relevant Skills

  1. Master JAVA language
  2. Have a basic understanding of Antlr g4 file
  3. Be familiar with MySQL SQLs
@Kiritsgu
Copy link
Contributor

Hi there,

I'd like to help with this issue, but I want to figure out something first. The statements ‘CALL mysql.sp_set_firewall_group_mode(group, mode);’ and ‘CALL sp_migrate_firewall_user_to_group('fwuser@localhost', 'mygroup');’ require MySQL Enterprise Firewall to be installed in order to execute correctly in the latest MySQL while the others run fine without any additional installations. Do we need to support this scenario as well?

Thanks!

@Kiritsgu
Copy link
Contributor

@zhuruixuan @strongduanmu Looking forward to your reply.

@strongduanmu
Copy link
Member

I think we should support because this is a legal MySQL statement.

@strongduanmu
Copy link
Member

Can we make the G4 rule more general to support any CALL functionName(functionParameter) statement?

@Kiritsgu
Copy link
Contributor

@strongduanmu Got it, please assign this issue to me. Thank you!

@strongduanmu
Copy link
Member

@Kiritsgu Assigned, and good luck for you.

@Kiritsgu
Copy link
Contributor

Kiritsgu commented May 31, 2024

@strongduanmu Hi, I found that this issue has already been resolved in a previous PR #31133.
The existing G4 rule for CALL should support any CALL functionName(functionParameter) statement:
call : CALL (owner DOT_)? identifier (LP_ (expr (COMMA_ expr)*)? RP_)? ;

Out of the four examples in this issue, the following two can be executed correctly.
CALL sys.ps_setup_enable_consumer('history_long');
CALL sys.ps_setup_reset_to_default(TRUE);

The third example cannot be executed correctly because the variable 'group' is a reserved keyword in MySQL.
CALL mysql.sp_set_firewall_group_mode(group, mode);
However, this should be considered an incorrect example in the official documentation. The 'group' here should refer to a user-defined group (which should be enclosed in quotes), and the subsequent example sentences also support this point.
image

The last example cannot be executed due to a syntax error in the official documentation example itself (missing a quotation mark after ‘mygroup’).
CALL sp_migrate_firewall_user_to_group('fwuser@localhost', 'mygroup);
image
In summary, this issue has been resolved, and I believe it can be closed.

@strongduanmu
Copy link
Member

@Kiritsgu Thank you for your great work, I will close this issue.

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