Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

MySqlStatementParser解析create procedure存储过程时,case when语句处理异常 #4953

Open
Junge-401 opened this issue Oct 11, 2022 · 0 comments

Comments

@Junge-401
Copy link
Contributor

Release Notes

1.2.13 及之前版本

Description

BUG复现SQL:

CREATE PROCEDURE drop_tab_index (IN db varchar(50),IN tb_name varchar(512),IN idx_type varchar(50),IN idx_name varchar(512))
BEGIN
    CASE 
        WHEN idx_type='PRIMARY' OR idx_type='primary' THEN
            IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA=db AND table_name=tb_name AND INDEX_NAME='PRIMARY') THEN
                SET @alter_sql=concat("ALTER TABLE ",db,".",tb_name," DROP PRIMARY KEY");
                prepare stmt from @alter_sql;
                execute stmt;
                SELECT @alter_sql;
            END IF;
        WHEN idx_type='UNIQUE' OR idx_type='unique' THEN
            IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA=db AND table_name=tb_name AND INDEX_NAME=idx_name) THEN
                SET @alter_sql=concat("ALTER TABLE ",db,".",tb_name," DROP KEY ",idx_name);
                prepare stmt from @alter_sql;
                execute stmt;
                SELECT @alter_sql;
            END IF;
        WHEN idx_type='SECONDARY' OR idx_type='secondary' THEN
            IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA=db AND table_name=tb_name AND INDEX_NAME=idx_name) THEN
                SET @alter_sql=concat("ALTER TABLE ",db,".",tb_name," DROP KEY ",idx_name);
                prepare stmt from @alter_sql;
                execute stmt;
                SELECT @alter_sql;
            END IF;
    END CASE;
END;;

异常信息:

com.alibaba.druid.sql.parser.ParserException: ERROR. pos 153, line 4, column 10, token WHEN

	at com.alibaba.druid.sql.parser.SQLExprParser.primary(SQLExprParser.java:1315)
	at com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser.primary(MySqlExprParser.java:527)
	at com.alibaba.druid.sql.parser.SQLExprParser.expr(SQLExprParser.java:95)
	at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseCase(MySqlStatementParser.java:8946)
	at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseCase(MySqlStatementParser.java:42)
	at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:366)
	at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseBlock(MySqlStatementParser.java:2347)
	at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseCreateProcedure(MySqlStatementParser.java:8503)
	at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseCreate(MySqlStatementParser.java:329)
	at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:245)
	at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatement(SQLStatementParser.java:4738)
	at com.alibaba.druid.bvt.sql.mysql.create.MySqlCreateProcedureTest16.test_0(MySqlCreateProcedureTest16.java:37)
        ...

BUG分析:
经分析发现是由于MySqlStatementParser在处理parseCase()时没有及时处理分词'WHEN'所致,以下是涉及的关键代码片段:

// code line# 8937
public MySqlCaseStatement parseCase() {

        MySqlCaseStatement stmt = new MySqlCaseStatement();
        
        accept(Token.CASE);

        if (lexer.token() == Token.WHEN)// grammar 1
        {
            while (lexer.token() == Token.WHEN) {
                MySqlWhenStatement when = new MySqlWhenStatement();
                
                // 此处应对分词WHEN进行处理
                accept(WHEN);

                // when expr
                when.setCondition(exprParser.expr());

                accept(Token.THEN);

                // when block
                this.parseStatementList(when.getStatements(), -1, when);

                stmt.addWhenStatement(when);
            }
           ...
        }
}

经修改后,确认解析正常。

@Junge-401 Junge-401 changed the title MySqlStatementParser解析create procedure时处理case when语句异常 MySqlStatementParser解析create procedure存储过程时,case when语句处理异常 Oct 11, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant