Skip to content

Commit

Permalink
Support create index statement sql bind (#34112)
Browse files Browse the repository at this point in the history
* Support create index statement sql bind

* update release note

* update binder expected file

* fix checkstyle
  • Loading branch information
strongduanmu authored Dec 21, 2024
1 parent d093932 commit 652d22d
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 11 deletions.
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
1. Agent: Simplify the use of Agent's Docker Image - [#33356](https://github.com/apache/shardingsphere/pull/33356)
1. Metadata: Add load-table-metadata-batch-size props to concurrent load table metadata - [#34009](https://github.com/apache/shardingsphere/pull/34009)
1. SQL Binder: Add sql bind logic for create table statement - [#34074](https://github.com/apache/shardingsphere/pull/34074)
1. SQL Binder: Support create index statement sql bind - [#34112](https://github.com/apache/shardingsphere/pull/34112)

### Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

import org.apache.shardingsphere.infra.binder.context.statement.ddl.CreateIndexStatementContext;
import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.table.NoSuchTableException;
import org.apache.shardingsphere.infra.exception.kernel.metadata.DuplicateIndexException;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.exception.kernel.metadata.DuplicateIndexException;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexNameSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexSegment;
Expand Down Expand Up @@ -52,7 +52,7 @@ class ShardingCreateIndexSupportedCheckerTest {

@Test
void assertCheckWhenTableExistIndexNotExistForPostgreSQL() {
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement(false);
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement();
sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
sqlStatement.setIndex(new IndexSegment(0, 0, new IndexNameSegment(0, 0, new IdentifierValue("t_order_index"))));
ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
Expand All @@ -62,7 +62,7 @@ void assertCheckWhenTableExistIndexNotExistForPostgreSQL() {

@Test
void assertCheckWhenTableNotExistIndexNotExistForPostgreSQL() {
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement(false);
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement();
sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
sqlStatement.setIndex(new IndexSegment(0, 0, new IndexNameSegment(0, 0, new IdentifierValue("t_order_index"))));
ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
Expand All @@ -72,7 +72,7 @@ void assertCheckWhenTableNotExistIndexNotExistForPostgreSQL() {

@Test
void assertCheckWhenTableExistIndexExistForPostgreSQL() {
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement(false);
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement();
sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
sqlStatement.setIndex(new IndexSegment(0, 0, new IndexNameSegment(0, 0, new IdentifierValue("t_order_index"))));
ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
Expand All @@ -83,7 +83,7 @@ void assertCheckWhenTableExistIndexExistForPostgreSQL() {

@Test
void assertCheckWithoutIndexNameWhenTableExistIndexNotExistForPostgreSQL() {
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement(false);
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement();
sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
sqlStatement.getColumns().add(new ColumnSegment(0, 0, new IdentifierValue("content")));
sqlStatement.setGeneratedIndexStartIndex(10);
Expand All @@ -94,7 +94,7 @@ void assertCheckWithoutIndexNameWhenTableExistIndexNotExistForPostgreSQL() {

@Test
void assertCheckWithoutIndexNameWhenTableNotExistIndexNotExistForPostgreSQL() {
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement(false);
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement();
sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
sqlStatement.getColumns().add(new ColumnSegment(0, 0, new IdentifierValue("content")));
sqlStatement.setGeneratedIndexStartIndex(10);
Expand All @@ -105,7 +105,7 @@ void assertCheckWithoutIndexNameWhenTableNotExistIndexNotExistForPostgreSQL() {

@Test
void assertCheckWithoutIndexNameWhenTableExistIndexExistForPostgreSQL() {
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement(false);
PostgreSQLCreateIndexStatement sqlStatement = new PostgreSQLCreateIndexStatement();
sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
sqlStatement.getColumns().add(new ColumnSegment(0, 0, new IdentifierValue("content")));
sqlStatement.setGeneratedIndexStartIndex(10);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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

import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.SneakyThrows;
import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
import org.apache.shardingsphere.infra.binder.engine.segment.expression.type.ColumnSegmentBinder;
import org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
import org.apache.shardingsphere.infra.binder.engine.segment.from.type.SimpleTableSegmentBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateIndexStatement;

/**
* Create index statement binder.
*/
public final class CreateIndexStatementBinder implements SQLStatementBinder<CreateIndexStatement> {

@Override
public CreateIndexStatement bind(final CreateIndexStatement sqlStatement, final SQLStatementBinderContext binderContext) {
CreateIndexStatement result = copy(sqlStatement);
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts = LinkedHashMultimap.create();
result.setTable(SimpleTableSegmentBinder.bind(sqlStatement.getTable(), binderContext, tableBinderContexts));
sqlStatement.getColumns()
.forEach(each -> result.getColumns().add(ColumnSegmentBinder.bind(each, SegmentType.DEFINITION_COLUMNS, binderContext, tableBinderContexts, LinkedHashMultimap.create())));
return result;
}

@SneakyThrows(ReflectiveOperationException.class)
private static CreateIndexStatement copy(final CreateIndexStatement sqlStatement) {
CreateIndexStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance();
result.setIndex(sqlStatement.getIndex());
sqlStatement.getGeneratedIndexStartIndex().ifPresent(result::setGeneratedIndexStartIndex);
result.setIfNotExists(sqlStatement.isIfNotExists());
sqlStatement.getAlgorithmType().ifPresent(result::setAlgorithmType);
sqlStatement.getLockTable().ifPresent(result::setLockTable);
result.addParameterMarkerSegments(sqlStatement.getParameterMarkerSegments());
result.getCommentSegments().addAll(sqlStatement.getCommentSegments());
result.getVariableNames().addAll(sqlStatement.getVariableNames());
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.CreateIndexStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.CreateTableStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.CursorStatementBinder;
import org.apache.shardingsphere.infra.hint.HintValueContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateIndexStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CursorStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement;
Expand Down Expand Up @@ -53,6 +55,9 @@ public DDLStatement bind(final DDLStatement statement) {
if (statement instanceof CreateTableStatement) {
return new CreateTableStatementBinder().bind((CreateTableStatement) statement, binderContext);
}
if (statement instanceof CreateIndexStatement) {
return new CreateIndexStatementBinder().bind((CreateIndexStatement) statement, binderContext);
}
return statement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,8 @@ public ASTNode visitTruncateTable(final TruncateTableContext ctx) {
@SuppressWarnings("unchecked")
@Override
public ASTNode visitCreateIndex(final CreateIndexContext ctx) {
OpenGaussCreateIndexStatement result = new OpenGaussCreateIndexStatement(null != ctx.ifNotExists());
OpenGaussCreateIndexStatement result = new OpenGaussCreateIndexStatement();
result.setIfNotExists(null != ctx.ifNotExists());
result.setTable((SimpleTableSegment) visit(ctx.tableName()));
result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(ctx.indexParams())).getValue());
if (null == ctx.indexName()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,8 @@ public ASTNode visitDropSubscription(final DropSubscriptionContext ctx) {
@SuppressWarnings("unchecked")
@Override
public ASTNode visitCreateIndex(final CreateIndexContext ctx) {
PostgreSQLCreateIndexStatement result = new PostgreSQLCreateIndexStatement(null != ctx.ifNotExists());
PostgreSQLCreateIndexStatement result = new PostgreSQLCreateIndexStatement();
result.setIfNotExists(null != ctx.ifNotExists());
result.setTable((SimpleTableSegment) visit(ctx.tableName()));
result.getColumns().addAll(((CollectionValue<ColumnSegment>) visit(ctx.indexParams())).getValue());
if (null != ctx.indexName()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ public Optional<Integer> getGeneratedIndexStartIndex() {
return Optional.empty();
}

/**
* Set generated index start index.
*
* @param generatedIndexStartIndex generated index start index
*/
public void setGeneratedIndexStartIndex(final Integer generatedIndexStartIndex) {
}

/**
* Judge whether contains if not exists or not.
*
Expand All @@ -61,6 +69,14 @@ public boolean isIfNotExists() {
return false;
}

/**
* Set if not exists or not.
*
* @param ifNotExists if not exists or not
*/
public void setIfNotExists(final boolean ifNotExists) {
}

/**
* Get algorithm type.
*
Expand All @@ -70,6 +86,14 @@ public Optional<AlgorithmTypeSegment> getAlgorithmType() {
return Optional.empty();
}

/**
* Set algorithm type.
*
* @param algorithmType algorithm type
*/
public void setAlgorithmType(final AlgorithmTypeSegment algorithmType) {
}

/**
* Get lock table.
*
Expand All @@ -78,4 +102,12 @@ public Optional<AlgorithmTypeSegment> getAlgorithmType() {
public Optional<LockTableSegment> getLockTable() {
return Optional.empty();
}

/**
* Set lock table.
*
* @param lockTable lock table
*/
public void setLockTable(final LockTableSegment lockTable) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
@Setter
public final class OpenGaussCreateIndexStatement extends CreateIndexStatement implements OpenGaussStatement {

private final boolean ifNotExists;
private boolean ifNotExists;

private Integer generatedIndexStartIndex;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
@Setter
public final class PostgreSQLCreateIndexStatement extends CreateIndexStatement implements PostgreSQLStatement {

private final boolean ifNotExists;
private boolean ifNotExists;

private Integer generatedIndexStartIndex;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.shardingsphere.test.it.sql.binder.dialect.opengauss;

import org.apache.shardingsphere.test.it.sql.binder.SQLBinderIT;
import org.apache.shardingsphere.test.it.sql.binder.SQLBinderITSettings;

@SQLBinderITSettings("openGauss")
class OpenGaussBinderIT extends SQLBinderIT {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.shardingsphere.test.it.sql.binder.dialect.postgresql;

import org.apache.shardingsphere.test.it.sql.binder.SQLBinderIT;
import org.apache.shardingsphere.test.it.sql.binder.SQLBinderITSettings;

@SQLBinderITSettings("PostgreSQL")
class PostgreSQLBinderIT extends SQLBinderIT {
}
40 changes: 40 additions & 0 deletions test/it/binder/src/test/resources/cases/ddl/create-index.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<sql-parser-test-cases>
<create-index sql-case-id="create_index_with_schema">
<table>
<simple-table name="t_order" start-index="28" stop-index="41">
<owner name="public" start-index="28" stop-index="33" />
<table-bound>
<original-database name="foo_db_1" />
<original-schema name="public" />
</table-bound>
</simple-table>
</table>
<index name="idx_name" start-index="13" stop-index="20" />
<column start-index="56" stop-index="62" name="user_id">
<column-bound>
<original-database name="foo_db_1" />
<original-schema name="public" />
<original-table name="t_order" />
<original-column name="user_id" />
</column-bound>
</column>
</create-index>
</sql-parser-test-cases>
21 changes: 21 additions & 0 deletions test/it/binder/src/test/resources/sqls/ddl/create-index.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<sql-cases>
<sql-case id="create_index_with_schema" value="CREATE INDEX idx_user_id ON public.t_order USING btree (user_id ASC NULLS LAST) TABLESPACE pg_default" db-types="PostgreSQL,openGauss" />
</sql-cases>

0 comments on commit 652d22d

Please sign in to comment.