22
33import com .clickhouse .client .api .sql .SQLUtils ;
44import com .clickhouse .data .ClickHouseUtils ;
5+ import com .clickhouse .jdbc .DriverProperties ;
56import com .clickhouse .jdbc .internal .parser .antlr4 .ClickHouseLexer ;
67import com .clickhouse .jdbc .internal .parser .antlr4 .ClickHouseParser ;
78import com .clickhouse .jdbc .internal .parser .antlr4 .ClickHouseParserBaseListener ;
2526import java .util .ArrayList ;
2627import java .util .Collections ;
2728import java .util .List ;
29+ import java .util .Map ;
2830import java .util .stream .Collectors ;
2931
3032public abstract class SqlParserFacade {
@@ -37,6 +39,12 @@ public abstract class SqlParserFacade {
3739
3840 private static class JavaCCParser extends SqlParserFacade {
3941
42+ private final boolean processUseRolesExpr ;
43+
44+ public JavaCCParser (boolean saveRoles ) {
45+ this .processUseRolesExpr = saveRoles ;
46+ }
47+
4048 @ Override
4149 public ParsedStatement parsedStatement (String sql ) {
4250 ParsedStatement stmt = new ParsedStatement ();
@@ -45,22 +53,11 @@ public ParsedStatement parsedStatement(String sql) {
4553 stmt .setUseDatabase (parsedStmt .getDatabase ());
4654 }
4755
48- String rolesCount = parsedStmt .getSettings ().get ("_ROLES_COUNT" );
49- if (rolesCount != null ) {
50- int rolesCountInt = Integer .parseInt (rolesCount );
51- ArrayList <String > roles = new ArrayList <>(rolesCountInt );
52- boolean resetRoles = false ;
53- for (int i = 0 ; i < rolesCountInt ; i ++) {
54- String role = parsedStmt .getSettings ().get ("_ROLE_" + i );
55- if (role .equalsIgnoreCase ("NONE" )) {
56- resetRoles = true ;
57- }
58- roles .add (parsedStmt .getSettings ().get ("_ROLE_" + i ));
59- }
60- if (resetRoles ) {
61- roles .clear ();
56+ if (processUseRolesExpr ) {
57+ List <String > roles = processRoles (parsedStmt .getSettings ());
58+ if (roles != null ) {
59+ stmt .setRoles (roles );
6260 }
63- stmt .setRoles (roles );
6461 }
6562
6663 stmt .setInsert (parsedStmt .getStatementType () == StatementType .INSERT );
@@ -109,11 +106,39 @@ public ParsedPreparedStatement parsePreparedStatement(String sql) {
109106 }
110107 }
111108
109+ if (processUseRolesExpr ) {
110+ List <String > roles = processRoles (parsedStmt .getSettings ());
111+ if (roles != null ) {
112+ stmt .setRoles (roles );
113+ }
114+ }
115+
112116 stmt .setUseFunction (parsedStmt .isFuncUsed ());
113117 parseParameters (sql , stmt );
114118 return stmt ;
115119 }
116120
121+ private List <String > processRoles (Map <String , String > settings ) {
122+ String rolesCount = settings .get ("_ROLES_COUNT" );
123+ if (rolesCount != null ) {
124+ int rolesCountInt = Integer .parseInt (rolesCount );
125+ ArrayList <String > roles = new ArrayList <>(rolesCountInt );
126+ boolean resetRoles = false ;
127+ for (int i = 0 ; i < rolesCountInt ; i ++) {
128+ String role = settings .get ("_ROLE_" + i );
129+ if (role .equalsIgnoreCase ("NONE" )) {
130+ resetRoles = true ;
131+ }
132+ roles .add (settings .get ("_ROLE_" + i ));
133+ }
134+ if (resetRoles ) {
135+ roles .clear ();
136+ }
137+ return roles ;
138+ }
139+ return null ; // no roles present
140+ }
141+
117142
118143 public ClickHouseSqlStatement parse (String sql ) {
119144 JdbcParseHandler handler = JdbcParseHandler .getInstance ();
@@ -127,17 +152,23 @@ public ClickHouseSqlStatement parse(String sql) {
127152
128153 private static class ANTLR4Parser extends SqlParserFacade {
129154
155+ protected final boolean processUseRolesExpr ;
156+
157+ public ANTLR4Parser (boolean saveRoles ) {
158+ this .processUseRolesExpr = saveRoles ;
159+ }
160+
130161 @ Override
131162 public ParsedStatement parsedStatement (String sql ) {
132163 ParsedStatement stmt = new ParsedStatement ();
133- parseSQL (sql , new ParsedStatementListener (stmt ));
164+ parseSQL (sql , new ParsedStatementListener (stmt , processUseRolesExpr ));
134165 return stmt ;
135166 }
136167
137168 @ Override
138169 public ParsedPreparedStatement parsePreparedStatement (String sql ) {
139170 ParsedPreparedStatement stmt = new ParsedPreparedStatement ();
140- parseSQL (sql , new ParsedPreparedStatementListener (stmt ));
171+ parseSQL (sql , new ParsedPreparedStatementListener (stmt , processUseRolesExpr ));
141172
142173 // Combine database and table like JavaCC does
143174 String tableName = stmt .getTable ();
@@ -177,12 +208,27 @@ static boolean isStmtWithResultSet(ClickHouseParser.QueryStmtContext stmtContext
177208 qCtx .existsStmt () != null || qCtx .checkStmt () != null );
178209 }
179210
211+ static List <String > processRolesExpr (ClickHouseParser .SetRoleStmtContext ctx ) {
212+ if (ctx .NONE () != null ) {
213+ return Collections .emptyList ();
214+ } else {
215+ List <String > roles = new ArrayList <>();
216+ for (ClickHouseParser .IdentifierContext id : ctx .setRolesList ().identifier ()) {
217+ roles .add (SQLUtils .unquoteIdentifier (id .getText ()));
218+ }
219+ return roles ;
220+ }
221+ }
222+
180223 private static class ParsedStatementListener extends ClickHouseParserBaseListener {
181224
182225 private final ParsedStatement parsedStatement ;
183226
184- public ParsedStatementListener (ParsedStatement parsedStatement ) {
227+ private final boolean processSetRolesExpr ;
228+
229+ public ParsedStatementListener (ParsedStatement parsedStatement , boolean processSetRolesExpr ) {
185230 this .parsedStatement = parsedStatement ;
231+ this .processSetRolesExpr = processSetRolesExpr ;
186232 }
187233
188234 @ Override
@@ -206,14 +252,8 @@ public void enterUseStmt(ClickHouseParser.UseStmtContext ctx) {
206252
207253 @ Override
208254 public void enterSetRoleStmt (ClickHouseParser .SetRoleStmtContext ctx ) {
209- if (ctx .NONE () != null ) {
210- parsedStatement .setRoles (Collections .emptyList ());
211- } else {
212- List <String > roles = new ArrayList <>();
213- for (ClickHouseParser .IdentifierContext id : ctx .setRolesList ().identifier ()) {
214- roles .add (SQLUtils .unquoteIdentifier (id .getText ()));
215- }
216- parsedStatement .setRoles (roles );
255+ if (processSetRolesExpr ) {
256+ parsedStatement .setRoles (processRolesExpr (ctx ));
217257 }
218258 }
219259 }
@@ -222,8 +262,11 @@ protected static class ParsedPreparedStatementListener extends ClickHouseParserB
222262
223263 protected final ParsedPreparedStatement parsedStatement ;
224264
225- public ParsedPreparedStatementListener (ParsedPreparedStatement parsedStatement ) {
265+ private final boolean processSetRolesExpr ;
266+
267+ public ParsedPreparedStatementListener (ParsedPreparedStatement parsedStatement , boolean processSetRolesExpr ) {
226268 this .parsedStatement = parsedStatement ;
269+ this .processSetRolesExpr = processSetRolesExpr ;
227270 }
228271
229272 @ Override
@@ -242,14 +285,8 @@ public void enterUseStmt(ClickHouseParser.UseStmtContext ctx) {
242285
243286 @ Override
244287 public void enterSetRoleStmt (ClickHouseParser .SetRoleStmtContext ctx ) {
245- if (ctx .NONE () != null ) {
246- parsedStatement .setRoles (Collections .emptyList ());
247- } else {
248- List <String > roles = new ArrayList <>();
249- for (ClickHouseParser .IdentifierContext id : ctx .setRolesList ().identifier ()) {
250- roles .add (SQLUtils .unquoteIdentifier (id .getText ()));
251- }
252- parsedStatement .setRoles (roles );
288+ if (processSetRolesExpr ) {
289+ parsedStatement .setRoles (processRolesExpr (ctx ));
253290 }
254291 }
255292
@@ -349,10 +386,15 @@ public void exitInsertParameterFuncExpr(ClickHouseParser.InsertParameterFuncExpr
349386
350387 private static class ANTLR4AndParamsParser extends ANTLR4Parser {
351388
389+
390+ public ANTLR4AndParamsParser (boolean saveRoles ) {
391+ super (saveRoles );
392+ }
393+
352394 @ Override
353395 public ParsedPreparedStatement parsePreparedStatement (String sql ) {
354396 ParsedPreparedStatement stmt = new ParsedPreparedStatement ();
355- parseSQL (sql , new ParseStatementAndParamsListener (stmt ));
397+ parseSQL (sql , new ParseStatementAndParamsListener (stmt , processUseRolesExpr ));
356398
357399 // Combine database and table like JavaCC does
358400 String tableName = stmt .getTable ();
@@ -366,8 +408,8 @@ public ParsedPreparedStatement parsePreparedStatement(String sql) {
366408
367409 private static class ParseStatementAndParamsListener extends ParsedPreparedStatementListener {
368410
369- public ParseStatementAndParamsListener (ParsedPreparedStatement parsedStatement ) {
370- super (parsedStatement );
411+ public ParseStatementAndParamsListener (ParsedPreparedStatement parsedStatement , boolean processSetRolesExpr ) {
412+ super (parsedStatement , processSetRolesExpr );
371413 }
372414
373415 @ Override
@@ -449,16 +491,18 @@ public enum SQLParser {
449491 ANTLR4
450492 }
451493
452- public static SqlParserFacade getParser (String name ) throws SQLException {
494+ public static SqlParserFacade getParser (String name , JdbcConfiguration jdbcConfiguration ) throws SQLException {
453495 try {
496+ boolean saveRoles = Boolean .parseBoolean (jdbcConfiguration .getDriverProperty (DriverProperties .REMEMBER_LAST_SET_ROLES .getKey (),
497+ DriverProperties .REMEMBER_LAST_SET_ROLES .getDefaultValue ()));
454498 SQLParser parserSelection = SQLParser .valueOf (name );
455499 switch (parserSelection ) {
456500 case JAVACC :
457- return new JavaCCParser ();
501+ return new JavaCCParser (saveRoles );
458502 case ANTLR4_PARAMS_PARSER :
459- return new ANTLR4AndParamsParser ();
503+ return new ANTLR4AndParamsParser (saveRoles );
460504 case ANTLR4 :
461- return new ANTLR4Parser ();
505+ return new ANTLR4Parser (saveRoles );
462506 }
463507 throw new SQLException ("Unsupported parser: " + parserSelection );
464508 } catch (IllegalArgumentException e ) {
0 commit comments