@@ -108,11 +114,11 @@ protected TableScan(RelOptCluster cluster, RelTraitSet traitSet, protected TableScan(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable table, SqlNodeList hints, SqlNode indexNode) { - this(cluster, traitSet, table, hints, indexNode, null, null); + this(cluster, traitSet, table, hints, indexNode, null, null, null); } protected TableScan(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable table, SqlNodeList hints, - SqlNode indexNode, RexNode flashback, SqlNode partitions) { + SqlNode indexNode, RexNode flashback, SqlOperator flashbackOperator, SqlNode partitions) { super(cluster, traitSet); this.table = table; this.hints = hints; @@ -121,6 +127,7 @@ protected TableScan(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable tab cluster.getPlanner().registerSchema(table.getRelOptSchema()); } this.flashback = flashback; + this.flashbackOperator = flashbackOperator; this.partitions = partitions; } /** @@ -265,6 +272,14 @@ public void setFlashback(RexNode flashback) { this.flashback = flashback; } + public SqlOperator getFlashbackOperator() { + return flashbackOperator; + } + + public void setFlashbackOperator(SqlOperator flashbackOperator) { + this.flashbackOperator = flashbackOperator; + } + public SqlNode getPartitions() { return partitions; } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/Window.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/Window.java index 58f228601..d388fd392 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/Window.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/Window.java @@ -64,7 +64,6 @@ public abstract class Window extends SingleRel { public final ImmutableListgroups; public final ImmutableList constants; - private RelOptCost fixedCost; /** * Creates a window relational expression. @@ -185,14 +184,6 @@ public List getConstants() { return planner.getCostFactory().makeCost(rowsIn, rowsIn * count, 0,0,0); } - public void setFixedCost(RelOptCost relOptCost) { - this.fixedCost = relOptCost; - } - - public RelOptCost getFixedCost() { - return fixedCost; - } - /** * Group of windowed aggregate calls that have the same window specification. * diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/WindowAggregateCall.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/WindowAggregateCall.java index 2f056fc9d..78456a56b 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/WindowAggregateCall.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/core/WindowAggregateCall.java @@ -67,6 +67,25 @@ public WindowAggregateCall copy(List args, int filterArg, List args, int filterArg) { + return new WindowAggregateCall(aggFunction, distinct, approximate, args, + filterArg, type, name, constants, offset); + } + + @Override + public AggregateCall copy(List args, int filterArg, boolean isDistinct, String newName) { + return new WindowAggregateCall(aggFunction, isDistinct, approximate, args, + filterArg, type, newName, constants, offset); + } + + @Override + public AggregateCall withDistinct(boolean distinct) { + return distinct == this.distinct ? this + : new WindowAggregateCall(aggFunction, distinct, approximate, argList, filterArg, type, name, + constants, offset); + } + public AggregateCall create(SqlAggFunction aggFunction, boolean distinct, boolean approximate, List argList, diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterInstance.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterInstance.java new file mode 100644 index 000000000..03ac5c460 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterInstance.java @@ -0,0 +1,50 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlAlterInstance; +import org.apache.calcite.sql.SqlNode; + +import java.util.List; + +/** + * Created by zhuqiwei. + * + * @author zhuqiwei + */ +public class AlterInstance extends DDL { + public AlterInstance(RelOptCluster cluster, RelTraitSet traitSet, SqlNode sqlNode, RelDataType rowType) { + super(cluster, traitSet, null); + this.sqlNode = sqlNode; + } + + public static AlterInstance create(SqlAlterInstance alterInstance, RelDataType rowType, RelOptCluster cluster) { + return new AlterInstance(cluster, cluster.traitSetOf(Convention.NONE), alterInstance, rowType); + } + + @Override + public AlterInstance copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new AlterInstance(this.getCluster(), traitSet, ((AlterInstance) inputs.get(0)).getAst(), rowType); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableDiscardTableSpace.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableDiscardTableSpace.java new file mode 100644 index 000000000..f54fe7901 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableDiscardTableSpace.java @@ -0,0 +1,59 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlAlterJoinGroup; +import org.apache.calcite.sql.SqlAlterTableDiscardTableSpace; +import org.apache.calcite.sql.SqlDdl; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.parser.SqlParserPos; + +import java.util.List; + +/** + * Created by luoyanxin. + * + * @author luoyanxin + */ +public class AlterTableDiscardTableSpace extends DDL { + protected AlterTableDiscardTableSpace(RelOptCluster cluster, RelTraitSet traits, + SqlDdl ddl, SqlNode tableNameNode) { + super(cluster, traits, null); + this.sqlNode = ddl; + this.setTableName(tableNameNode); + } + + public static AlterTableDiscardTableSpace create(SqlAlterTableDiscardTableSpace sqlAlterTableDiscardTableSpace, + SqlNode tableNameNode, RelOptCluster cluster) { + return new AlterTableDiscardTableSpace(cluster, cluster.traitSetOf(Convention.NONE), + sqlAlterTableDiscardTableSpace, tableNameNode); + } + + @Override + public AlterTableDiscardTableSpace copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new AlterTableDiscardTableSpace(this.getCluster(), traitSet, + ((AlterTableDiscardTableSpace) inputs.get(0)).getAst(), getTableName()); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableImportTableSpace.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableImportTableSpace.java new file mode 100644 index 000000000..5e2492c48 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableImportTableSpace.java @@ -0,0 +1,56 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.sql.SqlAlterTableDiscardTableSpace; +import org.apache.calcite.sql.SqlAlterTableImportTableSpace; +import org.apache.calcite.sql.SqlDdl; +import org.apache.calcite.sql.SqlNode; + +import java.util.List; + +/** + * Created by luoyanxin. + * + * @author luoyanxin + */ +public class AlterTableImportTableSpace extends DDL { + protected AlterTableImportTableSpace(RelOptCluster cluster, RelTraitSet traits, + SqlDdl ddl, SqlNode tableNameNode) { + super(cluster, traits, null); + this.sqlNode = ddl; + this.setTableName(tableNameNode); + } + + public static AlterTableImportTableSpace create(SqlAlterTableImportTableSpace sqlAlterTableImportTableSpace, + SqlNode tableNameNode, RelOptCluster cluster) { + return new AlterTableImportTableSpace(cluster, cluster.traitSetOf(Convention.NONE), + sqlAlterTableImportTableSpace, tableNameNode); + } + + @Override + public AlterTableImportTableSpace copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new AlterTableImportTableSpace(this.getCluster(), traitSet, + ((AlterTableImportTableSpace) inputs.get(0)).getAst(), getTableName()); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableSetTableGroup.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableSetTableGroup.java index f91c0ba3d..93fa770af 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableSetTableGroup.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/AlterTableSetTableGroup.java @@ -16,21 +16,17 @@ package org.apache.calcite.rel.ddl; -import com.alibaba.polardbx.common.exception.NotSupportException; import org.apache.calcite.plan.Convention; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.DDL; import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.rex.RexNode; import org.apache.calcite.sql.SqlDdl; import org.apache.calcite.sql.SqlIdentifier; import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.parser.SqlParserPos; import java.util.List; -import java.util.Map; /** * Created by luoyanxin. @@ -41,33 +37,39 @@ public class AlterTableSetTableGroup extends DDL { final String tableGroupName; final List objectNames; final boolean force; + final boolean implicit; protected AlterTableSetTableGroup(RelOptCluster cluster, RelTraitSet traits, SqlDdl ddl, RelDataType rowType, List objectNames, SqlNode tableName, String tableGroupName, + boolean implicit, boolean force) { super(cluster, traits, ddl, rowType); this.tableGroupName = tableGroupName; this.sqlNode = ddl; this.objectNames = objectNames; this.setTableName(tableName); + this.implicit = implicit; this.force = force; } public static AlterTableSetTableGroup create(RelOptCluster cluster, RelTraitSet traits, SqlDdl ddl, - RelDataType rowType, List objectNames, SqlNode tableName, - String tableGroupName, boolean force) { + RelDataType rowType, List objectNames, + SqlNode tableName, + String tableGroupName, boolean implicit, boolean force) { - return new AlterTableSetTableGroup(cluster, traits, ddl, rowType, objectNames, tableName, tableGroupName, force); + return new AlterTableSetTableGroup(cluster, traits, ddl, rowType, objectNames, tableName, tableGroupName, + implicit, force); } @Override public AlterTableSetTableGroup copy( RelTraitSet traitSet, List inputs) { assert traitSet.containsIfApplicable(Convention.NONE); - return new AlterTableSetTableGroup(this.getCluster(), traitSet, this.ddl, rowType, this.objectNames, getTableName(), tableGroupName, force); + return new AlterTableSetTableGroup(this.getCluster(), traitSet, this.ddl, rowType, this.objectNames, + getTableName(), tableGroupName, implicit, force); } public String getTableGroupName() { @@ -81,4 +83,8 @@ public List getObjectNames() { public boolean isForce() { return force; } + + public boolean isImplicit() { + return implicit; + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ClearFileStorage.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ClearFileStorage.java new file mode 100644 index 000000000..a2bd971d9 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ClearFileStorage.java @@ -0,0 +1,56 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlDdl; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.parser.SqlParserPos; + +import java.util.List; + +public class ClearFileStorage extends DDL { + final String fileStorageName; + + protected ClearFileStorage(RelOptCluster cluster, RelTraitSet traits, SqlDdl ddl, + RelDataType rowType, String fileStorageName) { + super(cluster, traits, ddl, rowType); + this.fileStorageName = fileStorageName; + this.sqlNode = ddl; + this.setTableName(new SqlIdentifier(fileStorageName, SqlParserPos.ZERO)); + } + + public static ClearFileStorage create(RelOptCluster cluster, RelTraitSet traits, SqlDdl ddl, + RelDataType rowType, String fileStorageName) { + return new ClearFileStorage(cluster, traits, ddl, rowType, fileStorageName); + } + + @Override + public ClearFileStorage copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new ClearFileStorage(this.getCluster(), traitSet, this.ddl, rowType, fileStorageName); + } + + public String getFileStorageName() { + return fileStorageName; + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ConvertAllSequences.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ConvertAllSequences.java new file mode 100644 index 000000000..624e95085 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ConvertAllSequences.java @@ -0,0 +1,53 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlConvertAllSequences; +import org.apache.calcite.sql.SqlNode; + +import java.util.List; + +/** + * Created by zhuqiwei. + * + * @author zhuqiwei + */ +public class ConvertAllSequences extends DDL { + public ConvertAllSequences(RelOptCluster cluster, RelTraitSet traitSet, SqlNode sqlNode, RelDataType relDataType) { + super(cluster, traitSet, null); + this.sqlNode = sqlNode; + } + + public static ConvertAllSequences create(SqlConvertAllSequences sqlConvertAllSequences, RelDataType relDataType, + RelOptCluster cluster) { + return new ConvertAllSequences(cluster, cluster.traitSetOf(Convention.NONE), sqlConvertAllSequences, + relDataType); + } + + @Override + public ConvertAllSequences copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new ConvertAllSequences(this.getCluster(), traitSet, ((ConvertAllSequences) (inputs.get(0))).getAst(), + rowType); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/CreateView.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/CreateView.java new file mode 100644 index 000000000..1c04ec929 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/CreateView.java @@ -0,0 +1,52 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlCreateView; +import org.apache.calcite.sql.SqlDdl; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.util.Util; + +import java.util.List; + +public class CreateView extends DDL { + + protected CreateView(RelOptCluster cluster, RelTraitSet traits, SqlDdl ddl, RelDataType rowType) { + super(cluster, traits, ddl, rowType); + this.sqlNode = ddl; + + SqlCreateView sqlCreateView = (SqlCreateView) ddl; + this.setTableName(sqlCreateView.getName()); + } + + public static CreateView create(SqlCreateView sqlCreateView, RelDataType rowType, RelOptCluster cluster) { + return new CreateView(cluster, cluster.traitSetOf(Convention.NONE), sqlCreateView, rowType); + } + + @Override + public CreateView copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new CreateView(this.getCluster(), traitSet, ((CreateView) inputs.get(0)).getAst(), rowType); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/DropView.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/DropView.java new file mode 100644 index 000000000..2190e4cee --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/DropView.java @@ -0,0 +1,50 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlCreateView; +import org.apache.calcite.sql.SqlDdl; +import org.apache.calcite.sql.SqlDropView; + +import java.util.List; + +public class DropView extends DDL { + + protected DropView(RelOptCluster cluster, RelTraitSet traits, SqlDdl ddl, RelDataType rowType) { + super(cluster, traits, ddl, rowType); + this.sqlNode = ddl; + + SqlDropView sqlDropView = (SqlDropView) ddl; + this.setTableName(sqlDropView.getName()); + } + + public static DropView create(SqlDropView sqlDropView, RelDataType rowType, RelOptCluster cluster) { + return new DropView(cluster, cluster.traitSetOf(Convention.NONE), sqlDropView, rowType); + } + + @Override + public DropView copy(RelTraitSet traitSet, List inputs) { + assert traitSet.containsIfApplicable(Convention.NONE); + return new DropView(this.getCluster(), traitSet, ((DropView) inputs.get(0)).getAst(), rowType); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ImportDatabase.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ImportDatabase.java new file mode 100644 index 000000000..513a094b9 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ImportDatabase.java @@ -0,0 +1,50 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlImportDatabase; +import org.apache.calcite.sql.SqlNode; + +import java.util.List; + +/** + * Created by zhuqiwei. + * + * @author zhuqiwei + */ +public class ImportDatabase extends DDL { + public ImportDatabase(RelOptCluster cluster, RelTraitSet traitSet, SqlNode sqlNode, RelDataType rowType) { + super(cluster, traitSet, null); + this.sqlNode = sqlNode; + } + + public static ImportDatabase create(SqlImportDatabase sqlImportDatabase, RelDataType rowType, RelOptCluster cluster) { + return new ImportDatabase(cluster, cluster.traitSetOf(Convention.NONE), sqlImportDatabase, rowType); + } + + @Override + public ImportDatabase copy(RelTraitSet traitSet, List inputs) { + return new ImportDatabase(this.getCluster(), traitSet, ((ImportDatabase) inputs.get(0)).getAst(), rowType); + } +} + diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ImportSequence.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ImportSequence.java new file mode 100644 index 000000000..2ef3f7f4e --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/ddl/ImportSequence.java @@ -0,0 +1,51 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.rel.ddl; + +import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.DDL; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlImportSequence; +import org.apache.calcite.sql.SqlNode; + +import java.util.List; + +/** + * Created by zhuqiwei. + * + * @author zhuqiwei + */ +public class ImportSequence extends DDL { + + public ImportSequence(RelOptCluster cluster, RelTraitSet traitSet, SqlNode sqlNode, RelDataType rowTyep) { + super(cluster, traitSet, null); + this.sqlNode = sqlNode; + } + + public static ImportSequence create(SqlImportSequence sqlImportSequence, RelDataType rowType, + RelOptCluster cluster) { + return new ImportSequence(cluster, cluster.traitSetOf(Convention.NONE), sqlImportSequence, rowType); + } + + @Override + public ImportSequence copy(RelTraitSet traitSet, List inputs) { + return new ImportSequence(this.getCluster(), traitSet, ((ImportSequence) inputs.get(0)).getAst(), rowType); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsJsonWriter.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsJsonWriter.java index 05843daa0..a64863272 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsJsonWriter.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsJsonWriter.java @@ -114,6 +114,10 @@ protected void explain_(RelNode rel, List > values) { node.put("actual_next_time", sketch.getDuration()); node.put("actual_worker_time", sketch.getWorkerDuration()); node.put("actual_rowcount", sketch.getRowCount()); + if (sketch.getRuntimeFilteredRowCount() > 0) { + node.put("runtime_filtered_count", sketch.getRuntimeFilteredRowCount()); + } + node.put("actual_memory", sketch.getMemory()); if (sketch.getSpillCnt() > 0) { diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsWriter.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsWriter.java index 1d14cb228..7c595547f 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsWriter.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelDrdsWriter.java @@ -190,6 +190,11 @@ protected void explain_(RelNode rel, List > values) { s.append(", actual time = ").append(String.format("%.3f", sketch.getStartupDuration())) .append(" + ").append(String.format("%.3f", sketch.getDuration())); s.append(", actual rowcount = ").append(sketch.getRowCount()); + + if (sketch.getRuntimeFilteredRowCount() > 0) { + s.append(", runtime filtered count = ").append(sketch.getRuntimeFilteredRowCount()); + } + s.append(", actual memory = ").append(sketch.getMemory()); if (sketch.getSpillCnt() > 0) { s.append(", spill count = ").append(sketch.getSpillCnt()); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJson.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJson.java index e862c3252..f8e6cb2b2 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJson.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJson.java @@ -29,6 +29,8 @@ import org.apache.calcite.rel.RelFieldCollation; import org.apache.calcite.rel.RelInput; import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.RelPartitionWise; +import org.apache.calcite.rel.RelPartitionWises; import org.apache.calcite.rel.core.AggregateCall; import org.apache.calcite.rel.core.CorrelationId; import org.apache.calcite.rel.type.RelDataType; @@ -60,14 +62,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * Utilities for converting {@link org.apache.calcite.rel.RelNode} * into JSON format. */ public class RelJson { - protected final Map constructorMap = - new HashMap (); + protected static final Map constructorMap = new ConcurrentHashMap<>(); protected final JsonBuilder jsonBuilder; public static final List PACKAGES = @@ -196,6 +198,10 @@ public RelDistribution toDistribution(Map map) { return RelDistributions.ANY; // TODO: } + public RelPartitionWise toPartitionWise(Map map) { + return RelPartitionWises.ANY; + } + public RelDataType toType(RelDataTypeFactory typeFactory, Object o) { if (o instanceof List) { @SuppressWarnings("unchecked") diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java index aab3c61d7..81776255f 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java @@ -31,6 +31,7 @@ import org.apache.calcite.rel.RelDistribution; import org.apache.calcite.rel.RelInput; import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.RelPartitionWise; import org.apache.calcite.rel.core.AggregateCall; import org.apache.calcite.rel.core.CorrelationId; import org.apache.calcite.rel.core.Window; @@ -304,6 +305,10 @@ public RelDistribution getDistribution() { return relJson.toDistribution((Map ) get("distribution")); } + public RelPartitionWise getPartitionWise() { + return relJson.toPartitionWise((Map ) get("partitionWise")); + } + public ImmutableList > getTuples(String tag) { //noinspection unchecked final List jsonTuples = (List) get(tag); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/JoinReorderContext.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/JoinReorderContext.java index f51eeda95..395c9db9c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/JoinReorderContext.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/JoinReorderContext.java @@ -17,19 +17,27 @@ package org.apache.calcite.rel.logical; public class JoinReorderContext { - /** left deep */ + /** + * left deep + */ private boolean hasCommute = false; private boolean hasTopPushThrough = false; - /** zig-zag */ + /** + * zig-zag + */ private boolean hasCommuteZigZag = false; - /** bushy */ + /** + * bushy + */ private boolean hasExchange = false; private boolean hasRightAssociate = false; private boolean hasLeftAssociate = false; + private boolean hasSemiFilter = false; - public JoinReorderContext() {} + public JoinReorderContext() { + } void copyFrom(JoinReorderContext joinReorderContext) { this.hasCommute = joinReorderContext.hasCommute; @@ -38,6 +46,7 @@ void copyFrom(JoinReorderContext joinReorderContext) { this.hasLeftAssociate = joinReorderContext.hasLeftAssociate; this.hasRightAssociate = joinReorderContext.hasRightAssociate; this.hasCommuteZigZag = joinReorderContext.hasCommuteZigZag; + this.hasSemiFilter = joinReorderContext.hasSemiFilter; } public void clear() { @@ -47,6 +56,7 @@ public void clear() { hasExchange = false; hasRightAssociate = false; hasLeftAssociate = false; + hasSemiFilter = false; } public void avoidParticipateInJoinReorder() { @@ -56,6 +66,17 @@ public void avoidParticipateInJoinReorder() { hasExchange = true; hasRightAssociate = true; hasLeftAssociate = true; + hasSemiFilter = true; + } + + public boolean reordered() { + return hasCommute + || hasTopPushThrough + || hasCommuteZigZag + || hasExchange + || hasRightAssociate + || hasLeftAssociate + || hasSemiFilter; } public boolean isHasCommute() { @@ -105,4 +126,12 @@ public boolean isHasCommuteZigZag() { public void setHasCommuteZigZag(boolean hasCommuteZigZag) { this.hasCommuteZigZag = hasCommuteZigZag; } + + public boolean isHasSemiFilter() { + return hasSemiFilter; + } + + public void setHasSemiFilter(boolean hasSemiFilter) { + this.hasSemiFilter = hasSemiFilter; + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalSemiJoin.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalSemiJoin.java index b2186a42d..ccab1e0a7 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalSemiJoin.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalSemiJoin.java @@ -79,6 +79,11 @@ public class LogicalSemiJoin extends SemiJoin { private String subqueryPosition; private static final String ERROR_SUBQUERY_MULTI_COLUMNS = " subquery with multi columns transform error"; + /** + * use for join reorder + */ + private final JoinReorderContext joinReorderContext = new JoinReorderContext(); + //~ Constructors ----------------------------------------------------------- /** @@ -594,6 +599,7 @@ public LogicalSemiJoin copy(RelTraitSet traitSet, RexNode condition, semiJoin.pushDownRelNode = this.pushDownRelNode; semiJoin.subqueryPosition = this.subqueryPosition; semiJoin.fromSetOp = this.fromSetOp; + semiJoin.getJoinReorderContext().copyFrom(this.getJoinReorderContext()); return semiJoin; } @@ -605,6 +611,10 @@ public RelNode accept(RelShuttle shuttle) { public boolean isFromSetOp() { return fromSetOp; } + + public JoinReorderContext getJoinReorderContext() { + return joinReorderContext; + } } // End SemiJoin.java diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java index 763733402..52eed454c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java @@ -31,6 +31,7 @@ import org.apache.calcite.schema.Table; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.parser.SqlParserPos; import java.util.List; @@ -81,8 +82,9 @@ public LogicalTableScan(RelOptCluster cluster, RelTraitSet traitSet, public LogicalTableScan(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable table, SqlNodeList hints, SqlNode indexNode, RexNode flashback, + SqlOperator flashbackOperator, SqlNode partitions) { - super(cluster, traitSet, table, hints, indexNode, flashback, partitions); + super(cluster, traitSet, table, hints, indexNode, flashback, flashbackOperator, partitions); } @Deprecated // to be removed before 2.0 @@ -110,12 +112,12 @@ public LogicalTableScan(RelInput input) { */ public static LogicalTableScan create(RelOptCluster cluster, final RelOptTable relOptTable) { - return create(cluster, relOptTable, new SqlNodeList(SqlParserPos.ZERO), null, null, null); + return create(cluster, relOptTable, new SqlNodeList(SqlParserPos.ZERO), null, null, null, null); } public static LogicalTableScan create(RelOptCluster cluster, final RelOptTable relOptTable, SqlNodeList hints, SqlNode indexNode, - RexNode flashback, SqlNode partitions) { + RexNode flashback, SqlOperator flashbackOperator, SqlNode partitions) { final Table table = relOptTable.unwrap(Table.class); final RelTraitSet traitSet = @@ -127,7 +129,8 @@ public static LogicalTableScan create(RelOptCluster cluster, } return ImmutableList.of(); }).simplify(); - return new LogicalTableScan(cluster, traitSet, relOptTable, hints, indexNode, flashback, partitions); + return new LogicalTableScan(cluster, traitSet, relOptTable, hints, indexNode, flashback, flashbackOperator, + partitions); } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java index 7bc89f470..cb72b09d2 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java @@ -93,7 +93,6 @@ public LogicalWindow(RelOptCluster cluster, RelTraitSet traitSet, List
inputs) { LogicalWindow logicalWindow = new LogicalWindow(getCluster(), traitSet, sole(inputs), constants, rowType, groups); - logicalWindow.setFixedCost(getFixedCost()); return logicalWindow; } @@ -113,9 +112,6 @@ public static LogicalWindow create(RelTraitSet traitSet, RelNode input, } @Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { - if (getFixedCost() != null) { - return getFixedCost(); - } // Cost is proportional to the number of rows and the number of // components (groups and aggregate functions). There is // no I/O cost. diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java index ee6bc94da..d8f8f9c1c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java @@ -22,24 +22,40 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.util.concurrent.UncheckedExecutionException; -import org.apache.calcite.adapter.enumerable.*; +import org.apache.calcite.adapter.enumerable.EnumerableAggregate; +import org.apache.calcite.adapter.enumerable.EnumerableFilter; +import org.apache.calcite.adapter.enumerable.EnumerableJoin; +import org.apache.calcite.adapter.enumerable.EnumerableProject; +import org.apache.calcite.adapter.enumerable.EnumerableTableScan; import org.apache.calcite.config.CalciteSystemProperty; import org.apache.calcite.interpreter.JaninoRexCompiler; import org.apache.calcite.linq4j.Ord; -import org.apache.calcite.linq4j.tree.ClassDeclaration; -import org.apache.calcite.linq4j.tree.MemberDeclaration; import org.apache.calcite.linq4j.tree.Primitive; import org.apache.calcite.plan.hep.HepRelVertex; import org.apache.calcite.plan.volcano.AbstractConverter; import org.apache.calcite.plan.volcano.RelSubset; -import org.apache.calcite.prepare.CalcitePrepareImpl; import org.apache.calcite.rel.AbstractRelNode; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.convert.ConverterImpl; -import org.apache.calcite.rel.core.DynamicValues; -import org.apache.calcite.rel.logical.*; +import org.apache.calcite.rel.logical.LogicalAggregate; +import org.apache.calcite.rel.logical.LogicalCalc; +import org.apache.calcite.rel.logical.LogicalCorrelate; +import org.apache.calcite.rel.logical.LogicalExchange; +import org.apache.calcite.rel.logical.LogicalFilter; +import org.apache.calcite.rel.logical.LogicalIntersect; +import org.apache.calcite.rel.logical.LogicalJoin; +import org.apache.calcite.rel.logical.LogicalMinus; +import org.apache.calcite.rel.logical.LogicalProject; +import org.apache.calcite.rel.logical.LogicalSort; +import org.apache.calcite.rel.logical.LogicalTableFunctionScan; +import org.apache.calcite.rel.logical.LogicalTableModify; +import org.apache.calcite.rel.logical.LogicalTableScan; +import org.apache.calcite.rel.logical.LogicalUnion; +import org.apache.calcite.rel.logical.LogicalValues; +import org.apache.calcite.rel.logical.LogicalWindow; import org.apache.calcite.rel.stream.LogicalChi; import org.apache.calcite.rel.stream.LogicalDelta; import org.apache.calcite.rex.RexNode; @@ -49,18 +65,20 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.codehaus.commons.compiler.CompileException; import org.codehaus.commons.compiler.CompilerFactoryFactory; -import org.codehaus.commons.compiler.IClassBodyEvaluator; import org.codehaus.commons.compiler.ICompilerFactory; import org.codehaus.commons.compiler.ISimpleCompiler; -import javax.annotation.Nonnull; import java.io.IOException; -import java.io.StringReader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ExecutionException; @@ -249,7 +267,7 @@ private static MetadataHandler load3( } safeArgList(buff, method.e) .append(");\n") - .append(" final Object v = mq.map.get(r, key);\n") + .append(" final Object v = mq.getCache(r, key);\n") .append(" if (v != null) {\n") .append(" if (v == ") .append(NullSentinel.class.getName()) @@ -267,9 +285,9 @@ private static MetadataHandler load3( .append(method.e.getReturnType().getName()) .append(") v;\n") .append(" }\n") - .append(" mq.map.put(r, key,") + .append(" mq.cache(r, key,") .append(NullSentinel.class.getName()) - .append(".ACTIVE);\n") + .append(".ACTIVE, 0);\n") .append(" try {\n") .append(" final ") .append(method.e.getReturnType().getName()) @@ -278,14 +296,14 @@ private static MetadataHandler load3( .append("_(r, mq"); argList(buff, method.e) .append(");\n") - .append(" mq.map.put(r, key, ") + .append(" mq.cache(r, key, ") .append(NullSentinel.class.getName()) - .append(".mask(x));\n") + .append(".mask(x), 0);\n") .append(" return x;\n") .append(" } catch (") .append(Exception.class.getName()) .append(" e) {\n") - .append(" mq.map.row(r).clear();\n") + .append(" mq.clearCache(r);\n") .append(" throw e;\n") .append(" }\n") .append(" }\n") diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java index 0f3fbde6a..ab6767fed 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java @@ -31,7 +31,6 @@ import com.google.common.collect.Multimap; import org.checkerframework.checker.nullness.qual.Nullable; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -182,7 +181,8 @@ private static RelMetadataProvider reflectiveSource( } key1 = FlatLists.copyOf(args2); } - if (mq.map.put(rel, key1, NullSentinel.INSTANCE) != null) { + Object o = mq.cache(rel, key1, NullSentinel.INSTANCE, 1); + if (o!= null) { throw new CyclicMetadataException(); } try { @@ -192,7 +192,7 @@ private static RelMetadataProvider reflectiveSource( Util.throwIfUnchecked(e.getCause()); throw new RuntimeException(e.getCause()); } finally { - mq.map.remove(rel, key1); + mq.clearCache(rel, key1); } }); methodsMap.put(key, function); @@ -321,7 +321,7 @@ Method find(final Class extends RelNode> relNodeClass, Method method) { } r = r.getSuperclass(); if (r == null || !RelNode.class.isAssignableFrom(r)) { - throw new IllegalArgumentException("No handler for method [" + method + throw new IllegalArgumentException("No handler for method [" + method + "] applied to argument of type [" + relNodeClass + "]; we recommend you create a catch-all (RelNode) handler"); } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java index a20fc453a..3ad2ea887 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java @@ -57,7 +57,7 @@ public MetadataDef getDef() { public Double getPopulationSize(Filter rel, RelMetadataQuery mq, ImmutableBitSet groupKey) { - return mq.getPopulationSize(rel.getInput(), groupKey); + return RelMdUtil.numDistinctVals(mq.getPopulationSize(rel.getInput(), groupKey), mq.getRowCount(rel)); } public Double getPopulationSize(Correlate rel, RelMetadataQuery mq, diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java index c0ba1d1ac..b64cf2dfe 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java @@ -298,6 +298,7 @@ public Double averageTypeValueSize(RelDataType type) { case REAL: case DECIMAL: case DATE: + case DATETIME: case TIME: case TIME_WITH_LOCAL_TIME_ZONE: case INTERVAL_YEAR: diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdUtil.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdUtil.java index c26b44740..aee47c0d1 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdUtil.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMdUtil.java @@ -416,6 +416,15 @@ public static double guessSelectivity( RexNode predicate, boolean artificialOnly) { double sel = 1.0; + if (predicate instanceof RexLiteral) { + if (((RexLiteral)predicate).isAlwaysTrueIntOrBoolean()) { + return sel; + } + if (((RexLiteral)predicate).isAlwaysFalseIntOrBoolean()) { + return 0.0; + } + } + if ((predicate == null) || predicate.isAlwaysTrue()) { return sel; } @@ -438,6 +447,8 @@ public static double guessSelectivity( sel *= .15; } else if (pred.isA(SqlKind.COMPARISON)) { sel *= .5; + } else if (pred.isA(SqlKind.LIKE)) { + sel *= .05; } else { sel *= .25; } @@ -571,6 +582,23 @@ public static void setAggChildKeys( } } + public static ImmutableBitSet keyThroughChildKeys( + ImmutableBitSet currentGroupKey, + ImmutableBitSet childGroupKey) { + final int childGroupCount = childGroupKey.cardinality(); + for (int bit : currentGroupKey) { + if (bit >= childGroupCount) { + return null; + } + } + + ImmutableBitSet.Builder result = ImmutableBitSet.builder(); + for (int bit : currentGroupKey) { + result.set(childGroupKey.nth(bit)); + } + return result.build(); + } + /** * Forms two bitmaps by splitting the columns in a bitmap according to * whether or not the column references the child input or is an expression diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java index 575710e1f..24fc2f2ea 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java @@ -16,8 +16,13 @@ */ package org.apache.calcite.rel.metadata; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; +import com.alibaba.polardbx.common.jdbc.Parameters; +import com.alibaba.polardbx.common.properties.DynamicConfig; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import org.apache.calcite.plan.RelOptCost; import org.apache.calcite.plan.RelOptPredicateList; import org.apache.calcite.plan.RelOptTable; @@ -30,18 +35,12 @@ import org.apache.calcite.rex.RexTableInputRef.RelTableRef; import org.apache.calcite.sql.SqlExplainLevel; import org.apache.calcite.util.ImmutableBitSet; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Multimap; import org.checkerframework.checker.nullness.qual.Nullable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -83,7 +82,9 @@ */ public class RelMetadataQuery { /** Set of active metadata queries, and cache of previous results. */ - public final Table map = HashBasedTable.create(); + public final Map > map = Maps.newConcurrentMap(); + + public final Map >> threadMap = Maps.newConcurrentMap(); public final JaninoRelMetadataProvider metadataProvider; @@ -132,6 +133,9 @@ protected JaninoRelMetadataProvider initialValue() { } }; + public static final ThreadLocal THREAD_PARAMETERS = + ThreadLocal.withInitial(() -> null); + protected RelMetadataQuery(JaninoRelMetadataProvider metadataProvider, RelMetadataQuery prototype) { this.metadataProvider = Preconditions.checkNotNull(metadataProvider); @@ -191,6 +195,14 @@ public static RelMetadataQuery instance() { return new RelMetadataQuery(THREAD_PROVIDERS.get(), EMPTY); } + /** + * @param metadataProvider target provider being used to build a meta query + * @return An instance of RelMetadataQuery + */ + public static RelMetadataQuery instance(JaninoRelMetadataProvider metadataProvider) { + return new RelMetadataQuery(metadataProvider, EMPTY); + } + /** Creates and initializes the instance that will serve as a prototype for * all other instances. */ private RelMetadataQuery(boolean dummy) { @@ -1122,20 +1134,130 @@ public void setIgnoreProjectDeriveOriginColumn(boolean ignoreProjectDeriveOrigin } } - /** - * Removes cached metadata values for specified RelNode. - * - * @param rel RelNode whose cached metadata should be removed - * @return true if cache for the provided RelNode was not empty - */ - public boolean clearCache(RelNode rel) { - Map row = map.row(rel); - if (row.isEmpty()) { - return false; + /** + * Removes cached metadata values for specified RelNode. + * + * @param rel RelNode whose cached metadata should be removed + * @return true if cache for the provided RelNode was not empty + */ + public boolean clearCache(RelNode rel) { + Map
row = null; + Map
row1 = null; + row = map.remove(rel); + Long threadId = Thread.currentThread().getId(); + Map
> m = threadMap.get(threadId); + if (m != null) { + row1 = m.remove(rel); + } + return row != null || row1 != null; } - row.clear(); - return true; + public void clearThreadCache() { + Long threadId = Thread.currentThread().getId(); + threadMap.remove(threadId); + } + + public void clearCache(RelNode rel, List key1) { + Map m = map.get(rel); + if (m != null) { + m.remove(key1); + } + Long threadId = Thread.currentThread().getId(); + Map > m1 = threadMap.get(threadId); + if (m1 != null) { + Map m2 = m1.get(rel); + if (m2 != null) { + m2.remove(key1); + } + } + } + + public Object cache(RelNode rel, List key, Object value, int classIndex) { + Object val = null; + if (DynamicConfig.getInstance().isEnableMQCacheByThread()) { + Class declaringClass = null; + boolean forceCacheByThread = false; + if(value==NullSentinel.ACTIVE){ + // NullSentinel.ACTIVE meaning the target of this cache is checking cycle, + // so it should be cached by thread to avoiding CyclicMetadataException + forceCacheByThread = true; + }else if (key.get(classIndex) instanceof MetadataDef) { + // key.get(classIndex) is a Method meaning this cache request was coming from JaninoRelMetadataProvider. + // Whether this cache request should be cached by thread depended on declaringClass + declaringClass = ((MetadataDef) key.get(classIndex)).metadataClass; + } else if (key.get(classIndex) instanceof Method) { + // key.get(classIndex) is a Method meaning this cache request was coming from ReflectiveRelMetadataProvider + // and ReflectiveRelMetadataProvider only use this cache to check dead cycle loop. + // so it should be cached by thread to avoiding CyclicMetadataException + forceCacheByThread = true; + } else { + throw new RuntimeException("not supported cache key:" + key.get(classIndex)); + } + + // if cache request was working for dead cycle loop check, forceCacheByThread was expected as true + // if declaringClass(mq api) was something connected to params, this cache shouldn't be cached beyond thread + if (forceCacheByThread || isDeclaringClassShouldBeCached(declaringClass)) { + Long threadId = Thread.currentThread().getId(); + Map > map = threadMap.get(threadId); + + if (map == null) { + map = Maps.newHashMap(); + threadMap.put(threadId, map); + } + Map subMap = map.get(rel); + if (subMap == null) { + subMap = Maps.newHashMap(); + map.put(rel, subMap); + } else { + val = subMap.get(key); + } + subMap.put(key, value); + return val; + } + } + Map
m = map.get(rel); + if (m == null) { + m = Maps.newConcurrentMap(); + map.put(rel, m); + } else { + val = m.get(key); + } + m.put(key, value); + return val; + } + + public static boolean isDeclaringClassShouldBeCached(Class declaringClass) { + return BuiltInMetadata.RowCount.class.equals(declaringClass) + || BuiltInMetadata.MaxRowCount.class.equals(declaringClass) + || BuiltInMetadata.MinRowCount.class.equals(declaringClass) + || BuiltInMetadata.PercentageOriginalRows.class.equals(declaringClass) + || BuiltInMetadata.StartUpCost.class.equals(declaringClass) + || BuiltInMetadata.NonCumulativeCost.class.equals(declaringClass) + || BuiltInMetadata.CumulativeCost.class.equals(declaringClass) + || BuiltInMetadata.Selectivity.class.equals(declaringClass) + || BuiltInMetadata.PopulationSize.class.equals(declaringClass) + || BuiltInMetadata.LowerBoundCost.class.equals(declaringClass) + || BuiltInMetadata.Memory.class.equals(declaringClass) + || BuiltInMetadata.DistinctRowCount.class.equals(declaringClass) + || BuiltInMetadata.Size.class.equals(declaringClass); + } + + public Object getCache(RelNode rel, List key) { + Map
row = map.get(rel); + if (row != null) { + if (row.containsKey(key)) { + return row.get(key); + } + } + Map
> relMap = threadMap.get(Thread.currentThread().getId()); + if (relMap != null && relMap.containsKey(rel)) { + Map subMap = relMap.get(rel); + if (subMap != null) { + return subMap.get(key); + } + } + return null; + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java index 076e55f15..b46e8b9f9 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java @@ -1441,7 +1441,8 @@ public SqlNode asFrom() { final SqlIdentifier identifier = (SqlIdentifier) node; final SqlIdentifier newIdentifier = new SqlIdentifier(((SqlIdentifier) node).names, ((SqlIdentifier) node).getCollation(), - node.getParserPosition(), null, null, identifier.partitions, identifier.flashback); + node.getParserPosition(), null, null, identifier.partitions, identifier.flashback, + identifier.flashbackOperator); final SqlIdentifier alias = new SqlIdentifier(ImmutableList.of(neededAlias), null, POS, null, identifier.indexNode); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java index 3d997cbd6..4307e646a 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java @@ -36,6 +36,8 @@ import org.apache.calcite.rel.core.Project; import org.apache.calcite.rel.core.RelFactories; import org.apache.calcite.rel.core.TableScan; +import org.apache.calcite.rel.metadata.JaninoRelMetadataProvider; +import org.apache.calcite.rel.metadata.RelMetadataProvider; import org.apache.calcite.rel.metadata.RelMetadataQuery; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeField; @@ -175,7 +177,11 @@ protected AbstractMaterializedViewRule(RelOptRuleOperand operand, */ protected void perform(RelOptRuleCall call, Project topProject, RelNode node) { final RexBuilder rexBuilder = node.getCluster().getRexBuilder(); - final RelMetadataQuery mq = RelMetadataQuery.instance(); + final RelMetadataQuery mq; + RelMetadataProvider provider = node.getCluster().getMetadataProvider(); + // provider in cluster cannot be a JaninoRelMetadataProvider, + // for it doesn't support RelMetadataProvider.apply method + mq = RelMetadataQuery.instance(JaninoRelMetadataProvider.of(provider)); final RelOptPlanner planner = call.getPlanner(); final RexExecutor executor = Util.first(planner.getExecutor(), RexUtil.EXECUTOR); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java index f3b03a9e9..2677755ad 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java @@ -401,6 +401,19 @@ private int chooseLevels( levelCount++; } } + + // For dynamic rex node (constant value), pull up its level to avoid project calculation. + int maxLevel = Integer.MIN_VALUE; + for (int i = 0; i < exprLevels.length; i++) { + maxLevel = Math.max(maxLevel, exprLevels[i]); + } + for (int i = 0; i < exprs.length; i++) { + RexNode rexNode = exprs[i]; + if (rexNode instanceof RexDynamicParam) { + exprLevels[i] = maxLevel; + } + } + return levelCount; } @@ -941,6 +954,12 @@ public Void visitLocalRef(RexLocalRef localRef) { return null; } + @Override + public Void visitDynamicParam(RexDynamicParam dynamicParam) { + level = 0; + return null; + } + /** * Returns the highest level of any of the inputs of an expression. */ diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectJoinTransposeRule.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectJoinTransposeRule.java index fc1618db9..5fc093419 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectJoinTransposeRule.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectJoinTransposeRule.java @@ -45,6 +45,7 @@ public class ProjectJoinTransposeRule extends RelOptRule { PushProjector.ExprCondition.TRUE, RelFactories.LOGICAL_BUILDER); + //~ Instance fields -------------------------------------------------------- /** @@ -70,6 +71,15 @@ public ProjectJoinTransposeRule( this.preserveExprCondition = preserveExprCondition; } + public ProjectJoinTransposeRule(int inputRefThreshold) { + super( + operand(Project.class, + operand(Join.class, any())), + RelFactories.LOGICAL_BUILDER, null); + + this.preserveExprCondition = new PushProjector.InputRefExprCondition(inputRefThreshold); + } + //~ Methods ---------------------------------------------------------------- // implement RelOptRule diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java index 2f5573877..b69246d2b 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java @@ -45,12 +45,16 @@ public class ProjectMergeRule extends RelOptRule { public static final ProjectMergeRule INSTANCE = new ProjectMergeRule(true, RelFactories.LOGICAL_BUILDER); + public static final ProjectMergeRule INSTANCE_WONT_IGNORE_REX_SUBQUERY = + new ProjectMergeRule(true, false, RelFactories.LOGICAL_BUILDER); + //~ Instance fields -------------------------------------------------------- /** * Whether to always merge projects. */ private final boolean force; + private boolean ignoreProjectSubquery = true; //~ Constructors ----------------------------------------------------------- @@ -68,6 +72,16 @@ public ProjectMergeRule(boolean force, RelBuilderFactory relBuilderFactory) { this.force = force; } + public ProjectMergeRule(boolean force, boolean ignoreProjectSubquery, RelBuilderFactory relBuilderFactory) { + super( + operand(Project.class, + operand(Project.class, any())), + relBuilderFactory, + "ProjectMergeRule" + (force ? ":force_mode" : "")); + this.force = force; + this.ignoreProjectSubquery = ignoreProjectSubquery; + } + @Deprecated // to be removed before 2.0 public ProjectMergeRule(boolean force, ProjectFactory projectFactory) { this(force, RelBuilder.proto(projectFactory)); @@ -128,6 +142,14 @@ public void onMatch(RelOptRuleCall call) { } } + if (!ignoreProjectSubquery) { + for (RexNode rexNode : topProject.getProjects()) { + if (RexUtil.hasSubQuery(rexNode)) { + return; + } + } + } + Set
corList = Sets.newHashSet(); if (topProject.getVariablesSet() != null) { corList.addAll(topProject.getVariablesSet()); @@ -139,6 +161,7 @@ public void onMatch(RelOptRuleCall call) { if (corList.size() > 1) { return; } + // replace the two projects with a combined projection relBuilder.push(bottomProject.getInput()); relBuilder.project(newProjects, topProject.getRowType().getFieldNames(), corList); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java index acb909638..f015d85e0 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java @@ -93,6 +93,15 @@ public ProjectWindowTransposeRule(RelBuilderFactory relBuilderFactory) { builder.add(relDataTypeField); } + // if there is no reference, use the first column + if (beReferred.isEmpty()) { + if (windowInputColumn > 1) { + final RelDataTypeField relDataTypeField = rowTypeWindowInput.get(0); + exps.add(new RexInputRef(0, relDataTypeField.getType())); + builder.add(relDataTypeField); + } + } + final LogicalProject projectBelowWindow = new LogicalProject(cluster, window.getTraitSet(), window.getInput(), exps, builder.build()); @@ -241,7 +250,7 @@ private ImmutableBitSet findReference(final LogicalProject project, private int getAdjustedIndex(final int initIndex, final ImmutableBitSet beReferred, final int windowInputColumn) { if (initIndex >= windowInputColumn) { - return beReferred.cardinality() + (initIndex - windowInputColumn); + return Math.max(beReferred.cardinality(), 1) + (initIndex - windowInputColumn); } else { return beReferred.get(0, initIndex).cardinality(); } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/PushProjector.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/PushProjector.java index 02c9f7029..d98b5ee43 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/PushProjector.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/rules/PushProjector.java @@ -21,7 +21,6 @@ import org.apache.calcite.plan.Strong; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Join; -import org.apache.calcite.rel.core.JoinRelType; import org.apache.calcite.rel.core.Project; import org.apache.calcite.rel.core.SemiJoin; import org.apache.calcite.rel.core.SetOp; @@ -33,10 +32,7 @@ import org.apache.calcite.rex.RexUtil; import org.apache.calcite.rex.RexVisitorImpl; import org.apache.calcite.runtime.PredicateImpl; -import org.apache.calcite.sql.SqlBasicCall; import org.apache.calcite.sql.SqlOperator; -import org.apache.calcite.sql.fun.SqlCastFunction; -import org.apache.calcite.sql.fun.SqlRowOperator; import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.util.BitSets; import org.apache.calcite.util.ImmutableBitSet; @@ -47,11 +43,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.BitSet; import java.util.List; -import java.util.Optional; import java.util.Set; /** @@ -886,6 +882,26 @@ public boolean test(RexNode expr) { && operatorSet.contains(((RexCall) expr).getOperator()); } } + + public static class InputRefExprCondition extends ExprConditionImpl { + + private final int inputRefThreshold; + + public InputRefExprCondition(int inputRefThreshold) { + this.inputRefThreshold = inputRefThreshold; + } + + @Override + public boolean test(@Nullable RexNode rexNode) { + if (rexNode instanceof RexInputRef) { + return true; + } else if (rexNode instanceof RexCall) { + return RexUtil.getInputRefCount(rexNode) >= inputRefThreshold; + } + return false; + } + } + } // End PushProjector.java diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java index 4e754f61d..f5121832d 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java @@ -266,11 +266,16 @@ RelDataType createEnumSqlType( SqlTypeName typeName, List values); + RelDataType createSetSqlType( + SqlTypeName typeName, + int precision, + List setValues); + /** * Creates a SQL interval type. * * @param intervalQualifier contains information if it is a year-month or a - * day-time interval along with precision information + * day-time interval along with precision information * @return canonical type descriptor */ RelDataType createSqlIntervalType( diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java b/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java index 79c35ed6d..a928ee067 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java @@ -127,6 +127,9 @@ public int getMaxScale(SqlTypeName typeName) { // SqlTypeName.getDefaultPrecision), but it should be 6 // (microseconds) per SQL99 part 2 section 6.1 syntax rule 30. return 0; + case BIT: + case BIG_BIT: + return 1; default: return -1; } @@ -163,6 +166,9 @@ public int getMaxScale(SqlTypeName typeName) { case INTERVAL_MINUTE_SECOND: case INTERVAL_SECOND: return SqlTypeName.MAX_INTERVAL_START_PRECISION; + case BIT: + case BIG_BIT: + return 64; default: return getDefaultPrecision(typeName); } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexLiteral.java b/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexLiteral.java index a8fb1a571..bffceabb3 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexLiteral.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexLiteral.java @@ -56,6 +56,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import static org.apache.calcite.sql.type.SqlTypeName.INT_TYPES; + /** * Constant value in a row-expression. * @@ -942,6 +944,20 @@ public boolean isAlwaysFalse() { return !booleanValue(this); } + public boolean isAlwaysTrueIntOrBoolean() { + if (INT_TYPES.contains(typeName)) { + return longValue(this) != 0; + } + return isAlwaysTrue(); + } + + public boolean isAlwaysFalseIntOrBoolean() { + if (INT_TYPES.contains(typeName)) { + return longValue(this) == 0; + } + return isAlwaysFalse(); + } + public boolean equals(Object obj) { return (obj instanceof RexLiteral) && equals(((RexLiteral) obj).value, value) && equals(((RexLiteral) obj).type, type); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexUtil.java b/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexUtil.java index 4910c6dbf..643d6f7a5 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexUtil.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/rex/RexUtil.java @@ -777,6 +777,12 @@ public static boolean isConstant(RexNode node) { return node.accept(ConstantFinder.INSTANCE); } + public static int getInputRefCount(RexNode node) { + RexInputRefVisitor visitor = new RexInputRefVisitor(); + node.accept(visitor); + return visitor.getInputRefCount(); + } + /** * Returns whether a given expression is deterministic. @@ -3393,6 +3399,33 @@ public static RexNode split(RexNode rex, ImmutableBitSet retain){ } } + public static class RexInputRefVisitor extends RexVisitorImpl
{ + + private int inputRefCount; + private BitSet bitSet; + + protected RexInputRefVisitor() { + super(true); + this.inputRefCount = 0; + this.bitSet = new BitSet(8); + } + + public Void visitInputRef(RexInputRef inputRef) { + final int ref = inputRef.getIndex(); + if (bitSet.get(ref)) { + // Remove duplicates input refs. + return null; + } + bitSet.set(ref); + inputRefCount++; + return null; + } + + public int getInputRefCount() { + return inputRefCount; + } + }; + /** * Returns whether a given tree contains any un-pushable function * diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/runtime/CalciteResource.java b/polardbx-calcite/src/main/java/org/apache/calcite/runtime/CalciteResource.java index 558b914fb..ffa642059 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/runtime/CalciteResource.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/runtime/CalciteResource.java @@ -746,9 +746,21 @@ public interface CalciteResource { @BaseMessage("View ''{0}'' not found") ExInst viewNotFound(String name); + @BaseMessage("Index ''{0}'' not found") + ExInst indexNotFound(String name); + @BaseMessage("Global Secondary Index ''{0}'' already exists") ExInst gsiExists(String name); + @BaseMessage("Clustered Columnar Index ''{0}'' already exists") + ExInst cciExists(String name); + + @BaseMessage("Do not support create more than one Clustered Columnar Index on table ''{0}''") + ExInst cciMoreThanOne(String name); + + @BaseMessage("Do not support create Clustered Columnar Index on table without primary key") + ExInst createCciOnTableWithoutPk(); + @BaseMessage("Duplicate column name ''{0}''") ExInst duplicateColumnNameInTable(String a0); @@ -775,7 +787,7 @@ public interface CalciteResource { @BaseMessage("Recursive CTE not support {0}") ExInst validatorRecursiveCTENotSupport(String a0); - + @BaseMessage("Cannot UPDATE generated column ''{0}''") ExInst updateAlwaysGenerated(String a0); } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAddIndex.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAddIndex.java index e967c4625..c8ec5e066 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAddIndex.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAddIndex.java @@ -78,6 +78,10 @@ public boolean isClusteredIndex() { return indexDef.isClustered(); } + public boolean isColumnarIndex() { + return indexDef.isColumnar(); + } + @Override public boolean supportFileStorage() { return true; diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAggFunction.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAggFunction.java index 6c1f6481a..c78b4372c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAggFunction.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAggFunction.java @@ -24,7 +24,9 @@ import org.apache.calcite.sql.type.SqlReturnTypeInference; import org.apache.calcite.sql.validate.SqlValidator; import org.apache.calcite.sql.validate.SqlValidatorScope; +import org.apache.calcite.util.Optionality; +import javax.annotation.Nonnull; import java.util.List; /** @@ -131,6 +133,23 @@ public RelDataType getReturnType(RelDataTypeFactory typeFactory) { public boolean allowsFilter() { return true; } + + /** Returns whether this aggregate function allows the {@code DISTINCT} + * keyword. + * + * The default implementation returns {@link Optionality#OPTIONAL}, + * which is appropriate for most aggregate functions, including {@code SUM} + * and {@code COUNT}. + * + *
Some aggregate functions, for example {@code MIN}, produce the same + * result with or without {@code DISTINCT}, and therefore return + * {@link Optionality#IGNORED} to indicate this. For such functions, + * Calcite will probably remove {@code DISTINCT} while optimizing the query. + */ + public @Nonnull + Optionality getDistinctOptionality() { + return Optionality.OPTIONAL; + } } // End SqlAggFunction.java diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterInstance.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterInstance.java new file mode 100644 index 000000000..4f3735094 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterInstance.java @@ -0,0 +1,83 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.List; + +/** + * Created by zhuqiwei. + * + * @author zhuqiwei + */ +public class SqlAlterInstance extends SqlDdl { + private static final SqlSpecialOperator OPERATOR = new SqlAlterInstanceOperator(); + private List
optitionList; + + public SqlAlterInstance(SqlParserPos pos, List optitionList) { + super(OPERATOR, pos); + this.optitionList = optitionList; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("ALTER INSTANCE"); + + for (SqlSetOption sqlSetOption : optitionList) { + sqlSetOption.unparse(writer, leftPrec, rightPrec); + } + } + + public List getOptitionList() { + return optitionList; + } + + public void setOptitionList(List optitionList) { + this.optitionList = optitionList; + } + + @Override + public List getOperandList() { + return ImmutableList.of(); + } + + public static class SqlAlterInstanceOperator extends SqlSpecialOperator { + public SqlAlterInstanceOperator() { + super("ALTER_INSTANCE", SqlKind.ALTER_INSTANCE); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + final RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("ALTER_INSTANCE_RESULT", 0, + columnType))); + } + } + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTable.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTable.java index 5ae47f27a..197e3129e 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTable.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTable.java @@ -43,6 +43,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; /** * DESCRIPTION @@ -81,6 +82,9 @@ public static enum ColumnOpt { private Map > partRexInfoCtxByLevel; + private String targetImplicitTableGroupName; + private Map indexTableGroupMap = new TreeMap<>(); + /** * Creates a SqlCreateIndex. */ @@ -147,12 +151,12 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec, boolean withO name.unparse(writer, leftPrec, rightPrec); } + SqlUtil.wrapSqlNodeList(alters).unparse(writer, 0, 0); + if (null != tableOptions) { tableOptions.unparse(writer, leftPrec, rightPrec); } - SqlUtil.wrapSqlNodeList(alters).unparse(writer, 0, 0); - writer.endList(frame); } @@ -217,8 +221,9 @@ private String prepare() { final int leftPrec = getOperator().getLeftPrec(); final int rightPrec = getOperator().getRightPrec(); alters.clear(); - alters.add(new SqlAlterTableDropIndex(dropForeignKey.getOriginTableName(), dropForeignKey.getIndexName(), - dropForeignKey.getSourceSql(), SqlParserPos.ZERO)); + alters.add( + SqlDdlNodes.alterTableDropIndex(dropForeignKey.getOriginTableName(), dropForeignKey.getIndexName(), + dropForeignKey.getSourceSql(), SqlParserPos.ZERO)); unparse(writer, leftPrec, rightPrec, true); sqlForExecute = writer.toSqlString().getSql(); alters.clear(); @@ -351,6 +356,11 @@ public boolean createGsi() { return addIndex() && ((SqlAddIndex) alters.get(0)).indexDef.isGlobal(); } + @Override + public boolean createCci() { + return addIndex() && ((SqlAddIndex) alters.get(0)).indexDef.isColumnar(); + } + public boolean isAllocateLocalPartition() { return alters != null && alters.size() == 1 && alters.get(0) instanceof SqlAlterTableAllocateLocalPartition; } @@ -539,4 +549,20 @@ public void setFromAlterIndexPartition(boolean fromAlterIndexPartition) { public void setAlterIndexName(SqlNode alterIndexName) { this.alterIndexName = alterIndexName; } + + public String getTargetImplicitTableGroupName() { + return targetImplicitTableGroupName; + } + + public void setTargetImplicitTableGroupName(String targetImplicitTableGroupName) { + this.targetImplicitTableGroupName = targetImplicitTableGroupName; + } + + public Map getIndexTableGroupMap() { + return indexTableGroupMap; + } + + public void addIndexTableGroup(String index, String tableGroupName) { + this.indexTableGroupMap.put(index, tableGroupName); + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDiscardTableSpace.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDiscardTableSpace.java new file mode 100644 index 000000000..7e5a14016 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDiscardTableSpace.java @@ -0,0 +1,102 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.List; + +/** + * Created by luoyanxin. + * + * @author luoyanxin + */ +public class SqlAlterTableDiscardTableSpace extends SqlDdl { + /** + * Creates a SqlDdl. + */ + private static final SqlOperator OPERATOR = new SqlAlterTableDiscardTableSpaceOperator(); + private SqlIdentifier tableName; + private final String sourceSql; + + public SqlAlterTableDiscardTableSpace(SqlParserPos pos, SqlIdentifier tableName, + String sourceSql) { + super(OPERATOR, pos); + this.tableName = tableName; + this.sourceSql = sourceSql; + } + + @Override + public List getOperandList() { + return ImmutableList.of(); + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public String toString() { + return sourceSql; + } + + public String getSourceSql() { + return sourceSql; + } + + public SqlIdentifier getTableName() { + return tableName; + } + + @Override + public SqlNode getTargetTable() { + return tableName; + } + + public static class SqlAlterTableDiscardTableSpaceOperator extends SqlSpecialOperator { + + public SqlAlterTableDiscardTableSpaceOperator() { + super("ALTER_TABLE_DISCARD_TABLESPACE", SqlKind.ALTER_TABLE_DISCARD_TABLESPACE); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + final RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("ALTER_TABLE_DISCARD_TABLESPACE_RESULT", + 0, + columnType))); + } + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.print(toString()); + } + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDropIndex.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDropIndex.java index eb8a2d4bf..03bcd953c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDropIndex.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableDropIndex.java @@ -16,14 +16,13 @@ package org.apache.calcite.sql; +import org.apache.calcite.sql.parser.SqlParserPos; + import java.util.Arrays; import java.util.List; -import org.apache.calcite.sql.parser.SqlParserPos; - /** * @author chenmo.cm - * @date 2019/1/23 12:07 AM */ public class SqlAlterTableDropIndex extends SqlAlterSpecification { private static final SqlOperator OPERATOR = @@ -31,22 +30,21 @@ public class SqlAlterTableDropIndex extends SqlAlterSpecification { /** * Creates a SqlAlterTableDropIndex. - * - * @param indexName - * @param tableName - * @param pos */ - public SqlAlterTableDropIndex(SqlIdentifier tableName, SqlIdentifier indexName , String sql, SqlParserPos pos) { + public SqlAlterTableDropIndex(SqlIdentifier tableName, SqlIdentifier indexName, SqlIdentifier originIndexName, + String sql, SqlParserPos pos) { super(pos); this.tableName = tableName; this.originTableName = tableName; + this.originIndexName = originIndexName; this.indexName = indexName; this.sourceSql = sql; } - private SqlNode tableName; + final private SqlIdentifier tableName; final private SqlIdentifier originTableName; final private SqlIdentifier indexName; + final private SqlIdentifier originIndexName; final private String sourceSql; @Override @@ -56,11 +54,7 @@ public SqlOperator getOperator() { @Override public List getOperandList() { - return Arrays.asList(tableName,indexName); - } - - public void setTargetTable(SqlNode tableName) { - this.tableName = tableName; + return Arrays.asList(tableName, indexName); } @Override @@ -80,6 +74,10 @@ public SqlIdentifier getIndexName() { return indexName; } + public SqlIdentifier getOriginIndexName() { + return originIndexName; + } + public String getSourceSql() { return sourceSql; } @@ -89,5 +87,11 @@ public SqlIdentifier getOriginTableName() { } @Override - public boolean supportFileStorage() { return true;} + public boolean supportFileStorage() { + return true; + } + + public SqlAlterTableDropIndex replaceIndexName(SqlIdentifier newIndexName) { + return new SqlAlterTableDropIndex(tableName, newIndexName, originIndexName, sourceSql, pos); + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableImportTableSpace.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableImportTableSpace.java new file mode 100644 index 000000000..985414b5f --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableImportTableSpace.java @@ -0,0 +1,102 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.List; + +/** + * Created by luoyanxin. + * + * @author luoyanxin + */ +public class SqlAlterTableImportTableSpace extends SqlDdl { + /** + * Creates a SqlDdl. + */ + private static final SqlOperator OPERATOR = new SqlAlterTableImportTableSpaceOperator(); + private SqlIdentifier tableName; + private final String sourceSql; + + public SqlAlterTableImportTableSpace(SqlParserPos pos, SqlIdentifier tableName, + String sourceSql) { + super(OPERATOR, pos); + this.tableName = tableName; + this.sourceSql = sourceSql; + } + + @Override + public List getOperandList() { + return ImmutableList.of(); + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public String toString() { + return sourceSql; + } + + public String getSourceSql() { + return sourceSql; + } + + public SqlIdentifier getTableName() { + return tableName; + } + + @Override + public SqlNode getTargetTable() { + return tableName; + } + + public static class SqlAlterTableImportTableSpaceOperator extends SqlSpecialOperator { + + public SqlAlterTableImportTableSpaceOperator() { + super("ALTER_TABLE_IMPORT_TABLESPACE", SqlKind.ALTER_TABLE_IMPORT_TABLESPACE); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + final RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("ALTER_TABLE_IMPORT_TABLESPACE_RESULT", + 0, + columnType))); + } + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.print(toString()); + } + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableRepartition.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableRepartition.java index 390326f4b..17d8e1d13 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableRepartition.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableRepartition.java @@ -70,6 +70,7 @@ static public SqlAlterTableRepartition create(SqlAlterTablePartitionKey sqlAlter sqlAlterTablePartitionKey.getAlters(), null, false, null, null); sqlAlterPartitionTableRepartition.setBroadcast(sqlAlterTablePartitionKey.isBroadcast()); sqlAlterPartitionTableRepartition.setSingle(sqlAlterTablePartitionKey.isSingle()); + sqlAlterPartitionTableRepartition.setTargetImplicitTableGroupName(sqlAlterTablePartitionKey.getTargetImplicitTableGroupName()); return sqlAlterPartitionTableRepartition; } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableSetTableGroup.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableSetTableGroup.java index 9d38c5063..a138c7569 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableSetTableGroup.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAlterTableSetTableGroup.java @@ -35,13 +35,16 @@ public class SqlAlterTableSetTableGroup extends SqlCreate { final String targetTableGroup; final List objectNames; final boolean force; + final boolean implicit; - public SqlAlterTableSetTableGroup(List objectNames, SqlIdentifier tableName, String targetTableGroup, String sql, SqlParserPos pos, boolean force){ + public SqlAlterTableSetTableGroup(List objectNames, SqlIdentifier tableName, String targetTableGroup, + String sql, SqlParserPos pos, boolean implicit, boolean force) { super(OPERATOR, SqlParserPos.ZERO, false, false); this.name = tableName; this.sourceSql = sql; this.targetTableGroup = targetTableGroup; this.objectNames = objectNames; + this.implicit = implicit; this.force = force; } @@ -61,6 +64,10 @@ public boolean isForce() { return force; } + public boolean isImplicit() { + return implicit; + } + @Override public List getOperandList() { return Arrays.asList(name); diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAsOf57Operator.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAsOf57Operator.java new file mode 100644 index 000000000..0f2737765 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlAsOf57Operator.java @@ -0,0 +1,65 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import org.apache.calcite.sql.type.InferTypes; +import org.apache.calcite.sql.type.OperandTypes; +import org.apache.calcite.sql.type.ReturnTypes; +import org.apache.calcite.sql.type.SqlOperandTypeChecker; +import org.apache.calcite.sql.type.SqlOperandTypeInference; +import org.apache.calcite.sql.type.SqlReturnTypeInference; + +public class SqlAsOf57Operator extends SqlSpecialOperator { + public SqlAsOf57Operator() { + this( + "AS OF TSO", + SqlKind.AS_OF, + 20, + true, + ReturnTypes.ARG0, + InferTypes.RETURN_TYPE, + OperandTypes.ANY_ANY); + } + + protected SqlAsOf57Operator(String name, SqlKind kind, int prec, + boolean leftAssoc, SqlReturnTypeInference returnTypeInference, + SqlOperandTypeInference operandTypeInference, + SqlOperandTypeChecker operandTypeChecker) { + super(name, kind, prec, leftAssoc, returnTypeInference, + operandTypeInference, operandTypeChecker); + } + + public void unparse( + SqlWriter writer, + SqlCall call, + int leftPrec, + int rightPrec) { + assert call.operandCount() >= 2; + final SqlWriter.Frame frame = + writer.startList( + SqlWriter.FrameTypeEnum.SIMPLE); + call.operand(0).unparse(writer, leftPrec, getLeftPrec()); + final boolean needsSpace = true; + writer.setNeedWhitespace(needsSpace); + if (writer.getDialect().allowsAsOf()) { + writer.sep("AS OF TSO"); + writer.setNeedWhitespace(needsSpace); + } + call.operand(1).unparse(writer, getRightPrec(), rightPrec); + writer.endList(frame); + } +} \ No newline at end of file diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCall.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCall.java index baee8906c..680f90ee5 100755 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCall.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCall.java @@ -253,6 +253,17 @@ public boolean isCountStar() { return false; } + public boolean isCountLiteral() { + if (getOperator().isName("COUNT") && operandCount() == 1) { + final SqlNode parm = operand(0); + if (parm instanceof SqlNumericLiteral) { + return true; + } + } + + return false; + } + /** * Test to see if it is the function CHECK_SUM(*) * @@ -271,6 +282,24 @@ public boolean isCheckSumStar() { return false; } + /** + * Test to see if it is the function CHECK_SUM_V2(*) + * + * @return boolean true if function call to CHECK_SUM_V2(*) + */ + public boolean isCheckSumV2Star() { + if (getOperator().isName("CHECK_SUM_V2") && operandCount() == 1) { + final SqlNode parm = operand(0); + if (parm instanceof SqlIdentifier) { + SqlIdentifier id = (SqlIdentifier) parm; + if (id.isStar() && id.names.size() == 1) { + return true; + } + } + } + return false; + } + public SqlLiteral getFunctionQuantifier() { return null; } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCancelReplicaCheck.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCancelReplicaCheck.java new file mode 100644 index 000000000..feff9ae08 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCancelReplicaCheck.java @@ -0,0 +1,98 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author yudong + * @since 2023/11/9 11:10 + **/ +public class SqlCancelReplicaCheck extends SqlDal { + + private static final SqlSpecialOperator OPERATOR = new SqlCancelReplicaCheckOperator(); + + private SqlNode dbName; + private SqlNode tableName; + + public SqlCancelReplicaCheck(SqlParserPos pos, SqlNode dbName) { + super(pos); + this.dbName = dbName; + } + + public SqlCancelReplicaCheck(SqlParserPos pos, SqlNode dbName, SqlNode tableName) { + super(pos); + this.dbName = dbName; + this.tableName = tableName; + } + + public SqlNode getDbName() { + return dbName; + } + + public void setDbName(SqlNode dbName) { + this.dbName = dbName; + } + + public SqlNode getTableName() { + return tableName; + } + + public void setTableName(SqlNode tableName) { + this.tableName = tableName; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CHECK REPLICA TABLE"); + dbName.unparse(writer, 0, 0); + if (tableName != null) { + writer.print("."); + tableName.unparse(writer, 0, 0); + } + writer.keyword("CANCEL"); + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + public static class SqlCancelReplicaCheckOperator extends SqlSpecialOperator { + + public SqlCancelReplicaCheckOperator() { + super("CANCEL_REPLICA_CHECK", SqlKind.CANCEL_REPLICA_CHECK); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + List columns = new LinkedList<>(); + columns.add(new RelDataTypeFieldImpl("RESULT", 0, typeFactory.createSqlType(SqlTypeName.INTEGER))); + return typeFactory.createStructType(columns); + } + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCheckColumnarIndex.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCheckColumnarIndex.java new file mode 100644 index 000000000..b6c8273d2 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCheckColumnarIndex.java @@ -0,0 +1,171 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.alibaba.polardbx.common.utils.TStringUtil; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class SqlCheckColumnarIndex extends SqlDdl { // Use DDL here to utilize async DDL framework. + + private static final SqlSpecialOperator OPERATOR = new SqlCheckColumnarIndex.SqlCheckColumnarIndexOperator(); + + private SqlIdentifier indexName; + private SqlIdentifier tableName; + private String extraCmd; + + public SqlCheckColumnarIndex(SqlParserPos pos, SqlIdentifier indexName, SqlIdentifier tableName, String extraCmd) { + super(OPERATOR, pos); + this.name = indexName; + this.indexName = indexName; + this.tableName = tableName; + this.extraCmd = extraCmd; + } + + public SqlIdentifier getIndexName() { + return indexName; + } + + public void setIndexName(SqlIdentifier indexName) { + this.indexName = indexName; + } + + public SqlIdentifier getTableName() { + return tableName; + } + + public void setTableName(SqlIdentifier tableName) { + this.tableName = tableName; + } + + public String getExtraCmd() { + return extraCmd; + } + + public void setExtraCmd(String extraCmd) { + this.extraCmd = extraCmd; + } + + public CheckCciExtraCmd getExtraCmdEnum() { + return CheckCciExtraCmd.of(this.extraCmd); + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + final SqlWriter.Frame selectFrame = writer.startList(SqlWriter.FrameTypeEnum.SELECT); + writer.sep("CHECK COLUMNAR INDEX"); + + if (indexName != null) { + indexName.unparse(writer, leftPrec, rightPrec); + } + + if (tableName != null) { + writer.sep("ON"); + tableName.unparse(writer, leftPrec, rightPrec); + } + + if (extraCmd != null) { + writer.sep(extraCmd); + } + + writer.endList(selectFrame); + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public List getOperandList() { + return Arrays.asList(name); + } + + @Override + public SqlKind getKind() { + return SqlKind.CHECK_COLUMNAR_INDEX; + } + + @Override + public void validate(SqlValidator validator, SqlValidatorScope scope) { + } + + public static class SqlCheckColumnarIndexOperator extends SqlSpecialOperator { + + public SqlCheckColumnarIndexOperator() { + super("CHECK_COLUMNAR_INDEX", SqlKind.CHECK_COLUMNAR_INDEX); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + List columns = new LinkedList<>(); + columns.add(new RelDataTypeFieldImpl("Table", 0, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + columns.add(new RelDataTypeFieldImpl("Op", 1, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + columns.add(new RelDataTypeFieldImpl("Msg_type", 2, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + columns.add(new RelDataTypeFieldImpl("Msg_text", 3, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + + return typeFactory.createStructType(columns); + } + } + + @Override + public SqlNode clone(SqlParserPos pos) { + return new SqlCheckColumnarIndex(this.pos, indexName, tableName, extraCmd); + } + + public SqlCheckColumnarIndex replaceIndexName(SqlIdentifier newIndexName) { + return new SqlCheckColumnarIndex(pos, newIndexName, tableName, extraCmd); + } + + public boolean withTableName() { + return null != tableName; + } + + public enum CheckCciExtraCmd { + UNKNOWN, DEFAULT, CHECK, LOCK, CLEAR, SHOW, META; + private static final Map VALUE_MAP = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + + static { + VALUE_MAP.put("CHECK", CHECK); + VALUE_MAP.put("LOCK", LOCK); + VALUE_MAP.put("CLEAR", CLEAR); + VALUE_MAP.put("SHOW", SHOW); + VALUE_MAP.put("META", META); + } + + public static CheckCciExtraCmd of(String stringVal) { + if (TStringUtil.isBlank(stringVal)) { + return DEFAULT; + } + + return VALUE_MAP.getOrDefault(stringVal, UNKNOWN); + } + } + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCheckColumnarPartition.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCheckColumnarPartition.java new file mode 100644 index 000000000..c5d79be6f --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCheckColumnarPartition.java @@ -0,0 +1,101 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import java.util.LinkedList; +import java.util.List; + +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +public class SqlCheckColumnarPartition extends SqlDal { + + private static final SqlSpecialOperator OPERATOR = new SqlCheckColumnarPartitionOperator(); + + private SqlNode tableName; + + public SqlCheckColumnarPartition(SqlParserPos pos, SqlNode tableName) { + super(pos); + this.tableName = tableName; + } + + public SqlNode getTableName() { + return tableName; + } + + public void setTableNames(SqlNode tableName) { + this.tableName = tableName; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + final SqlWriter.Frame selectFrame = writer.startList(SqlWriter.FrameTypeEnum.SELECT); + writer.sep("CHECK COLUMNAR PARTITION"); + tableName.unparse(writer, leftPrec, rightPrec); + writer.endList(selectFrame); + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public SqlKind getKind() { + return SqlKind.CHECK_COLUMNAR_PARTITION; + } + + @Override + public void validate(SqlValidator validator, SqlValidatorScope scope) { + } + + public static class SqlCheckColumnarPartitionOperator extends SqlSpecialOperator { + + public SqlCheckColumnarPartitionOperator() { + super("CHECK_COLUMNAR_PARTITION", SqlKind.CHECK_COLUMNAR_PARTITION); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + List columns = new LinkedList<>(); + columns.add(new RelDataTypeFieldImpl("Logical Table", 0, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + columns.add(new RelDataTypeFieldImpl("Columnar Index", 1, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + columns.add(new RelDataTypeFieldImpl("Partition", 2, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + columns.add( + new RelDataTypeFieldImpl("Orc Files", 3, typeFactory.createSqlType(SqlTypeName.INTEGER_UNSIGNED))); + columns.add( + new RelDataTypeFieldImpl("Orc Rows", 4, typeFactory.createSqlType(SqlTypeName.BIGINT_UNSIGNED))); + columns.add( + new RelDataTypeFieldImpl("Csv Files", 5, typeFactory.createSqlType(SqlTypeName.INTEGER_UNSIGNED))); + columns.add( + new RelDataTypeFieldImpl("Csv Rows", 6, typeFactory.createSqlType(SqlTypeName.BIGINT_UNSIGNED))); + columns.add(new RelDataTypeFieldImpl("Extra", 7, typeFactory.createSqlType(SqlTypeName.VARCHAR))); + return typeFactory.createStructType(columns); + } + } + + @Override + public SqlNode clone(SqlParserPos pos) { + return new SqlCheckColumnarPartition(this.pos, tableName); + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlClearFileStorage.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlClearFileStorage.java new file mode 100644 index 000000000..b86bc6620 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlClearFileStorage.java @@ -0,0 +1,90 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.ArrayList; +import java.util.List; + +public class SqlClearFileStorage extends SqlDdl { + + private static final SqlOperator OPERATOR = new SqlClearFilesStorageOperator(); + + /** + * Creates a SqlDdl. + */ + public SqlClearFileStorage(SqlIdentifier name) { + super(OPERATOR, SqlParserPos.ZERO); + this.name = name; + } + + @Override + public List getOperandList() { + return ImmutableList. of(name); + } + + public SqlIdentifier getName() { + return (SqlIdentifier) name; + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public SqlKind getKind() { + return SqlKind.CLEAR_FILESTORAGE; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword(getOperator().getName()); + name.unparse(writer, leftPrec, rightPrec); + } + + @Override + public void validate(SqlValidator validator, SqlValidatorScope scope) { + validator.validateDdl(this, validator.getUnknownType(), scope); + } + + public static class SqlClearFilesStorageOperator extends SqlSpecialOperator { + public SqlClearFilesStorageOperator() { + super("CLEAR FILESTORAGE", SqlKind.CLEAR_FILESTORAGE); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + List columns = new ArrayList<>(); + columns.add(new RelDataTypeFieldImpl( + "Clear_File_Storage_Count", + 0, + typeFactory.createSqlType(SqlTypeName.INTEGER_UNSIGNED) + )); + return typeFactory.createStructType(columns); + } + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlColumnDeclaration.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlColumnDeclaration.java index 7e3f1ecdc..491aad42c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlColumnDeclaration.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlColumnDeclaration.java @@ -87,6 +87,8 @@ public class SqlColumnDeclaration extends SqlCall { */ private final ColumnStrategy strategy; + private String securedWith; + /** * * data_type [NOT NULL | NULL] [DEFAULT {literal | (expr)} ] @@ -389,6 +391,14 @@ public SqlCall getGeneratedAlwaysExpr() { public ColumnStrategy getStrategy() { return strategy; } + + public String getSecuredWith() { + return securedWith; + } + + public void setSecuredWith(String securedWith) { + this.securedWith = securedWith; + } } // End SqlColumnDeclaration.java diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlContinueReplicaCheck.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlContinueReplicaCheck.java new file mode 100644 index 000000000..c8e2cb929 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlContinueReplicaCheck.java @@ -0,0 +1,97 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author yudong + * @since 2023/11/9 11:10 + **/ +public class SqlContinueReplicaCheck extends SqlDal { + private static final SqlSpecialOperator OPERATOR = new SqlContinueReplicaCheckOperator(); + + private SqlNode dbName; + private SqlNode tableName; + + public SqlContinueReplicaCheck(SqlParserPos pos, SqlNode dbName) { + super(pos); + this.dbName = dbName; + } + + public SqlContinueReplicaCheck(SqlParserPos pos, SqlNode dbName, SqlNode tableName) { + super(pos); + this.dbName = dbName; + this.tableName = tableName; + } + + public SqlNode getDbName() { + return dbName; + } + + public void setDbName(SqlNode dbName) { + this.dbName = dbName; + } + + public SqlNode getTableName() { + return tableName; + } + + public void setTableName(SqlNode tableName) { + this.tableName = tableName; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CHECK REPLICA TABLE"); + dbName.unparse(writer, 0, 0); + if (tableName != null) { + writer.print("."); + tableName.unparse(writer, 0, 0); + } + writer.keyword("CONTINUE"); + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + public static class SqlContinueReplicaCheckOperator extends SqlSpecialOperator { + + public SqlContinueReplicaCheckOperator() { + super("CONTINUE_REPLICA_CHECK", SqlKind.CONTINUE_REPLICA_CHECK); + } + + @Override + public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { + final RelDataTypeFactory typeFactory = validator.getTypeFactory(); + Listcolumns = new LinkedList<>(); + columns.add(new RelDataTypeFieldImpl("RESULT", 0, typeFactory.createSqlType(SqlTypeName.INTEGER))); + return typeFactory.createStructType(columns); + } + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlConvertAllSequences.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlConvertAllSequences.java index a1c107f55..cf363751d 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlConvertAllSequences.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlConvertAllSequences.java @@ -17,9 +17,13 @@ package org.apache.calcite.sql; import com.alibaba.polardbx.common.constants.SequenceAttribute.Type; +import com.alibaba.polardbx.gms.topology.SystemDbHelper; import org.apache.calcite.sql.parser.SqlParserPos; -public class SqlConvertAllSequences extends SqlDal { +import java.util.Arrays; +import java.util.List; + +public class SqlConvertAllSequences extends SqlDdl { private static final SqlSpecialOperator OPERATOR = new SqlAffectedRowsOperator("CONVERT_ALL_SEQUENCES", SqlKind.CONVERT_ALL_SEQUENCES); @@ -31,7 +35,7 @@ public class SqlConvertAllSequences extends SqlDal { public SqlConvertAllSequences(SqlParserPos pos, Type fromType, Type toType, String schemaName, boolean allSchemata) { - super(pos); + super(OPERATOR, SqlParserPos.ZERO); this.fromType = fromType; this.toType = toType; this.schemaName = schemaName; @@ -43,7 +47,7 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { final SqlWriter.Frame selectFrame = writer.startList(SqlWriter.FrameTypeEnum.SELECT); writer.keyword("CONVERT ALL SEQUENCES FROM"); writer.print(fromType.name()); - writer.keyword("TO"); + writer.keyword(" TO"); writer.print(toType.name()); if (!allSchemata) { writer.keyword("FOR"); @@ -73,6 +77,11 @@ public SqlOperator getOperator() { return OPERATOR; } + @Override + public List getOperandList() { + return Arrays.asList(); + } + @Override public SqlKind getKind() { return SqlKind.CONVERT_ALL_SEQUENCES; diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreate.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreate.java index 2fa500347..d2325616c 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreate.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreate.java @@ -88,6 +88,14 @@ public boolean createGsi() { return false; } + public boolean createCci() { + return false; + } + + public boolean createGsiOrCci() { + return createGsi() || createCci(); + } + } // End SqlCreate.java diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateIndex.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateIndex.java index 85ddab95b..e9fbb4dd4 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateIndex.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateIndex.java @@ -16,6 +16,8 @@ package org.apache.calcite.sql; +import com.alibaba.polardbx.common.ColumnarTableOptions; +import com.alibaba.polardbx.common.utils.GeneralUtil; import com.alibaba.polardbx.druid.sql.SQLUtils; import com.alibaba.polardbx.druid.sql.ast.SQLExpr; import com.alibaba.polardbx.druid.sql.ast.SQLStatement; @@ -24,7 +26,6 @@ import com.alibaba.polardbx.druid.sql.dialect.mysql.ast.statement.MySqlStatement; import com.alibaba.polardbx.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor; import com.alibaba.polardbx.druid.util.JdbcConstants; -import com.alibaba.polardbx.common.utils.GeneralUtil; import org.apache.calcite.sql.SqlIndexDefinition.SqlIndexResiding; import org.apache.calcite.sql.SqlIndexDefinition.SqlIndexType; import org.apache.calcite.sql.SqlWriter.Frame; @@ -34,10 +35,13 @@ import org.apache.calcite.sql.pretty.SqlPrettyWriter; import org.apache.calcite.sql.util.SqlString; import org.apache.calcite.util.ImmutableNullableList; +import org.apache.commons.collections.CollectionUtils; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -53,6 +57,10 @@ public class SqlCreateIndex extends SqlCreate { private final SqlIdentifier originTableName; private final SqlIdentifier indexName; + /** + * Index name without suffix + */ + private final SqlIdentifier originIndexName; private final List columns; private final SqlIndexConstraintType constraintType; private final SqlIndexResiding indexResiding; @@ -61,29 +69,58 @@ public class SqlCreateIndex extends SqlCreate { private final SqlIndexAlgorithmType algorithm; private final SqlIndexLockType lock; private final List covering; + private final List originCovering; + private final List clusteredKeys; private final SqlNode dbPartitionBy; private final SqlNode dbPartitions = null; private final SqlNode tbPartitionBy; private final SqlNode tbPartitions; private final SqlNode partitioning; + private final SqlNode originPartitioning; private final String sourceSql; + private final boolean clusteredIndex; + private final boolean columnarIndex; + private final SqlNode tableGroupName; + private final SqlNode engineName; + private final List dictColumns; //originalSql is the same as what user input, while sourceSql maybe rewrite private String originalSql; private String primaryTableDefinition; private SqlCreateTable primaryTableNode; - private final boolean clusteredIndex; - private final SqlNode tableGroupName; + private final boolean withImplicitTableGroup; private boolean visible = true; - private SqlCreateIndex(SqlParserPos pos, SqlIdentifier indexName, SqlIdentifier table, - List columns, SqlIndexConstraintType constraintType, - SqlIndexResiding indexResiding, SqlIndexType indexType, List options, - SqlIndexAlgorithmType algorithm, SqlIndexLockType lock, List covering, - SqlNode dbPartitionBy, SqlNode tbPartitionBy, SqlNode tbPartitions, SqlNode partitioning, - String sourceSql, boolean clusteredIndex, SqlNode tableGroupName, boolean visible) { + private SqlCreateIndex(SqlParserPos pos, + SqlIdentifier indexName, + SqlIdentifier originIndexName, + SqlIdentifier table, + List columns, + SqlIndexConstraintType constraintType, + SqlIndexResiding indexResiding, + SqlIndexType indexType, + List options, + SqlIndexAlgorithmType algorithm, + SqlIndexLockType lock, + List covering, + List originCovering, + SqlNode dbPartitionBy, + SqlNode tbPartitionBy, + SqlNode tbPartitions, + SqlNode partitioning, + SqlNode originPartitioning, + List clusteredKeys, + String sourceSql, + boolean clusteredIndex, + boolean columnarIndex, + SqlNode tableGroupName, + boolean withImplicitTableGroup, + SqlNode engineName, + List dictColumns, + boolean visible) { super(OPERATOR, pos, false, false); this.indexName = indexName; + this.originIndexName = originIndexName; this.name = table; this.originTableName = table; this.columns = columns; @@ -94,28 +131,60 @@ private SqlCreateIndex(SqlParserPos pos, SqlIdentifier indexName, SqlIdentifier this.algorithm = algorithm; this.lock = lock; this.covering = covering; + this.originCovering = originCovering; this.dbPartitionBy = dbPartitionBy; this.tbPartitionBy = tbPartitionBy; this.tbPartitions = tbPartitions; this.partitioning = partitioning; + this.originPartitioning = originPartitioning; + this.clusteredKeys = clusteredKeys; this.sourceSql = sourceSql; this.clusteredIndex = clusteredIndex; + this.columnarIndex = columnarIndex; this.tableGroupName = tableGroupName; + this.withImplicitTableGroup = withImplicitTableGroup; + this.engineName = engineName; + this.dictColumns = dictColumns; this.visible = visible; } - public SqlCreateIndex(SqlParserPos pos, boolean replace, boolean ifNotExists, SqlIdentifier originTableName, - SqlIdentifier indexName, List columns, - SqlIndexConstraintType constraintType, SqlIndexResiding indexResiding, - SqlIndexType indexType, List options, SqlIndexAlgorithmType algorithm, - SqlIndexLockType lock, List covering, SqlNode dbPartitionBy, - SqlNode tbPartitionBy, SqlNode tbPartitions, SqlNode partitioning, - String sourceSql, String primaryTableDefinition, - SqlCreateTable primaryTableNode, boolean clusteredIndex, - SqlNode tableGroupName, boolean visible) { + public SqlCreateIndex(SqlParserPos pos, + boolean replace, + boolean ifNotExists, + SqlNode name, + SqlIdentifier originTableName, + SqlIdentifier indexName, + SqlIdentifier originIndexName, + List columns, + SqlIndexConstraintType constraintType, + SqlIndexResiding indexResiding, + SqlIndexType indexType, + List options, + SqlIndexAlgorithmType algorithm, + SqlIndexLockType lock, + List covering, + List originCovering, + SqlNode dbPartitionBy, + SqlNode tbPartitionBy, + SqlNode tbPartitions, + SqlNode partitioning, + SqlNode originPartitioning, + List clusteredKeys, + String sourceSql, + String primaryTableDefinition, + SqlCreateTable primaryTableNode, + boolean clusteredIndex, + boolean columnarIndex, + SqlNode tableGroupName, + boolean withImplicitTableGroup, + SqlNode engineName, + List dictColumns, + boolean visible) { super(OPERATOR, pos, replace, ifNotExists); + this.name = name; this.originTableName = originTableName; this.indexName = indexName; + this.originIndexName = originIndexName; this.columns = columns; this.constraintType = constraintType; this.indexResiding = indexResiding; @@ -124,25 +193,35 @@ public SqlCreateIndex(SqlParserPos pos, boolean replace, boolean ifNotExists, Sq this.algorithm = algorithm; this.lock = lock; this.covering = covering; + this.originCovering = originCovering; this.dbPartitionBy = dbPartitionBy; this.tbPartitionBy = tbPartitionBy; this.tbPartitions = tbPartitions; + this.clusteredKeys = clusteredKeys; this.sourceSql = sourceSql; this.primaryTableDefinition = primaryTableDefinition; this.primaryTableNode = primaryTableNode; this.clusteredIndex = clusteredIndex; + this.columnarIndex = columnarIndex; this.partitioning = partitioning; + this.originPartitioning = originPartitioning; this.tableGroupName = tableGroupName; + this.withImplicitTableGroup = withImplicitTableGroup; + this.engineName = engineName; + this.dictColumns = dictColumns; this.visible = visible; } public static SqlCreateIndex createLocalIndex(SqlIdentifier indexName, SqlIdentifier tableName, List columns, + SqlNode tableGroupName, + boolean withImplicitTableGroup, SqlIndexConstraintType constraintType, boolean explicit, SqlIndexType indexType, List options, SqlIndexAlgorithmType algorithm, SqlIndexLockType lock, String sql, SqlParserPos pos) { return new SqlCreateIndex(pos, + indexName, indexName, tableName, columns, @@ -157,8 +236,15 @@ public static SqlCreateIndex createLocalIndex(SqlIdentifier indexName, SqlIdenti null, null, null, + null, + null, + null, sql, false, + false, + tableGroupName, + withImplicitTableGroup, + null, null, true); } @@ -170,8 +256,10 @@ public static SqlCreateIndex createGlobalIndex(SqlParserPos pos, SqlIdentifier i SqlIndexLockType lock, List covering, SqlNode dbPartitionBy, SqlNode tbPartitionBy, SqlNode tbPartitions, SqlNode partitioning, String sourceSql, SqlNode tableGroupName, + boolean withImplicitTableGroup, boolean visible) { return new SqlCreateIndex(pos, + indexName, indexName, table, columns, @@ -182,13 +270,20 @@ public static SqlCreateIndex createGlobalIndex(SqlParserPos pos, SqlIdentifier i algorithm, lock, covering, + covering, dbPartitionBy, tbPartitionBy, tbPartitions, partitioning, + partitioning, + null, sourceSql, false, + false, tableGroupName, + withImplicitTableGroup, + null, + null, visible); } @@ -200,8 +295,53 @@ public static SqlCreateIndex createClusteredIndex(SqlParserPos pos, SqlIdentifie SqlNode dbPartitionBy, SqlNode tbPartitionBy, SqlNode tbPartitions, SqlNode partitioning, String sourceSql, - SqlNode tableGroupName, boolean visible) { + SqlNode tableGroupName, + boolean withImplicitTableGroup, boolean visible) { + return new SqlCreateIndex(pos, + indexName, + indexName, + table, + columns, + constraintType, + SqlIndexResiding.GLOBAL, + indexType, + options, + algorithm, + lock, + covering, + covering, + dbPartitionBy, + tbPartitionBy, + tbPartitions, + partitioning, + partitioning, + null, + sourceSql, + true, + false, + tableGroupName, + withImplicitTableGroup, + null, + null, + visible); + } + + public static SqlCreateIndex createColumnarIndex(SqlParserPos pos, SqlIdentifier indexName, SqlIdentifier table, + List columns, + SqlIndexConstraintType constraintType, SqlIndexType indexType, + List options, SqlIndexAlgorithmType algorithm, + SqlIndexLockType lock, List covering, + SqlNode dbPartitionBy, SqlNode tbPartitionBy, + SqlNode tbPartitions, + SqlNode partitioning, List clusteredKeys, + String sourceSql, + SqlNode tableGroupName, + boolean withImplicitTableGroup, + SqlNode engineName, + List dictKeys, + boolean visible) { return new SqlCreateIndex(pos, + indexName, indexName, table, columns, @@ -212,16 +352,31 @@ public static SqlCreateIndex createClusteredIndex(SqlParserPos pos, SqlIdentifie algorithm, lock, covering, + covering, dbPartitionBy, tbPartitionBy, tbPartitions, partitioning, + partitioning, + clusteredKeys, sourceSql, true, + true, tableGroupName, + withImplicitTableGroup, + engineName, + dictKeys, visible); } + public SqlNode getEngineName() { + return engineName; + } + + public List getDictColumns() { + return dictColumns; + } + @Override public List getOperandList() { return ImmutableNullableList.of(name, @@ -241,7 +396,7 @@ public List getOperandList() { @Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { - unparse(writer, leftPrec, rightPrec, this.indexResiding, false); + unparse(writer, leftPrec, rightPrec, this.indexResiding, false, false); } @Override @@ -253,8 +408,13 @@ public boolean createClusteredIndex() { return clusteredIndex; } + @Override + public boolean createCci() { + return columnarIndex; + } + public void unparse(SqlWriter writer, int leftPrec, int rightPrec, SqlIndexResiding indexResiding, - boolean withOriginTableName) { + boolean withOriginTableName, boolean withOriginNames) { final boolean isGlobal = SqlUtil.isGlobal(indexResiding); final SqlWriter.Frame frame = writer.startList(SqlWriter.FrameTypeEnum.SELECT, "CREATE", ""); @@ -263,12 +423,22 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec, SqlIndexResid SqlUtil.wrapSqlLiteralSymbol(constraintType).unparse(writer, leftPrec, rightPrec); } - if (isGlobal) { + if (clusteredIndex) { + writer.keyword("CLUSTERED"); + } + + if (columnarIndex) { + writer.keyword("COLUMNAR"); + } else if (isGlobal) { SqlUtil.wrapSqlLiteralSymbol(indexResiding).unparse(writer, leftPrec, rightPrec); } writer.keyword("INDEX"); - indexName.unparse(writer, leftPrec, rightPrec); + if (withOriginNames) { + originIndexName.unparse(writer, leftPrec, rightPrec); + } else { + indexName.unparse(writer, leftPrec, rightPrec); + } if (null != indexType) { writer.keyword("USING"); @@ -289,13 +459,25 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec, SqlIndexResid } if (isGlobal) { - if (null != covering && !covering.isEmpty()) { + final List coveringToShow = withOriginNames ? originCovering : covering; + if (null != coveringToShow && !coveringToShow.isEmpty()) { writer.keyword("COVERING"); final Frame frame2 = writer.startList(FrameTypeEnum.FUN_CALL, "(", ")"); - SqlUtil.wrapSqlNodeList(covering).commaList(writer); + SqlUtil.wrapSqlNodeList(coveringToShow).commaList(writer); writer.endList(frame2); } + } + if (columnarIndex) { + if (clusteredKeys != null && !clusteredKeys.isEmpty()) { + writer.keyword("CLUSTERED KEY"); + final Frame frame2 = writer.startList(FrameTypeEnum.FUN_CALL, "(", ")"); + SqlUtil.wrapSqlNodeList(clusteredKeys).commaList(writer); + writer.endList(frame2); + } + } + + if (isGlobal || columnarIndex) { final boolean quoteAllIdentifiers = writer.isQuoteAllIdentifiers(); if (writer instanceof SqlPrettyWriter) { ((SqlPrettyWriter) writer).setQuoteAllIdentifiers(false); @@ -316,11 +498,23 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec, SqlIndexResid tbPartitions.unparse(writer, leftPrec, rightPrec); } + final SqlNode partitioningToShow = withOriginNames ? originPartitioning : partitioning; + if (null != partitioningToShow) { + writer.print(" "); + partitioningToShow.unparse(writer, leftPrec, rightPrec); + } + if (writer instanceof SqlPrettyWriter) { ((SqlPrettyWriter) writer).setQuoteAllIdentifiers(quoteAllIdentifiers); } } + if (columnarIndex && null != engineName) { + writer.keyword("ENGINE"); + writer.keyword("="); + engineName.unparse(writer, leftPrec, rightPrec); + } + if (null != options) { for (SqlIndexOption option : options) { option.unparse(writer, leftPrec, rightPrec); @@ -353,6 +547,10 @@ public void setTargetTable(SqlIdentifier sqlIdentifier) { } private String prepare() { + return prepare(false); + } + + private String prepare(boolean withOriginNames) { String sqlForExecute = sourceSql; if (SqlUtil.isGlobal(indexResiding)) { // generate CREATE INDEX for executing on MySQL @@ -362,7 +560,7 @@ private String prepare() { writer.setIndentation(0); final int leftPrec = getOperator().getLeftPrec(); final int rightPrec = getOperator().getRightPrec(); - unparse(writer, leftPrec, rightPrec, indexResiding, true); + unparse(writer, leftPrec, rightPrec, indexResiding, true, withOriginNames); sqlForExecute = writer.toSqlString().getSql(); } @@ -401,6 +599,10 @@ public SqlString toSqlString(SqlDialect dialect) { return new SqlString(dialect, sql); } + public String toString(boolean withOriginNames) { + return prepare(withOriginNames); + } + public SqlNode getDbPartitionBy() { return dbPartitionBy; } @@ -421,6 +623,10 @@ public SqlIdentifier getIndexName() { return indexName; } + public SqlIdentifier getOriginIndexName() { + return originIndexName; + } + public List getColumns() { return columns; } @@ -429,21 +635,16 @@ public List getCovering() { return covering; } - public SqlNode getTableGroupName() { - return tableGroupName; - } - - public static enum SqlIndexConstraintType { - UNIQUE, FULLTEXT, SPATIAL; - + public List getOriginCovering() { + return originCovering; } - public static enum SqlIndexAlgorithmType { - DEFAULT, INPLACE, COPY; + public List getClusteredKeys() { + return clusteredKeys; } - public static enum SqlIndexLockType { - DEFAULT, NONE, SHARED, EXCLUSIVE; + public SqlNode getTableGroupName() { + return tableGroupName; } public String getPrimaryTableDefinition() { @@ -506,6 +707,46 @@ public SqlNode getPartitioning() { return partitioning; } + public SqlNode getOriginPartitioning() { + return originPartitioning; + } + + @Override + public SqlNode clone(SqlParserPos pos) { + return new SqlCreateIndex(pos, + replace, + ifNotExists, + name, + originTableName, + indexName, + originIndexName, + columns, + constraintType, + indexResiding, + indexType, + options, + algorithm, + lock, + covering, + originCovering, + dbPartitionBy, + tbPartitionBy, + tbPartitions, + partitioning, + originPartitioning, + clusteredKeys, + sourceSql, + primaryTableDefinition, + primaryTableNode, + clusteredIndex, + columnarIndex, + tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, + visible); + } + public SqlCreateIndex rebuildCovering(Collection coveringColumns) { if (GeneralUtil.isEmpty(coveringColumns)) { return this; @@ -518,8 +759,10 @@ public SqlCreateIndex rebuildCovering(Collection coveringColumns) { return new SqlCreateIndex(pos, replace, ifNotExists, + name, originTableName, indexName, + originIndexName, columns, constraintType, indexResiding, @@ -528,21 +771,36 @@ public SqlCreateIndex rebuildCovering(Collection coveringColumns) { algorithm, lock, newCovering, + originCovering, dbPartitionBy, tbPartitionBy, tbPartitions, partitioning, + originPartitioning, + clusteredKeys, sourceSql, primaryTableDefinition, primaryTableNode, clusteredIndex, + columnarIndex, tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, this.visible); } - public SqlCreateIndex rebuildToGsi(SqlIdentifier newName, SqlNode dbpartition, boolean clustered) { + /** + * Rebuild gsi definition with new index name and full partition definition + * + * @param newName New index name, with random suffix + * @param dbPartition Update with full partition definition, with DBPARTITION BY appended + * @return Copied SqlIndexDefinition + */ + public SqlCreateIndex rebuildToGsi(SqlIdentifier newName, SqlNode dbPartition) { return new SqlCreateIndex(pos, null == newName ? indexName : newName, + originIndexName, originTableName, columns, constraintType, @@ -551,20 +809,35 @@ public SqlCreateIndex rebuildToGsi(SqlIdentifier newName, SqlNode dbpartition, b options, algorithm, lock, - clustered ? null : covering, - null == dbpartition ? dbPartitionBy : dbpartition, - null == dbpartition ? tbPartitionBy : null, - null == dbpartition ? tbPartitions : null, + covering, + originCovering, + null == dbPartition ? dbPartitionBy : dbPartition, + null == dbPartition ? tbPartitionBy : null, + null == dbPartition ? tbPartitions : null, partitioning, + originPartitioning, + columnarIndex ? clusteredKeys : null, sourceSql, - clustered, + clusteredIndex, + columnarIndex, tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, this.visible); } - public SqlCreateIndex rebuildToGsiNewPartition(SqlIdentifier newName, SqlNode newPartition, boolean clustered) { + /** + * Rebuild gsi definition with new index name and full partition definition + * + * @param newName New index name, with random suffix + * @param newPartition Update with full partition definition, with PARTITION BY/PARTITIONS appended + * @return Copied SqlIndexDefinition + */ + public SqlCreateIndex rebuildToGsiNewPartition(SqlIdentifier newName, SqlNode newPartition) { return new SqlCreateIndex(pos, null == newName ? indexName : newName, + originIndexName, originTableName, columns, constraintType, @@ -573,20 +846,28 @@ public SqlCreateIndex rebuildToGsiNewPartition(SqlIdentifier newName, SqlNode ne options, algorithm, lock, - clustered ? null : covering, + covering, + originCovering, null == newPartition ? dbPartitionBy : null, null == newPartition ? tbPartitionBy : null, null == newPartition ? tbPartitions : null, null == newPartition ? partitioning : newPartition, + originPartitioning, + columnarIndex ? clusteredKeys : null, sourceSql, - clustered, + clusteredIndex, + columnarIndex, tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, this.visible); } public SqlCreateIndex rebuildToExplicitLocal(SqlIdentifier newName, String sql) { return new SqlCreateIndex(pos, null == newName ? indexName : newName, + originIndexName, originTableName, columns, constraintType, @@ -600,15 +881,23 @@ public SqlCreateIndex rebuildToExplicitLocal(SqlIdentifier newName, String sql) null, null, null, + null, + null, + null, null == sql ? sourceSql : sql, false, + false, tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, this.visible); } public SqlCreateIndex replaceTableName(SqlIdentifier newTableName) { return new SqlCreateIndex(pos, indexName, + originIndexName, null == newTableName ? originTableName : newTableName, columns, constraintType, @@ -618,13 +907,81 @@ public SqlCreateIndex replaceTableName(SqlIdentifier newTableName) { algorithm, lock, covering, + originCovering, + dbPartitionBy, + tbPartitionBy, + tbPartitions, + partitioning, + originPartitioning, + clusteredKeys, + sourceSql, + clusteredIndex, + columnarIndex, + tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, + this.visible); + } + + public SqlCreateIndex replaceIndexName(SqlIdentifier newIndexName) { + return new SqlCreateIndex(pos, + null == newIndexName ? indexName : newIndexName, + originIndexName, + originTableName, + columns, + constraintType, + indexResiding, + indexType, + options, + algorithm, + lock, + covering, + originCovering, dbPartitionBy, tbPartitionBy, tbPartitions, partitioning, + originPartitioning, + clusteredKeys, sourceSql, clusteredIndex, + columnarIndex, tableGroupName, + withImplicitTableGroup, + engineName, + dictColumns, this.visible); } + + /** + * columnar index options + */ + public Map getColumnarOptions() { + Map options = new HashMap<>(); + if (CollectionUtils.isNotEmpty(dictColumns)) { + String columns = dictColumns.stream() + .map(sqlIndexColumnName -> SqlIdentifier.surroundWithBacktick(sqlIndexColumnName.getColumnNameStr())) + .collect(Collectors.joining(",")); + options.put(ColumnarTableOptions.DICTIONARY_COLUMNS, columns); + } + return options; + } + + public static enum SqlIndexConstraintType { + UNIQUE, FULLTEXT, SPATIAL; + + } + + public static enum SqlIndexAlgorithmType { + DEFAULT, INPLACE, COPY; + } + + public static enum SqlIndexLockType { + DEFAULT, NONE, SHARED, EXCLUSIVE; + } + + public boolean isWithImplicitTableGroup() { + return withImplicitTableGroup; + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityEntity.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityEntity.java new file mode 100644 index 000000000..b9005127b --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityEntity.java @@ -0,0 +1,109 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +/** + * @author pangzhaoxing + */ +public class SqlCreateSecurityEntity extends SqlDal{ + private static final SqlOperator OPERATOR = new SqlCreateSecurityEntity.SqlCreateSecurityEntityOperator(); + + private SqlIdentifier entityType; + + private SqlIdentifier entityKey; + + private SqlIdentifier entityAttr; + + public SqlCreateSecurityEntity(SqlParserPos pos, SqlIdentifier entityType, SqlIdentifier entityKey, + SqlIdentifier entityAttr) { + super(pos); + this.entityType = entityType; + this.entityKey = entityKey; + this.entityAttr = entityAttr; + } + + @Override + public SqlKind getKind() { + return SqlKind.CREATE_SECURITY_ENTITY; + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CREATE SECURITY ENTITY"); + entityType.unparse(writer, leftPrec, rightPrec); + entityKey.unparse(writer, leftPrec, rightPrec); + entityAttr.unparse(writer, leftPrec, rightPrec); + } + + public SqlIdentifier getEntityType() { + return entityType; + } + + public void setEntityType(SqlIdentifier entityType) { + this.entityType = entityType; + } + + public SqlIdentifier getEntityKey() { + return entityKey; + } + + public void setEntityKey(SqlIdentifier entityKey) { + this.entityKey = entityKey; + } + + public SqlIdentifier getEntityAttr() { + return entityAttr; + } + + public void setEntityAttr(SqlIdentifier entityAttr) { + this.entityAttr = entityAttr; + } + + public static class SqlCreateSecurityEntityOperator extends SqlSpecialOperator { + + public SqlCreateSecurityEntityOperator() { + super("CREATE_SECURITY_ENTITY", SqlKind.CREATE_SECURITY_ENTITY); + } + + @Override + public RelDataType deriveType(final SqlValidator validator, final SqlValidatorScope scope, final SqlCall call) { + RelDataTypeFactory typeFactory = validator.getTypeFactory(); + RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("CREATE_SECURITY_ENTITY", + 0, + columnType))); + } + } + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityLabel.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityLabel.java new file mode 100644 index 000000000..0227bdfc4 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityLabel.java @@ -0,0 +1,115 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author pangzhaoxing + */ +public class SqlCreateSecurityLabel extends SqlDal{ + + private static final SqlOperator OPERATOR = new SqlCreateSecurityLabelOperator(); + + private SqlIdentifier labelName; + private SqlIdentifier policyName; + private SqlCharStringLiteral labelContent; + + protected SqlCreateSecurityLabel(SqlParserPos pos) { + super(pos); + } + + public SqlCreateSecurityLabel(SqlParserPos pos, SqlIdentifier labelName, SqlIdentifier policyName, + SqlCharStringLiteral labelContent) { + super(pos); + this.labelName = labelName; + this.policyName = policyName; + this.labelContent = labelContent; + } + + @Override + public SqlKind getKind() { + return SqlKind.CREATE_SECURITY_LABEL; + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CREATE SECURITY LABEL"); + writer.keyword(policyName.toString() + "." + labelName.toString()); + labelContent.unparse(writer, leftPrec, rightPrec); + } + + public SqlIdentifier getLabelName() { + return labelName; + } + + public void setLabelName(SqlIdentifier labelName) { + this.labelName = labelName; + } + + public SqlIdentifier getPolicyName() { + return policyName; + } + + public void setPolicyName(SqlIdentifier policyName) { + this.policyName = policyName; + } + + public SqlCharStringLiteral getLabelContent() { + return labelContent; + } + + public void setLabelContent(SqlCharStringLiteral labelContent) { + this.labelContent = labelContent; + } + + public static class SqlCreateSecurityLabelOperator extends SqlSpecialOperator { + + public SqlCreateSecurityLabelOperator() { + super("CREATE_SECURITY_LABEL", SqlKind.CREATE_SECURITY_LABEL); + } + + @Override + public RelDataType deriveType(final SqlValidator validator, final SqlValidatorScope scope, final SqlCall call) { + RelDataTypeFactory typeFactory = validator.getTypeFactory(); + RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("CREATE_SECURITY_LABEL", + 0, + columnType))); + } + } + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityLabelComponent.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityLabelComponent.java new file mode 100644 index 000000000..0876276a5 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityLabelComponent.java @@ -0,0 +1,114 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; +import org.apache.commons.lang3.StringUtils; + +/** + * @author pangzhaoxing + */ +public class SqlCreateSecurityLabelComponent extends SqlDal{ + + private static final SqlOperator OPERATOR = + new SqlCreateSecurityLabelComponentOperator(); + + private SqlIdentifier componentName; + private SqlIdentifier componentType; + private SqlCharStringLiteral componentContent; + + public SqlCreateSecurityLabelComponent(SqlParserPos pos, SqlIdentifier componentName, SqlIdentifier componentType, + SqlCharStringLiteral componentContent) { + super(pos); + this.componentName = componentName; + this.componentType = componentType; + this.componentContent = componentContent; + } + + protected SqlCreateSecurityLabelComponent(SqlParserPos pos) { + super(pos); + } + + @Override + public SqlKind getKind() { + return SqlKind.CREATE_SECURITY_LABEL_COMPONENT; + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CREATE SECURITY LABEL COMPONENT"); + this.componentName.unparse(writer, leftPrec, rightPrec); + this.componentType.unparse(writer, leftPrec, rightPrec); + this.componentContent.unparse(writer, leftPrec, rightPrec); + } + + public static class SqlCreateSecurityLabelComponentOperator extends SqlSpecialOperator { + + public SqlCreateSecurityLabelComponentOperator() { + super("CREATE_SECURITY_LABEL_COMPONENT", SqlKind.CREATE_SECURITY_LABEL_COMPONENT); + } + + @Override + public RelDataType deriveType(final SqlValidator validator, final SqlValidatorScope scope, final SqlCall call) { + RelDataTypeFactory typeFactory = validator.getTypeFactory(); + RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("CREATE_SECURITY_LABEL_COMPONENT", + 0, + columnType))); + } + } + + public SqlIdentifier getComponentName() { + return componentName; + } + + public void setComponentName(SqlIdentifier componentName) { + this.componentName = componentName; + } + + public SqlIdentifier getComponentType() { + return componentType; + } + + public void setComponentType(SqlIdentifier componentType) { + this.componentType = componentType; + } + + public SqlCharStringLiteral getComponentContent() { + return componentContent; + } + + public void setComponentContent(SqlCharStringLiteral componentContent) { + this.componentContent = componentContent; + } +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityPolicy.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityPolicy.java new file mode 100644 index 000000000..94a28ef12 --- /dev/null +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateSecurityPolicy.java @@ -0,0 +1,104 @@ +/* + * Copyright [2013-2021], Alibaba Group Holding Limited + * + * Licensed 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.calcite.sql; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelDataTypeFieldImpl; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +/** + * @author pangzhaoxing + */ +public class SqlCreateSecurityPolicy extends SqlDal{ + + private static final SqlOperator OPERATOR = + new SqlCreateSecurityPolicyOperator(); + + private SqlIdentifier policyName; + private SqlCharStringLiteral policyComponents; + + protected SqlCreateSecurityPolicy(SqlParserPos pos) { + super(pos); + } + + public SqlCreateSecurityPolicy(SqlParserPos pos, SqlIdentifier policyName, SqlCharStringLiteral policyComponents) { + super(pos); + this.policyName = policyName; + this.policyComponents = policyComponents; + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CREATE SECURITY POLICY"); + this.policyName.unparse(writer, leftPrec, rightPrec); + writer.keyword("COMPONENTS"); + this.policyComponents.unparse(writer, leftPrec, rightPrec); + } + + @Override + public SqlKind getKind() { + return SqlKind.CREATE_SECURITY_POLICY; + } + + @Override + public SqlOperator getOperator() { + return OPERATOR; + } + + public SqlIdentifier getPolicyName() { + return policyName; + } + + public void setPolicyName(SqlIdentifier policyName) { + this.policyName = policyName; + } + + public SqlCharStringLiteral getPolicyComponents() { + return policyComponents; + } + + public void setPolicyComponents(SqlCharStringLiteral policyComponents) { + this.policyComponents = policyComponents; + } + + public static class SqlCreateSecurityPolicyOperator extends SqlSpecialOperator { + + public SqlCreateSecurityPolicyOperator() { + super("CREATE_SECURITY_POLICY", SqlKind.CREATE_SECURITY_POLICY); + } + + @Override + public RelDataType deriveType(final SqlValidator validator, final SqlValidatorScope scope, final SqlCall call) { + RelDataTypeFactory typeFactory = validator.getTypeFactory(); + RelDataType columnType = typeFactory.createSqlType(SqlTypeName.CHAR); + + return typeFactory.createStructType( + ImmutableList.of((RelDataTypeField) new RelDataTypeFieldImpl("CREATE_SECURITY_POLICY", + 0, + columnType))); + } + } + + + +} diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTable.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTable.java index 6d9b2c594..ca20cf251 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTable.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTable.java @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.calcite.sql; import com.alibaba.polardbx.common.ArchiveMode; @@ -39,6 +40,8 @@ import com.alibaba.polardbx.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.polardbx.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.polardbx.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.polardbx.druid.sql.ast.statement.SQLAssignItem; +import com.alibaba.polardbx.druid.sql.ast.statement.SQLCharacterDataType; import com.alibaba.polardbx.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.polardbx.druid.sql.ast.statement.SQLColumnPrimaryKey; import com.alibaba.polardbx.druid.sql.ast.statement.SQLColumnUniqueKey; @@ -155,6 +158,7 @@ public class SqlCreateTable extends SqlCreate { private List > globalKeys; private List > globalUniqueKeys; private List > clusteredKeys; + private List > columnarKeys; private List > clusteredUniqueKeys; private List > keys; private List > fullTextKeys; @@ -165,6 +169,7 @@ public class SqlCreateTable extends SqlCreate { private List logicalReferencedTables = null; private List physicalReferencedTables = null; private List addedForeignKeys; + private List isAddLogicalForeignKeyOnly; public boolean pushDownForeignKeys; /** @@ -196,13 +201,21 @@ public class SqlCreateTable extends SqlCreate { private SqlNode localPartition = null; private SqlNode tableGroupName = null; + private boolean withImplicitTableGroup = false; private SqlNode joinGroupName = null; private SQLPartitionByRange localPartitionSuffix; private Engine engine = null; private ArchiveMode archiveMode; + + private String loadTableName = null; + private String loadTableSchema = null; + private List dictColumns = null; + + private String securityPolicy; + private final static int MAX_AUTO_INDEX_LEN = 191; boolean ignore = false; @@ -210,6 +223,7 @@ public class SqlCreateTable extends SqlCreate { // use for create table replace select // different from base class‘s replace boolean replaceInto = false; + protected boolean onlyConvertTableMode = false; public void setIgnore(boolean ignore) { this.ignore = ignore; @@ -227,6 +241,14 @@ public SqlNode getAsTableName() { return asTableName; } + public boolean isOnlyConvertTableMode() { + return onlyConvertTableMode; + } + + public void setOnlyConvertTableMode(boolean onlyConvertTableMode) { + this.onlyConvertTableMode = onlyConvertTableMode; + } + public boolean isIgnore() { return ignore; } @@ -241,13 +263,22 @@ public String getLoadTableSchema() { public void setLoadTableSchema(String loadTableSchema) { this.loadTableSchema = loadTableSchema; } - private String loadTableName = null; + public String getLoadTableName() { return loadTableName; } public void setLoadTableName(String loadTableName) { this.loadTableName = loadTableName; } + + public List getDictColumns() { + return dictColumns; + } + + public void setDictColumns(List dictColumns) { + this.dictColumns = dictColumns; + } + public Engine getEngine() { return engine; } @@ -285,6 +316,14 @@ public void setEncryption(String defaultEncryption) { this.encryption = defaultEncryption; } + public String getSecurityPolicy() { + return securityPolicy; + } + + public void setSecurityPolicy(String securityPolicy) { + this.securityPolicy = securityPolicy; + } + public void setRowFormat(String rf) { rowFormat = rf; } @@ -325,6 +364,14 @@ public boolean isSelect() { return isSelect; } + public boolean isWithImplicitTableGroup() { + return withImplicitTableGroup; + } + + public void setWithImplicitTableGroup(boolean withImplicitTableGroup) { + this.withImplicitTableGroup = withImplicitTableGroup; + } + private static final SqlOperator OPERATOR = new SqlSpecialOperator("CREATE TABLE", SqlKind.CREATE_TABLE); /** @@ -368,8 +415,35 @@ public SqlCreateTable(SqlParserPos pos, boolean replace, boolean ifNotExists, Sq List > spatialKeys, List > foreignKeys, List checks, SqlIdentifier primaryKeyConstraint, boolean hasPrimaryKeyConstraint, SqlNode sqlPartition, - SqlNode localPartition, SqlNode tableGroupName, SqlNode joinGroupName, - List addedForeignKeys, String defaultCharset, String defaultCollation) { + SqlNode localPartition, + SqlNode tableGroupName, + SqlNode joinGroupName, + boolean dbPartition, + List addedForeignKeys, + List isAddLogicalForeignKeyOnly, + ArchiveMode archiveMode, + SqlNode asTableName, + boolean autoSplit, + List > clusteredKeys, + List > clusteredUniqueKeys, + List > columnarKeys, + String comment, + String defaultCharset, + String defaultCollation, + String encryption, + Engine engine, + boolean ignore, + boolean isSelect, + String loadTableSchema, + String locality, + List logicalReferencedTables, + List mappingRules, + String originalSql, + List physicalReferencedTables, + boolean pushDownForeignKeys, + boolean replaceInto, + String rowFormat, + boolean uniqueShardingKey) { super(OPERATOR, pos, replace, ifNotExists); this.name = name; this.likeTableName = likeTableName; @@ -402,9 +476,33 @@ public SqlCreateTable(SqlParserPos pos, boolean replace, boolean ifNotExists, Sq this.localPartition = localPartition; this.tableGroupName = tableGroupName; this.joinGroupName = joinGroupName; + this.DbPartition = dbPartition; this.addedForeignKeys = addedForeignKeys; + this.isAddLogicalForeignKeyOnly = isAddLogicalForeignKeyOnly; + this.archiveMode = archiveMode; + this.asTableName = asTableName; + this.autoSplit = autoSplit; + this.clusteredKeys = clusteredKeys; + this.clusteredUniqueKeys = clusteredUniqueKeys; + this.columnarKeys = columnarKeys; + this.comment = comment; this.defaultCharset = defaultCharset; this.defaultCollation = defaultCollation; + this.encryption = encryption; + this.engine = engine; + this.ignore = ignore; + this.isSelect = isSelect; + this.loadTableName = loadTableName; + this.loadTableSchema = loadTableSchema; + this.locality = locality; + this.logicalReferencedTables = logicalReferencedTables; + this.mappingRules = mappingRules; + this.originalSql = originalSql; + this.physicalReferencedTables = physicalReferencedTables; + this.pushDownForeignKeys = pushDownForeignKeys; + this.replaceInto = replaceInto; + this.rowFormat = rowFormat; + this.uniqueShardingKey = uniqueShardingKey; } public boolean shouldLoad() { @@ -423,6 +521,8 @@ public boolean shouldLoad() { || trimmedComment.equalsIgnoreCase("load_s3") || trimmedComment.equalsIgnoreCase("load_local_disk") || trimmedComment.equalsIgnoreCase("load_nfs") + || trimmedComment.equalsIgnoreCase("load_s3") + || trimmedComment.equalsIgnoreCase("load_abs") || trimmedComment.equalsIgnoreCase("load_external_disk"); } @@ -513,7 +613,7 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { String n = convertName(otherName); writer.keyword(n); } else { - writer.keyword(c.getKey().getLastName()); + writer.identifier(c.getKey().getLastName()); } c.getValue().unparse(writer, 0, 0); // throw new TddlRuntimeException(ERR_CREATE_SELECT_WITH_GSI, "create select don't support table with GSI"); @@ -532,7 +632,7 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { String n = convertName(otherName); writer.keyword(n); } else { - writer.keyword(c.getKey().getLastName()); + writer.identifier(c.getKey().getLastName()); } c.getValue().unparse(writer, 0, 0); // throw new TddlRuntimeException(ERR_CREATE_SELECT_WITH_GSI, "create select don't support table with GSI"); @@ -544,6 +644,7 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { writer.sep(","); writer.keyword("clustered"); writer.keyword("index"); + writer.identifier(c.getKey().getLastName()); c.getValue().unparse(writer, 0, 0); } } @@ -554,6 +655,18 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { writer.keyword("unique"); writer.keyword("clustered"); writer.keyword("index"); + writer.identifier(c.getKey().getLastName()); + c.getValue().unparse(writer, 0, 0); + } + } + + if (columnarKeys != null) { + for (Pair c : columnarKeys) { + writer.sep(","); + writer.keyword("clustered"); + writer.keyword("columnar"); + writer.keyword("index"); + writer.identifier(c.getKey().getLastName()); c.getValue().unparse(writer, 0, 0); } } @@ -642,6 +755,22 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { writer.keyword("BROADCAST"); } + if (tableGroupName != null) { + if (withImplicitTableGroup) { + writer.keyword("WITH TABLEGROUP="); + tableGroupName.unparse(writer, 0, 0); + writer.keyword("IMPLICIT"); + } else { + writer.keyword("TABLEGROUP="); + tableGroupName.unparse(writer, 0, 0); + } + } + + if (joinGroupName != null) { + writer.keyword("JOINGROUP="); + joinGroupName.unparse(writer, 0, 0); + } + if (engine != null) { writer.keyword("ENGINE="); writer.keyword(engine.name()); @@ -923,11 +1052,33 @@ public SqlCreateTable clone(SqlParserPos pos) { localPartition, tableGroupName, joinGroupName, + DbPartition, addedForeignKeys, + isAddLogicalForeignKeyOnly, + archiveMode, + asTableName, + autoSplit, + clusteredKeys, + clusteredUniqueKeys, + columnarKeys, + comment, defaultCharset, - defaultCollation); - ret.setEngine(engine); - ret.setDBPartition(DbPartition); + defaultCollation, + encryption, + engine, + ignore, + isSelect, + loadTableSchema, + locality, + logicalReferencedTables, + mappingRules, + originalSql, + physicalReferencedTables, + pushDownForeignKeys, + replaceInto, + rowFormat, + uniqueShardingKey); + ret.setWithImplicitTableGroup(withImplicitTableGroup); return ret; } @@ -967,7 +1118,7 @@ public MySqlStatement rewriteForGsi() { }); addIndex(shardKeys, stmt, uniqueShardingKey); - } else if (sqlPartition != null) { + } else if (sqlPartition != null || createCci()) { // Patch for implicit pk if needed. colDefs.stream() .filter(pair -> pair.left.getLastName().equalsIgnoreCase(IMPLICIT_COL_NAME)) @@ -993,7 +1144,7 @@ public MySqlStatement rewriteForGsi() { addLocalPartitionSuffix(stmt); } stmt.setBroadCast(false); - removeSequenceAndGsi(stmt); + removePolarDBXExclusiveFeature(stmt); stmt.setDbPartitionBy(null); stmt.setDbPartitions(null); @@ -1017,60 +1168,40 @@ public MySqlStatement rewrite() { removeFKs.add(sqlTableElement); } } - for (ForeignKeyData foreignKeyData : getAddedForeignKeys()) { - Set foreignKeys = new LinkedHashSet<>(foreignKeyData.columns); - - addForeignKeyIndex(foreignKeys, stmt, uniqueShardingKey, foreignKeyData); + for (int i = 0; i < addedForeignKeys.size(); i++) { + if (GeneralUtil.isNotEmpty(isAddLogicalForeignKeyOnly) && !isAddLogicalForeignKeyOnly.get(i)) { + Set foreignKeys = new LinkedHashSet<>(addedForeignKeys.get(i).columns); + addForeignKeyIndex(foreignKeys, stmt, uniqueShardingKey, addedForeignKeys.get(i)); + } } stmt.getTableElementList().removeAll(removeFKs); } if (dbpartitionBy != null) { + // fetch dbShardKeys for drdsTbl shardKeys = getShardingKeys(dbpartitionBy, shardKeys); } - if (tbpartitionBy != null) { + // fetch tbShardKeys for drdsTbl getShardingKeys(tbpartitionBy, shardKeys); } if (sqlPartition != null) { + // fetch partkeys and subpartKeys for partTbl getPartitionKeys(sqlPartition, shardKeys, subPartKeys); } // Remove implicit pk in shard keys, because it must be primary key. shardKeys.removeIf(SqlValidatorImpl::isImplicitKey); - boolean useSubPartBy = false; - boolean subPartKeyContainAllPartKeyAsPrefixCols = false; - if (subPartKeys != null && subPartKeys.size() > 0) { - useSubPartBy = true; - List partKeyList = shardKeys.stream().collect(Collectors.toList()); - List subPartKeyList = subPartKeys.stream().collect(Collectors.toList()); - subPartKeyContainAllPartKeyAsPrefixCols = checkIfContainPrefixPartCols(subPartKeyList, partKeyList); - } - if (shardKeys.size() > 0) { - if (!(useSubPartBy && subPartKeyContainAllPartKeyAsPrefixCols)) { - if (sqlPartition == null) { - addIndex(shardKeys, stmt, uniqueShardingKey); - } else { - addCompositeIndex(shardKeys, stmt); - } - } - if (useSubPartBy) { - addCompositeIndex(subPartKeys, stmt); - } + // add local indexes for shard keys + addLocalIndexesForShardKeys(stmt, shardKeys, subPartKeys); -// if (sqlPartition == null || shardKeys.size() == 1) { -// addIndex(shardKeys, stmt, uniqueShardingKey); -// } else { -// // create composite indexes for key/range column/list column partitions -// addCompositeIndex(shardKeys, stmt); -// } - } stmt.setBroadCast(false); // remove locality on mysql stmt.setLocality(null); - removeSequenceAndGsi(stmt); + removePolarDBXExclusiveFeature(stmt); + SqlCreateTable.removeLBACAttr(stmt); for (Pair pair : colDefs) { String columnName = pair.left.getSimple(); @@ -1097,6 +1228,53 @@ public MySqlStatement rewrite() { return stmt; } + /** + * Add local index for shardkeys and subshardKeys + */ + private void addLocalIndexesForShardKeys(MySqlCreateTableStatement stmt, Set shardKeys, + Set subPartKeys) { + String partStrategy = SqlCreateTable.fetchPartStrategy(sqlPartition, false); + String subpartStrategy = SqlCreateTable.fetchPartStrategy(sqlPartition, true); + boolean usePartBy = !partStrategy.isEmpty(); + boolean useSubPartBy = false; + boolean subPartKeyContainAllPartKeyAsPrefixCols = false; + + List partKeyList = shardKeys.stream().collect(Collectors.toList()); + List subPartKeyList = subPartKeys.stream().collect(Collectors.toList()); + boolean addPartColIndexLater = false; + if (subPartKeys != null && subPartKeys.size() > 0) { + useSubPartBy = true; + subPartKeyContainAllPartKeyAsPrefixCols = checkIfContainPrefixPartCols(subPartKeyList, partKeyList); + addPartColIndexLater = needAddPartColLocalIndexLater(partStrategy, subpartStrategy); + } + if (shardKeys.size() > 0) { + if (!(useSubPartBy && subPartKeyContainAllPartKeyAsPrefixCols)) { + if (sqlPartition == null) { + /** + * add local index for drds sharding keys + */ + addIndex(shardKeys, stmt, uniqueShardingKey); + } else { +// addCompositeIndex(shardKeys, stmt); + if (usePartBy && !addPartColIndexLater) { + SqlCreateTable.addCompositeIndexForAutoTbl(null, stmt, + false, ImmutableList. of(), false, partStrategy, partKeyList, false, ""); + } + } + } + + if (useSubPartBy) { +// addCompositeIndex(subPartKeys, stmt); + SqlCreateTable.addCompositeIndexForAutoTbl(null, stmt, + false, ImmutableList. of(), false, subpartStrategy, subPartKeyList, false, ""); + if (usePartBy && addPartColIndexLater) { + SqlCreateTable.addCompositeIndexForAutoTbl(null, stmt, + false, ImmutableList. of(), false, partStrategy, partKeyList, false, ""); + } + } + } + } + public void addLocalPartitionSuffix(MySqlCreateTableStatement stmt) { if (stmt == null || localPartitionSuffix == null) { return; @@ -1105,7 +1283,7 @@ public void addLocalPartitionSuffix(MySqlCreateTableStatement stmt) { Lists.newArrayList(new SQLCommentHint("!50500 PARTITION BY " + localPartitionSuffix.toString()))); } - private static void removeSequenceAndGsi(MySqlCreateTableStatement stmt) { + private static void removePolarDBXExclusiveFeature(MySqlCreateTableStatement stmt) { final Iterator iterator = stmt.getTableElementList().iterator(); while (iterator.hasNext()) { final SQLTableElement tableElement = iterator.next(); @@ -1117,11 +1295,40 @@ private static void removeSequenceAndGsi(MySqlCreateTableStatement stmt) { sqlColumnDefinition.setUnitCount(null); sqlColumnDefinition.setUnitIndex(null); } else if ((tableElement instanceof MySqlTableIndex && (((MySqlTableIndex) tableElement).isGlobal() - || ((MySqlTableIndex) tableElement).isClustered())) + || ((MySqlTableIndex) tableElement).isClustered() || ((MySqlTableIndex) tableElement).isColumnar())) || (tableElement instanceof MySqlUnique && (((MySqlUnique) tableElement).isGlobal() || ((MySqlUnique) tableElement).isClustered()))) { // remove gsi definition iterator.remove(); + } else if (tableElement instanceof MySqlTableIndex) { + final MySqlTableIndex index = (MySqlTableIndex) tableElement; + index.setTableGroup(null); + index.setWithImplicitTablegroup(false); + } else if (tableElement instanceof MySqlKey) { + final MySqlKey index = (MySqlKey) tableElement; + index.setTableGroup(null); + index.setWithImplicitTablegroup(false); + } + } + } + + private static void removeLBACAttr(final MySqlCreateTableStatement stmt) { + Iterator iterator = stmt.getTableElementList().iterator(); + while (iterator.hasNext()) { + SQLTableElement tableElement = iterator.next(); + //去除列的安全标号 + if (tableElement instanceof SQLColumnDefinition) { + SQLColumnDefinition sqlColumnDefinition = (SQLColumnDefinition) tableElement; + sqlColumnDefinition.setSecuredWith(null); + } + } + Iterator optionIterator = stmt.getTableOptions().iterator(); + while (optionIterator.hasNext()){ + SQLAssignItem item = optionIterator.next(); + //去除表的安全策略 + if (item.getTarget() instanceof SQLIdentifierExpr && + "SECURITY POLICY".equalsIgnoreCase(((SQLIdentifierExpr) item.getTarget()).getName())){ + optionIterator.remove(); } } } @@ -1374,6 +1581,8 @@ public static void addIndex(Map indexColumnDefMap, M .equalsIgnoreCase(UGSI_PK_INDEX_NAME)) { it.remove(); // Need to be replaced with MySqlUnique } + } else if (sqlTableElement instanceof MySqlPrimaryKey) { + needAddIndexColumns = false; } else { needAddIndexColumns = false; ((MySqlKey) sqlTableElement).setIndexType(indexType); @@ -1693,10 +1902,38 @@ public static Set getPartitionKeys(SqlNode partitionBy, return getPartitionKeys(partitionBy, partKeys, subPartKeys, true); } + /** + * Check if need add local index of the 1st-level part cols after subpart-part cols + */ + public static boolean needAddPartColLocalIndexLater( + String partStrategy, + String subPartStrategy + ) { + boolean useSubPart = subPartStrategy != null && !subPartStrategy.isEmpty(); + boolean usePart = partStrategy != null && !partStrategy.isEmpty(); + boolean isPartUsingCoHash = usePart && partStrategy.equalsIgnoreCase("CO_HASH"); + boolean isSubPartUsingCoHash = useSubPart && subPartStrategy.equalsIgnoreCase("CO_HASH"); + + if (!useSubPart) { + return false; + } + if (isPartUsingCoHash) { + if (isSubPartUsingCoHash) { + return false; + } else { + return true; + } + } else { + return false; + } + } + /** * Check if the target partition columns contains the target prefix part columns */ - public static boolean checkIfContainPrefixPartCols(List targetPartCols, List targetPrefixCols) { + public static boolean checkIfContainPrefixPartCols( + List targetPartCols, + List targetPrefixCols) { if (targetPartCols.size() < targetPrefixCols.size()) { return false; } @@ -1901,6 +2138,14 @@ public void setClusteredKeys(List > clust this.clusteredKeys = clusteredKeys; } + public List > getColumnarKeys() { + return columnarKeys; + } + + public void setColumnarKeys(List > columnarKeys) { + this.columnarKeys = columnarKeys; + } + public List > getClusteredUniqueKeys() { return clusteredUniqueKeys; } @@ -1967,6 +2212,20 @@ public void setPushDownForeignKeys(boolean pushDownForeignKeys) { this.pushDownForeignKeys = pushDownForeignKeys; } + public List getIsAddLogicalForeignKeyOnly() { + return isAddLogicalForeignKeyOnly; + } + + public void setIsAddLogicalForeignKeyOnly(List isAddLogicalForeignKeyOnly) { + if (null == this.isAddLogicalForeignKeyOnly) { + this.isAddLogicalForeignKeyOnly = new ArrayList<>(); + } + + if (isAddLogicalForeignKeyOnly != null) { + this.isAddLogicalForeignKeyOnly.addAll(isAddLogicalForeignKeyOnly); + } + } + public List getChecks() { return checks; } @@ -2007,6 +2266,11 @@ public boolean createGsi() { || GeneralUtil.isNotEmpty(clusteredKeys) || GeneralUtil.isNotEmpty(clusteredUniqueKeys); } + @Override + public boolean createCci() { + return GeneralUtil.isNotEmpty(columnarKeys); + } + public boolean createClusteredIndex() { return GeneralUtil.isNotEmpty(clusteredKeys) || GeneralUtil.isNotEmpty(clusteredUniqueKeys); } @@ -2060,6 +2324,136 @@ public static void addCompositeIndex(Set shardKeys, MySqlCreateTableStat new ArrayList<>(shardKeys), false, ""); } + public static void addCompositeIndexForAutoTbl(Map indexColumnNameMap, + MySqlCreateTableStatement stmt, + boolean isUniqueIndex, + List options, + boolean isGsi, + String shardKeysPartStrategy, + List shardKeys, + boolean addFkIndex, + String fkIndexName + ) { + /** + * The linked-hash Map can key the key's order by their insert order + */ + final Map newIndexColumnNameMap = + new LinkedHashMap (); + + /** + * The tree-set can handle the CASE_INSENSITIVE_ORDER that can remove duplicated items + */ + final Set newIndexColumnNameTreeSet = + new TreeSet(CaseInsensitive.CASE_INSENSITIVE_ORDER); + + if (indexColumnNameMap != null && !indexColumnNameMap.isEmpty()) { + newIndexColumnNameMap.putAll(indexColumnNameMap); + newIndexColumnNameTreeSet.addAll(newIndexColumnNameMap.keySet()); + } + + if (!isGsi && newIndexColumnNameMap.isEmpty()) { + for (String columnName : shardKeys) { + if (!newIndexColumnNameTreeSet.contains(columnName)) { + newIndexColumnNameMap.put(columnName, + new SqlIndexColumnName(SqlParserPos.ZERO, new SqlIdentifier(columnName, + SqlParserPos.ZERO), null, null)); + newIndexColumnNameTreeSet.add(columnName); + } + } + } + + if (shardKeysPartStrategy.equalsIgnoreCase("co_hash")) { + for (String shardKey : shardKeys) { + List tmpShardKey = new ArrayList<>(); + tmpShardKey.add(shardKey); +// addCompositeIndex(newIndexColumnNameMap, stmt, false, ImmutableList. of(), false, +// tmpShardKey, false, ""); + addCompositeIndex(newIndexColumnNameMap, stmt, isUniqueIndex, options, isGsi, + tmpShardKey, addFkIndex, fkIndexName); + } + } else { + addCompositeIndex(newIndexColumnNameMap, stmt, isUniqueIndex, options, isGsi, + shardKeys, addFkIndex, fkIndexName); + } + } + + private static String fetchPartStrategy(SqlNode sqlPartition, boolean isForSubPart) { + String partStrategy = ""; + if (sqlPartition == null) { + return partStrategy; + } + + SqlPartitionBy partBy = (SqlPartitionBy) sqlPartition; + SqlSubPartitionBy subPartBy = partBy.getSubPartitionBy(); + boolean useSubPart = subPartBy != null; + + if (isForSubPart) { + if (subPartBy == null) { + return partStrategy; + } + if (subPartBy instanceof SqlSubPartitionByHash) { + boolean isKey = ((SqlSubPartitionByHash) subPartBy).isKey(); + if (isKey) { + partStrategy = "KEY"; + } else { + partStrategy = "HASH"; + } + } else if (subPartBy instanceof SqlSubPartitionByCoHash) { + partStrategy = "CO_HASH"; + + } else if (subPartBy instanceof SqlSubPartitionByUdfHash) { + partStrategy = "UDF_HASH"; + } else if (subPartBy instanceof SqlSubPartitionByRange) { + boolean isColumns = subPartBy.isColumns(); + if (isColumns) { + partStrategy = "RANGE_COLUMNS"; + } else { + partStrategy = "RANGE"; + } + } else if (subPartBy instanceof SqlSubPartitionByList) { + boolean isColumns = subPartBy.isColumns(); + if (isColumns) { + partStrategy = "LIST_COLUMNS"; + } else { + partStrategy = "LIST"; + } + } else { + return partStrategy; + } + } else { + if (partBy instanceof SqlPartitionByHash) { + boolean isKey = ((SqlPartitionByHash) partBy).isKey(); + if (isKey) { + partStrategy = "KEY"; + } else { + partStrategy = "HASH"; + } + } else if (partBy instanceof SqlPartitionByCoHash) { + partStrategy = "CO_HASH"; + } else if (partBy instanceof SqlPartitionByUdfHash) { + partStrategy = "UDF_HASH"; + } else if (partBy instanceof SqlPartitionByRange) { + boolean isColumns = ((SqlPartitionByRange) partBy).isColumns(); + if (isColumns) { + partStrategy = "RANGE_COLUMNS"; + } else { + partStrategy = "RANGE"; + } + } else if (partBy instanceof SqlPartitionByList) { + boolean isColumns = ((SqlPartitionByList) partBy).isColumns(); + if (isColumns) { + partStrategy = "LIST_COLUMNS"; + } else { + partStrategy = "LIST"; + } + } else { + return partStrategy; + } + } + return partStrategy; + + } + /** * only for auto mode, add global index or create table * @@ -2346,8 +2740,7 @@ public static void addCompositeIndex(Map indexColumn Set orderedIndexColumnNames = new LinkedHashSet<>(shardingKey); final String suffix = buildUnifyIndexName(orderedIndexColumnNames, 45); - final String indexName = addFkIndex ? (foreignKeyIndexName == null ? - buildForeignKeyIndexName(existingIndexNames, suffix) : foreignKeyIndexName) : + final String indexName = addFkIndex ? buildForeignKeyName(foreignKeyIndexName, existingIndexNames, suffix) : buildIndexName(existingIndexNames, suffix); final MySqlTableIndex mySqlTableIndex = new MySqlTableIndex(); @@ -2373,6 +2766,13 @@ public static void addCompositeIndex(Map indexColumn } } + public static String buildForeignKeyName(String foreignKeyIndexName, Set existingIndexNames, + String suffix) { + return foreignKeyIndexName == null ? + buildForeignKeyIndexName(existingIndexNames, suffix) : + SqlIdentifier.surroundWithBacktick(foreignKeyIndexName); + } + private static List preparAutoCompositeIndexs(List shardKeys, Map columnDefMap, int maxLen) { @@ -2493,6 +2893,18 @@ private static List preparAutoCompositeIndexs(List shar } return indexColumnInfos; } + + public void replaceCciDef(String indexName, SqlIndexDefinition newIndexDef) { + this.setColumnarKeys(getColumnarKeys() + .stream() + .map(p -> { + if (TStringUtil.equalsIgnoreCase(p.getKey().getLastName(), indexName)) { + return Pair.of(p.getKey(), newIndexDef); + } + return p; + }) + .collect(Collectors.toList())); + } } class IndexColumnInfo { diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTableGroup.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTableGroup.java index cdb170256..a608531bc 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTableGroup.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateTableGroup.java @@ -44,15 +44,17 @@ public class SqlCreateTableGroup extends SqlDdl { final String tableGroupName; final String schemaName; final SqlNode sqlPartition; + final boolean single; public SqlCreateTableGroup(SqlParserPos pos, boolean ifNotExists, String schemaName, - String tableGroupName, String locality, SqlNode sqlPartition) { + String tableGroupName, String locality, SqlNode sqlPartition, boolean single) { super(OPERATOR, pos); this.ifNotExists = ifNotExists; this.schemaName = schemaName; this.tableGroupName = tableGroupName; this.locality = locality; this.sqlPartition = sqlPartition; + this.single = single; } @Override @@ -71,6 +73,8 @@ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { if (sqlPartition != null) { writer.keyword(" "); sqlPartition.unparse(writer, 0, 0); + } else if (single) { + writer.keyword("SINGLE"); } if (TStringUtil.isNotEmpty(locality)) { writer.keyword("LOCALITY = "); @@ -98,6 +102,10 @@ public SqlNode getSqlPartition() { return sqlPartition; } + public boolean isSingle() { + return single; + } + @Override public SqlOperator getOperator() { return OPERATOR; diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateView.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateView.java index 390e28d3f..247c39a40 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateView.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlCreateView.java @@ -48,10 +48,13 @@ public class SqlCreateView extends SqlCreate { private static final SqlOperator OPERATOR = new SqlSpecialOperator("CREATE VIEW", SqlKind.CREATE_VIEW); + private boolean alter; + /** Creates a SqlCreateView. */ - public SqlCreateView(SqlParserPos pos, boolean replace, SqlIdentifier name, + public SqlCreateView(SqlParserPos pos, boolean replace, boolean alter, SqlIdentifier name, SqlNodeList columnList, SqlNode query) { super(OPERATOR, pos, replace, false); + this.alter = alter; this.name = Preconditions.checkNotNull(name); this.columnList = columnList; // may be null this.query = Preconditions.checkNotNull(query); @@ -97,4 +100,8 @@ public SqlNode getQuery() { public SqlIdentifier getName() { return (SqlIdentifier) name; } + + public boolean isAlter() { + return alter; + } } diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java index 708586b46..dd258330f 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java @@ -25,6 +25,7 @@ import org.apache.calcite.sql.SqlWriter.FrameTypeEnum; import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.sql.type.EnumSqlType; +import org.apache.calcite.sql.type.SetSqlType; import org.apache.calcite.sql.type.SqlTypeFactoryImpl; import org.apache.calcite.sql.type.SqlTypeFamily; import org.apache.calcite.sql.type.SqlTypeName; @@ -596,6 +597,11 @@ public RelDataType deriveType(RelDataTypeFactory typeFactory, } } + //bit 类型 bit(1) length > 1, 则使用BIG_BIT,兼容DataTypeUtil.jdbcTypeToRelDataType + if (sqlTypeName == SqlTypeName.BIT && precision > 1) { + sqlTypeName = SqlTypeName.BIG_BIT; + } + // For time/datetime/timestamp types if (SqlTypeFamily.DATETIME.getTypeNames().contains(sqlTypeName) && sqlTypeName != SqlTypeName.DATE) { // fix scale and precision of datetime type. @@ -618,6 +624,15 @@ public RelDataType deriveType(RelDataTypeFactory typeFactory, } RelDataType newType = new EnumSqlType(typeFactory.getTypeSystem(), SqlTypeName.ENUM, list, null, null); type = ((SqlTypeFactoryImpl) typeFactory).canonize(newType); + } else if (drdsTypeName == DrdsTypeName.SET) { + List list = new ArrayList(); + for (SqlNode sqlNode : this.collectionVals.getList()) { + assert sqlNode instanceof SqlLiteral; + final String stringValue = ((SqlLiteral) sqlNode).getStringValue(); + list.add(stringValue); + } + RelDataType newType = new SetSqlType(typeFactory.getTypeSystem(), sqlTypeName, list); + type = ((SqlTypeFactoryImpl) typeFactory).canonize(newType); } else if ((precision >= 0) && (scale >= 0)) { assert sqlTypeName.allowsPrecScale(true, true); type = typeFactory.createSqlType(sqlTypeName, precision, scale); @@ -716,7 +731,8 @@ public enum DrdsTypeName { MEDIUMTEXT(SqlTypeName.VARCHAR), LONGTEXT(SqlTypeName.VARCHAR), ENUM(SqlTypeName.ENUM), - SET(SqlTypeName.VARCHAR), + //metaDb中构建用的char + SET(SqlTypeName.CHAR), GEOMETRY(SqlTypeName.GEOMETRY), POINT(SqlTypeName.BINARY), LINESTRING(SqlTypeName.BINARY), @@ -735,7 +751,7 @@ public enum DrdsTypeName { ; public static final EnumSet TYPE_WITH_LENGTH = - EnumSet.of(TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT, DOUBLE, REAL, FLOAT, DECIMAL); + EnumSet.of(TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT, DOUBLE, REAL, FLOAT, DECIMAL, BIT); public static final EnumSet TYPE_WITH_LENGTH_DECIMALS = EnumSet.of(DOUBLE, REAL, FLOAT, DECIMAL); @@ -807,6 +823,34 @@ public boolean isA(EnumSet enumSet) { public boolean isUnsigned() { return unsigned; } + + public boolean isZerofill() { + return zerofill; + } + + public boolean isBinary() { + return binary; + } + + public SqlLiteral getDecimals() { + return decimals; + } + + public SqlLiteral getCharSet() { + return charSet; + } + + public SqlLiteral getCollation() { + return collation; + } + + public SqlNodeList getCollectionVals() { + return collectionVals; + } + + public SqlLiteral getFsp() { + return fsp; + } } // End SqlDataTypeSpec.java diff --git a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDdlNodes.java b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDdlNodes.java index 3099a6d19..54b480981 100644 --- a/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDdlNodes.java +++ b/polardbx-calcite/src/main/java/org/apache/calcite/sql/SqlDdlNodes.java @@ -45,9 +45,12 @@ private SqlDdlNodes() { public static SqlCreateDatabase createDatabase(SqlParserPos pos, boolean ifNotExists, SqlIdentifier dbName, String charSet, String collate, Boolean encryption, String locality, - String partitionMode, Boolean defaultSingle, SqlIdentifier sourceDataBase, boolean like, boolean as, List includeTables, List excludeTables, + String partitionMode, Boolean defaultSingle, + SqlIdentifier sourceDataBase, boolean like, boolean as, + List