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
   
![image](https://github.com/user-attachments/assets/2f147ac4-415a-453f-96e0-412420c8fc23)
   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

Reply via email to