Skip to content

Commit f375220

Browse files
committed
IGNITE-28556 Calcite. Support wrap_key and wrap_value flags
1 parent a4c4ab6 commit f375220

File tree

9 files changed

+504
-7
lines changed

9 files changed

+504
-7
lines changed

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@
6464

6565
import static org.apache.ignite.internal.processors.query.QueryUtils.convert;
6666
import static org.apache.ignite.internal.processors.query.QueryUtils.isDdlOnSchemaSupported;
67+
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.KEY_TYPE;
68+
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.VALUE_TYPE;
69+
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.WRAP_KEY;
70+
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.WRAP_VALUE;
6771

6872
/** */
6973
public class DdlCommandHandler {
@@ -136,6 +140,8 @@ private void handle0(CreateTableCommand cmd) throws IgniteCheckedException {
136140
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_EXISTS, cmd.tableName());
137141
}
138142

143+
checkKVWrappedParam(cmd);
144+
139145
CacheConfiguration<?, ?> ccfg = new CacheConfiguration<>(cmd.tableName());
140146

141147
QueryEntity e = toQueryEntity(cmd);
@@ -177,6 +183,37 @@ private void handle0(CreateTableCommand cmd) throws IgniteCheckedException {
177183
}
178184
}
179185

186+
/** */
187+
private void checkKVWrappedParam(CreateTableCommand cmd) {
188+
Boolean wrapKey = cmd.wrapKey();
189+
190+
if (wrapKey != null && !wrapKey) {
191+
if (cmd.primaryKeyColumns().size() > 1) {
192+
throw new IgniteSQLException(WRAP_KEY + " parameter cannot be \"false\" when composite primary key exists.",
193+
IgniteQueryErrorCode.PARSING);
194+
}
195+
196+
if (!F.isEmpty(cmd.keyTypeName())) {
197+
throw new IgniteSQLException(WRAP_KEY + " cannot be \"false\" when " + KEY_TYPE + " is defined.",
198+
IgniteQueryErrorCode.PARSING);
199+
}
200+
}
201+
202+
boolean wrapVal = cmd.wrapValue();
203+
204+
if (!wrapVal) {
205+
if (!cmd.primaryKeyColumns().isEmpty() && cmd.columns().size() - cmd.primaryKeyColumns().size() > 1) {
206+
throw new IgniteSQLException(WRAP_VALUE + " parameter cannot be \"false\" with multiple columns.",
207+
IgniteQueryErrorCode.PARSING);
208+
}
209+
210+
if (!F.isEmpty(cmd.valueTypeName())) {
211+
throw new IgniteSQLException(WRAP_VALUE + " cannot be \"false\" when " + VALUE_TYPE + " is defined.",
212+
IgniteQueryErrorCode.PARSING);
213+
}
214+
}
215+
}
216+
180217
/** */
181218
private void handle0(DropTableCommand cmd) throws IgniteCheckedException {
182219
isDdlOnSchemaSupported(cmd.schemaName());
@@ -214,7 +251,7 @@ private void handle0(AlterTableAddCommand cmd) throws IgniteCheckedException {
214251

215252
if (QueryUtils.isSqlType(typeDesc.valueClass())) {
216253
throw new SchemaOperationException("Cannot add column(s) because table was created " +
217-
"with WRAP_VALUE=false option.");
254+
"based on cache configured with built-in types or with " + WRAP_VALUE + "=false option.");
218255
}
219256

220257
List<QueryField> cols = new ArrayList<>(cmd.columns().size());
@@ -386,6 +423,22 @@ else if (!F.isEmpty(cmd.primaryKeyColumns()) && cmd.primaryKeyColumns().size() =
386423
res = new QueryEntityEx(res).implicitPk(true);
387424
}
388425

426+
if (!cmd.wrapValue()) {
427+
ColumnDefinition valCol = null;
428+
429+
for (ColumnDefinition col : cmd.columns()) {
430+
if (!cmd.primaryKeyColumns().contains(col.name())) {
431+
valCol = col;
432+
break;
433+
}
434+
}
435+
436+
if (valCol != null) {
437+
valTypeName = Commons.typeFactory().getResultClass(valCol.type()).getTypeName();
438+
res.setValueFieldName(valCol.name());
439+
}
440+
}
441+
389442
res.setValueType(F.isEmpty(cmd.valueTypeName()) ? valTypeName : cmd.valueTypeName());
390443
res.setKeyType(keyTypeName);
391444

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/ddl/CreateTableCommand.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.ignite.internal.processors.query.calcite.prepare.ddl;
1919

20+
import java.util.Collections;
2021
import java.util.List;
2122
import org.apache.calcite.sql.SqlInsert;
2223
import org.apache.ignite.cache.CacheAtomicityMode;
@@ -45,6 +46,12 @@ public class CreateTableCommand implements DdlCommand {
4546
/** Name of cache key type. */
4647
private String keyTypeName;
4748

49+
/** Wrap key flag. */
50+
private Boolean wrapKey;
51+
52+
/** Wrap value flag. */
53+
private boolean wrapValue = true;
54+
4855
/** Name of cache value type. */
4956
private String valTypeName;
5057

@@ -67,7 +74,7 @@ public class CreateTableCommand implements DdlCommand {
6774
private List<ColumnDefinition> cols;
6875

6976
/** Primary key columns. */
70-
private List<String> pkCols;
77+
private List<String> pkCols = Collections.emptyList();
7178

7279
/** Name of the column that represents affinity key. */
7380
private String affinityKey;
@@ -109,6 +116,34 @@ public void cacheName(String cacheName) {
109116
this.cacheName = cacheName;
110117
}
111118

119+
/**
120+
* @return wrap_key flag.
121+
*/
122+
@Nullable public Boolean wrapKey() {
123+
return wrapKey;
124+
}
125+
126+
/**
127+
* @param wrapKey wrap_key flag.
128+
*/
129+
public void wrapKey(boolean wrapKey) {
130+
this.wrapKey = wrapKey;
131+
}
132+
133+
/**
134+
* @return wrap_value flag.
135+
*/
136+
public boolean wrapValue() {
137+
return wrapValue;
138+
}
139+
140+
/**
141+
* @param wrapValue wrap_value flag.
142+
*/
143+
public void wrapValue(boolean wrapValue) {
144+
this.wrapValue = wrapValue;
145+
}
146+
112147
/**
113148
* @return Name of cache key type.
114149
*/

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/ddl/DdlSqlToCommandConverter.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Arrays;
2323
import java.util.HashSet;
2424
import java.util.List;
25+
import java.util.Locale;
2526
import java.util.Map;
2627
import java.util.Set;
2728
import java.util.function.BiConsumer;
@@ -74,6 +75,8 @@
7475
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.KEY_TYPE;
7576
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.TEMPLATE;
7677
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.VALUE_TYPE;
78+
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.WRAP_KEY;
79+
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.WRAP_VALUE;
7780
import static org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlCreateTableOptionEnum.WRITE_SYNCHRONIZATION_MODE;
7881
import static org.apache.ignite.internal.processors.query.calcite.util.PlanUtils.deriveObjectName;
7982
import static org.apache.ignite.internal.processors.query.calcite.util.PlanUtils.deriveSchemaName;
@@ -88,6 +91,20 @@ public class DdlSqlToCommandConverter {
8891
return ((SqlIdentifier)opt.value()).getSimple();
8992
};
9093

94+
/** Processor that validates that value can be parsed as boolean. */
95+
private static final BiFunction<IgniteSqlCreateTableOption, PlanningContext, Boolean> VALUE_IS_BOOL_IDENTIFIER_VALIDATOR =
96+
(opt, ctx) -> {
97+
SqlNode val = opt.value();
98+
if (!(val instanceof SqlIdentifier) || !((SqlIdentifier)val).isSimple())
99+
throwOptionParsingException(opt, "a simple identifier", ctx.query());
100+
101+
String simple = ((SqlIdentifier)val).getSimple().toLowerCase(Locale.ROOT);
102+
if (!"true".equals(simple) && !"false".equals(simple))
103+
throwOptionParsingException(opt, "Unexpected identifier: " + simple, ctx.query());
104+
105+
return Boolean.valueOf(((SqlIdentifier)val).getSimple());
106+
};
107+
91108
/** Processor that unconditionally throws an AssertionException. */
92109
private static final TableOptionProcessor<Void> UNSUPPORTED_OPTION_PROCESSOR = new TableOptionProcessor<>(
93110
null,
@@ -105,6 +122,8 @@ public class DdlSqlToCommandConverter {
105122
new TableOptionProcessor<>(DATA_REGION, VALUE_IS_IDENTIFIER_VALIDATOR, CreateTableCommand::dataRegionName),
106123
new TableOptionProcessor<>(KEY_TYPE, VALUE_IS_IDENTIFIER_VALIDATOR, CreateTableCommand::keyTypeName),
107124
new TableOptionProcessor<>(VALUE_TYPE, VALUE_IS_IDENTIFIER_VALIDATOR, CreateTableCommand::valueTypeName),
125+
new TableOptionProcessor<>(WRAP_KEY, VALUE_IS_BOOL_IDENTIFIER_VALIDATOR, CreateTableCommand::wrapKey),
126+
new TableOptionProcessor<>(WRAP_VALUE, VALUE_IS_BOOL_IDENTIFIER_VALIDATOR, CreateTableCommand::wrapValue),
108127
new TableOptionProcessor<>(ATOMICITY, validatorForEnumValue(CacheAtomicityMode.class), CreateTableCommand::atomicityMode),
109128
new TableOptionProcessor<>(WRITE_SYNCHRONIZATION_MODE, validatorForEnumValue(CacheWriteSynchronizationMode.class),
110129
CreateTableCommand::writeSynchronizationMode),

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateTableOptionEnum.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,10 @@ public enum IgniteSqlCreateTableOptionEnum {
5252

5353
/** This flag specified whether the encryption should be enabled for the underlying cache. */
5454
ENCRYPTED,
55+
56+
/** Flag controls whether a single column PRIMARY KEY should be wrapped in the BinaryObjects format. */
57+
WRAP_KEY,
58+
59+
/** Flag controls whether a single column value of a primitive type should be wrapped in the BinaryObjects format. */
60+
WRAP_VALUE,
5561
}

0 commit comments

Comments
 (0)