diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 381f3afc1..1f358b03b 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -1845,7 +1845,11 @@ TOKEN : /* Numeric Constants */ SPECIAL_TOKEN: { - < LINE_COMMENT: ("--" | "//") (~["\r","\n"])*> + // The `#` comment requires a following blank: `#` without one stays an + // identifier start (SQL Server `#temp`, `##global`) and `#>` / `#>>` + // JSON operators must keep their usual lexing (issue #1197, #1695). + < LINE_COMMENT: ("--" | "//") (~["\r","\n"])* + | "#" [" ", "\t"] (~["\r","\n"])*> } // Nested block comments: /* ... /* ... */ ... */ diff --git a/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java b/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java index dd9b55732..c3a9563a6 100644 --- a/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java +++ b/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java @@ -221,6 +221,40 @@ public void accept(Statement statement) { assertEquals(3, list.size()); } + @Test + public void testLineCommentHashTrailing() throws Exception { + assertEquals("SELECT 1", CCJSqlParserUtil.parse("SELECT 1 # trailing comment").toString()); + } + + @Test + public void testLineCommentHashLeading() throws Exception { + assertEquals("SELECT 1", CCJSqlParserUtil.parse("# leading comment\nSELECT 1").toString()); + } + + @Test + public void testLineCommentHashWithinSelect() throws Exception { + assertEquals("SELECT 1 + 2, 3", + CCJSqlParserUtil.parse("SELECT 1 + 2 # note\n, 3").toString()); + } + + @Test + public void testHashWithoutBlankStaysIdentifier() throws Exception { + // without a following blank `#` is an identifier start, not a comment (#1197, #1695) + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM #temp"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM ##global"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM #$tab1#"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM $#tab1#"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM #$tab#tab1"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT a#b FROM t"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT 1 #note"); + } + + @Test + public void testHashJsonOperatorsStayOperators() throws Exception { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT js #> '{a}' FROM t"); + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT js #>> '{a,b}' FROM t"); + } + @Test public void testParseStatementsFail() throws Exception { String sqlStr = "select * from dual;WHATEVER!!";