alibaba / druid

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

解析 MySQL 语句 "SHOW FULL TABLES FROM test-db WHERE Table_type != 'VIEW'" 时,通过 MySqlShowTablesStatement.getDatabase() 获取 database 名字不正确 #1002

Open ifrenzyc opened 8 years ago

ifrenzyc commented 8 years ago

代码如下:

String stmt = "SHOW FULL TABLES FROM test-ds WHERE Table_type != 'VIEW'";

MySqlStatementParser parser = new MySqlStatementParser(stmt);
MySqlShowTablesStatement statement = (MySqlShowTablesStatement) parser.parseStatement();

SQLName database = statement.getDatabase();

执行后获取的 database = 'test',不是预期的 'test-ds'

ifrenzyc commented 8 years ago

分析代码,发现是 CharTypes.identifierFlags 判断 identifier 缺少判断 ‘-’ 字符。 由于 odps 采用 ‘--’ 做 comment 因此只修改了 MySQL 的逻辑: MysqlLexer.java

+    private final static boolean[] identifierFlags = new boolean[256];                
+    static {                                                                          
+        identifierFlags['-'] = true;                                                  
+    }                                                                                 
+                                                                                      
+    private boolean isIdentifierChar0(char c) {                                       
+        if (c <= identifierFlags.length) {                                            
+            return identifierFlags[c];                                                
+        }                                                                             
+                                                                                      
+        return c != ' ' && c != ',';                                                  
+    }                                                                                 

     private boolean isIdentifierChar(char c) {                                        
-        return c != '#' && CharTypes.isIdentifierChar(c);                             
+        return c != '#' && (CharTypes.isIdentifierChar(c) || isIdentifierChar0(c));   
     }