You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ko...@apache.org on 2023/01/20 06:31:28 UTC
[ignite-3] branch main updated: IGNITE-18254: Sql. Extend SQL grammar with ALTER ZONE statement (#1521)
This is an automated email from the ASF dual-hosted git repository.
korlov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 488d3ba84e IGNITE-18254: Sql. Extend SQL grammar with ALTER ZONE statement (#1521)
488d3ba84e is described below
commit 488d3ba84e636c864ccfcdf8b9e8caaafc35c983
Author: Max Zhuravkov <sh...@gmail.com>
AuthorDate: Fri Jan 20 10:31:21 2023 +0400
IGNITE-18254: Sql. Extend SQL grammar with ALTER ZONE statement (#1521)
---
modules/sql-engine/src/main/codegen/config.fmpp | 12 +-
.../src/main/codegen/includes/parserImpls.ftl | 112 ++++++++++-
.../prepare/ddl/DdlSqlToCommandConverter.java | 26 +--
.../sql/engine/sql/IgniteAbstractSqlAlterZone.java | 76 ++++++++
.../sql/engine/sql/IgniteSqlAlterZoneRenameTo.java | 61 ++++++
.../sql/engine/sql/IgniteSqlAlterZoneSet.java | 60 ++++++
...ateZoneOption.java => IgniteSqlZoneOption.java} | 14 +-
...ptionEnum.java => IgniteSqlZoneOptionEnum.java} | 4 +-
.../sql/DistributionZoneSqlDdlParserTest.java | 205 ++++++++++++++++++---
9 files changed, 509 insertions(+), 61 deletions(-)
diff --git a/modules/sql-engine/src/main/codegen/config.fmpp b/modules/sql-engine/src/main/codegen/config.fmpp
index bbd0330ded..84aaaed0a6 100644
--- a/modules/sql-engine/src/main/codegen/config.fmpp
+++ b/modules/sql-engine/src/main/codegen/config.fmpp
@@ -37,12 +37,14 @@ data: {
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateIndex",
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateTableOption",
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZone",
- "org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOption",
- "org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum",
+ "org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOption",
+ "org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum",
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropIndex",
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropZone",
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlIntervalTypeNameSpec",
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlIndexType",
+ "org.apache.ignite.internal.sql.engine.sql.IgniteSqlAlterZoneSet",
+ "org.apache.ignite.internal.sql.engine.sql.IgniteSqlAlterZoneRenameTo",
"org.apache.calcite.sql.ddl.SqlDdlNodes",
]
@@ -63,7 +65,8 @@ data: {
"DATA_NODES_FILTER"
"DATA_NODES_AUTO_ADJUST"
"DATA_NODES_AUTO_ADJUST_SCALE_UP"
- "DATA_NODES_AUTO_ADJUST_SCALE_DOWN"
+ "DATA_NODES_AUTO_ADJUST_SCALE_DOWN",
+ "RENAME",
]
# List of non-reserved keywords to add;
@@ -594,7 +597,8 @@ data: {
# Return type of method implementation should be 'SqlNode'.
# Example: "SqlShowDatabases()", "SqlShowTables()".
statementParserMethods: [
- "SqlAlterTable()"
+ "SqlAlterTable()",
+ "SqlAlterZone()"
]
# List of methods for parsing extensions to "CREATE [OR REPLACE]" calls.
diff --git a/modules/sql-engine/src/main/codegen/includes/parserImpls.ftl b/modules/sql-engine/src/main/codegen/includes/parserImpls.ftl
index f176a33c82..fd7ad0655c 100644
--- a/modules/sql-engine/src/main/codegen/includes/parserImpls.ftl
+++ b/modules/sql-engine/src/main/codegen/includes/parserImpls.ftl
@@ -479,7 +479,7 @@ void CreateZoneOption(List<SqlNode> list) :
)
)
{
- list.add(new IgniteSqlCreateZoneOption(key, val, s.end(this)));
+ list.add(new IgniteSqlZoneOption(key, val, s.end(this)));
}
}
@@ -489,27 +489,27 @@ SqlLiteral CreateNumericZoneOptionKey() :
{
<PARTITIONS>
{
- return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.PARTITIONS, getPos());
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.PARTITIONS, getPos());
}
|
<REPLICAS>
{
- return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.REPLICAS, getPos());
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.REPLICAS, getPos());
}
|
<DATA_NODES_AUTO_ADJUST>
{
- return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST, getPos());
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST, getPos());
}
|
<DATA_NODES_AUTO_ADJUST_SCALE_UP>
{
- return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_UP, getPos());
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_UP, getPos());
}
|
<DATA_NODES_AUTO_ADJUST_SCALE_DOWN>
{
- return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_DOWN, getPos());
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_DOWN, getPos());
}
}
@@ -517,9 +517,9 @@ SqlLiteral CreateStringZoneOptionKey() :
{
}
{
- <AFFINITY_FUNCTION> { return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.AFFINITY_FUNCTION, getPos()); }
+ <AFFINITY_FUNCTION> { return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.AFFINITY_FUNCTION, getPos()); }
|
- <DATA_NODES_FILTER> { return SqlLiteral.createSymbol(IgniteSqlCreateZoneOptionEnum.DATA_NODES_FILTER, getPos()); }
+ <DATA_NODES_FILTER> { return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_FILTER, getPos()); }
}
SqlDrop SqlDropZone(Span s, boolean replace) :
@@ -532,3 +532,99 @@ SqlDrop SqlDropZone(Span s, boolean replace) :
return new IgniteSqlDropZone(s.end(this), ifExists, zoneId);
}
}
+
+SqlNode SqlAlterZone() :
+{
+ final Span s;
+ final SqlIdentifier zoneId;
+ final boolean ifExists;
+ final SqlIdentifier newZoneId;
+ SqlNodeList optionList = null;
+}
+{
+ <ALTER> { s = span(); }
+ <ZONE>
+ ifExists = IfExistsOpt()
+ zoneId = CompoundIdentifier()
+ (
+ <RENAME> <TO> newZoneId = SimpleIdentifier() {
+ return new IgniteSqlAlterZoneRenameTo(s.end(this), zoneId, newZoneId, ifExists);
+ }
+ |
+ <SET> { s.add(this); } optionList = AlterZoneOptions() {
+ return new IgniteSqlAlterZoneSet(s.end(this), zoneId, optionList, ifExists);
+ }
+ )
+}
+
+SqlNodeList AlterZoneOptions() :
+{
+ List<SqlNode> list = new ArrayList<SqlNode>();
+ final Span s = Span.of();
+}
+{
+ AlterZoneOption(list)
+ (
+ <COMMA> { s.add(this); } AlterZoneOption(list)
+ )*
+ {
+ return new SqlNodeList(list, s.end(this));
+ }
+}
+
+void AlterZoneOption(List<SqlNode> list) :
+{
+ final Span s;
+ final SqlLiteral key;
+ final SqlNode val;
+}
+{
+ (
+ (
+ key = AlterZoneNumericOptionKey() { s = span(); }
+ <EQ>
+ val = NumericLiteral()
+ )
+ |
+ (
+ key = AlterZoneStringOptionKey() { s = span(); }
+ <EQ>
+ val = StringLiteral()
+ )
+ )
+ {
+ list.add(new IgniteSqlZoneOption(key, val, s.end(this)));
+ }
+}
+
+SqlLiteral AlterZoneNumericOptionKey() :
+{
+}
+{
+ <REPLICAS>
+ {
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.REPLICAS, getPos());
+ }
+|
+ <DATA_NODES_AUTO_ADJUST>
+ {
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST, getPos());
+ }
+|
+ <DATA_NODES_AUTO_ADJUST_SCALE_UP>
+ {
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_UP, getPos());
+ }
+|
+ <DATA_NODES_AUTO_ADJUST_SCALE_DOWN>
+ {
+ return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_DOWN, getPos());
+ }
+}
+
+SqlLiteral AlterZoneStringOptionKey() :
+{
+}
+{
+ <DATA_NODES_FILTER> { return SqlLiteral.createSymbol(IgniteSqlZoneOptionEnum.DATA_NODES_FILTER, getPos()); }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ddl/DdlSqlToCommandConverter.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ddl/DdlSqlToCommandConverter.java
index 262a206665..3020baa0ef 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ddl/DdlSqlToCommandConverter.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ddl/DdlSqlToCommandConverter.java
@@ -20,13 +20,13 @@ package org.apache.ignite.internal.sql.engine.prepare.ddl;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toUnmodifiableMap;
import static org.apache.ignite.internal.schema.configuration.storage.UnknownDataStorageConfigurationSchema.UNKNOWN_DATA_STORAGE;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.AFFINITY_FUNCTION;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_DOWN;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_UP;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.DATA_NODES_FILTER;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.PARTITIONS;
-import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum.REPLICAS;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.AFFINITY_FUNCTION;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_DOWN;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST_SCALE_UP;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.DATA_NODES_FILTER;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.PARTITIONS;
+import static org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum.REPLICAS;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
import static org.apache.ignite.lang.ErrorGroups.Sql.PRIMARY_KEYS_MULTIPLE_ERR;
import static org.apache.ignite.lang.ErrorGroups.Sql.PRIMARY_KEY_MISSING_ERR;
@@ -83,11 +83,11 @@ import org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateIndex;
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateTable;
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateTableOption;
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZone;
-import org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOption;
-import org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZoneOptionEnum;
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropIndex;
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropZone;
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlIndexType;
+import org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOption;
+import org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionEnum;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.sql.SqlException;
@@ -114,7 +114,7 @@ public class DdlSqlToCommandConverter {
private final Map<String, Map<String, DdlOptionInfo<CreateTableCommand, ?>>> dataStorageOptionInfos;
/** Mapping: Zone option ID -> DDL option info. */
- private final Map<IgniteSqlCreateZoneOptionEnum, DdlOptionInfo<CreateZoneCommand, ?>> zoneOptionInfos;
+ private final Map<IgniteSqlZoneOptionEnum, DdlOptionInfo<CreateZoneCommand, ?>> zoneOptionInfos;
/**
* Constructor.
@@ -492,11 +492,11 @@ public class DdlSqlToCommandConverter {
return createZoneCmd;
}
- Set<IgniteSqlCreateZoneOptionEnum> knownOptionNames = EnumSet.allOf(IgniteSqlCreateZoneOptionEnum.class);
+ Set<IgniteSqlZoneOptionEnum> knownOptionNames = EnumSet.allOf(IgniteSqlZoneOptionEnum.class);
for (SqlNode optionNode : createZoneNode.createOptionList().getList()) {
- IgniteSqlCreateZoneOption option = (IgniteSqlCreateZoneOption) optionNode;
- IgniteSqlCreateZoneOptionEnum optionName = option.key().symbolValue(IgniteSqlCreateZoneOptionEnum.class);
+ IgniteSqlZoneOption option = (IgniteSqlZoneOption) optionNode;
+ IgniteSqlZoneOptionEnum optionName = option.key().symbolValue(IgniteSqlZoneOptionEnum.class);
if (!knownOptionNames.remove(optionName)) {
throw new IgniteException(QUERY_VALIDATION_ERR,
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteAbstractSqlAlterZone.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteAbstractSqlAlterZone.java
new file mode 100644
index 0000000000..70a45270fc
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteAbstractSqlAlterZone.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.sql;
+
+import org.apache.calcite.sql.SqlDdl;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSpecialOperator;
+import org.apache.calcite.sql.SqlWriter;
+import org.apache.calcite.sql.parser.SqlParserPos;
+
+/**
+ * A base class for a parse tree for {@code ALTER ZONE} statement.
+ */
+public abstract class IgniteAbstractSqlAlterZone extends SqlDdl {
+
+ /** Alter operator. */
+ private static final SqlOperator OPERATOR =
+ new SqlSpecialOperator("ALTER ZONE", SqlKind.OTHER_DDL);
+
+ protected final SqlIdentifier name;
+
+ protected final boolean ifExists;
+
+ /** Constructor. */
+ public IgniteAbstractSqlAlterZone(SqlParserPos pos, SqlIdentifier name, boolean ifExists) {
+ super(OPERATOR, pos);
+ this.name = name;
+ this.ifExists = ifExists;
+ }
+
+ /** The name of a distribution zone to alter. **/
+ public SqlIdentifier name() {
+ return name;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword(getOperator().getName());
+
+ if (ifExists) {
+ writer.keyword("IF EXISTS");
+ }
+
+ name.unparse(writer, leftPrec, rightPrec);
+
+ unparseAlterZoneOperation(writer, leftPrec, rightPrec);
+ }
+
+ /**
+ * Unparse rest of the ALTER ZONE command.
+ */
+ protected abstract void unparseAlterZoneOperation(SqlWriter writer, int leftPrec, int rightPrec);
+
+
+ /** Returns whether IF EXISTS was specified or not. **/
+ public boolean ifExists() {
+ return ifExists;
+ }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java
new file mode 100644
index 0000000000..20c7a4efaa
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.sql;
+
+import java.util.List;
+import java.util.Objects;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlWriter;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.util.ImmutableNullableList;
+
+/**
+ * Parse tree for {@code ALTER ZONE RENAME TO} statement.
+ */
+public class IgniteSqlAlterZoneRenameTo extends IgniteAbstractSqlAlterZone {
+
+ private final SqlIdentifier newName;
+
+ /** Constructor. */
+ public IgniteSqlAlterZoneRenameTo(SqlParserPos pos, SqlIdentifier name, SqlIdentifier newName, boolean ifExists) {
+ super(pos, name, ifExists);
+ this.newName = Objects.requireNonNull(newName, "newName");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<SqlNode> getOperandList() {
+ return ImmutableNullableList.of(name, newName);
+ }
+
+ /**
+ * The new name for a distribution zone.
+ */
+ public SqlIdentifier newName() {
+ return newName;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void unparseAlterZoneOperation(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword("RENAME TO");
+
+ newName.unparse(writer, leftPrec, rightPrec);
+ }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java
new file mode 100644
index 0000000000..432ad3a836
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.sql;
+
+import java.util.List;
+import java.util.Objects;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlWriter;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.util.ImmutableNullableList;
+
+/**
+ * Parse tree for {@code ALTER ZONE SET} statement.
+ */
+public class IgniteSqlAlterZoneSet extends IgniteAbstractSqlAlterZone {
+
+ private final SqlNodeList optionList;
+
+ /** Constructor. */
+ public IgniteSqlAlterZoneSet(SqlParserPos pos, SqlIdentifier name, SqlNodeList optionList, boolean ifExists) {
+ super(pos, name, ifExists);
+ this.optionList = Objects.requireNonNull(optionList, "optionList");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<SqlNode> getOperandList() {
+ return ImmutableNullableList.of(name, optionList);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void unparseAlterZoneOperation(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword("SET");
+
+ optionList.unparse(writer, 0, 0);
+ }
+
+ /** The list of modification options. **/
+ public SqlNodeList alterOptionsList() {
+ return optionList;
+ }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZoneOption.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlZoneOption.java
similarity index 87%
rename from modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZoneOption.java
rename to modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlZoneOption.java
index 4f40784864..67090ef264 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZoneOption.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlZoneOption.java
@@ -31,8 +31,8 @@ import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.util.Litmus;
-/** An AST node representing option to create distribution zone with. */
-public class IgniteSqlCreateZoneOption extends SqlCall {
+/** An AST node representing option in CREATE ZONE and ALTER ZONE statements. */
+public class IgniteSqlZoneOption extends SqlCall {
private static final SqlOperator OPERATOR =
new SqlSpecialOperator("ZoneOption", SqlKind.OTHER);
@@ -42,8 +42,8 @@ public class IgniteSqlCreateZoneOption extends SqlCall {
/** Option value. */
private final SqlNode value;
- /** Creates {@link IgniteSqlCreateZoneOption}. */
- public IgniteSqlCreateZoneOption(SqlLiteral key, SqlNode value, SqlParserPos pos) {
+ /** Creates {@link IgniteSqlZoneOption}. */
+ public IgniteSqlZoneOption(SqlLiteral key, SqlNode value, SqlParserPos pos) {
super(pos);
this.key = key;
@@ -65,7 +65,7 @@ public class IgniteSqlCreateZoneOption extends SqlCall {
/** {@inheritDoc} */
@Override
public SqlNode clone(SqlParserPos pos) {
- return new IgniteSqlCreateZoneOption(key, value, pos);
+ return new IgniteSqlZoneOption(key, value, pos);
}
/** {@inheritDoc} */
@@ -91,11 +91,11 @@ public class IgniteSqlCreateZoneOption extends SqlCall {
/** {@inheritDoc} */
@Override
public boolean equalsDeep(SqlNode node, Litmus litmus) {
- if (!(node instanceof IgniteSqlCreateZoneOption)) {
+ if (!(node instanceof IgniteSqlZoneOption)) {
return litmus.fail("{} != {}", this, node);
}
- IgniteSqlCreateZoneOption that = (IgniteSqlCreateZoneOption) node;
+ IgniteSqlZoneOption that = (IgniteSqlZoneOption) node;
if (key != that.key) {
return litmus.fail("{} != {}", this, node);
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZoneOptionEnum.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlZoneOptionEnum.java
similarity index 92%
rename from modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZoneOptionEnum.java
rename to modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlZoneOptionEnum.java
index 04d231ce1e..9347082b11 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZoneOptionEnum.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlZoneOptionEnum.java
@@ -18,9 +18,9 @@
package org.apache.ignite.internal.sql.engine.sql;
/**
- * Enumerates the options for CREATE ZONE statement.
+ * Enumerates the options for CREATE ZONE and ALTER ZONE statements.
*/
-public enum IgniteSqlCreateZoneOptionEnum {
+public enum IgniteSqlZoneOptionEnum {
/** Number of partitions. */
PARTITIONS,
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/DistributionZoneSqlDdlParserTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/DistributionZoneSqlDdlParserTest.java
index 737e3e8c28..6362f751e6 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/DistributionZoneSqlDdlParserTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/DistributionZoneSqlDdlParserTest.java
@@ -21,7 +21,9 @@ import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -32,6 +34,7 @@ import java.util.List;
import java.util.Objects;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.pretty.SqlPrettyWriter;
import org.hamcrest.Matchers;
@@ -41,6 +44,11 @@ import org.junit.jupiter.api.Test;
* Test suite to verify parsing of the DDL "ZONE" commands.
*/
public class DistributionZoneSqlDdlParserTest extends AbstractDdlParserTest {
+
+ private static final List<String> NUMERIC_OPTIONS = Arrays.asList("PARTITIONS", "REPLICAS", "DATA_NODES_AUTO_ADJUST",
+ "DATA_NODES_AUTO_ADJUST_SCALE_UP", "DATA_NODES_AUTO_ADJUST_SCALE_DOWN");
+ private static final List<String> STRING_OPTIONS = Arrays.asList("AFFINITY_FUNCTION", "DATA_NODES_FILTER");
+
/**
* Parse simple CREATE ZONE statement.
*/
@@ -96,23 +104,20 @@ public class DistributionZoneSqlDdlParserTest extends AbstractDdlParserTest {
List<SqlNode> optList = createZone.createOptionList().getList();
- assertThatZoneOptionPresent(optList, IgniteSqlCreateZoneOptionEnum.REPLICAS, 2);
- assertThatZoneOptionPresent(optList, IgniteSqlCreateZoneOptionEnum.PARTITIONS, 3);
- assertThatZoneOptionPresent(optList, IgniteSqlCreateZoneOptionEnum.AFFINITY_FUNCTION, "test_Affinity");
- assertThatZoneOptionPresent(optList, IgniteSqlCreateZoneOptionEnum.DATA_NODES_FILTER, "(\"US\" || \"EU\") && \"SSD\"");
- assertThatZoneOptionPresent(optList, IgniteSqlCreateZoneOptionEnum.DATA_NODES_AUTO_ADJUST, 1);
-
- SqlPrettyWriter w = new SqlPrettyWriter();
- createZone.unparse(w, 0, 0);
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.REPLICAS, 2);
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.PARTITIONS, 3);
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.AFFINITY_FUNCTION, "test_Affinity");
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.DATA_NODES_FILTER, "(\"US\" || \"EU\") && \"SSD\"");
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST, 1);
- assertThat(w.toString(), equalTo("CREATE ZONE \"TEST_ZONE\" WITH "
+ expectUnparsed(createZone, "CREATE ZONE \"TEST_ZONE\" WITH "
+ "REPLICAS = 2, "
+ "PARTITIONS = 3, "
+ "DATA_NODES_FILTER = '(\"US\" || \"EU\") && \"SSD\"', "
+ "AFFINITY_FUNCTION = 'test_Affinity', "
+ "DATA_NODES_AUTO_ADJUST = 1, "
+ "DATA_NODES_AUTO_ADJUST_SCALE_UP = 2, "
- + "DATA_NODES_AUTO_ADJUST_SCALE_DOWN = 3"));
+ + "DATA_NODES_AUTO_ADJUST_SCALE_DOWN = 3");
}
/**
@@ -126,17 +131,12 @@ public class DistributionZoneSqlDdlParserTest extends AbstractDdlParserTest {
// Invalid option type.
String query = "create zone test_zone with %s=%s";
- List<String> numericOptNames = Arrays.asList("PARTITIONS", "REPLICAS", "DATA_NODES_AUTO_ADJUST",
- "DATA_NODES_AUTO_ADJUST_SCALE_UP", "DATA_NODES_AUTO_ADJUST_SCALE_DOWN");
-
- for (String optName : numericOptNames) {
- assertThrows(SqlParseException.class, () -> parseCreateZone(String.format(query, optName, "'bar'")));
+ for (String optName : NUMERIC_OPTIONS) {
+ assertSqlParseError(String.format(query, optName, "'bar'"), optName);
}
- List<String> stringOptNames = Arrays.asList("AFFINITY_FUNCTION", "DATA_NODES_FILTER");
-
- for (String optName : stringOptNames) {
- assertThrows(SqlParseException.class, () -> parseCreateZone(String.format(query, optName, "1")));
+ for (String optName : STRING_OPTIONS) {
+ assertSqlParseError(String.format(query, optName, "1"), optName);
}
}
@@ -170,10 +170,131 @@ public class DistributionZoneSqlDdlParserTest extends AbstractDdlParserTest {
assertTrue(dropZone.ifExists());
- SqlPrettyWriter w = new SqlPrettyWriter();
- dropZone.unparse(w, 0, 0);
+ expectUnparsed(dropZone, "DROP ZONE IF EXISTS \"TEST_ZONE\"");
+ }
+
+ /**
+ * Parsing ALTER ZONE RENAME TO statement.
+ */
+ @Test
+ public void alterZoneRenameTo() throws SqlParseException {
+ IgniteSqlAlterZoneRenameTo alterZone = parseAlterZoneRenameTo("alter zone a.test_zone rename to zone1");
+ assertFalse(alterZone.ifExists());
+
+ String expectedStmt = "ALTER ZONE \"A\".\"TEST_ZONE\" RENAME TO \"ZONE1\"";
+ expectUnparsed(alterZone, expectedStmt);
+ }
+
+ /**
+ * Parsing ALTER ZONE RENAME TO statement.
+ */
+ @Test
+ public void alterZoneIfExistsRenameTo() throws SqlParseException {
+ IgniteSqlAlterZoneRenameTo alterZone = parseAlterZoneRenameTo("alter zone if exists a.test_zone rename to zone1");
+ assertTrue(alterZone.ifExists());
+
+ String expectedStmt = "ALTER ZONE IF EXISTS \"A\".\"TEST_ZONE\" RENAME TO \"ZONE1\"";
+ expectUnparsed(alterZone, expectedStmt);
+ }
+
+ /**
+ * Parsing ALTER ZONE RENAME TO statement with invalid arguments.
+ */
+ @Test
+ public void alterZoneRenameToWithCompoundIdIsIllegal() {
+ assertThrows(SqlParseException.class, () -> parse("alter zone a.test_zone rename to b.zone1"));
+ }
+
+ /**
+ * Parsing ALTER ZONE SET statement.
+ */
+ @Test
+ public void alterZoneSet() throws SqlParseException {
+ IgniteSqlAlterZoneSet alterZoneSet = parseAlterZoneSet("alter zone a.test_zone set replicas=2");
+ assertFalse(alterZoneSet.ifExists());
+
+ String expectedStmt = "ALTER ZONE \"A\".\"TEST_ZONE\" SET REPLICAS = 2";
+ expectUnparsed(alterZoneSet, expectedStmt);
+ }
+
+ /**
+ * Parsing ALTER ZONE IF EXISTS SET statement.
+ */
+ @Test
+ public void alterZoneIfExistsSet() throws SqlParseException {
+ IgniteSqlAlterZoneSet alterZoneSet = parseAlterZoneSet("alter zone if exists a.test_zone set replicas=2");
+ assertTrue(alterZoneSet.ifExists());
+
+ String expectedStmt = "ALTER ZONE IF EXISTS \"A\".\"TEST_ZONE\" SET REPLICAS = 2";
+ expectUnparsed(alterZoneSet, expectedStmt);
+ }
+
+ /**
+ * Parsing ALTER ZONE SET statement.
+ */
+ @Test
+ public void alterZoneSetOptions() throws SqlParseException {
+ IgniteSqlAlterZoneSet alterZoneSet = parseAlterZoneSet(
+ "alter zone a.test_zone set "
+ + "replicas=2, "
+ + "data_nodes_filter='(\"US\" || \"EU\") && \"SSD\"', "
+ + "data_nodes_auto_adjust=1, "
+ + "data_nodes_auto_adjust_scale_up=2, "
+ + "data_nodes_auto_adjust_scale_down=3"
+ );
+
+ assertEquals(List.of("A", "TEST_ZONE"), alterZoneSet.name().names);
+ assertNotNull(alterZoneSet.alterOptionsList());
+ assertFalse(alterZoneSet.ifExists());
+
+ List<SqlNode> optList = alterZoneSet.alterOptionsList().getList();
+
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.REPLICAS, 2);
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.DATA_NODES_FILTER, "(\"US\" || \"EU\") && \"SSD\"");
+ assertThatZoneOptionPresent(optList, IgniteSqlZoneOptionEnum.DATA_NODES_AUTO_ADJUST, 1);
+
+ String expectedStmt = "ALTER ZONE \"A\".\"TEST_ZONE\" SET "
+ + "REPLICAS = 2, "
+ + "DATA_NODES_FILTER = '(\"US\" || \"EU\") && \"SSD\"', "
+ + "DATA_NODES_AUTO_ADJUST = 1, "
+ + "DATA_NODES_AUTO_ADJUST_SCALE_UP = 2, "
+ + "DATA_NODES_AUTO_ADJUST_SCALE_DOWN = 3";
+ expectUnparsed(alterZoneSet, expectedStmt);
+ }
+
+ /**
+ * Parses ALTER ZONE SET w/o provided options.
+ */
+ @Test
+ public void alterZoneSetNoOptionsIsIllegal() {
+ assertThrows(SqlParseException.class, () -> parse("alter zone test_zone set"));
+ }
+
+ /**
+ * Parses ALTER ZONE WITH invalid options.
+ */
+ @Test
+ public void alterZoneSetInvalidOptions() {
+ String query = "alter zone test_zone set %s=%s";
+
+ // invalid option
+
+ assertThrows(SqlParseException.class, () -> parse(String.format(query, "foo", "'bar'")));
+
+ // invalid option values
+
+ for (String optName : NUMERIC_OPTIONS) {
+ assertSqlParseError(String.format(query, optName, "'bar'"), optName);
+ }
+
+ for (String optName : STRING_OPTIONS) {
+ assertSqlParseError(String.format(query, optName, "1"), optName);
+ }
- assertThat(w.toString(), equalTo("DROP ZONE IF EXISTS \"TEST_ZONE\""));
+ // non modifiable options can only be set in CREATE ZONE.
+
+ assertSqlParseError(String.format(query, "PARTITIONS", 2), "partitions");
+ assertSqlParseError(String.format(query, "AFFINITY_FUNCTION", "'function'"), "affinity_function");
}
/**
@@ -185,17 +306,47 @@ public class DistributionZoneSqlDdlParserTest extends AbstractDdlParserTest {
private IgniteSqlCreateZone parseCreateZone(String stmt) throws SqlParseException {
SqlNode node = parse(stmt);
- assertThat(node, instanceOf(IgniteSqlCreateZone.class));
+ return assertInstanceOf(IgniteSqlCreateZone.class, node);
+ }
+
+ /**
+ * Parse ALTER ZONE SET statement.
+ */
+ private IgniteSqlAlterZoneSet parseAlterZoneSet(String stmt) throws SqlParseException {
+ SqlNode node = parse(stmt);
+
+ return assertInstanceOf(IgniteSqlAlterZoneSet.class, node);
+ }
+
+ /**
+ * Parse ALTER ZONE RENAME TO statement.
+ */
+ private IgniteSqlAlterZoneRenameTo parseAlterZoneRenameTo(String stmt) throws SqlParseException {
+ SqlNode node = parse(stmt);
+
+ return assertInstanceOf(IgniteSqlAlterZoneRenameTo.class, node);
+ }
+
+ /**
+ * Compares the result of calling {@link SqlNode#unparse(SqlWriter, int, int)}} on the given node with the expected string.
+ */
+ private static void expectUnparsed(SqlNode node, String expectedStmt) {
+ SqlPrettyWriter w = new SqlPrettyWriter();
+ node.unparse(w, 0, 0);
+
+ assertThat(w.toString(), equalTo(expectedStmt));
+ }
- return (IgniteSqlCreateZone) node;
+ private void assertSqlParseError(String stmt, String name) {
+ assertThrows(SqlParseException.class, () -> parse(stmt), name);
}
- private void assertThatZoneOptionPresent(List<SqlNode> optionList, IgniteSqlCreateZoneOptionEnum name, Object expVal) {
+ private void assertThatZoneOptionPresent(List<SqlNode> optionList, IgniteSqlZoneOptionEnum name, Object expVal) {
assertThat(optionList, Matchers.hasItem(ofTypeMatching(
name + "=" + expVal,
- IgniteSqlCreateZoneOption.class,
+ IgniteSqlZoneOption.class,
opt -> {
- if (name == opt.key().symbolValue(IgniteSqlCreateZoneOptionEnum.class)) {
+ if (name == opt.key().symbolValue(IgniteSqlZoneOptionEnum.class)) {
if (opt.value() instanceof SqlLiteral) {
return Objects.equals(expVal, ((SqlLiteral) opt.value()).getValueAs(expVal.getClass()));
}