YoWuwuuuw opened a new issue, #7217: URL: https://github.com/apache/incubator-seata/issues/7217
<!-- Please do not use this issue template to report security vulnerabilities but refer to our [security policy](https://github.com/seata/seata/security/policy). --> - [ ] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate. ### Ⅰ. Issue Description 1. Solve the situation where NotSupportExc should throw out When: add more tests for the seata-sqlparser-druid module  Discovery: The following two create()'s, which should have thrown an exception, did not succeed in throwing an exception. Instead, they returned recognizer (is null) ``` Assertions.assertThrows(NotSupportYetException.class, () -> recognizerFactory.create(sql11, JdbcConstants.KINGBASE)); Assertions.assertThrows(NotSupportYetException.class, () -> recognizerFactory.create(sql11, JdbcConstants.OSCAR)); ``` Comparing the code, it is clear that this is wrong: ``` // BaseKingbaseRecognizer.isSqlSyntaxSupports() @Override public boolean visit(OracleSelectSubqueryTableSource x) { //just like: select * from (select * from t) for update throw new NotSupportYetException("not support the sql syntax with SubQuery:" + x + "\nplease see the doc about SQL restrictions https://seata.apache.org/zh-cn/docs/user/sqlreference/dml"); } ``` The investigation found that the reason was that the visit() method parameter type did not hit, so "OracleSelectSubqueryTableSource" was changed to "SQLSubqueryTableSource" Similarly, in the rewritten isSqlSyntaxSupports() in BaseKingbaseRecognizer ``` @Override public boolean visit(OracleUpdateStatement x) { System.out.println("kingbase 1"); if (x.getTableSource() instanceof OracleSelectSubqueryTableSource) { //just like: "update (select a.id,a.name from a inner join b on a.id = b.id) t set t.name = 'xxx'" throw new NotSupportYetException("not support the sql syntax with join table:" + x + "\nplease see the doc about SQL restrictions https://seata.apache.org/zh-cn/docs/user/sqlreference/dml"); } List<SQLUpdateSetItem> updateSetItems = x.getItems(); for (SQLUpdateSetItem updateSetItem : updateSetItems) { System.out.println("item:" + updateSetItem); if (updateSetItem.getValue() instanceof SQLQueryExpr) { System.out.println("kingbase 2"); //just like: "update a set a.id = (select id from b where a.pid = b.pid)" throw new NotSupportYetException("not support the sql syntax with join table:" + x + "\nplease see the doc about SQL restrictions https://seata.apache.org/zh-cn/docs/user/sqlreference/dml"); } } return true; } ``` This method will never be entered and should have its parameter type changed to SQLUpdateStatement, which is responsible for determining the notsupport situation of the update statement 2. the same bug when 'replace' and 'merge' sql syntax bug:When the sql statement is "merge into" or "replace into", RecognizerFactory (like DruidSQLRecognizerFactoryImpl) returns recognizer as null, which makes it impossible to pass the "recognizer! = null && recognizer.isSqlSyntaxSupports()" check, and the checking method for the "merge into" and "replace into" syntax in the isSqlSyntaxSupports method will never be reached fix:Remove the checks on "replace" and "merge" from the isSqlSyntaxSupports() in BaseRecognizer and its other implementation classes, check them in DruidSQLRecognizerFactoryImpl, and add checks before isSqlSyntaxSupports() is executed ``` // When recognizer is null, it indicates that recognizerHolder cannot allocate unsupported syntax, like merge and replace if (recognizer == null) { if (ast instanceof SQLReplaceStatement) { //just like:replace into t (id,dr) values (1,'2'), (2,'3') throw new NotSupportYetException("not support the sql syntax with ReplaceStatement:" + ast + "\nplease see the doc about SQL restrictions https://seata.apache.org/zh-cn/docs/user/sqlreference/dml"); } else { throw new NotSupportYetException("Unsupported SQL syntax: " + ast.getClass().getName() + "\nplease see the doc about SQL restrictions https://seata.apache.org/zh-cn/docs/user/sqlreference/dml"); } } if (recognizer != null && recognizer.isSqlSyntaxSupports()) { if (recognizers == null) { recognizers = new ArrayList<>(); } recognizers.add(recognizer); } ``` ps1: When dbtype are dm and sqlserver, druid cannot parse 'replace' syntax and will report an exception com.alibaba.druid.sql.parser.ParserException, so when the sql syntax is 'replace', these two dbtype will throw an ParserException exception just like before ps2: Druid does not seem to be able to parse the merge into syntax. Therefore, when the sql syntax is merge, an ParserException exception will be thrown as before error position: DruidSQLRecognizerFactoryImpl.create() First line `List asts = SQLUtils.parseStatements(sql,DruidDbTypeAdapter.getAdaptiveDbType (dbType));` ### Ⅱ. Describe what happened If there is an exception, please attach the exception trace: ``` Just paste your stack trace here! ``` ### Ⅲ. Describe what you expected to happen ### Ⅳ. How to reproduce it (as minimally and precisely as possible) 1. xxx 2. xxx 3. xxx Minimal yet complete reproducer code (or URL to code): ### Ⅴ. Anything else we need to know? ### Ⅵ. Environment: - JDK version(e.g. `java -version`): - Seata client/server version: - Database version: - OS(e.g. `uname -a`): - Others: -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org For additional commands, e-mail: notifications-h...@seata.apache.org