Skip to content

Commit 1e4e92b

Browse files
authored
fix(parser): support CHARACTER SET in CAST CHAR types (JSQLParser#2497)
1 parent aa7df62 commit 1e4e92b

2 files changed

Lines changed: 23 additions & 6 deletions

File tree

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11410,12 +11410,14 @@ ColDataType DataType():
1141011410
( tk=<K_DATETIMELITERAL> | tk=<DT_ZONE> | tk = <DATA_TYPE> | tk = <K_SIGNED> | tk = <K_UNSIGNED>
1141111411
| tk=<K_CHARACTER> | tk=<K_BIT> | tk=<K_BYTES> | tk=<K_BINARY> | tk=<K_BOOLEAN>
1141211412
| tk=<K_CHAR> | tk=<K_JSON> | tk=<K_STRING> ) { type = tk.image; }
11413-
[
11414-
// MySQL seems to allow: INT UNSIGNED
11415-
LOOKAHEAD(2) ( LOOKAHEAD(2) ( tk = <DATA_TYPE> | tk = <K_SIGNED> | tk = <K_UNSIGNED>
11416-
| tk=<K_CHARACTER> | tk=<K_BIT> | tk=<K_BYTES> | tk=<K_BINARY> | tk=<K_BOOLEAN>
11417-
| tk=<K_CHAR> | tk=<K_JSON> | tk=<K_STRING> ) { type += " " + tk.image; } )+
11418-
]
11413+
(
11414+
// MySQL seems to allow: INT UNSIGNED. Do not consume CHARACTER when it starts
11415+
// the trailing CHARACTER SET clause of a character type.
11416+
LOOKAHEAD(2, { getToken(1).kind != K_CHARACTER || getToken(2).kind != K_SET })
11417+
( tk = <DATA_TYPE> | tk = <K_SIGNED> | tk = <K_UNSIGNED>
11418+
| tk=<K_CHARACTER> | tk=<K_BIT> | tk=<K_BYTES> | tk=<K_BINARY> | tk=<K_BOOLEAN>
11419+
| tk=<K_CHAR> | tk=<K_JSON> | tk=<K_STRING> ) { type += " " + tk.image; }
11420+
)*
1141911421
[
1142011422
LOOKAHEAD(2) "(" ( tk=<S_LONG> { precision = Integer.valueOf(tk.image); } | tk=<K_MAX> { precision = Integer.MAX_VALUE; } )
1142111423
[ <K_BYTE> | <K_CHAR> ]

src/test/java/net/sf/jsqlparser/expression/CastExpressionTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ void testImplicitCastDoublePrecisionIssue1344() throws JSQLParserException {
6868
Assertions.assertTrue(select.getSelectItem(0).getExpression() instanceof CastExpression);
6969
}
7070

71+
@Test
72+
void testCastCharWithCharacterSet() throws JSQLParserException {
73+
String sqlStr = "SELECT CAST('abc' AS CHAR CHARACTER SET utf8mb4)";
74+
PlainSelect select = (PlainSelect) assertSqlCanBeParsedAndDeparsed(sqlStr, true);
75+
CastExpression castExpression = Assertions.assertInstanceOf(CastExpression.class,
76+
select.getSelectItem(0).getExpression());
77+
78+
Assertions.assertEquals("CHAR", castExpression.getColDataType().getDataType());
79+
Assertions.assertEquals("utf8mb4", castExpression.getColDataType().getCharacterSet());
80+
81+
assertSqlCanBeParsedAndDeparsed(
82+
"SELECT CAST('abc' AS CHAR(10) CHARACTER SET utf8mb4)", true);
83+
assertSqlCanBeParsedAndDeparsed("SELECT CAST('abc' AS CHARACTER VARYING)", true);
84+
}
85+
7186

7287
@Test
7388
public void testCastToSigned() throws JSQLParserException {

0 commit comments

Comments
 (0)