Skip to content

Commit 4b77b8d

Browse files
lizongbowenshao
authored andcommitted
优化MySQL8.x的json类型字段默认值解析逻辑 #6102
优化MySQL8.x的json类型字段默认值解析逻辑 #6102
1 parent 0d98ecc commit 4b77b8d

File tree

5 files changed

+74
-4
lines changed

5 files changed

+74
-4
lines changed

core/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlCharExpr.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class MySqlCharExpr extends SQLCharExpr implements MySqlExpr {
2424
private String collate;
2525

2626
private String type;
27-
27+
protected boolean parenthesized;
2828
public MySqlCharExpr() {
2929
}
3030

@@ -67,6 +67,16 @@ public void setType(String type) {
6767
this.type = type;
6868
}
6969

70+
@Override
71+
public boolean isParenthesized() {
72+
return parenthesized;
73+
}
74+
75+
@Override
76+
public void setParenthesized(boolean parenthesized) {
77+
this.parenthesized = parenthesized;
78+
}
79+
7080
public void output(StringBuilder buf) {
7181
if (charset != null) {
7282
buf.append(charset);

core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,8 @@ public SQLExpr primary() {
10481048
accept(Token.IDENTIFIER);
10491049
}
10501050
}
1051-
1052-
charExpr = new MySqlCharExpr(str, "_utf8", collate);
1051+
String charset = hash_lower == FnvHash.Constants._UTF8 ? "_utf8" : "_utf8mb4";
1052+
charExpr = new MySqlCharExpr(str, charset, collate);
10531053
} else {
10541054
String str = MySqlUtils.utf8(hexString);
10551055
charExpr = new SQLCharExpr(str);

core/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3767,7 +3767,9 @@ public boolean visit(MySqlCharExpr x) {
37673767
}
37683768
return false;
37693769
}
3770-
3770+
if (x.isParenthesized()) {
3771+
print("(");
3772+
}
37713773
String charset = x.getCharset();
37723774
String collate = x.getCollate();
37733775
String text = x.getText();
@@ -3793,6 +3795,9 @@ public boolean visit(MySqlCharExpr x) {
37933795
print(" COLLATE ");
37943796
print(collate);
37953797
}
3798+
if (x.isParenthesized()) {
3799+
print(")");
3800+
}
37963801
return false;
37973802
}
37983803

core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.alibaba.druid.sql.ast.*;
2121
import com.alibaba.druid.sql.ast.expr.*;
2222
import com.alibaba.druid.sql.ast.statement.*;
23+
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
2324
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
2425
import com.alibaba.druid.sql.parser.Lexer.SavePoint;
2526
import com.alibaba.druid.util.FnvHash;
@@ -157,6 +158,9 @@ public SQLExpr expr() {
157158
if (parenthesized && sqlExpr instanceof SQLUnaryExpr) {
158159
((SQLUnaryExpr) sqlExpr).setParenthesized(true);
159160
}
161+
if (parenthesized && sqlExpr instanceof MySqlCharExpr) {
162+
((MySqlCharExpr) sqlExpr).setParenthesized(true);
163+
}
160164
return sqlExpr;
161165
}
162166
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.alibaba.druid.bvt.sql.mysql.issues;
2+
3+
import java.util.List;
4+
5+
import com.alibaba.druid.DbType;
6+
import com.alibaba.druid.sql.SQLParseAssertUtil;
7+
import com.alibaba.druid.sql.ast.SQLStatement;
8+
import com.alibaba.druid.sql.parser.SQLParserUtils;
9+
import com.alibaba.druid.sql.parser.SQLStatementParser;
10+
11+
import org.junit.Test;
12+
13+
import static org.junit.Assert.assertTrue;
14+
15+
/**
16+
* @author lizongbo
17+
* @see <a href="https://github.com/alibaba/druid/issues/6102" >Issue来源</a>
18+
* @see <a href="https://dev.mysql.com/doc/refman/8.4/en/create-table.html">mysql create table </a>
19+
*/
20+
public class Issue6102 {
21+
22+
23+
@Test
24+
public void test_parse_create() {
25+
for (DbType dbType : new DbType[]{DbType.mysql}) {
26+
for (String sql : new String[]{
27+
"CREATE TABLE `account_info` (\n"
28+
+ " `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '主键id',\n"
29+
+ " `account_num` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '账户编号',\n"
30+
+ " `open_acct_agreement_info` json DEFAULT (_utf8mb4'{}') COMMENT '协议信息',\n"
31+
+ " `ext_info` json DEFAULT (_utf8mb4'{}') COMMENT '扩展信息',\n"
32+
+ " `last_push_time` datetime DEFAULT NULL COMMENT '账户推送时间',\n"
33+
+ " `create_time` datetime NOT NULL COMMENT '创建时间',\n"
34+
+ " `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',\n"
35+
+ " PRIMARY KEY (`id`) USING BTREE,\n"
36+
+ " UNIQUE KEY `idx_account_num` (`account_num`) USING BTREE\n"
37+
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=COMPACT COMMENT='账户信息表';",
38+
39+
}) {
40+
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
41+
List<SQLStatement> statementList = parser.parseStatementList();
42+
System.out.println(statementList);
43+
String sqlnew=statementList.toString();
44+
assertTrue(sqlnew.contains("DEFAULT (_utf8mb4 '{}')"));
45+
SQLParseAssertUtil.assertParseSql(sql, dbType);
46+
}
47+
}
48+
}
49+
50+
51+
}

0 commit comments

Comments
 (0)