alibaba / druid

阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
https://github.com/alibaba/druid/wiki
Apache License 2.0
27.76k stars 8.55k forks source link

druid 解析 oracle select 语句 bug #5966

Closed ryan-0526 closed 1 week ago

ryan-0526 commented 4 weeks ago

dbtype: oracle dbversion: 11g druid verion: 1.2.23 版本执行报错 , <= 1.2.22 版本解析会出现括号错位 error sql: SELECT 'ryan055' FROM (SELECT 'ryan055' FROM dual) UNION ALL SELECT 'ryan055' FROM (SELECT 'ryan055' FROM dual) testcase code: SQLUtils.parseStatements(sql, JdbcConstants.ORACLE);

bug 描述: 执行 “SQLUtils.parseStatements(sql, JdbcConstants.ORACLE);” 代码后,解析出来的sql 右括号错位,导致sql在数据库执行失败

图片标注解析前后错误点: 括号

stacktrace info: 无 error info: 无

lizongbo commented 2 weeks ago

看来下最新代码解析也还是多了括号,把 第一个from的内容当初和后面的union all并列的内容了,要修正解析逻辑比较复杂,温少出马来搞定这种情况的解析吧


  @Test
    public void test_parse_select() {
        for (DbType dbType : new DbType[]{DbType.oracle}) {
            for (String sql : new String[]{
                "SELECT 'ryan000'\n"
                    + "FROM (SELECT 'ryan111' FROM dualaaa)\n"
                    + "UNION ALL\n"
                    + "SELECT 'ryan222'\n"
                    + "FROM (SELECT 'ryan333' FROM dualbbb);",
            }) {
                SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
                List<SQLStatement> statementList = parser.parseStatementList();
                assertEquals(1, statementList.size());
                SQLParseAssertUtil.assertParseSql(sql, dbType);
            }
        }
    }

执行结果:


SELECT 'ryan000'
FROM (
    (SELECT 'ryan111'
    FROM dualaaa)
    UNION ALL
    SELECT 'ryan222'
    FROM (
        SELECT 'ryan333'
        FROM dualbbb
    )
);