Skip to content

Commit

Permalink
Refactor SQLStatementBinder (#32058)
Browse files Browse the repository at this point in the history
* Refactor SQLStatementBinder

* Refactor SQLStatementBinder
  • Loading branch information
terrymanu authored Jul 10, 2024
1 parent 7eebe94 commit b4d7ff3
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ public static CombineSegment bind(final CombineSegment segment, final SQLStateme
ShardingSphereMetaData metaData = statementBinderContext.getMetaData();
String currentDatabaseName = statementBinderContext.getCurrentDatabaseName();
Map<String, TableSegmentBinderContext> externalTableBinderContexts = statementBinderContext.getExternalTableBinderContexts();
SelectStatement boundLeftSelect = new SelectStatementBinder().bind(segment.getLeft().getSelect(), metaData, currentDatabaseName, externalTableBinderContexts);
SelectStatement boundRightSelect = new SelectStatementBinder().bind(segment.getRight().getSelect(), metaData, currentDatabaseName, externalTableBinderContexts);
SelectStatement boundLeftSelect = new SelectStatementBinder().bind(
segment.getLeft().getSelect(), createBinderContext(segment.getLeft().getSelect(), metaData, currentDatabaseName, externalTableBinderContexts));
SelectStatement boundRightSelect = new SelectStatementBinder().bind(
segment.getRight().getSelect(), createBinderContext(segment.getRight().getSelect(), metaData, currentDatabaseName, externalTableBinderContexts));
SubquerySegment boundLeft = new SubquerySegment(segment.getLeft().getStartIndex(), segment.getLeft().getStopIndex(), segment.getLeft().getText());
boundLeft.setSelect(boundLeftSelect);
boundLeft.setSubqueryType(segment.getLeft().getSubqueryType());
Expand All @@ -56,4 +58,11 @@ public static CombineSegment bind(final CombineSegment segment, final SQLStateme
boundedRight.setSubqueryType(segment.getRight().getSubqueryType());
return new CombineSegment(segment.getStartIndex(), segment.getStopIndex(), boundLeft, segment.getCombineType(), boundedRight);
}

private static SQLStatementBinderContext createBinderContext(final SelectStatement select, final ShardingSphereMetaData metaData,
final String currentDatabaseName, final Map<String, TableSegmentBinderContext> externalTableBinderContexts) {
SQLStatementBinderContext result = new SQLStatementBinderContext(select, metaData, currentDatabaseName);
result.getExternalTableBinderContexts().putAll(externalTableBinderContexts);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ public final class SubquerySegmentBinder {
* @return bounded subquery segment
*/
public static SubquerySegment bind(final SubquerySegment segment, final SQLStatementBinderContext statementBinderContext, final Map<String, TableSegmentBinderContext> outerTableBinderContexts) {
SelectStatement boundedSelectStatement = new SelectStatementBinder().bindCorrelateSubquery(segment.getSelect(), statementBinderContext.getMetaData(),
statementBinderContext.getCurrentDatabaseName(), outerTableBinderContexts, statementBinderContext.getExternalTableBinderContexts());
SQLStatementBinderContext binderContext = new SQLStatementBinderContext(segment.getSelect(), statementBinderContext.getMetaData(), statementBinderContext.getCurrentDatabaseName());
binderContext.getExternalTableBinderContexts().putAll(statementBinderContext.getExternalTableBinderContexts());
SelectStatement boundedSelectStatement = new SelectStatementBinder(outerTableBinderContexts).bind(segment.getSelect(), binderContext);
SubquerySegment result = new SubquerySegment(segment.getStartIndex(), segment.getStopIndex(), boundedSelectStatement, segment.getText());
result.setSubqueryType(segment.getSubqueryType());
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ public final class SubqueryTableSegmentBinder {
public static SubqueryTableSegment bind(final SubqueryTableSegment segment, final SQLStatementBinderContext statementBinderContext,
final Map<String, TableSegmentBinderContext> tableBinderContexts, final Map<String, TableSegmentBinderContext> outerTableBinderContexts) {
fillPivotColumnNamesInBinderContext(segment, statementBinderContext);
SelectStatement boundedSelect = new SelectStatementBinder().bindCorrelateSubquery(segment.getSubquery().getSelect(), statementBinderContext.getMetaData(),
statementBinderContext.getCurrentDatabaseName(), outerTableBinderContexts, statementBinderContext.getExternalTableBinderContexts());
SQLStatementBinderContext binderContext = new SQLStatementBinderContext(
segment.getSubquery().getSelect(), statementBinderContext.getMetaData(), statementBinderContext.getCurrentDatabaseName());
binderContext.getExternalTableBinderContexts().putAll(statementBinderContext.getExternalTableBinderContexts());
SelectStatement boundedSelect = new SelectStatementBinder(outerTableBinderContexts).bind(segment.getSubquery().getSelect(), binderContext);
SubquerySegment boundedSubquerySegment = new SubquerySegment(segment.getSubquery().getStartIndex(), segment.getSubquery().getStopIndex(), boundedSelect, segment.getSubquery().getText());
boundedSubquerySegment.setSubqueryType(segment.getSubquery().getSubqueryType());
IdentifierValue subqueryTableName = segment.getAliasSegment().map(AliasSegment::getIdentifier).orElseGet(() -> new IdentifierValue(""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package org.apache.shardingsphere.infra.binder.statement;

import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;

/**
Expand All @@ -31,9 +30,8 @@ public interface SQLStatementBinder<T extends SQLStatement> {
* Bind SQL statement.
*
* @param sqlStatement SQL statement
* @param metaData meta data
* @param currentDatabaseName current database name
* @param binderContext SQL statement binder context
* @return bound SQL statement
*/
T bind(T sqlStatement, ShardingSphereMetaData metaData, String currentDatabaseName);
T bind(T sqlStatement, SQLStatementBinderContext binderContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

import lombok.SneakyThrows;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementBinder;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CursorStatement;

/**
Expand All @@ -29,9 +29,9 @@
public final class CursorStatementBinder implements SQLStatementBinder<CursorStatement> {

@Override
public CursorStatement bind(final CursorStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName) {
public CursorStatement bind(final CursorStatement sqlStatement, final SQLStatementBinderContext binderContext) {
CursorStatement result = copy(sqlStatement);
result.setSelect(new SelectStatementBinder().bind(sqlStatement.getSelect(), metaData, currentDatabaseName));
result.setSelect(new SelectStatementBinder().bind(sqlStatement.getSelect(), binderContext));
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.apache.shardingsphere.infra.binder.segment.where.WhereSegmentBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DeleteStatement;

import java.util.Collections;
Expand All @@ -36,18 +35,11 @@
public final class DeleteStatementBinder implements SQLStatementBinder<DeleteStatement> {

@Override
public DeleteStatement bind(final DeleteStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName) {
return bind(sqlStatement, metaData, currentDatabaseName, Collections.emptyMap());
}

private DeleteStatement bind(final DeleteStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName,
final Map<String, TableSegmentBinderContext> externalTableBinderContexts) {
public DeleteStatement bind(final DeleteStatement sqlStatement, final SQLStatementBinderContext binderContext) {
DeleteStatement result = copy(sqlStatement);
Map<String, TableSegmentBinderContext> tableBinderContexts = new LinkedHashMap<>();
SQLStatementBinderContext statementBinderContext = new SQLStatementBinderContext(sqlStatement, metaData, currentDatabaseName);
statementBinderContext.getExternalTableBinderContexts().putAll(externalTableBinderContexts);
result.setTable(TableSegmentBinder.bind(sqlStatement.getTable(), statementBinderContext, tableBinderContexts, Collections.emptyMap()));
sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, statementBinderContext, tableBinderContexts, Collections.emptyMap())));
result.setTable(TableSegmentBinder.bind(sqlStatement.getTable(), binderContext, tableBinderContexts, Collections.emptyMap()));
sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, binderContext, tableBinderContexts, Collections.emptyMap())));
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@
import org.apache.shardingsphere.infra.binder.segment.from.impl.SimpleTableSegmentBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.InsertStatement;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
Expand All @@ -43,24 +41,17 @@
public final class InsertStatementBinder implements SQLStatementBinder<InsertStatement> {

@Override
public InsertStatement bind(final InsertStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName) {
return bind(sqlStatement, metaData, currentDatabaseName, Collections.emptyMap());
}

private InsertStatement bind(final InsertStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName,
final Map<String, TableSegmentBinderContext> externalTableBinderContexts) {
public InsertStatement bind(final InsertStatement sqlStatement, final SQLStatementBinderContext binderContext) {
InsertStatement result = copy(sqlStatement);
SQLStatementBinderContext statementBinderContext = new SQLStatementBinderContext(sqlStatement, metaData, currentDatabaseName);
statementBinderContext.getExternalTableBinderContexts().putAll(externalTableBinderContexts);
Map<String, TableSegmentBinderContext> tableBinderContexts = new LinkedHashMap<>();
Optional.ofNullable(sqlStatement.getTable()).ifPresent(optional -> result.setTable(SimpleTableSegmentBinder.bind(optional, statementBinderContext, tableBinderContexts)));
Optional.ofNullable(sqlStatement.getTable()).ifPresent(optional -> result.setTable(SimpleTableSegmentBinder.bind(optional, binderContext, tableBinderContexts)));
if (sqlStatement.getInsertColumns().isPresent() && !sqlStatement.getInsertColumns().get().getColumns().isEmpty()) {
result.setInsertColumns(InsertColumnsSegmentBinder.bind(sqlStatement.getInsertColumns().get(), statementBinderContext, tableBinderContexts));
result.setInsertColumns(InsertColumnsSegmentBinder.bind(sqlStatement.getInsertColumns().get(), binderContext, tableBinderContexts));
} else {
sqlStatement.getInsertColumns().ifPresent(result::setInsertColumns);
tableBinderContexts.values().forEach(each -> result.getDerivedInsertColumns().addAll(getVisibleColumns(each.getProjectionSegments())));
}
sqlStatement.getInsertSelect().ifPresent(optional -> result.setInsertSelect(SubquerySegmentBinder.bind(optional, statementBinderContext, tableBinderContexts)));
sqlStatement.getInsertSelect().ifPresent(optional -> result.setInsertSelect(SubquerySegmentBinder.bind(optional, binderContext, tableBinderContexts)));
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.shardingsphere.infra.binder.statement.dml;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.shardingsphere.infra.binder.segment.combine.CombineSegmentBinder;
import org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinder;
Expand All @@ -27,7 +28,6 @@
import org.apache.shardingsphere.infra.binder.segment.with.WithSegmentBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement;

Expand All @@ -39,56 +39,27 @@
/**
* Select statement binder.
*/
@RequiredArgsConstructor
public final class SelectStatementBinder implements SQLStatementBinder<SelectStatement> {

/**
* Bind correlate subquery select statement.
*
* @param sqlStatement subquery select statement
* @param metaData meta data
* @param currentDatabaseName current database name
* @param outerTableBinderContexts outer select statement table binder contexts
* @param externalTableBinderContexts external table binder contexts
* @return bounded correlate subquery select statement
*/
public SelectStatement bindCorrelateSubquery(final SelectStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName,
final Map<String, TableSegmentBinderContext> outerTableBinderContexts, final Map<String, TableSegmentBinderContext> externalTableBinderContexts) {
return bind(sqlStatement, metaData, currentDatabaseName, outerTableBinderContexts, externalTableBinderContexts);
}
private final Map<String, TableSegmentBinderContext> outerTableBinderContexts;

/**
* Bind with external table contexts.
*
* @param statement select statement
* @param metaData meta data
* @param currentDatabaseName current database name
* @param externalTableContexts external table contexts
* @return select statement
*/
public SelectStatement bind(final SelectStatement statement, final ShardingSphereMetaData metaData, final String currentDatabaseName,
final Map<String, TableSegmentBinderContext> externalTableContexts) {
return bind(statement, metaData, currentDatabaseName, Collections.emptyMap(), externalTableContexts);
public SelectStatementBinder() {
outerTableBinderContexts = Collections.emptyMap();
}

@Override
public SelectStatement bind(final SelectStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName) {
return bind(sqlStatement, metaData, currentDatabaseName, Collections.emptyMap(), Collections.emptyMap());
}

private SelectStatement bind(final SelectStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName,
final Map<String, TableSegmentBinderContext> outerTableBinderContexts, final Map<String, TableSegmentBinderContext> externalTableBinderContexts) {
public SelectStatement bind(final SelectStatement sqlStatement, final SQLStatementBinderContext binderContext) {
SelectStatement result = copy(sqlStatement);
Map<String, TableSegmentBinderContext> tableBinderContexts = new LinkedHashMap<>();
SQLStatementBinderContext statementBinderContext = new SQLStatementBinderContext(sqlStatement, metaData, currentDatabaseName);
statementBinderContext.getExternalTableBinderContexts().putAll(externalTableBinderContexts);
sqlStatement.getWithSegment()
.ifPresent(optional -> result.setWithSegment(WithSegmentBinder.bind(optional, statementBinderContext, tableBinderContexts, statementBinderContext.getExternalTableBinderContexts())));
Optional<TableSegment> boundedTableSegment = sqlStatement.getFrom().map(optional -> TableSegmentBinder.bind(optional, statementBinderContext, tableBinderContexts, outerTableBinderContexts));
.ifPresent(optional -> result.setWithSegment(WithSegmentBinder.bind(optional, binderContext, tableBinderContexts, binderContext.getExternalTableBinderContexts())));
Optional<TableSegment> boundedTableSegment = sqlStatement.getFrom().map(optional -> TableSegmentBinder.bind(optional, binderContext, tableBinderContexts, outerTableBinderContexts));
boundedTableSegment.ifPresent(result::setFrom);
result.setProjections(ProjectionsSegmentBinder.bind(sqlStatement.getProjections(), statementBinderContext, boundedTableSegment.orElse(null), tableBinderContexts, outerTableBinderContexts));
sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, statementBinderContext, tableBinderContexts, outerTableBinderContexts)));
sqlStatement.getCombine().ifPresent(optional -> result.setCombine(CombineSegmentBinder.bind(optional, statementBinderContext)));
sqlStatement.getLock().ifPresent(optional -> result.setLock(LockSegmentBinder.bind(optional, statementBinderContext, tableBinderContexts, outerTableBinderContexts)));
result.setProjections(ProjectionsSegmentBinder.bind(sqlStatement.getProjections(), binderContext, boundedTableSegment.orElse(null), tableBinderContexts, outerTableBinderContexts));
sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, binderContext, tableBinderContexts, outerTableBinderContexts)));
sqlStatement.getCombine().ifPresent(optional -> result.setCombine(CombineSegmentBinder.bind(optional, binderContext)));
sqlStatement.getLock().ifPresent(optional -> result.setLock(LockSegmentBinder.bind(optional, binderContext, tableBinderContexts, outerTableBinderContexts)));
// TODO support other segment bind in select statement
return result;
}
Expand Down
Loading

0 comments on commit b4d7ff3

Please sign in to comment.