Skip to content

Commit 8f3e362

Browse files
authored
IGNITE-24071 Introduce the new value for REPLICAS parameter into CREATE ZONE and ALTER ZONE commands (#5167)
1 parent 0f4d6ea commit 8f3e362

File tree

9 files changed

+213
-106
lines changed

9 files changed

+213
-106
lines changed

modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateZoneCommand.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public List<UpdateEntry> get(UpdateContext updateContext) {
137137
}
138138

139139
private CatalogZoneDescriptor descriptor(int objectId) {
140-
CatalogZoneDescriptor zone = new CatalogZoneDescriptor(
140+
return new CatalogZoneDescriptor(
141141
objectId,
142142
zoneName,
143143
Objects.requireNonNullElse(partitions, DEFAULT_PARTITION_COUNT),
@@ -152,8 +152,6 @@ private CatalogZoneDescriptor descriptor(int objectId) {
152152
fromParams(storageProfileParams),
153153
Objects.requireNonNullElse(consistencyMode, STRONG_CONSISTENCY)
154154
);
155-
156-
return zone;
157155
}
158156

159157
private void validate() {

modules/partition-distribution/src/main/java/org/apache/ignite/internal/partitiondistribution/PartitionDistributionUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class PartitionDistributionUtils {
3838
* @param replicas Replicas count.
3939
* @return List assignments by partition.
4040
*/
41-
// TODO https://issues.apache.org/jira/browse/IGNITE-24071 pass the consensus group size as the parameter here
41+
// TODO https://issues.apache.org/jira/browse/IGNITE-24391 pass the consensus group size as the parameter here
4242
public static List<Set<Assignment>> calculateAssignments(
4343
Collection<String> dataNodes,
4444
int partitions,
@@ -62,7 +62,7 @@ public static List<Set<Assignment>> calculateAssignments(
6262
* @param replicas Replicas count.
6363
* @return Set of assignments.
6464
*/
65-
// TODO https://issues.apache.org/jira/browse/IGNITE-24071 pass the consensus group size as the parameter here
65+
// TODO https://issues.apache.org/jira/browse/IGNITE-24391 pass the consensus group size as the parameter here
6666
public static Set<Assignment> calculateAssignmentForPartition(
6767
Collection<String> dataNodes,
6868
int partitionId,

modules/sql-engine/src/main/codegen/config.fmpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ data: {
4444
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateZone",
4545
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlCreateSchema",
4646
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOption",
47+
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionMode",
4748
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropIndex",
4849
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropTable",
4950
"org.apache.ignite.internal.sql.engine.sql.IgniteSqlDropZone",

modules/sql-engine/src/main/codegen/includes/parserImpls.ftl

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,15 @@ void CreateZoneOption(List<SqlNode> list) :
564564
{
565565
key = SimpleIdentifier() { s = span(); }
566566
<EQ>
567-
val = Literal()
568-
{
569-
list.add(new IgniteSqlZoneOption(key, val, s.end(this)));
570-
}
567+
(
568+
<ALL> {
569+
list.add(new IgniteSqlZoneOption(key, IgniteSqlZoneOptionMode.ALL.symbol(getPos()), s.end(this)));
570+
}
571+
|
572+
val = Literal() {
573+
list.add(new IgniteSqlZoneOption(key, val, s.end(this)));
574+
}
575+
)
571576
}
572577

573578
SqlDrop SqlDropZone(Span s, boolean replace) :
@@ -635,12 +640,17 @@ void AlterZoneOption(List<SqlNode> list) :
635640
final SqlNode val;
636641
}
637642
{
638-
key = SimpleIdentifier() { s = span(); }
639-
<EQ>
640-
val = Literal()
641-
{
642-
list.add(new IgniteSqlZoneOption(key, val, s.end(this)));
643-
}
643+
key = SimpleIdentifier() { s = span(); }
644+
<EQ>
645+
(
646+
<ALL> {
647+
list.add(new IgniteSqlZoneOption(key, IgniteSqlZoneOptionMode.ALL.symbol(getPos()), s.end(this)));
648+
}
649+
|
650+
val = Literal() {
651+
list.add(new IgniteSqlZoneOption(key, val, s.end(this)));
652+
}
653+
)
644654
}
645655

646656
/**

modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ddl/DdlSqlToCommandConverter.java

Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
import org.apache.ignite.internal.catalog.commands.TableSortedPrimaryKey;
114114
import org.apache.ignite.internal.catalog.descriptors.CatalogColumnCollation;
115115
import org.apache.ignite.internal.catalog.descriptors.ConsistencyMode;
116+
import org.apache.ignite.internal.partitiondistribution.DistributionAlgorithm;
116117
import org.apache.ignite.internal.sql.engine.prepare.IgnitePlanner;
117118
import org.apache.ignite.internal.sql.engine.prepare.IgniteSqlValidator;
118119
import org.apache.ignite.internal.sql.engine.prepare.PlanningContext;
@@ -136,6 +137,7 @@
136137
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlPrimaryKeyIndexType;
137138
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlTypeNameSpec;
138139
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOption;
140+
import org.apache.ignite.internal.sql.engine.sql.IgniteSqlZoneOptionMode;
139141
import org.apache.ignite.internal.sql.engine.type.UuidType;
140142
import org.apache.ignite.internal.sql.engine.util.Commons;
141143
import org.apache.ignite.lang.IgniteException;
@@ -154,6 +156,12 @@ public class DdlSqlToCommandConverter {
154156
/** Mapping: Zone option ID -> DDL option info. */
155157
private final Map<ZoneOptionEnum, DdlOptionInfo<AlterZoneCommandBuilder, ?>> alterZoneOptionInfos;
156158

159+
/** DDL option info for an integer CREATE ZONE REPLICAS option. */
160+
private final DdlOptionInfo<CreateZoneCommandBuilder, Integer> createReplicasOptionInfo;
161+
162+
/** DDL option info for an integer ALTER ZONE REPLICAS option. */
163+
private final DdlOptionInfo<AlterZoneCommandBuilder, Integer> alterReplicasOptionInfo;
164+
157165
/** Zone options set. */
158166
private final Set<String> knownZoneOptionNames;
159167

@@ -168,7 +176,6 @@ public DdlSqlToCommandConverter() {
168176

169177
// CREATE ZONE options.
170178
zoneOptionInfos = new EnumMap<>(Map.of(
171-
REPLICAS, new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, CreateZoneCommandBuilder::replicas),
172179
PARTITIONS, new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, CreateZoneCommandBuilder::partitions),
173180
// TODO https://issues.apache.org/jira/browse/IGNITE-22162 appropriate setter method should be used.
174181
DISTRIBUTION_ALGORITHM, new DdlOptionInfo<>(String.class, null, (builder, params) -> {}),
@@ -185,9 +192,10 @@ public DdlSqlToCommandConverter() {
185192
(builder, params) -> builder.consistencyModeParams(parseConsistencyMode(params)))
186193
));
187194

195+
createReplicasOptionInfo = new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, CreateZoneCommandBuilder::replicas);
196+
188197
// ALTER ZONE options.
189198
alterZoneOptionInfos = new EnumMap<>(Map.of(
190-
REPLICAS, new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, AlterZoneCommandBuilder::replicas),
191199
PARTITIONS, new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, AlterZoneCommandBuilder::partitions),
192200
DATA_NODES_FILTER, new DdlOptionInfo<>(String.class, null, AlterZoneCommandBuilder::filter),
193201
DATA_NODES_AUTO_ADJUST,
@@ -197,6 +205,8 @@ public DdlSqlToCommandConverter() {
197205
DATA_NODES_AUTO_ADJUST_SCALE_DOWN,
198206
new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, AlterZoneCommandBuilder::dataNodesAutoAdjustScaleDown)
199207
));
208+
209+
alterReplicasOptionInfo = new DdlOptionInfo<>(Integer.class, this::checkPositiveNumber, AlterZoneCommandBuilder::replicas);
200210
}
201211

202212
/**
@@ -205,10 +215,10 @@ public DdlSqlToCommandConverter() {
205215
* @param consistencyMode String representation of consistency mode.
206216
* @return Consistency mode
207217
*/
208-
public static ConsistencyMode parseConsistencyMode(String consistencyMode) {
218+
private static ConsistencyMode parseConsistencyMode(String consistencyMode) {
209219
try {
210220
return ConsistencyMode.valueOf(consistencyMode);
211-
} catch (IllegalArgumentException e) {
221+
} catch (IllegalArgumentException ignored) {
212222
throw new SqlException(STMT_VALIDATION_ERR, "Failed to parse consistency mode: " + consistencyMode
213223
+ ". Valid values are: " + Arrays.toString(ConsistencyMode.values()));
214224
}
@@ -678,23 +688,7 @@ private CatalogCommand convertCreateZone(IgniteSqlCreateZone createZoneNode, Pla
678688
for (SqlNode optionNode : createZoneNode.createOptionList().getList()) {
679689
IgniteSqlZoneOption option = (IgniteSqlZoneOption) optionNode;
680690

681-
assert option.key().isSimple() : option.key();
682-
683-
String optionName = option.key().getSimple().toUpperCase();
684-
685-
DdlOptionInfo<CreateZoneCommandBuilder, ?> zoneOptionInfo = null;
686-
687-
if (remainingKnownOptions.remove(optionName)) {
688-
zoneOptionInfo = zoneOptionInfos.get(ZoneOptionEnum.valueOf(optionName));
689-
} else if (knownZoneOptionNames.contains(optionName)) {
690-
throw duplicateZoneOption(ctx, optionName);
691-
}
692-
693-
if (zoneOptionInfo == null) {
694-
throw unexpectedZoneOption(ctx, optionName);
695-
}
696-
697-
updateCommandOption("Zone", optionName, option.value(), zoneOptionInfo, ctx.query(), builder);
691+
updateZoneOption(option, remainingKnownOptions, zoneOptionInfos, createReplicasOptionInfo, ctx, builder);
698692
}
699693

700694
if (remainingKnownOptions.contains(STORAGE_PROFILES.name())) {
@@ -704,7 +698,6 @@ private CatalogCommand convertCreateZone(IgniteSqlCreateZone createZoneNode, Pla
704698
return builder.build();
705699
}
706700

707-
708701
/**
709702
* Converts the given '{@code ALTER ZONE}' AST to the {@link AlterZoneCommand} catalog command.
710703
*/
@@ -718,20 +711,8 @@ private CatalogCommand convertAlterZoneSet(IgniteSqlAlterZoneSet alterZoneSet, P
718711

719712
for (SqlNode optionNode : alterZoneSet.alterOptionsList().getList()) {
720713
IgniteSqlZoneOption option = (IgniteSqlZoneOption) optionNode;
721-
String optionName = option.key().getSimple().toUpperCase();
722-
723-
if (!knownZoneOptionNames.contains(optionName)) {
724-
throw unexpectedZoneOption(ctx, optionName);
725-
} else if (!remainingKnownOptions.remove(optionName)) {
726-
throw duplicateZoneOption(ctx, optionName);
727-
}
728-
729-
DdlOptionInfo<AlterZoneCommandBuilder, ?> zoneOptionInfo = alterZoneOptionInfos.get(ZoneOptionEnum.valueOf(optionName));
730714

731-
assert zoneOptionInfo != null : optionName;
732-
assert option.value() instanceof SqlLiteral : option.value();
733-
734-
updateCommandOption("Zone", optionName, option.value(), zoneOptionInfo, ctx.query(), builder);
715+
updateZoneOption(option, remainingKnownOptions, alterZoneOptionInfos, alterReplicasOptionInfo, ctx, builder);
735716
}
736717

737718
return builder.build();
@@ -809,7 +790,56 @@ private String deriveObjectName(SqlIdentifier id, PlanningContext ctx, String ob
809790
return objId.getSimple();
810791
}
811792

812-
private <S, T> void updateCommandOption(
793+
private <S> void updateZoneOption(
794+
IgniteSqlZoneOption option,
795+
Set<String> remainingKnownOptions,
796+
Map<ZoneOptionEnum, DdlOptionInfo<S, ?>> optionInfos,
797+
DdlOptionInfo<S, Integer> replicasOptionInfo,
798+
PlanningContext ctx,
799+
S target
800+
) {
801+
assert option.key().isSimple() : option.key();
802+
803+
String optionName = option.key().getSimple().toUpperCase();
804+
805+
if (!knownZoneOptionNames.contains(optionName)) {
806+
throw unexpectedZoneOption(ctx, optionName);
807+
} else if (!remainingKnownOptions.remove(optionName)) {
808+
throw duplicateZoneOption(ctx, optionName);
809+
}
810+
811+
ZoneOptionEnum zoneOption = ZoneOptionEnum.valueOf(optionName);
812+
DdlOptionInfo<S, ?> zoneOptionInfo = optionInfos.get(zoneOption);
813+
814+
// Options infos doesn't contain REPLICAS, it's handled separately
815+
assert zoneOptionInfo != null || zoneOption == REPLICAS : optionName;
816+
817+
assert option.value() instanceof SqlLiteral : option.value();
818+
SqlLiteral literal = (SqlLiteral) option.value();
819+
820+
if (zoneOption == REPLICAS) {
821+
if (literal.getTypeName() == SqlTypeName.SYMBOL) {
822+
IgniteSqlZoneOptionMode zoneOptionMode = literal.symbolValue(IgniteSqlZoneOptionMode.class);
823+
824+
if (zoneOptionMode != IgniteSqlZoneOptionMode.ALL) {
825+
throw new SqlException(STMT_VALIDATION_ERR, format(
826+
"Unexpected value of zone replicas [expected ALL, was {}; query=\"{}\"",
827+
zoneOptionMode, ctx.query()
828+
));
829+
}
830+
831+
// Directly set the option value and return
832+
replicasOptionInfo.setter.accept(target, DistributionAlgorithm.ALL_REPLICAS);
833+
return;
834+
} else {
835+
zoneOptionInfo = replicasOptionInfo;
836+
}
837+
}
838+
839+
updateCommandOption("Zone", optionName, literal, zoneOptionInfo, ctx.query(), target);
840+
}
841+
842+
private static <S, T> void updateCommandOption(
813843
String sqlObjName,
814844
Object optId,
815845
SqlNode value,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.sql.engine.sql;
19+
20+
import org.apache.calcite.sql.Symbolizable;
21+
22+
/**
23+
* Symbol for an {@code ALL} zone option.
24+
*/
25+
public enum IgniteSqlZoneOptionMode implements Symbolizable {
26+
ALL
27+
}

modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/ddl/AbstractDdlSqlToCommandConverterTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.apache.ignite.internal.sql.engine.util.Commons.FRAMEWORK_CONFIG;
2222
import static org.hamcrest.MatcherAssert.assertThat;
2323
import static org.hamcrest.Matchers.empty;
24+
import static org.hamcrest.Matchers.instanceOf;
2425
import static org.hamcrest.Matchers.not;
2526
import static org.mockito.Mockito.mock;
2627

@@ -38,7 +39,6 @@
3839
import org.apache.ignite.internal.sql.engine.prepare.PlanningContext;
3940
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
4041
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
41-
import org.hamcrest.Matchers;
4242

4343
/**
4444
* Common methods for {@link DdlSqlToCommandConverter} testing.
@@ -82,7 +82,7 @@ <T> T invokeAndGetFirstEntry(CatalogCommand cmd, Class<T> expected) {
8282

8383
UpdateEntry entry = entries.get(0);
8484

85-
assertThat(entry, Matchers.instanceOf(expected));
85+
assertThat(entry, instanceOf(expected));
8686

8787
return (T) entry;
8888
}

0 commit comments

Comments
 (0)