Skip to content

Commit 3281659

Browse files
committed
fix: stop 0x hex literal from swallowing trailing whitespace (#2435)
HEX_VALUE included a space character, so the "0x" hex literal form greedily consumed trailing whitespace and any adjacent hex letters (e.g. the "F" of FROM). Consequently `SELECT 0xFF FROM t` failed with "Encountered <S_IDENTIFIER> t", while `SELECT 0xFF,1 FROM t` (comma, no space) parsed fine. The space is only required by the X'..' form, which deliberately allows internal whitespace (e.g. X'01 bc 2a', covered by StringValueTest). Split the shared token: X'..' keeps HEX_VALUE (with space), while the 0x.. form uses a new space-less HEX_DIGIT token. Signed-off-by: 付典 <fudianchn@gmail.com>
1 parent f0ba123 commit 3281659

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1601,8 +1601,9 @@ TOKEN : /* Numeric Constants */
16011601
)>
16021602
| < S_LONG: ( <DIGIT> )+ >
16031603
| < #DIGIT: ["0" - "9"] >
1604-
| < S_HEX: ("X" ("'" ( <HEX_VALUE> )* "'" (" ")*)+ | "0x" ( <HEX_VALUE> )+ ) >
1604+
| < S_HEX: ("X" ("'" ( <HEX_VALUE> )* "'" (" ")*)+ | "0x" ( <HEX_DIGIT> )+ ) >
16051605
| < #HEX_VALUE: ["0"-"9","A"-"F", " "] >
1606+
| < #HEX_DIGIT: ["0"-"9","A"-"F"] >
16061607
}
16071608

16081609
SPECIAL_TOKEN:

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,23 @@ void testHexCode() throws JSQLParserException {
3939

4040
Assertions.assertEquals("'\\xC3\\xBC'", hex3.getBlob().toString());
4141
}
42+
43+
@Test
44+
void testHexLiteralFollowedByPrimaryKeyword() throws JSQLParserException {
45+
// Issue #2435: a "0x"-prefixed hex literal must not greedily consume the
46+
// following whitespace nor adjacent hex letters (e.g. the "F" of FROM),
47+
// which previously made "SELECT 0xFF FROM t" fail to parse.
48+
assertHexSelectItem("SELECT 0xFF FROM t", "FF");
49+
assertHexSelectItem("SELECT 0xff FROM t", "ff");
50+
assertHexSelectItem("SELECT 0xDEADBEEF FROM t", "DEADBEEF");
51+
assertHexSelectItem("SELECT 0xab FROM dual", "ab");
52+
}
53+
54+
private static void assertHexSelectItem(String sql, String expectedDigits)
55+
throws JSQLParserException {
56+
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sql);
57+
Expression expr = select.getSelectItem(0).getExpression();
58+
Assertions.assertTrue(expr instanceof HexValue, () -> "Expected HexValue for: " + sql);
59+
Assertions.assertEquals(expectedDigits, ((HexValue) expr).getDigits());
60+
}
4261
}

0 commit comments

Comments
 (0)