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.infra.binder.engine;
19  
20  import lombok.RequiredArgsConstructor;
21  import org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
22  import org.apache.shardingsphere.infra.binder.context.SQLStatementContextFactory;
23  import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
24  import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
25  import org.apache.shardingsphere.infra.binder.engine.type.DALStatementBindEngine;
26  import org.apache.shardingsphere.infra.binder.engine.type.DCLStatementBindEngine;
27  import org.apache.shardingsphere.infra.binder.engine.type.DDLStatementBindEngine;
28  import org.apache.shardingsphere.infra.binder.engine.type.DMLStatementBindEngine;
29  import org.apache.shardingsphere.infra.hint.HintManager;
30  import org.apache.shardingsphere.infra.hint.HintValueContext;
31  import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
32  import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
33  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.DALStatement;
34  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.DCLStatement;
35  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.DDLStatement;
36  import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DMLStatement;
37  
38  import java.util.Optional;
39  
40  /**
41   * SQL bind engine.
42   */
43  @RequiredArgsConstructor
44  public final class SQLBindEngine {
45      
46      private final ShardingSphereMetaData metaData;
47      
48      private final String currentDatabaseName;
49      
50      private final HintValueContext hintValueContext;
51      
52      /**
53       * Bind SQL statement.
54       *
55       * @param sqlStatement SQL statement
56       * @return SQL statement context
57       */
58      public SQLStatementContext bind(final SQLStatement sqlStatement) {
59          SQLStatement boundSQLStatement = isNeedBind() ? bindSQLStatement(sqlStatement) : sqlStatement;
60          return SQLStatementContextFactory.newInstance(metaData, boundSQLStatement, currentDatabaseName);
61      }
62      
63      private SQLStatement bindSQLStatement(final SQLStatement sqlStatement) {
64          SQLStatementBinderContext binderContext = new SQLStatementBinderContext(metaData, currentDatabaseName, hintValueContext, sqlStatement);
65          Optional<DialectSQLBindEngine> dialectSQLBindEngine = DatabaseTypedSPILoader.findService(DialectSQLBindEngine.class, sqlStatement.getDatabaseType());
66          if (dialectSQLBindEngine.isPresent()) {
67              Optional<SQLStatement> boundSQLStatement = dialectSQLBindEngine.get().bind(sqlStatement, binderContext);
68              if (boundSQLStatement.isPresent()) {
69                  return boundSQLStatement.get();
70              }
71          }
72          if (sqlStatement instanceof DMLStatement) {
73              return new DMLStatementBindEngine().bind((DMLStatement) sqlStatement, binderContext);
74          }
75          if (sqlStatement instanceof DDLStatement) {
76              return new DDLStatementBindEngine().bind((DDLStatement) sqlStatement, binderContext);
77          }
78          if (sqlStatement instanceof DCLStatement) {
79              return new DCLStatementBindEngine().bind((DCLStatement) sqlStatement, binderContext);
80          }
81          if (sqlStatement instanceof DALStatement) {
82              return new DALStatementBindEngine().bind((DALStatement) sqlStatement, binderContext);
83          }
84          return sqlStatement;
85      }
86      
87      private boolean isNeedBind() {
88          return !hintValueContext.findHintDataSourceName().isPresent() && !HintManager.getDataSourceName().isPresent();
89      }
90  }