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