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.sharding.distsql.parser.core;
19  
20  import org.antlr.v4.runtime.tree.ParseTree;
21  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementBaseVisitor;
22  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.AlgorithmDefinitionContext;
23  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.AlterDefaultShardingStrategyContext;
24  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.AlterShardingTableReferenceRuleContext;
25  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.AlterShardingTableRuleContext;
26  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.AuditDefinitionContext;
27  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.AutoShardingColumnDefinitionContext;
28  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.CountShardingRuleContext;
29  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.CreateDefaultShardingStrategyContext;
30  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.CreateShardingTableReferenceRuleContext;
31  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.CreateShardingTableRuleContext;
32  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DataNodesContext;
33  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DatabaseNameContext;
34  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DropDefaultShardingStrategyContext;
35  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DropShardingAlgorithmContext;
36  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DropShardingAuditorContext;
37  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DropShardingKeyGeneratorContext;
38  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DropShardingTableReferenceRuleContext;
39  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.DropShardingTableRuleContext;
40  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.KeyGenerateDefinitionContext;
41  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.PropertiesDefinitionContext;
42  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.PropertyContext;
43  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShardingAutoTableRuleContext;
44  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShardingColumnDefinitionContext;
45  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShardingStrategyContext;
46  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShardingTableRuleContext;
47  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShardingTableRuleDefinitionContext;
48  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowDefaultShardingStrategyContext;
49  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingAlgorithmPluginsContext;
50  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingAlgorithmsContext;
51  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingAuditorsContext;
52  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingKeyGeneratorsContext;
53  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingTableNodesContext;
54  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingTableReferenceRulesContext;
55  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingTableRulesContext;
56  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingTableRulesUsedAlgorithmContext;
57  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingTableRulesUsedAuditorContext;
58  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowShardingTableRulesUsedKeyGeneratorContext;
59  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowUnusedShardingAlgorithmsContext;
60  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowUnusedShardingAuditorsContext;
61  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.ShowUnusedShardingKeyGeneratorsContext;
62  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.SingleAuditDefinitionContext;
63  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.StorageUnitsContext;
64  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.TableNameContext;
65  import org.apache.shardingsphere.distsql.parser.autogen.ShardingDistSQLStatementParser.TableReferenceRuleDefinitionContext;
66  import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
67  import org.apache.shardingsphere.distsql.statement.ral.queryable.show.ShowPluginsStatement;
68  import org.apache.shardingsphere.distsql.statement.rql.rule.database.CountRuleStatement;
69  import org.apache.shardingsphere.sharding.distsql.segment.strategy.AuditStrategySegment;
70  import org.apache.shardingsphere.sharding.distsql.segment.strategy.KeyGenerateStrategySegment;
71  import org.apache.shardingsphere.sharding.distsql.segment.strategy.ShardingAuditorSegment;
72  import org.apache.shardingsphere.sharding.distsql.segment.strategy.ShardingStrategySegment;
73  import org.apache.shardingsphere.sharding.distsql.segment.table.AbstractTableRuleSegment;
74  import org.apache.shardingsphere.sharding.distsql.segment.table.AutoTableRuleSegment;
75  import org.apache.shardingsphere.sharding.distsql.segment.table.TableReferenceRuleSegment;
76  import org.apache.shardingsphere.sharding.distsql.segment.table.TableRuleSegment;
77  import org.apache.shardingsphere.sharding.distsql.statement.AlterDefaultShardingStrategyStatement;
78  import org.apache.shardingsphere.sharding.distsql.statement.AlterShardingTableReferenceRuleStatement;
79  import org.apache.shardingsphere.sharding.distsql.statement.AlterShardingTableRuleStatement;
80  import org.apache.shardingsphere.sharding.distsql.statement.CreateDefaultShardingStrategyStatement;
81  import org.apache.shardingsphere.sharding.distsql.statement.CreateShardingTableReferenceRuleStatement;
82  import org.apache.shardingsphere.sharding.distsql.statement.CreateShardingTableRuleStatement;
83  import org.apache.shardingsphere.sharding.distsql.statement.DropDefaultShardingStrategyStatement;
84  import org.apache.shardingsphere.sharding.distsql.statement.DropShardingAlgorithmStatement;
85  import org.apache.shardingsphere.sharding.distsql.statement.DropShardingAuditorStatement;
86  import org.apache.shardingsphere.sharding.distsql.statement.DropShardingKeyGeneratorStatement;
87  import org.apache.shardingsphere.sharding.distsql.statement.DropShardingTableReferenceRuleStatement;
88  import org.apache.shardingsphere.sharding.distsql.statement.DropShardingTableRuleStatement;
89  import org.apache.shardingsphere.sharding.distsql.statement.ShowDefaultShardingStrategyStatement;
90  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingAlgorithmsStatement;
91  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingAuditorsStatement;
92  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingKeyGeneratorsStatement;
93  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingTableNodesStatement;
94  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingTableReferenceRulesStatement;
95  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingTableRulesStatement;
96  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingTableRulesUsedAlgorithmStatement;
97  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingTableRulesUsedAuditorStatement;
98  import org.apache.shardingsphere.sharding.distsql.statement.ShowShardingTableRulesUsedKeyGeneratorStatement;
99  import org.apache.shardingsphere.sharding.distsql.statement.ShowUnusedShardingAlgorithmsStatement;
100 import org.apache.shardingsphere.sharding.distsql.statement.ShowUnusedShardingAuditorsStatement;
101 import org.apache.shardingsphere.sharding.distsql.statement.ShowUnusedShardingKeyGeneratorsStatement;
102 import org.apache.shardingsphere.sql.parser.api.ASTNode;
103 import org.apache.shardingsphere.sql.parser.api.visitor.SQLVisitor;
104 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DatabaseSegment;
105 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
106 import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
107 
108 import java.util.Collection;
109 import java.util.LinkedList;
110 import java.util.List;
111 import java.util.Objects;
112 import java.util.Optional;
113 import java.util.Properties;
114 import java.util.stream.Collectors;
115 
116 /**
117  * Sharding DistSQL statement visitor.
118  */
119 public final class ShardingDistSQLStatementVisitor extends ShardingDistSQLStatementBaseVisitor<ASTNode> implements SQLVisitor<ASTNode> {
120     
121     @Override
122     public ASTNode visitCreateShardingTableRule(final CreateShardingTableRuleContext ctx) {
123         Collection<AbstractTableRuleSegment> tableRuleSegments = ctx.shardingTableRuleDefinition().stream()
124                 .map(each -> (AbstractTableRuleSegment) visit(each)).filter(Objects::nonNull).collect(Collectors.toList());
125         return new CreateShardingTableRuleStatement(null != ctx.ifNotExists(), tableRuleSegments);
126     }
127     
128     @Override
129     public ASTNode visitCreateShardingTableReferenceRule(final CreateShardingTableReferenceRuleContext ctx) {
130         return new CreateShardingTableReferenceRuleStatement(null != ctx.ifNotExists(), getTableReferenceRuleSegments(ctx.tableReferenceRuleDefinition()));
131     }
132     
133     private Collection<TableReferenceRuleSegment> getTableReferenceRuleSegments(final List<TableReferenceRuleDefinitionContext> ctx) {
134         Collection<TableReferenceRuleSegment> result = new LinkedList<>();
135         for (TableReferenceRuleDefinitionContext each : ctx) {
136             String ruleName = getIdentifierValue(each.ruleName());
137             String reference = each.tableName().stream().map(this::getIdentifierValue).collect(Collectors.joining(","));
138             result.add(new TableReferenceRuleSegment(ruleName, reference));
139         }
140         return result;
141     }
142     
143     @Override
144     public ASTNode visitAlterShardingTableRule(final AlterShardingTableRuleContext ctx) {
145         List<AbstractTableRuleSegment> tableRuleSegments = ctx.shardingTableRuleDefinition().stream()
146                 .map(each -> (AbstractTableRuleSegment) visit(each)).filter(Objects::nonNull).collect(Collectors.toList());
147         return new AlterShardingTableRuleStatement(tableRuleSegments);
148     }
149     
150     @Override
151     public ASTNode visitAlterShardingTableReferenceRule(final AlterShardingTableReferenceRuleContext ctx) {
152         return new AlterShardingTableReferenceRuleStatement(getTableReferenceRuleSegments(ctx.tableReferenceRuleDefinition()));
153     }
154     
155     @Override
156     public ASTNode visitDropShardingTableRule(final DropShardingTableRuleContext ctx) {
157         return new DropShardingTableRuleStatement(null != ctx.ifExists(), ctx.tableName().stream().map(each -> (TableNameSegment) visit(each)).collect(Collectors.toList()));
158     }
159     
160     @Override
161     public ASTNode visitDropShardingTableReferenceRule(final DropShardingTableReferenceRuleContext ctx) {
162         return new DropShardingTableReferenceRuleStatement(null != ctx.ifExists(), ctx.ruleName().stream().map(this::getIdentifierValue).collect(Collectors.toList()));
163     }
164     
165     @Override
166     public ASTNode visitCreateDefaultShardingStrategy(final CreateDefaultShardingStrategyContext ctx) {
167         ShardingStrategyContext shardingStrategyContext = ctx.shardingStrategy();
168         String defaultType = new IdentifierValue(ctx.type.getText()).getValue();
169         String strategyType = getIdentifierValue(shardingStrategyContext.strategyType());
170         if ("none".equalsIgnoreCase(strategyType)) {
171             return new CreateDefaultShardingStrategyStatement(null != ctx.ifNotExists(), defaultType, "none", null, null);
172         }
173         AlgorithmSegment algorithmSegment = null == shardingStrategyContext.shardingAlgorithm().algorithmDefinition()
174                 ? null
175                 : (AlgorithmSegment) visitAlgorithmDefinition(shardingStrategyContext.shardingAlgorithm().algorithmDefinition());
176         String shardingColumn = null == ctx.shardingStrategy().shardingColumnDefinition() ? null : buildShardingColumn(ctx.shardingStrategy().shardingColumnDefinition());
177         return new CreateDefaultShardingStrategyStatement(null != ctx.ifNotExists(), defaultType, strategyType, shardingColumn, algorithmSegment);
178     }
179     
180     @Override
181     public ASTNode visitAlterDefaultShardingStrategy(final AlterDefaultShardingStrategyContext ctx) {
182         String defaultType = new IdentifierValue(ctx.type.getText()).getValue();
183         String strategyType = getIdentifierValue(ctx.shardingStrategy().strategyType());
184         if ("none".equalsIgnoreCase(strategyType)) {
185             return new AlterDefaultShardingStrategyStatement(defaultType, "none", null, null);
186         }
187         AlgorithmSegment algorithmSegment = null == ctx.shardingStrategy().shardingAlgorithm().algorithmDefinition()
188                 ? null
189                 : (AlgorithmSegment) visitAlgorithmDefinition(ctx.shardingStrategy().shardingAlgorithm().algorithmDefinition());
190         String shardingColumn = null == ctx.shardingStrategy().shardingColumnDefinition() ? null : buildShardingColumn(ctx.shardingStrategy().shardingColumnDefinition());
191         return new AlterDefaultShardingStrategyStatement(defaultType, strategyType, shardingColumn, algorithmSegment);
192     }
193     
194     @Override
195     public ASTNode visitDropDefaultShardingStrategy(final DropDefaultShardingStrategyContext ctx) {
196         return new DropDefaultShardingStrategyStatement(null != ctx.ifExists(), new IdentifierValue(ctx.type.getText()).getValue().toLowerCase());
197     }
198     
199     @Override
200     public ASTNode visitDropShardingAlgorithm(final DropShardingAlgorithmContext ctx) {
201         return new DropShardingAlgorithmStatement(null != ctx.ifExists(), ctx.shardingAlgorithmName().stream().map(this::getIdentifierValue).collect(Collectors.toList()));
202     }
203     
204     @Override
205     public ASTNode visitShowShardingTableRules(final ShowShardingTableRulesContext ctx) {
206         return new ShowShardingTableRulesStatement(null == ctx.tableRule() ? null : getIdentifierValue(ctx.tableRule().tableName()),
207                 null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
208     }
209     
210     @Override
211     public ASTNode visitShowShardingAlgorithms(final ShowShardingAlgorithmsContext ctx) {
212         return new ShowShardingAlgorithmsStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
213     }
214     
215     @Override
216     public ASTNode visitShardingTableRuleDefinition(final ShardingTableRuleDefinitionContext ctx) {
217         if (null != ctx.shardingTableRule()) {
218             return visit(ctx.shardingTableRule());
219         }
220         if (null != ctx.shardingAutoTableRule()) {
221             return visit(ctx.shardingAutoTableRule());
222         }
223         return null;
224     }
225     
226     @Override
227     public ASTNode visitShardingTableRule(final ShardingTableRuleContext ctx) {
228         KeyGenerateStrategySegment keyGenerateSegment = null == ctx.keyGenerateDefinition() ? null : (KeyGenerateStrategySegment) visit(ctx.keyGenerateDefinition());
229         AuditStrategySegment auditStrategySegment = null == ctx.auditDefinition() ? null : (AuditStrategySegment) visitAuditDefinition(getIdentifierValue(ctx.tableName()), ctx.auditDefinition());
230         TableRuleSegment result = new TableRuleSegment(getIdentifierValue(ctx.tableName()), getDataNodes(ctx.dataNodes()), keyGenerateSegment, auditStrategySegment);
231         Optional.ofNullable(ctx.tableStrategy()).ifPresent(optional -> result.setTableStrategySegment((ShardingStrategySegment) visit(ctx.tableStrategy().shardingStrategy())));
232         Optional.ofNullable(ctx.databaseStrategy()).ifPresent(optional -> result.setDatabaseStrategySegment((ShardingStrategySegment) visit(ctx.databaseStrategy().shardingStrategy())));
233         return result;
234     }
235     
236     private ASTNode visitAuditDefinition(final String tableName, final AuditDefinitionContext ctx) {
237         if (null == ctx) {
238             return null;
239         }
240         Collection<ShardingAuditorSegment> shardingAuditorSegments = new LinkedList<>();
241         int index = 0;
242         for (SingleAuditDefinitionContext each : ctx.multiAuditDefinition().singleAuditDefinition()) {
243             String algorithmTypeName = getIdentifierValue(each.algorithmDefinition().algorithmTypeName());
244             String auditorName = String.format("%s_%s_%s", tableName, algorithmTypeName, index++).toLowerCase();
245             shardingAuditorSegments.add(new ShardingAuditorSegment(auditorName, (AlgorithmSegment) visit(each.algorithmDefinition())));
246         }
247         return new AuditStrategySegment(shardingAuditorSegments, Boolean.parseBoolean(getIdentifierValue(ctx.auditAllowHintDisable())));
248     }
249     
250     @Override
251     public ASTNode visitShowShardingTableNodes(final ShowShardingTableNodesContext ctx) {
252         return new ShowShardingTableNodesStatement(null == ctx.tableName() ? null : getIdentifierValue(ctx.tableName()),
253                 null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
254     }
255     
256     @Override
257     public ASTNode visitShardingAutoTableRule(final ShardingAutoTableRuleContext ctx) {
258         AutoTableRuleSegment result = new AutoTableRuleSegment(getIdentifierValue(ctx.tableName()), getResources(ctx.storageUnits()));
259         Optional.ofNullable(ctx.keyGenerateDefinition()).ifPresent(optional -> result.setKeyGenerateStrategySegment((KeyGenerateStrategySegment) visit(ctx.keyGenerateDefinition())));
260         Optional.ofNullable(ctx.auditDefinition()).ifPresent(optional -> result.setAuditStrategySegment((AuditStrategySegment) visitAuditDefinition(getIdentifierValue(ctx.tableName()),
261                 ctx.auditDefinition())));
262         Optional.ofNullable(ctx.autoShardingColumnDefinition()).ifPresent(optional -> result.setShardingColumn(buildShardingColumn(ctx.autoShardingColumnDefinition())));
263         Optional.ofNullable(ctx.algorithmDefinition()).ifPresent(optional -> result.setShardingAlgorithmSegment((AlgorithmSegment) visit(ctx.algorithmDefinition())));
264         return result;
265     }
266     
267     @Override
268     public ASTNode visitKeyGenerateDefinition(final KeyGenerateDefinitionContext ctx) {
269         return null == ctx ? null : new KeyGenerateStrategySegment(getIdentifierValue(ctx.columnName()), (AlgorithmSegment) visit(ctx.algorithmDefinition()));
270     }
271     
272     @Override
273     public ASTNode visitShardingStrategy(final ShardingStrategyContext ctx) {
274         String strategyType = getIdentifierValue(ctx.strategyType());
275         if ("none".equalsIgnoreCase(strategyType)) {
276             return new ShardingStrategySegment(strategyType, null, null);
277         }
278         AlgorithmSegment algorithmSegment = null == ctx.shardingAlgorithm().algorithmDefinition() ? null : (AlgorithmSegment) visitAlgorithmDefinition(ctx.shardingAlgorithm().algorithmDefinition());
279         String shardingColumn = null == ctx.shardingColumnDefinition() ? null : buildShardingColumn(ctx.shardingColumnDefinition());
280         return new ShardingStrategySegment(strategyType, shardingColumn, algorithmSegment);
281     }
282     
283     private Collection<String> getResources(final StorageUnitsContext ctx) {
284         return ctx.storageUnit().stream().map(this::getIdentifierValue).collect(Collectors.toList());
285     }
286     
287     private Collection<String> getDataNodes(final DataNodesContext ctx) {
288         return ctx.dataNode().stream().map(this::getIdentifierValueForDataNodes).collect(Collectors.toList());
289     }
290     
291     @Override
292     public ASTNode visitAlgorithmDefinition(final AlgorithmDefinitionContext ctx) {
293         return new AlgorithmSegment(getIdentifierValue(ctx.algorithmTypeName()), getProperties(ctx.propertiesDefinition()));
294     }
295     
296     private String getIdentifierValue(final ParseTree context) {
297         return null == context ? null : new IdentifierValue(context.getText()).getValue();
298     }
299     
300     private String getIdentifierValueForDataNodes(final ParseTree context) {
301         if (null == context) {
302             return null;
303         }
304         String value = new IdentifierValue(context.getText(), "[]'").getValue();
305         return value.startsWith("'") ? value.substring(1, value.length() - 1) : value.trim();
306     }
307     
308     private Properties getProperties(final PropertiesDefinitionContext ctx) {
309         Properties result = new Properties();
310         if (null == ctx || null == ctx.properties()) {
311             return result;
312         }
313         for (PropertyContext each : ctx.properties().property()) {
314             result.setProperty(IdentifierValue.getQuotedContent(each.key.getText()), IdentifierValue.getQuotedContent(each.value.getText()));
315         }
316         return result;
317     }
318     
319     @Override
320     public ASTNode visitTableName(final TableNameContext ctx) {
321         return new TableNameSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), new IdentifierValue(ctx.getText()));
322     }
323     
324     @Override
325     public ASTNode visitShowShardingTableReferenceRules(final ShowShardingTableReferenceRulesContext ctx) {
326         return new ShowShardingTableReferenceRulesStatement(null == ctx.ruleName() ? null : getIdentifierValue(ctx.ruleName()),
327                 null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
328     }
329     
330     @Override
331     public ASTNode visitDatabaseName(final DatabaseNameContext ctx) {
332         return new DatabaseSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), new IdentifierValue(ctx.getText()));
333     }
334     
335     @Override
336     public ASTNode visitShowShardingKeyGenerators(final ShowShardingKeyGeneratorsContext ctx) {
337         return new ShowShardingKeyGeneratorsStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
338     }
339     
340     @Override
341     public ASTNode visitDropShardingKeyGenerator(final DropShardingKeyGeneratorContext ctx) {
342         return new DropShardingKeyGeneratorStatement(null != ctx.ifExists(), ctx.keyGeneratorName().stream().map(this::getIdentifierValue).collect(Collectors.toList()));
343     }
344     
345     @Override
346     public ASTNode visitDropShardingAuditor(final DropShardingAuditorContext ctx) {
347         return new DropShardingAuditorStatement(null != ctx.ifExists(), ctx.auditorName().stream().map(this::getIdentifierValue).collect(Collectors.toList()));
348     }
349     
350     @Override
351     public ASTNode visitShowShardingAuditors(final ShowShardingAuditorsContext ctx) {
352         return new ShowShardingAuditorsStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
353     }
354     
355     @Override
356     public ASTNode visitShowDefaultShardingStrategy(final ShowDefaultShardingStrategyContext ctx) {
357         return new ShowDefaultShardingStrategyStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
358     }
359     
360     @Override
361     public ASTNode visitShowUnusedShardingAlgorithms(final ShowUnusedShardingAlgorithmsContext ctx) {
362         return new ShowUnusedShardingAlgorithmsStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
363     }
364     
365     private String buildShardingColumn(final AutoShardingColumnDefinitionContext ctx) {
366         return null == ctx.shardingColumn() ? null : getIdentifierValue(ctx.shardingColumn().columnName());
367     }
368     
369     private String buildShardingColumn(final ShardingColumnDefinitionContext ctx) {
370         String result = Optional.ofNullable(ctx.shardingColumn()).map(optional -> getIdentifierValue(optional.columnName()))
371                 .orElseGet(() -> ctx.shardingColumns().columnName().stream().map(this::getIdentifierValue).collect(Collectors.joining(",")));
372         return result.isEmpty() ? null : result;
373     }
374     
375     @Override
376     public ASTNode visitShowUnusedShardingKeyGenerators(final ShowUnusedShardingKeyGeneratorsContext ctx) {
377         return new ShowUnusedShardingKeyGeneratorsStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
378     }
379     
380     @Override
381     public ASTNode visitShowUnusedShardingAuditors(final ShowUnusedShardingAuditorsContext ctx) {
382         return new ShowUnusedShardingAuditorsStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
383     }
384     
385     @Override
386     public ASTNode visitShowShardingTableRulesUsedAlgorithm(final ShowShardingTableRulesUsedAlgorithmContext ctx) {
387         return new ShowShardingTableRulesUsedAlgorithmStatement(
388                 getIdentifierValue(ctx.shardingAlgorithmName()), null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
389     }
390     
391     @Override
392     public ASTNode visitShowShardingTableRulesUsedKeyGenerator(final ShowShardingTableRulesUsedKeyGeneratorContext ctx) {
393         return new ShowShardingTableRulesUsedKeyGeneratorStatement(getIdentifierValue(ctx.keyGeneratorName()), null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
394     }
395     
396     @Override
397     public ASTNode visitShowShardingTableRulesUsedAuditor(final ShowShardingTableRulesUsedAuditorContext ctx) {
398         return new ShowShardingTableRulesUsedAuditorStatement(getIdentifierValue(ctx.auditorName()), null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
399     }
400     
401     @Override
402     public ASTNode visitCountShardingRule(final CountShardingRuleContext ctx) {
403         return new CountRuleStatement(null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()), "SHARDING");
404     }
405     
406     @Override
407     public ASTNode visitShowShardingAlgorithmPlugins(final ShowShardingAlgorithmPluginsContext ctx) {
408         return new ShowPluginsStatement("SHARDING_ALGORITHM");
409     }
410 }