1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.sql.parser.sqlserver.visitor.statement.type;
19
20 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
21 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
22 import org.apache.shardingsphere.sql.parser.api.ASTNode;
23 import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DCLStatementVisitor;
24 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AlterLoginContext;
25 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AlterRoleContext;
26 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AlterUserContext;
27 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ClassPrivilegesContext;
28 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ColumnNamesContext;
29 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateLoginContext;
30 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateRoleContext;
31 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateUserContext;
32 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateUserLoginWindowsPrincipalClauseContext;
33 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateUserWindowsPrincipalClauseContext;
34 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DenyContext;
35 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DropLoginContext;
36 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DropRoleContext;
37 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DropUserContext;
38 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.GrantContext;
39 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.IgnoredNameIdentifierContext;
40 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OnClassClauseContext;
41 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OnClassTypeClauseContext;
42 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OwnerContext;
43 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RevertContext;
44 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RevokeContext;
45 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SecurableContext;
46 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SetUserContext;
47 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UserNameContext;
48 import org.apache.shardingsphere.sql.parser.sqlserver.visitor.statement.SQLServerStatementVisitor;
49 import org.apache.shardingsphere.sql.parser.statement.core.segment.dcl.LoginSegment;
50 import org.apache.shardingsphere.sql.parser.statement.core.segment.dcl.UserSegment;
51 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
52 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
53 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
54 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
55 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.role.AlterRoleStatement;
56 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.role.CreateRoleStatement;
57 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.role.DropRoleStatement;
58 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.user.AlterUserStatement;
59 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.user.CreateUserStatement;
60 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.user.DropUserStatement;
61 import org.apache.shardingsphere.sql.parser.statement.core.value.collection.CollectionValue;
62 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
63 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.StringLiteralValue;
64 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.SQLServerGrantStatement;
65 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.SQLServerRevertStatement;
66 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.SQLServerRevokeStatement;
67 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.login.SQLServerAlterLoginStatement;
68 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.login.SQLServerCreateLoginStatement;
69 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.login.SQLServerDropLoginStatement;
70 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.user.SQLServerDenyUserStatement;
71 import org.apache.shardingsphere.sql.parser.statement.sqlserver.dcl.user.SQLServerSetUserStatement;
72
73 import java.util.Collections;
74 import java.util.Optional;
75
76
77
78
79 public final class SQLServerDCLStatementVisitor extends SQLServerStatementVisitor implements DCLStatementVisitor {
80
81 private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "SQLServer");
82
83 @Override
84 public ASTNode visitGrant(final GrantContext ctx) {
85 SQLServerGrantStatement result = new SQLServerGrantStatement(databaseType);
86 if (null != ctx.grantClassPrivilegesClause()) {
87 findTableSegment(ctx.grantClassPrivilegesClause().onClassClause(), ctx.grantClassPrivilegesClause().classPrivileges()).ifPresent(optional -> result.getTables().add(optional));
88 if (null != ctx.grantClassPrivilegesClause().classPrivileges().columnNames()) {
89 for (ColumnNamesContext each : ctx.grantClassPrivilegesClause().classPrivileges().columnNames()) {
90 result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(each)).getValue());
91 }
92 }
93 }
94 if (null != ctx.grantClassTypePrivilegesClause()) {
95 findTableSegment(ctx.grantClassTypePrivilegesClause().onClassTypeClause()).ifPresent(optional -> result.getTables().add(optional));
96 }
97 return result;
98 }
99
100 @Override
101 public ASTNode visitRevoke(final RevokeContext ctx) {
102 SQLServerRevokeStatement result = new SQLServerRevokeStatement(databaseType);
103 if (null != ctx.revokeClassPrivilegesClause()) {
104 findTableSegment(ctx.revokeClassPrivilegesClause().onClassClause(), ctx.revokeClassPrivilegesClause().classPrivileges()).ifPresent(optional -> result.getTables().add(optional));
105 if (null != ctx.revokeClassPrivilegesClause().classPrivileges().columnNames()) {
106 for (ColumnNamesContext each : ctx.revokeClassPrivilegesClause().classPrivileges().columnNames()) {
107 result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(each)).getValue());
108 }
109 }
110 }
111 if (null != ctx.revokeClassTypePrivilegesClause()) {
112 findTableSegment(ctx.revokeClassTypePrivilegesClause().onClassTypeClause()).ifPresent(optional -> result.getTables().add(optional));
113 }
114 return result;
115 }
116
117 @Override
118 public ASTNode visitSecurable(final SecurableContext ctx) {
119 SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(), ctx.name().getStop().getStopIndex(), (IdentifierValue) visit(ctx.name())));
120 OwnerContext owner = ctx.owner();
121 if (null != owner) {
122 result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
123 }
124 return result;
125 }
126
127 @Override
128 public ASTNode visitCreateUser(final CreateUserContext ctx) {
129 CreateUserStatement result = new CreateUserStatement(databaseType);
130 if (null != ctx.createUserLoginClause()) {
131 result.getUsers().add((UserSegment) visit(ctx.createUserLoginClause().userName()));
132 } else if (null != ctx.createUserWindowsPrincipalClause()) {
133 result.getUsers().add((UserSegment) visit(ctx.createUserWindowsPrincipalClause()));
134 } else if (null != ctx.createUserLoginWindowsPrincipalClause()) {
135 result.getUsers().add((UserSegment) visit(ctx.createUserLoginWindowsPrincipalClause()));
136 } else if (null != ctx.createUserWithoutLoginClause()) {
137 result.getUsers().add((UserSegment) visit(ctx.createUserWithoutLoginClause().userName()));
138 } else if (null != ctx.createUserFromExternalProviderClause()) {
139 result.getUsers().add((UserSegment) visit(ctx.createUserFromExternalProviderClause().userName()));
140 } else if (null != ctx.createUserWithDefaultSchema()) {
141 result.getUsers().add((UserSegment) visit(ctx.createUserWithDefaultSchema().userName()));
142 } else if (null != ctx.createUserWithAzureActiveDirectoryPrincipalClause()) {
143 result.getUsers().add((UserSegment) visit(ctx.createUserWithAzureActiveDirectoryPrincipalClause().azureActiveDirectoryPrincipal().userName()));
144 } else {
145 result.getUsers().add((UserSegment) visit(ctx.userName()));
146 }
147 return result;
148 }
149
150 @Override
151 public ASTNode visitUserName(final UserNameContext ctx) {
152 UserSegment result = new UserSegment();
153 String user = ((IdentifierValue) visit(ctx.ignoredNameIdentifier())).getValue();
154 result.setUser(user);
155 return result;
156 }
157
158 @Override
159 public ASTNode visitIgnoredNameIdentifier(final IgnoredNameIdentifierContext ctx) {
160 int identifierCount = ctx.identifier().size();
161 return 1 == identifierCount ? (IdentifierValue) visit(ctx.identifier(0)) : new IdentifierValue(ctx.getText());
162 }
163
164 @Override
165 public ASTNode visitCreateUserWindowsPrincipalClause(final CreateUserWindowsPrincipalClauseContext ctx) {
166 if (null != ctx.windowsPrincipal()) {
167 return visit(ctx.windowsPrincipal().userName());
168 }
169 if (null != ctx.azureActiveDirectoryPrincipal()) {
170 return visit(ctx.azureActiveDirectoryPrincipal().userName());
171 }
172 return visit(ctx.userName());
173 }
174
175 @Override
176 public ASTNode visitCreateUserLoginWindowsPrincipalClause(final CreateUserLoginWindowsPrincipalClauseContext ctx) {
177 return null == ctx.userName() ? (UserSegment) visit(ctx.windowsPrincipal(0)) : (UserSegment) visit(ctx.userName());
178 }
179
180 @Override
181 public ASTNode visitAlterUser(final AlterUserContext ctx) {
182 return new AlterUserStatement(databaseType, (UserSegment) visit(ctx.userName()));
183 }
184
185 @Override
186 public ASTNode visitDeny(final DenyContext ctx) {
187 SQLServerDenyUserStatement result = new SQLServerDenyUserStatement(databaseType);
188 if (null != ctx.denyClassPrivilegesClause()) {
189 findTableSegment(ctx.denyClassPrivilegesClause().onClassClause(), ctx.denyClassPrivilegesClause().classPrivileges()).ifPresent(result::setTable);
190 if (null != ctx.denyClassPrivilegesClause().classPrivileges().columnNames()) {
191 for (ColumnNamesContext each : ctx.denyClassPrivilegesClause().classPrivileges().columnNames()) {
192 result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(each)).getValue());
193 }
194 }
195 }
196 if (null != ctx.denyClassTypePrivilegesClause()) {
197 findTableSegment(ctx.denyClassTypePrivilegesClause().onClassTypeClause()).ifPresent(result::setTable);
198 }
199 return result;
200 }
201
202 private Optional<SimpleTableSegment> findTableSegment(final OnClassClauseContext onClassClauseCtx, final ClassPrivilegesContext classPrivilegesCtx) {
203 if (null == onClassClauseCtx) {
204 return Optional.empty();
205 }
206 if (null != onClassClauseCtx.classItem() && null != onClassClauseCtx.classItem().OBJECT()
207 || null != classPrivilegesCtx.privilegeType().get(0).objectPermission() || null != classPrivilegesCtx.privilegeType().get(0).PRIVILEGES()) {
208 return Optional.of((SimpleTableSegment) visit(onClassClauseCtx.securable()));
209 }
210 return Optional.empty();
211 }
212
213 private Optional<SimpleTableSegment> findTableSegment(final OnClassTypeClauseContext ctx) {
214 return null == ctx || null == ctx.classType() || null == ctx.classType().OBJECT() ? Optional.empty() : Optional.of((SimpleTableSegment) visit(ctx.securable()));
215 }
216
217 @Override
218 public ASTNode visitDropUser(final DropUserContext ctx) {
219 return new DropUserStatement(databaseType, Collections.singleton(((UserSegment) visit(ctx.userName())).getUser()));
220 }
221
222 @Override
223 public ASTNode visitCreateRole(final CreateRoleContext ctx) {
224 return new CreateRoleStatement(databaseType);
225 }
226
227 @Override
228 public ASTNode visitAlterRole(final AlterRoleContext ctx) {
229 return new AlterRoleStatement(databaseType);
230 }
231
232 @Override
233 public ASTNode visitDropRole(final DropRoleContext ctx) {
234 return new DropRoleStatement(databaseType);
235 }
236
237 @Override
238 public ASTNode visitCreateLogin(final CreateLoginContext ctx) {
239 return new SQLServerCreateLoginStatement(databaseType,
240 null == ctx.ignoredNameIdentifier()
241 ? null
242 : new LoginSegment(
243 ctx.ignoredNameIdentifier().getStart().getStartIndex(), ctx.ignoredNameIdentifier().getStop().getStopIndex(), (IdentifierValue) visit(ctx.ignoredNameIdentifier())));
244 }
245
246 @Override
247 public ASTNode visitAlterLogin(final AlterLoginContext ctx) {
248 return new SQLServerAlterLoginStatement(databaseType, null == ctx.ignoredNameIdentifier()
249 ? null
250 : new LoginSegment(
251 ctx.ignoredNameIdentifier().getStart().getStartIndex(), ctx.ignoredNameIdentifier().getStop().getStopIndex(), (IdentifierValue) visit(ctx.ignoredNameIdentifier())));
252 }
253
254 @Override
255 public ASTNode visitDropLogin(final DropLoginContext ctx) {
256 return new SQLServerDropLoginStatement(databaseType, new LoginSegment(
257 ctx.ignoredNameIdentifier().getStart().getStartIndex(), ctx.ignoredNameIdentifier().getStop().getStopIndex(), (IdentifierValue) visit(ctx.ignoredNameIdentifier())));
258 }
259
260 @Override
261 public ASTNode visitSetUser(final SetUserContext ctx) {
262 return new SQLServerSetUserStatement(databaseType, null == ctx.stringLiterals() ? null : getUserSegment(ctx));
263 }
264
265 private UserSegment getUserSegment(final SetUserContext ctx) {
266 UserSegment result = new UserSegment();
267 result.setUser(((StringLiteralValue) visit(ctx.stringLiterals())).getValue());
268 result.setStartIndex(ctx.stringLiterals().start.getStartIndex());
269 result.setStopIndex(ctx.stringLiterals().stop.getStopIndex());
270 return result;
271 }
272
273 @Override
274 public ASTNode visitRevert(final RevertContext ctx) {
275 return new SQLServerRevertStatement(databaseType);
276 }
277 }