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