View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.sql.parser.sqlserver.visitor.statement.type;
19  
20  import org.apache.shardingsphere.sql.parser.api.ASTNode;
21  import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DCLStatementVisitor;
22  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AlterLoginContext;
23  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AlterRoleContext;
24  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AlterUserContext;
25  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ClassPrivilegesContext;
26  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ColumnNamesContext;
27  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateLoginContext;
28  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateRoleContext;
29  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateUserContext;
30  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateUserLoginWindowsPrincipalClauseContext;
31  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateUserWindowsPrincipalClauseContext;
32  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DenyContext;
33  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DropLoginContext;
34  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DropRoleContext;
35  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DropUserContext;
36  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.GrantContext;
37  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.IgnoredNameIdentifierContext;
38  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OnClassClauseContext;
39  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OnClassTypeClauseContext;
40  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OwnerContext;
41  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RevertContext;
42  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RevokeContext;
43  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SecurableContext;
44  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SetUserContext;
45  import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UserNameContext;
46  import org.apache.shardingsphere.sql.parser.sql.common.segment.dcl.LoginSegment;
47  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
48  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
49  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
50  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
51  import org.apache.shardingsphere.sql.parser.sql.common.value.collection.CollectionValue;
52  import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
53  import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.StringLiteralValue;
54  import org.apache.shardingsphere.sql.parser.sql.common.segment.dcl.UserSegment;
55  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerAlterLoginStatement;
56  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerAlterRoleStatement;
57  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerAlterUserStatement;
58  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerCreateLoginStatement;
59  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerCreateRoleStatement;
60  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerCreateUserStatement;
61  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerDenyUserStatement;
62  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerDropLoginStatement;
63  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerDropRoleStatement;
64  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerDropUserStatement;
65  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerGrantStatement;
66  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerRevertStatement;
67  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerRevokeStatement;
68  import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dcl.SQLServerSetUserStatement;
69  import org.apache.shardingsphere.sql.parser.sqlserver.visitor.statement.SQLServerStatementVisitor;
70  
71  import java.util.Optional;
72  
73  /**
74   * DCL statement visitor for SQLServer.
75   */
76  public final class SQLServerDCLStatementVisitor extends SQLServerStatementVisitor implements DCLStatementVisitor {
77      
78      @Override
79      public ASTNode visitGrant(final GrantContext ctx) {
80          SQLServerGrantStatement result = new SQLServerGrantStatement();
81          if (null != ctx.grantClassPrivilegesClause()) {
82              findTableSegment(ctx.grantClassPrivilegesClause().onClassClause(), ctx.grantClassPrivilegesClause().classPrivileges()).ifPresent(optional -> result.getTables().add(optional));
83              if (null != ctx.grantClassPrivilegesClause().classPrivileges().columnNames()) {
84                  for (ColumnNamesContext each : ctx.grantClassPrivilegesClause().classPrivileges().columnNames()) {
85                      result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(each)).getValue());
86                  }
87              }
88          }
89          if (null != ctx.grantClassTypePrivilegesClause()) {
90              findTableSegment(ctx.grantClassTypePrivilegesClause().onClassTypeClause()).ifPresent(optional -> result.getTables().add(optional));
91          }
92          return result;
93      }
94      
95      @Override
96      public ASTNode visitRevoke(final RevokeContext ctx) {
97          SQLServerRevokeStatement result = new SQLServerRevokeStatement();
98          if (null != ctx.revokeClassPrivilegesClause()) {
99              findTableSegment(ctx.revokeClassPrivilegesClause().onClassClause(), ctx.revokeClassPrivilegesClause().classPrivileges()).ifPresent(optional -> result.getTables().add(optional));
100             if (null != ctx.revokeClassPrivilegesClause().classPrivileges().columnNames()) {
101                 for (ColumnNamesContext each : ctx.revokeClassPrivilegesClause().classPrivileges().columnNames()) {
102                     result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(each)).getValue());
103                 }
104             }
105         }
106         if (null != ctx.revokeClassTypePrivilegesClause()) {
107             findTableSegment(ctx.revokeClassTypePrivilegesClause().onClassTypeClause()).ifPresent(optional -> result.getTables().add(optional));
108         }
109         return result;
110     }
111     
112     @Override
113     public ASTNode visitSecurable(final SecurableContext ctx) {
114         SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(), ctx.name().getStop().getStopIndex(), (IdentifierValue) visit(ctx.name())));
115         OwnerContext owner = ctx.owner();
116         if (null != owner) {
117             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
118         }
119         return result;
120     }
121     
122     @Override
123     public ASTNode visitCreateUser(final CreateUserContext ctx) {
124         SQLServerCreateUserStatement result = new SQLServerCreateUserStatement();
125         if (null != ctx.createUserLoginClause()) {
126             result.getUsers().add((UserSegment) visit(ctx.createUserLoginClause().userName()));
127         } else if (null != ctx.createUserWindowsPrincipalClause()) {
128             result.getUsers().add((UserSegment) visit(ctx.createUserWindowsPrincipalClause()));
129         } else if (null != ctx.createUserLoginWindowsPrincipalClause()) {
130             result.getUsers().add((UserSegment) visit(ctx.createUserLoginWindowsPrincipalClause()));
131         } else if (null != ctx.createUserWithoutLoginClause()) {
132             result.getUsers().add((UserSegment) visit(ctx.createUserWithoutLoginClause().userName()));
133         } else if (null != ctx.createUserFromExternalProviderClause()) {
134             result.getUsers().add((UserSegment) visit(ctx.createUserFromExternalProviderClause().userName()));
135         } else if (null != ctx.createUserWithDefaultSchema()) {
136             result.getUsers().add((UserSegment) visit(ctx.createUserWithDefaultSchema().userName()));
137         } else if (null != ctx.createUserWithAzureActiveDirectoryPrincipalClause()) {
138             result.getUsers().add((UserSegment) visit(ctx.createUserWithAzureActiveDirectoryPrincipalClause().azureActiveDirectoryPrincipal().userName()));
139         } else {
140             result.getUsers().add((UserSegment) visit(ctx.userName()));
141         }
142         return result;
143     }
144     
145     @Override
146     public ASTNode visitUserName(final UserNameContext ctx) {
147         UserSegment result = new UserSegment();
148         String user = ((IdentifierValue) visit(ctx.ignoredNameIdentifier())).getValue();
149         result.setUser(user);
150         return result;
151     }
152     
153     @Override
154     public ASTNode visitIgnoredNameIdentifier(final IgnoredNameIdentifierContext ctx) {
155         int identifierCount = ctx.identifier().size();
156         return 1 == identifierCount ? (IdentifierValue) visit(ctx.identifier(0)) : new IdentifierValue(ctx.getText());
157     }
158     
159     @Override
160     public ASTNode visitCreateUserWindowsPrincipalClause(final CreateUserWindowsPrincipalClauseContext ctx) {
161         if (null != ctx.windowsPrincipal()) {
162             return visit(ctx.windowsPrincipal().userName());
163         }
164         if (null != ctx.azureActiveDirectoryPrincipal()) {
165             return visit(ctx.azureActiveDirectoryPrincipal().userName());
166         }
167         return visit(ctx.userName());
168     }
169     
170     @Override
171     public ASTNode visitCreateUserLoginWindowsPrincipalClause(final CreateUserLoginWindowsPrincipalClauseContext ctx) {
172         return null == ctx.userName() ? (UserSegment) visit(ctx.windowsPrincipal(0)) : (UserSegment) visit(ctx.userName());
173     }
174     
175     @Override
176     public ASTNode visitAlterUser(final AlterUserContext ctx) {
177         SQLServerAlterUserStatement result = new SQLServerAlterUserStatement();
178         result.setUser((UserSegment) visit(ctx.userName()));
179         return result;
180     }
181     
182     @Override
183     public ASTNode visitDeny(final DenyContext ctx) {
184         SQLServerDenyUserStatement result = new SQLServerDenyUserStatement();
185         if (null != ctx.denyClassPrivilegesClause()) {
186             findTableSegment(ctx.denyClassPrivilegesClause().onClassClause(), ctx.denyClassPrivilegesClause().classPrivileges()).ifPresent(result::setTable);
187             if (null != ctx.denyClassPrivilegesClause().classPrivileges().columnNames()) {
188                 for (ColumnNamesContext each : ctx.denyClassPrivilegesClause().classPrivileges().columnNames()) {
189                     result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(each)).getValue());
190                 }
191             }
192         }
193         if (null != ctx.denyClassTypePrivilegesClause()) {
194             findTableSegment(ctx.denyClassTypePrivilegesClause().onClassTypeClause()).ifPresent(result::setTable);
195         }
196         return result;
197     }
198     
199     private Optional<SimpleTableSegment> findTableSegment(final OnClassClauseContext onClassClauseCtx, final ClassPrivilegesContext classPrivilegesCtx) {
200         if (null == onClassClauseCtx) {
201             return Optional.empty();
202         }
203         if (null != onClassClauseCtx.classItem() && null != onClassClauseCtx.classItem().OBJECT()
204                 || null != classPrivilegesCtx.privilegeType().get(0).objectPermission() || null != classPrivilegesCtx.privilegeType().get(0).PRIVILEGES()) {
205             return Optional.of((SimpleTableSegment) visit(onClassClauseCtx.securable()));
206         }
207         return Optional.empty();
208     }
209     
210     private Optional<SimpleTableSegment> findTableSegment(final OnClassTypeClauseContext ctx) {
211         return null == ctx || null == ctx.classType() || null == ctx.classType().OBJECT() ? Optional.empty() : Optional.of((SimpleTableSegment) visit(ctx.securable()));
212     }
213     
214     @Override
215     public ASTNode visitDropUser(final DropUserContext ctx) {
216         SQLServerDropUserStatement result = new SQLServerDropUserStatement();
217         result.getUsers().add(((UserSegment) visit(ctx.userName())).getUser());
218         return result;
219     }
220     
221     @Override
222     public ASTNode visitCreateRole(final CreateRoleContext ctx) {
223         return new SQLServerCreateRoleStatement();
224     }
225     
226     @Override
227     public ASTNode visitAlterRole(final AlterRoleContext ctx) {
228         return new SQLServerAlterRoleStatement();
229     }
230     
231     @Override
232     public ASTNode visitDropRole(final DropRoleContext ctx) {
233         return new SQLServerDropRoleStatement();
234     }
235     
236     @Override
237     public ASTNode visitCreateLogin(final CreateLoginContext ctx) {
238         SQLServerCreateLoginStatement result = new SQLServerCreateLoginStatement();
239         if (null != ctx.ignoredNameIdentifier()) {
240             LoginSegment loginSegment = new LoginSegment(
241                     ctx.ignoredNameIdentifier().getStart().getStartIndex(), ctx.ignoredNameIdentifier().getStop().getStopIndex(), (IdentifierValue) visit(ctx.ignoredNameIdentifier()));
242             result.setLoginSegment(loginSegment);
243         }
244         return result;
245     }
246     
247     @Override
248     public ASTNode visitAlterLogin(final AlterLoginContext ctx) {
249         SQLServerAlterLoginStatement result = new SQLServerAlterLoginStatement();
250         if (null != ctx.ignoredNameIdentifier()) {
251             LoginSegment loginSegment = new LoginSegment(
252                     ctx.ignoredNameIdentifier().getStart().getStartIndex(), ctx.ignoredNameIdentifier().getStop().getStopIndex(), (IdentifierValue) visit(ctx.ignoredNameIdentifier()));
253             result.setLoginSegment(loginSegment);
254         }
255         return result;
256     }
257     
258     @Override
259     public ASTNode visitDropLogin(final DropLoginContext ctx) {
260         SQLServerDropLoginStatement result = new SQLServerDropLoginStatement();
261         LoginSegment loginSegment = new LoginSegment(
262                 ctx.ignoredNameIdentifier().getStart().getStartIndex(), ctx.ignoredNameIdentifier().getStop().getStopIndex(), (IdentifierValue) visit(ctx.ignoredNameIdentifier()));
263         result.setLoginSegment(loginSegment);
264         return result;
265     }
266     
267     @Override
268     public ASTNode visitSetUser(final SetUserContext ctx) {
269         SQLServerSetUserStatement result = new SQLServerSetUserStatement();
270         if (null != ctx.stringLiterals()) {
271             UserSegment userSegment = new UserSegment();
272             userSegment.setUser(((StringLiteralValue) visit(ctx.stringLiterals())).getValue());
273             userSegment.setStartIndex(ctx.stringLiterals().start.getStartIndex());
274             userSegment.setStopIndex(ctx.stringLiterals().stop.getStopIndex());
275             result.setUser(userSegment);
276         }
277         return result;
278     }
279     
280     @Override
281     public ASTNode visitRevert(final RevertContext ctx) {
282         return new SQLServerRevertStatement();
283     }
284 }