开发者社区> 问答> 正文

SQLASTOutputVisitor格式化有bug只拼了一半单引号导致生成的SQL语法不对

我继承StatFilter将sql做了采样分析,采样的时候将sql进行格式化只会再次参数化处理,结果生产遇到问题 然后发现SQLASTOutputVisitor在拼sql的时候针对Reader等类型只拼了前半截单引号,没有后半截单引号就return了。

https://github.com/alibaba/druid/blob/master/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java#L2310

我的代码如下:

private static List getSqlParamObjetList(StatementProxy statement) { List parameters = null; int parametersSize = statement.getParametersSize(); if (parametersSize > 0) { parameters = new ArrayList<>(parametersSize); for (int i = 0; i < parametersSize; ++i) { JdbcParameter jdbcParam = statement.getParameter(i); Object param = jdbcParam != null ? jdbcParam.getValue() : null; if (param instanceof String) { String str = (String) param; if (str.length() > 300) {// 超长文本做截取 param = str.subSequence(0, 300) + "........."; } } //以下是为了兼容druid SQLASTOutputVisitor的bug,返回指定字符串 if (param instanceof InputStream) { param = ("< InputStream >"); } if (param instanceof Reader) { param = ("< Reader >"); } if (param instanceof Blob) { param = ("< Blob >"); } if (param instanceof NClob) { param = ("< NClob >"); }
            if (param instanceof Clob) {
                param = ("< Clob >");
            }
            parameters.add(param);
        }
    }
    return parameters;
}

private void trySamplingSql(String method, StatementProxy statement, String sql) { String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType(); List parameters = getSqlParamObjetList(statement);

String formattedSql = SQLUtils.format(sql, dbType, parameters); String mergedSql = null; try { //parameters里有Reader等类型就会出错了。 mergedSql = ParameterizedOutputVisitorUtils.parameterize(formattedSql, "mysql"); } catch (Exception e) { if (LOG.isWarnEnabled()) { String msg = "doAsyncSqlSampling|buterr|" + (formattedSql); LOG.warn(msg, e); } return; } //以mergedSql为基准每调采样10次。 }

原提问者GitHub用户lizongbo

展开
收起
山海行 2023-07-05 19:41:09 67 0
2 条回答
写回答
取消 提交回答
  • 北京阿里云ACE会长

    用SQLASTOutputVisitor来生成SQL时,确实有可能出现格式化错误,导致生成的SQL语法不正确。

    你所说的只拼了一半单引号的bug,可能是SQLASTOutputVisitor对字符串表示存有缺陷。

    SQLASTOutputVisitor做的事情就是:

    遍历AST节点
    根据节点类型调用相应的输出方法,生成SQL字符串
    对于字符串节点,应该输出成'xxx'这样,包含完整的单引号。

    但是SQLASTOutputVisitor实现有误,往往只输出了开头的单引号,而没有闭合。

    所以导致的结果是一个不完整的字符串表示,后续SQL解析就会出错。

    2023-07-30 16:31:58
    赞同 展开评论 打赏
  • 问题已修复,请用新版本 https://github.com/alibaba/druid/releases/tag/1.1.14

    原回答者GitHub用户wenshao

    2023-07-06 11:04:43
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载