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.postgresql.visitor.statement.type;
19  
20  import org.antlr.v4.runtime.misc.Interval;
21  import org.apache.shardingsphere.sql.parser.api.ASTNode;
22  import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DMLStatementVisitor;
23  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CallArgumentContext;
24  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CallContext;
25  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CopyContext;
26  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CopyWithTableBinaryContext;
27  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CopyWithTableOrQueryBinaryCsvContext;
28  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CopyWithTableOrQueryContext;
29  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.DoStatementContext;
30  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.PreparableStmtContext;
31  import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ReturningClauseContext;
32  import org.apache.shardingsphere.sql.parser.postgresql.visitor.statement.PostgreSQLStatementVisitor;
33  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.ReturningSegment;
34  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
35  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
36  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonExpressionSegment;
37  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
38  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.prepare.PrepareStatementQuerySegment;
39  import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
40  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.CallStatement;
41  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DeleteStatement;
42  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DoStatement;
43  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
44  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
45  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
46  import org.apache.shardingsphere.sql.parser.statement.core.value.collection.CollectionValue;
47  import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
48  import org.apache.shardingsphere.sql.parser.statement.postgresql.dml.PostgreSQLCopyStatement;
49  
50  import java.util.Collections;
51  import java.util.List;
52  import java.util.stream.Collectors;
53  
54  /**
55   * DML statement visitor for PostgreSQL.
56   */
57  public final class PostgreSQLDMLStatementVisitor extends PostgreSQLStatementVisitor implements DMLStatementVisitor {
58      
59      @Override
60      public ASTNode visitCall(final CallContext ctx) {
61          String procedureName = ((IdentifierValue) visit(ctx.identifier())).getValue();
62          List<ExpressionSegment> params = null == ctx.callArguments()
63                  ? Collections.emptyList()
64                  : ctx.callArguments().callArgument().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
65          return new CallStatement(procedureName, params);
66      }
67      
68      @Override
69      public ASTNode visitCallArgument(final CallArgumentContext ctx) {
70          if (null == ctx.positionalNotation()) {
71              String text = ctx.namedNotation().start.getInputStream().getText(new Interval(ctx.namedNotation().start.getStartIndex(), ctx.namedNotation().stop.getStopIndex()));
72              return new CommonExpressionSegment(ctx.namedNotation().getStart().getStartIndex(), ctx.namedNotation().getStop().getStopIndex(), text);
73          }
74          return visit(ctx.positionalNotation().aExpr());
75      }
76      
77      @Override
78      public ASTNode visitDoStatement(final DoStatementContext ctx) {
79          return new DoStatement(Collections.emptyList());
80      }
81      
82      @Override
83      public ASTNode visitCopy(final CopyContext ctx) {
84          if (null != ctx.copyWithTableOrQuery()) {
85              return visit(ctx.copyWithTableOrQuery());
86          }
87          if (null != ctx.copyWithTableOrQueryBinaryCsv()) {
88              return visit(ctx.copyWithTableOrQueryBinaryCsv());
89          }
90          return visit(ctx.copyWithTableBinary());
91      }
92      
93      @Override
94      public ASTNode visitCopyWithTableOrQuery(final CopyWithTableOrQueryContext ctx) {
95          return new PostgreSQLCopyStatement(null == ctx.qualifiedName() ? null : (SimpleTableSegment) visit(ctx.qualifiedName()),
96                  null == ctx.columnNames() ? Collections.emptyList() : ((CollectionValue<ColumnSegment>) visit(ctx.columnNames())).getValue(),
97                  null == ctx.preparableStmt() ? null : extractPrepareStatementQuerySegmentFromPreparableStmt(ctx.preparableStmt()));
98      }
99      
100     private PrepareStatementQuerySegment extractPrepareStatementQuerySegmentFromPreparableStmt(final PreparableStmtContext ctx) {
101         PrepareStatementQuerySegment result = new PrepareStatementQuerySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
102         if (null != ctx.select()) {
103             result.setSelect((SelectStatement) visit(ctx.select()));
104         } else if (null != ctx.insert()) {
105             result.setInsert((InsertStatement) visit(ctx.insert()));
106         } else if (null != ctx.update()) {
107             result.setUpdate((UpdateStatement) visit(ctx.update()));
108         } else {
109             result.setDelete((DeleteStatement) visit(ctx.delete()));
110         }
111         return result;
112     }
113     
114     @Override
115     public ASTNode visitCopyWithTableOrQueryBinaryCsv(final CopyWithTableOrQueryBinaryCsvContext ctx) {
116         return new PostgreSQLCopyStatement(null == ctx.qualifiedName() ? null : (SimpleTableSegment) visit(ctx.qualifiedName()),
117                 null == ctx.columnNames() ? Collections.emptyList() : ((CollectionValue<ColumnSegment>) visit(ctx.columnNames())).getValue(),
118                 null == ctx.preparableStmt() ? null : extractPrepareStatementQuerySegmentFromPreparableStmt(ctx.preparableStmt()));
119     }
120     
121     @Override
122     public ASTNode visitCopyWithTableBinary(final CopyWithTableBinaryContext ctx) {
123         return new PostgreSQLCopyStatement(null == ctx.qualifiedName() ? null : (SimpleTableSegment) visit(ctx.qualifiedName()), Collections.emptyList(), null);
124     }
125     
126     @Override
127     public ASTNode visitReturningClause(final ReturningClauseContext ctx) {
128         return new ReturningSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (ProjectionsSegment) visit(ctx.targetList()));
129     }
130 }