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

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
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

No branches or pull requests

1 participant