Skip to content

Commit 942a2c8

Browse files
committed
added create user statement
1 parent a607f93 commit 942a2c8

File tree

6 files changed

+114
-8
lines changed

6 files changed

+114
-8
lines changed

jdbc-v2/src/main/antlr4/com/clickhouse/jdbc/internal/ClickHouseLexer.g4

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ ATTACH : A T T A C H;
2727
BETWEEN : B E T W E E N;
2828
BOTH : B O T H;
2929
BY : B Y;
30+
BCRYPT_PASSWORD : B C R Y P T '_' P A S S W O R D;
31+
BCRYPT_HASH : B C R Y P T '_' H A S H;
3032
CASE : C A S E;
3133
CAST : C A S T;
3234
CHECK : C H E C K;
3335
CLEAR : C L E A R;
3436
CLUSTER : C L U S T E R;
37+
CN : C N;
3538
CODEC : C O D E C;
3639
COLLATE : C O L L A T E;
3740
COLUMN : C O L U M N;
@@ -59,6 +62,8 @@ DICTIONARY : D I C T I O N A R Y;
5962
DISK : D I S K;
6063
DISTINCT : D I S T I N C T;
6164
DISTRIBUTED : D I S T R I B U T E D;
65+
DOUBLE_SHA1_PASSWORD : D O U B L E '_' S H A '1' '_' P A S S W O R D;
66+
DOUBLE_SHA1_HASH : D O U B L E '_' S H A '1' '_' H A S H;
6267
DROP : D R O P;
6368
ELSE : E L S E;
6469
END : E N D;
@@ -82,11 +87,15 @@ FULL : F U L L;
8287
FUNCTION : F U N C T I O N;
8388
GLOBAL : G L O B A L;
8489
GRANULARITY : G R A N U L A R I T Y;
90+
GRANTEES : G R A N T E E S;
8591
GROUP : G R O U P;
8692
HAVING : H A V I N G;
8793
HIERARCHICAL : H I E R A R C H I C A L;
94+
HTTP : H T T P;
95+
HOST : H O S T;
8896
HOUR : H O U R;
8997
ID : I D;
98+
IDENTIFIED : I D E N T I F I E D;
9099
IF : I F;
91100
ILIKE : I L I K E;
92101
IN : I N;
@@ -97,13 +106,16 @@ INNER : I N N E R;
97106
INSERT : I N S E R T;
98107
INTERVAL : I N T E R V A L;
99108
INTO : I N T O;
109+
IP : I P;
100110
IS : I S;
101111
IS_OBJECT_ID : I S UNDERSCORE O B J E C T UNDERSCORE I D;
102112
JOIN : J O I N;
103113
KEY : K E Y;
114+
KERBEROS : K E R B E R O S;
104115
KILL : K I L L;
105116
LAST : L A S T;
106117
LAYOUT : L A Y O U T;
118+
LDAP : L D A P;
107119
LEADING : L E A D I N G;
108120
LEFT : L E F T;
109121
LIFETIME : L I F E T I M E;
@@ -123,7 +135,9 @@ MONTH : M O N T H;
123135
MOVE : M O V E;
124136
MUTATION : M U T A T I O N;
125137
NAN_SQL : N A N; // conflicts with macro NAN
138+
NAME : N A M E;
126139
NO : N O;
140+
NO_PASSWORD : N O '_' P A S S W O R D;
127141
NONE : N O N E;
128142
NOT : N O T;
129143
NULL_SQL : N U L L; // conflicts with macro NULL
@@ -142,8 +156,11 @@ PRECEDING : P R E C E D I N G;
142156
PREWHERE : P R E W H E R E;
143157
PRIMARY : P R I M A R Y;
144158
PROJECTION : P R O J E C T I O N;
159+
PLAINTEXT_PASSWORD : P L A I N T E X T '_' P A S S W O R D;
145160
QUARTER : Q U A R T E R;
146161
RANGE : R A N G E;
162+
REALM : R E A L M;
163+
REGEXP : R E G E X P;
147164
RELOAD : R E L O A D;
148165
REMOVE : R E M O V E;
149166
RENAME : R E N A M E;
@@ -156,13 +173,21 @@ ROLLUP : R O L L U P;
156173
ROW : R O W;
157174
ROWS : R O W S;
158175
SAMPLE : S A M P L E;
176+
SCHEMA : S C H E M A;
177+
SCRAM_SHA256_PASSWORD : S C R A M '_' S H A '2' '5' '6' '_' P A S S W O R D;
178+
SCRAM_SHA256_HASH : S C R A M '_' S H A '2' '5' '6' '_' H A S H;
159179
SECOND : S E C O N D;
160180
SELECT : S E L E C T;
161181
SEMI : S E M I;
162182
SENDS : S E N D S;
183+
SERVER : S E R V E R;
184+
SSL_CERTIFICATE : S S L '_' C E R T I F I C A T E;
185+
SSH_KEY : S S H '_' K E Y;
163186
SET : S E T;
164187
SETTINGS : S E T T I N G S;
165188
SHOW : S H O W;
189+
SHA256_PASSWORD : S H A '2' '5' '6' '_' P A S S W O R D;
190+
SHA256_HASH : S H A '2' '5' '6' '_' H A S H;
166191
SOURCE : S O U R C E;
167192
START : S T A R T;
168193
STOP : S T O P;
@@ -190,6 +215,7 @@ UNBOUNDED : U N B O U N D E D;
190215
UNION : U N I O N;
191216
UPDATE : U P D A T E;
192217
USE : U S E;
218+
USER : U S E R;
193219
USING : U S I N G;
194220
UUID : U U I D;
195221
VALUES : V A L U E S;

jdbc-v2/src/main/antlr4/com/clickhouse/jdbc/internal/ClickHouseParser.g4

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,50 @@ createStmt
142142
engineClause? subqueryClause? # CreateTableStmt
143143
| (ATTACH | CREATE) (OR REPLACE)? VIEW (IF NOT EXISTS)? tableIdentifier uuidClause? clusterClause? tableSchemaClause? subqueryClause #
144144
CreateViewStmt
145+
| CREATE USER ((IF NOT EXISTS) | (OR REPLACE))? userIdentifier (COMMA userIdentifier)* clusterClause?
146+
userIdentifiedClause?
147+
userCreateHostClause?
148+
validUntilClause?
149+
(DEFAULT ROLE identifier (COMMA identifier)*)?
150+
(DEFAULT DATABASE identifier | NONE)?
151+
152+
settingsClause? #CreateUserStmt
153+
;
154+
155+
userIdentifier
156+
: (IDENTIFIER | STRING_LITERAL)
157+
;
158+
159+
userIdentifiedClause
160+
: IDENTIFIED BY literal
161+
| IDENTIFIED WITH userIdentifiedWithClause validUntilClause? (COMMA userIdentifiedWithClause VALID UNTIL literal)*
162+
| NOT IDENTIFIED
163+
;
164+
165+
userIdentifiedWithClause
166+
: (PLAINTEXT_PASSWORD | SHA256_PASSWORD | SHA256_HASH | DOUBLE_SHA1_PASSWORD | DOUBLE_SHA1_HASH | SCRAM_SHA256_PASSWORD | SCRAM_SHA256_HASH | BCRYPT_PASSWORD | BCRYPT_HASH) BY literal
167+
| NO_PASSWORD
168+
| LDAP SERVER literal
169+
| KERBEROS (REALM literal)?
170+
| SSL_CERTIFICATE CN literal
171+
| SSH_KEY BY KEY literal TYPE literal
172+
| HTTP SERVER literal (SCHEMA literal)?
173+
;
174+
175+
userCreateHostClause
176+
: HOST (userCreateHostDef (COMMA userCreateHostDef)*) | ANY | NONE
177+
;
178+
179+
userCreateHostDef
180+
: LOCAL | NAME literal | REGEXP literal | IP literal | LIKE literal
181+
;
182+
183+
userCreateGranteesClause
184+
: GRANTEES (identifier | STRING_LITERAL | ANY | NONE ) (COMMA (identifier | STRING_LITERAL | ANY | NONE ))*
185+
(EXCEPT (identifier | STRING_LITERAL) (COMMA (identifier | STRING_LITERAL ))*)
186+
;
187+
validUntilClause
188+
: VALID UNTIL interval
145189
;
146190

147191
dictionarySchemaClause
@@ -950,4 +994,4 @@ identifierOrNull
950994

951995
enumValue
952996
: STRING_LITERAL EQ_SINGLE numberLiteral
953-
;
997+
;

jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ protected ResultSetImpl executeQueryImpl(String sql, QuerySettings settings) thr
129129

130130
try {
131131
lastStatementSql = parseJdbcEscapeSyntax(sql);
132-
LOG.debug("SQL Query: {}", lastStatementSql);
132+
LOG.trace("SQL Query: {}", lastStatementSql); // this is not secure for create statements because of passwords
133133
QueryResponse response;
134134
if (queryTimeout == 0) {
135135
response = connection.client.query(lastStatementSql, mergedSettings).get();
@@ -179,7 +179,7 @@ protected int executeUpdateImpl(String sql, QuerySettings settings) throws SQLEx
179179
}
180180

181181
lastStatementSql = parseJdbcEscapeSyntax(sql);
182-
LOG.debug("SQL Query: {}", lastStatementSql);
182+
LOG.trace("SQL Query: {}", lastStatementSql);
183183
int updateCount = 0;
184184
try (QueryResponse response = queryTimeout == 0 ? connection.client.query(lastStatementSql, mergedSettings).get()
185185
: connection.client.query(lastStatementSql, mergedSettings).get(queryTimeout, TimeUnit.SECONDS)) {

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/ParsedStatement.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,6 @@ public void enterSetRoleStmt(ClickHouseParser.SetRoleStmtContext ctx) {
103103
setRoles(roles);
104104
}
105105
}
106+
107+
106108
}

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/SqlParser.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
package com.clickhouse.jdbc.internal;
22

3+
import org.antlr.v4.runtime.ANTLRErrorListener;
4+
import org.antlr.v4.runtime.BaseErrorListener;
35
import org.antlr.v4.runtime.CharStream;
46
import org.antlr.v4.runtime.CharStreams;
57
import org.antlr.v4.runtime.CommonTokenStream;
8+
import org.antlr.v4.runtime.RecognitionException;
9+
import org.antlr.v4.runtime.Recognizer;
610
import org.antlr.v4.runtime.tree.IterativeParseTreeWalker;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
713

814
import java.util.regex.Matcher;
915
import java.util.regex.Pattern;
1016

1117
public class SqlParser {
1218

19+
private static Logger LOG = LoggerFactory.getLogger(SqlParser.class);
20+
1321
public ParsedStatement parsedStatement(String sql) {
1422

1523
CharStream charStream = CharStreams.fromString(sql);
1624
ClickHouseLexer lexer = new ClickHouseLexer(charStream);
1725
ClickHouseParser parser = new ClickHouseParser(new CommonTokenStream(lexer));
26+
parser.removeErrorListeners();
27+
parser.addErrorListener(new ParserErrorListener());
1828
ClickHouseParser.QueryStmtContext parseTree = parser.queryStmt();
1929
ParsedStatement parserListener = new ParsedStatement();
2030
IterativeParseTreeWalker.DEFAULT.walk(parserListener, parseTree);
2131

22-
2332
return parserListener;
2433
}
2534

@@ -54,4 +63,11 @@ public static String escapeQuotes(String str) {
5463
.replace("'", "\\'")
5564
.replace("\"", "\\\"");
5665
}
66+
67+
private static class ParserErrorListener extends BaseErrorListener {
68+
@Override
69+
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
70+
LOG.warn("SQL syntax error at line: " + line + ", pos: " + charPositionInLine + ", " + msg);
71+
}
72+
}
5773
}

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ public void testExecuteQueryTimeout() throws Exception {
341341

342342

343343
@Test(groups = { "integration" })
344-
private void testSettingRole() throws SQLException {
344+
public void testSettingRole() throws SQLException {
345345
if (earlierThan(24, 4)) {//Min version is 24.4
346346
return;
347347
}
@@ -550,8 +550,8 @@ public void testSwitchDatabase() throws Exception {
550550
}
551551
}
552552
}
553-
554-
553+
554+
555555
@Test(groups = { "integration" })
556556
public void testNewLineSQLParsing() throws Exception {
557557
try (Connection conn = getJdbcConnection()) {
@@ -616,7 +616,7 @@ public void testNewLineSQLParsing() throws Exception {
616616
}
617617
}
618618

619-
619+
620620
@Test(groups = { "integration" })
621621
public void testNullableFixedStringType() throws Exception {
622622
try (Connection conn = getJdbcConnection()) {
@@ -707,4 +707,22 @@ public void testExecuteWithMaxRows() throws Exception {
707707
}
708708
}
709709

710+
@Test(groups = {"integration"})
711+
public void testDDLStatements() throws Exception {
712+
try (Connection conn = getJdbcConnection()) {
713+
try (Statement stmt = conn.createStatement()){
714+
Assert.assertFalse(stmt.execute("CREATE USER IF NOT EXISTS 'user011' IDENTIFIED BY 'password'"));
715+
716+
try (ResultSet rs = stmt.executeQuery("SHOW USERS")) {
717+
boolean found = false;
718+
while (rs.next()) {
719+
if (rs.getString("name").equals("user011")) {
720+
found = true;
721+
}
722+
}
723+
Assert.assertTrue(found);
724+
}
725+
}
726+
}
727+
}
710728
}

0 commit comments

Comments
 (0)