1515import java .io .StringReader ;
1616import java .nio .charset .StandardCharsets ;
1717import java .util .List ;
18+ import java .util .function .Consumer ;
1819import java .util .stream .Stream ;
1920import net .sf .jsqlparser .JSQLParserException ;
21+ import net .sf .jsqlparser .parser .AbstractJSqlParser .Dialect ;
2022import net .sf .jsqlparser .parser .CCJSqlParser ;
2123import net .sf .jsqlparser .parser .CCJSqlParserConstants ;
2224import net .sf .jsqlparser .parser .CCJSqlParserUtil ;
25+ import net .sf .jsqlparser .parser .StreamProvider ;
2326import net .sf .jsqlparser .parser .Token ;
2427import net .sf .jsqlparser .schema .Column ;
2528import net .sf .jsqlparser .statement .Statements ;
@@ -46,7 +49,8 @@ void preservesLiteralBodiesAndDelimiters(String tag) throws Exception {
4649 "$1 $other$ こんにちは" )) {
4750 String literal = delimiter + body + delimiter ;
4851 String sql = "SELECT " + literal + " AS value, 2 FROM t" ;
49- PlainSelect select = (PlainSelect ) TestUtils .assertSqlCanBeParsedAndDeparsed (sql );
52+ PlainSelect select = (PlainSelect ) TestUtils .assertSqlCanBeParsedAndDeparsed (sql , true ,
53+ parser -> parser .withDialect (Dialect .POSTGRESQL ));
5054 StringValue value =
5155 assertInstanceOf (StringValue .class , select .getSelectItem (0 ).getExpression ());
5256 assertEquals (body , value .getValue ());
@@ -55,7 +59,8 @@ void preservesLiteralBodiesAndDelimiters(String tag) throws Exception {
5559 assertEquals (literal , value .toString ());
5660 StringBuilder builder = new StringBuilder ();
5761 select .accept (new StatementDeParser (builder ), null );
58- PlainSelect again = (PlainSelect ) CCJSqlParserUtil .parse (builder .toString ());
62+ PlainSelect again = (PlainSelect ) CCJSqlParserUtil .parse (builder .toString (),
63+ parser -> parser .withDialect (Dialect .POSTGRESQL ));
5964 assertEquals (body , again .getSelectItem (0 ).getExpression (StringValue .class ).getValue ());
6065 assertEquals (select .toString (), builder .toString ());
6166 }
@@ -65,45 +70,70 @@ void preservesLiteralBodiesAndDelimiters(String tag) throws Exception {
6570 void keepsDifferentTagsAndDollarSignsInsideBody () throws Exception {
6671 String body = "$other$ text $Tag$ $$ $1 $t" ;
6772 PlainSelect select =
68- (PlainSelect ) CCJSqlParserUtil .parse ("SELECT $tag$" + body + "$tag$::text, $1" );
73+ (PlainSelect ) CCJSqlParserUtil .parse ("SELECT $tag$" + body + "$tag$::text, $1" ,
74+ parser -> parser .withDialect (Dialect .POSTGRESQL ));
6975 CastExpression cast = select .getSelectItem (0 ).getExpression (CastExpression .class );
7076 assertEquals (body , ((StringValue ) cast .getLeftExpression ()).getValue ());
7177 assertInstanceOf (JdbcParameter .class , select .getSelectItem (1 ).getExpression ());
7278 }
7379
7480 @ Test
75- void retainsIdentifiersAndSupportsOptOut () throws Exception {
81+ void retainsIdentifiersWithPostgreSqlDialect () throws Exception {
7682 PlainSelect select = (PlainSelect ) CCJSqlParserUtil
77- .parse ("SELECT $parameter, foo$bar, \" $tag$abc$tag$\" , $1 FROM t" );
83+ .parse ("SELECT $parameter, foo$bar, \" $tag$abc$tag$\" , $1 FROM t" ,
84+ parser -> parser .withDialect (Dialect .POSTGRESQL ));
7885 for (int i = 0 ; i < 3 ; i ++) {
7986 assertInstanceOf (Column .class , select .getSelectItem (i ).getExpression ());
8087 }
8188 assertInstanceOf (JdbcParameter .class , select .getSelectItem (3 ).getExpression ());
89+ }
90+
91+ static Stream <Consumer <CCJSqlParser >> identifierConfigurations () {
92+ return Stream .concat (
93+ Stream .<Consumer <CCJSqlParser >>of (parser -> {
94+ },
95+ parser -> parser .withDialect (Dialect .POSTGRESQL )
96+ .withDollarQuotedStringTags (false )),
97+ Stream .of (Dialect .values ()).filter (dialect -> dialect != Dialect .POSTGRESQL )
98+ .map (dialect -> parser -> parser .withDialect (dialect )));
99+ }
100+
101+ @ ParameterizedTest
102+ @ MethodSource ("identifierConfigurations" )
103+ void retainsIdentifiersAndUntaggedLiterals (Consumer <CCJSqlParser > configuration )
104+ throws Exception {
82105 for (String identifier : List .of ("$tag$abc$tag$" , "$tag$identifier" )) {
83- PlainSelect legacy = ( PlainSelect ) CCJSqlParserUtil . parse ( "SELECT " + identifier ,
84- parser -> parser . withDollarQuotedStringTags ( false ) );
106+ PlainSelect select =
107+ ( PlainSelect ) CCJSqlParserUtil . parse ( "SELECT " + identifier , configuration );
85108 assertEquals (identifier ,
86- legacy .getSelectItem (0 ).getExpression (Column .class ).getColumnName ());
109+ select .getSelectItem (0 ).getExpression (Column .class ).getColumnName ());
87110 }
88111 PlainSelect untagged = (PlainSelect ) CCJSqlParserUtil .parse ("SELECT $$text$$" ,
89- parser -> parser . withDollarQuotedStringTags ( false ) );
112+ configuration );
90113 assertEquals ("text" , untagged .getSelectItem (0 ).getExpression (StringValue .class ).getValue ());
91114 }
92115
116+ @ Test
117+ void supportsExplicitOptInWithoutDialect () throws Exception {
118+ PlainSelect select = (PlainSelect ) CCJSqlParserUtil .parse ("SELECT $tag$abc$tag$" ,
119+ parser -> parser .withDollarQuotedStringTags (true ));
120+ assertEquals ("abc" , select .getSelectItem (0 ).getExpression (StringValue .class ).getValue ());
121+ }
122+
93123 @ Test
94124 void retainsBodyWithOtherLexerOptions () throws Exception {
95125 PlainSelect select = (PlainSelect ) CCJSqlParserUtil .parse (
96126 "SELECT $t$#hash\n \\ text't$tag$ \" q\" $t$" ,
97- parser -> parser
98- .withDialect (net .sf .jsqlparser .parser .AbstractJSqlParser .Dialect .MYSQL ));
127+ parser -> parser .withDialect (Dialect .MYSQL ).withDollarQuotedStringTags (true ));
99128 assertEquals ("#hash\n \\ text't$tag$ \" q\" " ,
100129 select .getSelectItem (0 ).getExpression (StringValue .class ).getValue ());
101130 }
102131
103132 @ Test
104133 void keepsLineColumnAndAbsoluteTokenPositions () {
105134 String literal = "$tag$a\n b$tag$" ;
106- CCJSqlParser parser = CCJSqlParserUtil .newParser ("SELECT " + literal + ", 2" );
135+ CCJSqlParser parser = CCJSqlParserUtil .newParser ("SELECT " + literal + ", 2" )
136+ .withDialect (Dialect .POSTGRESQL );
107137 parser .getNextToken ();
108138 Token value = parser .getNextToken ();
109139 Token comma = parser .getNextToken ();
@@ -124,23 +154,28 @@ void recognizesFunctionBodyAndFollowingStatement() throws Exception {
124154 String body = "SELECT 'a;''b'::text;\n " ;
125155 String sql =
126156 "CREATE FUNCTION f() RETURNS text AS $fn$" + body + "$fn$ LANGUAGE SQL; SELECT 42;" ;
127- Statements statements = CCJSqlParserUtil .parseStatements (sql );
157+ Statements statements = CCJSqlParserUtil .parseStatements (sql ,
158+ parser -> parser .withDialect (Dialect .POSTGRESQL ));
128159 assertEquals (2 , statements .size ());
129160 assertEquals ("SELECT 42" , statements .get (1 ).toString ());
130161 org .junit .jupiter .api .Assertions
131162 .assertTrue (statements .get (0 ).toString ().contains ("$fn$" + body + "$fn$" ));
132- assertEquals (2 , CCJSqlParserUtil .parseStatements (statements .toString ()).size ());
163+ assertEquals (2 , CCJSqlParserUtil .parseStatements (statements .toString (),
164+ parser -> parser .withDialect (Dialect .POSTGRESQL )).size ());
133165 }
134166
135167 @ Test
136168 @ Timeout (10 )
137169 void handlesLongBodiesAndOverlappingDelimiterPrefixes () throws Exception {
138170 String body = "$ta$tagX $tagtagX\n " .repeat (12000 );
139171 String sql = "SELECT $tagtag$" + body + "$tagtag$" ;
140- PlainSelect select = (PlainSelect ) CCJSqlParserUtil .parse (new StringReader (sql ));
172+ PlainSelect select =
173+ (PlainSelect ) new CCJSqlParser (new StreamProvider (new StringReader (sql )))
174+ .withDialect (Dialect .POSTGRESQL ).Statement ();
141175 assertEquals (body , select .getSelectItem (0 ).getExpression (StringValue .class ).getValue ());
142- PlainSelect streamed = (PlainSelect ) CCJSqlParserUtil .parse (
143- new java .io .ByteArrayInputStream (sql .getBytes (StandardCharsets .UTF_8 )), "UTF-8" );
176+ PlainSelect streamed = (PlainSelect ) CCJSqlParserUtil .newParser (
177+ new java .io .ByteArrayInputStream (sql .getBytes (StandardCharsets .UTF_8 )), "UTF-8" )
178+ .withDialect (Dialect .POSTGRESQL ).Statement ();
144179 assertEquals (body , streamed .getSelectItem (0 ).getExpression (StringValue .class ).getValue ());
145180 }
146181
@@ -149,6 +184,7 @@ void handlesLongBodiesAndOverlappingDelimiterPrefixes() throws Exception {
149184 "SELECT $a$text$b$" , "SELECT $$missing" })
150185 void rejectsUnterminatedOrMismatchedTags (String sql ) {
151186 assertThrows (JSQLParserException .class ,
152- () -> CCJSqlParserUtil .parse (sql , parser -> parser .withTimeOut (1000 )));
187+ () -> CCJSqlParserUtil .parse (sql ,
188+ parser -> parser .withDialect (Dialect .POSTGRESQL ).withTimeOut (1000 )));
153189 }
154190}
0 commit comments