You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2018/01/09 07:36:54 UTC
[18/22] ignite git commit: IGNITE-5623: SQL: default column values
support for CREATE TABLE. This closes #3256.
IGNITE-5623: SQL: default column values support for CREATE TABLE. This closes #3256.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/78e79e01
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/78e79e01
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/78e79e01
Branch: refs/heads/ignite-zk
Commit: 78e79e011f1bb017653e628587faf606cfd37510
Parents: 2f2fa8b
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Fri Jan 5 12:08:54 2018 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Jan 5 12:08:54 2018 +0300
----------------------------------------------------------------------
.../jdbc/thin/JdbcThinMetadataSelfTest.java | 27 ++-
.../org/apache/ignite/cache/QueryEntity.java | 37 ++-
.../ignite/internal/binary/BinaryFieldImpl.java | 5 +
.../jdbc/thin/JdbcThinDatabaseMetadata.java | 2 +-
.../internal/jdbc/thin/JdbcThinTcpIo.java | 9 +-
.../processors/odbc/jdbc/JdbcColumnMeta.java | 7 +
.../processors/odbc/jdbc/JdbcColumnMetaV3.java | 83 +++++++
.../odbc/jdbc/JdbcConnectionContext.java | 6 +-
.../odbc/jdbc/JdbcMetaColumnsResultV3.java | 50 ++++
.../odbc/jdbc/JdbcRequestHandler.java | 13 +-
.../processors/odbc/jdbc/JdbcResult.java | 8 +
.../utils/PlatformConfigurationUtils.java | 10 +
.../processors/query/GridQueryProcessor.java | 2 +-
.../processors/query/GridQueryProperty.java | 7 +
.../query/GridQueryTypeDescriptor.java | 13 +-
.../internal/processors/query/QueryField.java | 21 ++
.../query/QueryTypeDescriptorImpl.java | 23 ++
.../internal/processors/query/QueryUtils.java | 17 +-
.../query/property/QueryBinaryProperty.java | 13 +-
.../query/property/QueryClassProperty.java | 5 +
.../query/h2/ddl/DdlStatementsProcessor.java | 13 +-
.../processors/query/h2/dml/UpdatePlan.java | 3 +
.../processors/query/h2/sql/GridSqlColumn.java | 10 +
.../query/h2/sql/GridSqlQueryParser.java | 34 ++-
.../query/IgniteSqlDefaultValueTest.java | 234 +++++++++++++++++++
.../h2/GridIndexingSpiAbstractSelfTest.java | 10 +
.../query/h2/sql/GridQueryParsingTest.java | 20 +-
.../IgniteCacheQuerySelfTestSuite.java | 3 +
.../QueryEntityConfigurationParityTest.cs | 3 +-
.../Cache/CacheConfigurationTest.cs | 5 +-
.../Cache/Query/CacheDmlQueriesTest.cs | 42 +++-
.../Config/full-config.xml | 4 +-
.../IgniteConfigurationSerializerTest.cs | 4 +-
.../Cache/Configuration/QueryEntity.cs | 3 +-
.../Cache/Configuration/QueryField.cs | 7 +
.../Configuration/QuerySqlFieldAttribute.cs | 5 +
.../IgniteConfigurationSection.xsd | 7 +
37 files changed, 721 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
index 2fd40d1..16b0ad5 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
@@ -138,7 +138,8 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
try (Connection conn = DriverManager.getConnection(URL)) {
Statement stmt = conn.createStatement();
- stmt.execute("CREATE TABLE TEST (ID INT, NAME VARCHAR(50), VAL VARCHAR(50), PRIMARY KEY (ID, NAME))");
+ stmt.execute("CREATE TABLE TEST (ID INT, NAME VARCHAR(50) default 'default name', " +
+ "age int default 21, VAL VARCHAR(50), PRIMARY KEY (ID, NAME))");
stmt.execute("CREATE TABLE \"Quoted\" (\"Id\" INT primary key, \"Name\" VARCHAR(50)) WITH WRAP_KEY");
stmt.execute("CREATE INDEX \"MyTestIndex quoted\" on \"Quoted\" (\"Id\" DESC)");
stmt.execute("CREATE INDEX IDX ON TEST (ID ASC)");
@@ -371,23 +372,25 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
ResultSet rs = meta.getColumns(null, null, null, null);
Set<String> expectedCols = new HashSet<>(Arrays.asList(
- "org.ORGANIZATION.ID",
- "org.ORGANIZATION.NAME",
- "pers.PERSON.ORGID",
- "pers.PERSON.AGE",
- "pers.PERSON.NAME",
- "PUBLIC.TEST.ID",
- "PUBLIC.TEST.NAME",
- "PUBLIC.TEST.VAL",
- "PUBLIC.Quoted.Id",
- "PUBLIC.Quoted.Name"));
+ "org.ORGANIZATION.ID.null",
+ "org.ORGANIZATION.NAME.null",
+ "pers.PERSON.ORGID.null",
+ "pers.PERSON.AGE.null",
+ "pers.PERSON.NAME.null",
+ "PUBLIC.TEST.ID.null",
+ "PUBLIC.TEST.NAME.'default name'",
+ "PUBLIC.TEST.VAL.null",
+ "PUBLIC.TEST.AGE.21",
+ "PUBLIC.Quoted.Id.null",
+ "PUBLIC.Quoted.Name.null"));
Set<String> actualCols = new HashSet<>(expectedCols.size());
while(rs.next()) {
actualCols.add(rs.getString("TABLE_SCHEM") + '.'
+ rs.getString("TABLE_NAME") + "."
- + rs.getString("COLUMN_NAME"));
+ + rs.getString("COLUMN_NAME") + "."
+ + rs.getString("COLUMN_DEF"));
}
assert expectedCols.equals(actualCols) : "expectedCols=" + expectedCols +
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 2002b4f..0065bae 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -86,6 +86,9 @@ public class QueryEntity implements Serializable {
/** Fields that must have non-null value. NB: DO NOT remove underscore to avoid clashes with QueryEntityEx. */
private Set<String> _notNullFields;
+ /** Fields default values. */
+ private Map<String, Object> defaultFieldValues = new HashMap<>();
+
/**
* Creates an empty query entity.
*/
@@ -114,6 +117,9 @@ public class QueryEntity implements Serializable {
tableName = other.tableName;
_notNullFields = other._notNullFields != null ? new HashSet<>(other._notNullFields) : null;
+
+ defaultFieldValues = other.defaultFieldValues != null ? new HashMap<>(other.defaultFieldValues)
+ : new HashMap<String, Object>();
}
/**
@@ -355,9 +361,12 @@ public class QueryEntity implements Serializable {
* Sets table name for this query entity.
*
* @param tableName table name
+ * @return {@code this} for chaining.
*/
- public void setTableName(String tableName) {
+ public QueryEntity setTableName(String tableName) {
this.tableName = tableName;
+
+ return this;
}
/**
@@ -382,6 +391,27 @@ public class QueryEntity implements Serializable {
}
/**
+ * Gets fields default values.
+ *
+ * @return Field's name to default value map.
+ */
+ public Map<String, Object> getDefaultFieldValues() {
+ return defaultFieldValues;
+ }
+
+ /**
+ * Sets fields default values.
+ *
+ * @param defaultFieldValues Field's name to default value map.
+ * @return {@code this} for chaining.
+ */
+ public QueryEntity setDefaultFieldValues(Map<String, Object> defaultFieldValues) {
+ this.defaultFieldValues = defaultFieldValues;
+
+ return this;
+ }
+
+ /**
* Utility method for building query entities programmatically.
*
* @param fullName Full name of the field.
@@ -639,13 +669,14 @@ public class QueryEntity implements Serializable {
F.eq(aliases, entity.aliases) &&
F.eqNotOrdered(idxs, entity.idxs) &&
F.eq(tableName, entity.tableName) &&
- F.eq(_notNullFields, entity._notNullFields);
+ F.eq(_notNullFields, entity._notNullFields) &&
+ F.eq(defaultFieldValues, entity.defaultFieldValues);
}
/** {@inheritDoc} */
@Override public int hashCode() {
return Objects.hash(keyType, valType, keyFieldName, valueFieldName, fields, keyFields, aliases, idxs,
- tableName, _notNullFields);
+ tableName, _notNullFields, defaultFieldValues);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java
index 59bd03d..883576c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java
@@ -56,6 +56,8 @@ public class BinaryFieldImpl implements BinaryFieldEx {
/**
* Constructor.
*
+ * @param ctx Binary context.
+ * @param typeId Type ID.
* @param schemas Schemas.
* @param fieldName Field name.
* @param fieldId Field ID.
@@ -278,6 +280,9 @@ public class BinaryFieldImpl implements BinaryFieldEx {
int schemaId = obj.schemaId();
+ if (schemaId == 0)
+ return BinarySchema.ORDER_NOT_FOUND;
+
BinarySchema schema = schemas.schema(schemaId);
if (schema == null) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
index cfc3b68..dd8b733 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
@@ -852,7 +852,7 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData {
row.add(10); // 10. NUM_PREC_RADIX
row.add(colMeta.isNullable() ? columnNullable : columnNoNulls); // 11. NULLABLE
row.add((String)null); // 12. REMARKS
- row.add((String)null); // 13. COLUMN_DEF
+ row.add(colMeta.defaultValue()); // 13. COLUMN_DEF
row.add(colMeta.dataType()); // 14. SQL_DATA_TYPE
row.add((Integer)null); // 15. SQL_DATETIME_SUB
row.add(Integer.MAX_VALUE); // 16. CHAR_OCTET_LENGTH
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index 4d23934..fec218e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -74,8 +74,11 @@ public class JdbcThinTcpIo {
/** Version 2.3.1. */
private static final ClientListenerProtocolVersion VER_2_3_0 = ClientListenerProtocolVersion.create(2, 3, 0);
+ /** Version 2.4.0. */
+ private static final ClientListenerProtocolVersion VER_2_4_0 = ClientListenerProtocolVersion.create(2, 4, 0);
+
/** Current version. */
- private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_0;
+ private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_4_0;
/** Initial output stream capacity for handshake. */
private static final int HANDSHAKE_MSG_SIZE = 13;
@@ -212,8 +215,8 @@ public class JdbcThinTcpIo {
ClientListenerProtocolVersion srvProtocolVer = ClientListenerProtocolVersion.create(maj, min, maintenance);
- if (VER_2_1_5.equals(srvProtocolVer))
- handshake(VER_2_1_5);
+ if (VER_2_3_0.equals(srvProtocolVer) || VER_2_1_5.equals(srvProtocolVer))
+ handshake(srvProtocolVer);
else if (VER_2_1_0.equals(srvProtocolVer))
handshake_2_1_0();
else {
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
index d927c26..c0ac322 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
@@ -128,6 +128,13 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
}
/**
+ * @return Column's default value.
+ */
+ public String defaultValue() {
+ return null;
+ }
+
+ /**
* Return 'nullable' flag in compatibility mode (according with column name and column type).
*
* @return {@code true} in case the column allows null values. Otherwise returns {@code false}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV3.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV3.java
new file mode 100644
index 0000000..9911be0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV3.java
@@ -0,0 +1,83 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC column metadata V3.
+ */
+public class JdbcColumnMetaV3 extends JdbcColumnMetaV2 {
+ /** Default value. */
+ private String dfltValue;
+
+ /**
+ * Default constructor is used for serialization.
+ */
+ JdbcColumnMetaV3() {
+ // No-op.
+ }
+
+ /**
+ * @param schemaName Schema.
+ * @param tblName Table.
+ * @param colName Column.
+ * @param cls Type.
+ * @param nullable Allow nulls.
+ * @param dfltVal Default value.
+ */
+ public JdbcColumnMetaV3(String schemaName, String tblName, String colName, Class<?> cls, boolean nullable,
+ Object dfltVal) {
+ super(schemaName, tblName, colName, cls, nullable);
+
+ if (dfltVal == null)
+ dfltValue = null;
+ else {
+ if (dfltVal instanceof String)
+ dfltValue = "'" + String.valueOf(dfltVal) + "'";
+ else
+ dfltValue = String.valueOf(dfltVal);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String defaultValue() {
+ return dfltValue;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriterExImpl writer) {
+ super.writeBinary(writer);
+
+ writer.writeString(dfltValue);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReaderExImpl reader) {
+ super.readBinary(reader);
+
+ dfltValue = reader.readString();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(JdbcColumnMetaV3.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
index 7b40466..5841a4d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
@@ -40,8 +40,11 @@ public class JdbcConnectionContext implements ClientListenerConnectionContext {
/** Version 2.3.1: added "multiple statements query" feature. */
public static final ClientListenerProtocolVersion VER_2_3_0 = ClientListenerProtocolVersion.create(2, 3, 0);
+ /** Version 2.4.0: adds default values for columns feature. */
+ public static final ClientListenerProtocolVersion VER_2_4_0 = ClientListenerProtocolVersion.create(2, 4, 0);
+
/** Current version. */
- private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_0;
+ private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_4_0;
/** Supported versions. */
private static final Set<ClientListenerProtocolVersion> SUPPORTED_VERS = new HashSet<>();
@@ -63,6 +66,7 @@ public class JdbcConnectionContext implements ClientListenerConnectionContext {
static {
SUPPORTED_VERS.add(CURRENT_VER);
+ SUPPORTED_VERS.add(VER_2_3_0);
SUPPORTED_VERS.add(VER_2_1_5);
SUPPORTED_VERS.add(VER_2_1_0);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV3.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV3.java
new file mode 100644
index 0000000..0cee9b7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV3.java
@@ -0,0 +1,50 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.Collection;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC columns metadata result.
+ */
+public class JdbcMetaColumnsResultV3 extends JdbcMetaColumnsResult {
+ /**
+ * Default constructor is used for deserialization.
+ */
+ JdbcMetaColumnsResultV3() {
+ super(META_COLUMNS_V3);
+ }
+
+ /**
+ * @param meta Columns metadata.
+ */
+ JdbcMetaColumnsResultV3(Collection<JdbcColumnMeta> meta) {
+ super(META_COLUMNS_V3, meta);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected JdbcColumnMeta createMetaColumn() {
+ return new JdbcColumnMetaV3();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(JdbcMetaColumnsResultV3.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index e3b6f5b..458c99c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -54,6 +54,7 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcConnectionContext.VER_2_3_0;
+import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcConnectionContext.VER_2_4_0;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.BATCH_EXEC;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_COLUMNS;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_INDEXES;
@@ -592,7 +593,13 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
JdbcColumnMeta columnMeta;
- if (protocolVer.compareTo(VER_2_3_0) >= 0) {
+ if (protocolVer.compareTo(VER_2_4_0) >= 0) {
+ GridQueryProperty prop = table.property(colName);
+
+ columnMeta = new JdbcColumnMetaV3(table.schemaName(), table.tableName(),
+ field.getKey(), field.getValue(), !prop.notNull(), prop.defaultValue());
+ }
+ else if (protocolVer.compareTo(VER_2_3_0) >= 0) {
GridQueryProperty prop = table.property(colName);
columnMeta = new JdbcColumnMetaV2(table.schemaName(), table.tableName(),
@@ -610,7 +617,9 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
JdbcMetaColumnsResult res;
- if (protocolVer.compareTo(VER_2_3_0) >= 0)
+ if (protocolVer.compareTo(VER_2_4_0) >= 0)
+ res = new JdbcMetaColumnsResultV3(meta);
+ else if (protocolVer.compareTo(VER_2_3_0) >= 0)
res = new JdbcMetaColumnsResultV2(meta);
else
res = new JdbcMetaColumnsResult(meta);
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
index 6d460e6..623a339 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
@@ -62,6 +62,9 @@ public class JdbcResult implements JdbcRawBinarylizable {
/** Columns metadata result V2. */
static final byte META_COLUMNS_V2 = 14;
+ /** Columns metadata result V3. */
+ static final byte META_COLUMNS_V3 = 15;
+
/** Success status. */
private byte type;
@@ -155,6 +158,11 @@ public class JdbcResult implements JdbcRawBinarylizable {
break;
+ case META_COLUMNS_V3:
+ res = new JdbcMetaColumnsResultV3();
+
+ break;
+
default:
throw new IgniteException("Unknown SQL listener request ID: [request ID=" + resId + ']');
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
index b048f48..c4c354e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
@@ -489,6 +489,7 @@ public class PlatformConfigurationUtils {
int cnt = in.readInt();
Set<String> keyFields = new HashSet<>(cnt);
Set<String> notNullFields = new HashSet<>(cnt);
+ Map<String, Object> defVals = new HashMap<>(cnt);
if (cnt > 0) {
LinkedHashMap<String, String> fields = new LinkedHashMap<>(cnt);
@@ -504,6 +505,10 @@ public class PlatformConfigurationUtils {
if (in.readBoolean())
notNullFields.add(fieldName);
+
+ Object defVal = in.readObject();
+ if (defVal != null)
+ defVals.put(fieldName, defVal);
}
res.setFields(fields);
@@ -513,6 +518,9 @@ public class PlatformConfigurationUtils {
if (!notNullFields.isEmpty())
res.setNotNullFields(notNullFields);
+
+ if (!defVals.isEmpty())
+ res.setDefaultFieldValues(defVals);
}
// Aliases
@@ -996,6 +1004,7 @@ public class PlatformConfigurationUtils {
if (fields != null) {
Set<String> keyFields = qryEntity.getKeyFields();
Set<String> notNullFields = qryEntity.getNotNullFields();
+ Map<String, Object> defVals = qryEntity.getDefaultFieldValues();
writer.writeInt(fields.size());
@@ -1004,6 +1013,7 @@ public class PlatformConfigurationUtils {
writer.writeString(field.getValue());
writer.writeBoolean(keyFields != null && keyFields.contains(field.getKey()));
writer.writeBoolean(notNullFields != null && notNullFields.contains(field.getKey()));
+ writer.writeObject(defVals != null ? defVals.get(field.getKey()) : null);
}
}
else
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index dbe2e9b..ab84a1a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -2423,7 +2423,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
for (QueryField col : cols) {
try {
props.add(new QueryBinaryProperty(ctx, col.name(), null, Class.forName(col.typeName()),
- false, null, !col.isNullable()));
+ false, null, !col.isNullable(), null));
}
catch (ClassNotFoundException e) {
throw new SchemaOperationException("Class not found for new property: " + col.typeName());
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
index c8ae212..b258b7c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
@@ -70,4 +70,11 @@ public interface GridQueryProperty {
* @return {@code true} if property does not allow {@code null} value.
*/
public boolean notNull();
+
+ /**
+ * Gets the default value for this property.
+ *
+ * @return {@code null} if a default value is not set for the property.
+ */
+ public Object defaultValue();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
index dcf850c..8a23e50 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.processors.query;
import java.util.Map;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.CacheObject;
+import org.apache.ignite.internal.util.lang.GridMapEntry;
import org.jetbrains.annotations.Nullable;
/**
@@ -177,4 +179,13 @@ public interface GridQueryTypeDescriptor {
* @throws IgniteCheckedException, If failure happens.
*/
public void validateKeyAndValue(Object key, Object val) throws IgniteCheckedException;
-}
\ No newline at end of file
+
+ /**
+ * Sets defaults value for given key and value.
+ *
+ * @param key Key.
+ * @param val Value.
+ * @throws IgniteCheckedException If failed.
+ */
+ public void setDefaults(Object key, Object val) throws IgniteCheckedException;
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
index 8c7d367..1a75ef1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
@@ -37,15 +37,29 @@ public class QueryField implements Serializable {
/** Nullable flag. */
private final boolean nullable;
+ /** Default value. */
+ private final Object dfltValue;
+
/**
* @param name Field name.
* @param typeName Class name for this field's values.
* @param nullable Nullable flag.
*/
public QueryField(String name, String typeName, boolean nullable) {
+ this(name, typeName, nullable, null);
+ }
+
+ /**
+ * @param name Field name.
+ * @param typeName Class name for this field's values.
+ * @param nullable Nullable flag.
+ * @param dfltValue Default value.
+ */
+ public QueryField(String name, String typeName, boolean nullable, Object dfltValue) {
this.name = name;
this.typeName = typeName;
this.nullable = nullable;
+ this.dfltValue = dfltValue;
}
/**
@@ -69,6 +83,13 @@ public class QueryField implements Serializable {
return nullable;
}
+ /**
+ * @return Default value.
+ */
+ public Object defaultValue() {
+ return dfltValue;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(QueryField.class, this);
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
index de58a4d..a7710f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
@@ -107,6 +107,9 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
/** */
private List<GridQueryProperty> validateProps;
+ /** */
+ private List<GridQueryProperty> propsWithDefaultValue;
+
/**
* Constructor.
*
@@ -380,6 +383,13 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
validateProps.add(prop);
}
+ if (prop.defaultValue() != null) {
+ if (propsWithDefaultValue == null)
+ propsWithDefaultValue = new ArrayList<>();
+
+ propsWithDefaultValue.add(prop);
+ }
+
fields.put(name, prop.type());
}
@@ -537,4 +547,17 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
throw new IgniteSQLException("Null value is not allowed for column '" + prop.name() + "'", errCode);
}
}
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ @Override public void setDefaults(Object key, Object val) throws IgniteCheckedException {
+ if (F.isEmpty(propsWithDefaultValue))
+ return;
+
+ for (int i = 0; i < propsWithDefaultValue.size(); ++i) {
+ GridQueryProperty prop = propsWithDefaultValue.get(i);
+
+ prop.setValue(key, val, prop.defaultValue());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
index 91509f4..3397492 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
@@ -241,6 +241,7 @@ public class QueryUtils {
normalEntity.setKeyFieldName(entity.getKeyFieldName());
normalEntity.setValueFieldName(entity.getValueFieldName());
normalEntity.setNotNullFields(entity.getNotNullFields());
+ normalEntity.setDefaultFieldValues(entity.getDefaultFieldValues());
// Normalize table name.
String normalTblName = entity.getTableName();
@@ -515,6 +516,7 @@ public class QueryUtils {
throws IgniteCheckedException {
Set<String> keyFields = qryEntity.getKeyFields();
Set<String> notNulls = qryEntity.getNotNullFields();
+ Map<String, Object> dlftVals = qryEntity.getDefaultFieldValues();
// We have to distinguish between empty and null keyFields when the key is not of SQL type -
// when a key is not of SQL type, absence of a field in nonnull keyFields tell us that this field
@@ -543,9 +545,11 @@ public class QueryUtils {
boolean notNull = notNulls != null && notNulls.contains(entry.getKey());
+ Object dfltVal = dlftVals != null ? dlftVals.get(entry.getKey()) : null;
+
QueryBinaryProperty prop = buildBinaryProperty(ctx, entry.getKey(),
U.classForName(entry.getValue(), Object.class, true),
- d.aliases(), isKeyField, notNull);
+ d.aliases(), isKeyField, notNull, dfltVal);
d.addProperty(prop, false);
}
@@ -688,10 +692,12 @@ public class QueryUtils {
* @param isKeyField Key ownership flag, as defined in {@link QueryEntity#keyFields}: {@code true} if field belongs
* to key, {@code false} if it belongs to value, {@code null} if QueryEntity#keyFields is null.
* @param notNull {@code true} if {@code null} value is not allowed.
+ * @param dlftVal Default value.
* @return Binary property.
+ * @throws IgniteCheckedException On error.
*/
public static QueryBinaryProperty buildBinaryProperty(GridKernalContext ctx, String pathStr, Class<?> resType,
- Map<String, String> aliases, @Nullable Boolean isKeyField, boolean notNull) throws IgniteCheckedException {
+ Map<String, String> aliases, @Nullable Boolean isKeyField, boolean notNull, Object dlftVal) throws IgniteCheckedException {
String[] path = pathStr.split("\\.");
QueryBinaryProperty res = null;
@@ -707,7 +713,7 @@ public class QueryUtils {
String alias = aliases.get(fullName.toString());
// The key flag that we've found out is valid for the whole path.
- res = new QueryBinaryProperty(ctx, prop, res, resType, isKeyField, alias, notNull);
+ res = new QueryBinaryProperty(ctx, prop, res, resType, isKeyField, alias, notNull, dlftVal);
}
return res;
@@ -1365,5 +1371,10 @@ public class QueryUtils {
@Override public boolean notNull() {
return true;
}
+
+ /** {@inheritDoc} */
+ @Override public Object defaultValue() {
+ return null;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
index 18508a8..f440d12 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
@@ -68,6 +68,9 @@ public class QueryBinaryProperty implements GridQueryProperty {
/** */
private final boolean notNull;
+ /** */
+ private final Object defaultValue;
+
/**
* Constructor.
*
@@ -78,9 +81,10 @@ public class QueryBinaryProperty implements GridQueryProperty {
* @param key {@code true} if key property, {@code false} otherwise, {@code null} if unknown.
* @param alias Field alias.
* @param notNull {@code true} if null value is not allowed.
+ * @param defaultValue Default value.
*/
public QueryBinaryProperty(GridKernalContext ctx, String propName, QueryBinaryProperty parent,
- Class<?> type, @Nullable Boolean key, String alias, boolean notNull) {
+ Class<?> type, @Nullable Boolean key, String alias, boolean notNull, Object defaultValue) {
this.ctx = ctx;
log = ctx.log(QueryBinaryProperty.class);
@@ -93,6 +97,8 @@ public class QueryBinaryProperty implements GridQueryProperty {
if (key != null)
this.isKeyProp = key ? 1 : -1;
+
+ this.defaultValue = defaultValue;
}
/** {@inheritDoc} */
@@ -275,4 +281,9 @@ public class QueryBinaryProperty implements GridQueryProperty {
@Override public boolean notNull() {
return notNull;
}
+
+ /** {@inheritDoc} */
+ @Override public Object defaultValue() {
+ return defaultValue;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
index 076a769..575fe17 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
@@ -141,4 +141,9 @@ public class QueryClassProperty implements GridQueryProperty {
@Override public boolean notNull() {
return notNull;
}
+
+ /** {@inheritDoc} */
+ @Override public Object defaultValue() {
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
index b198922..01629ce 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.query.h2.ddl;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -347,7 +348,7 @@ public class DdlStatementsProcessor {
QueryField field = new QueryField(col.columnName(),
DataType.getTypeClassName(col.column().getType()),
- col.column().isNullable());
+ col.column().isNullable(), col.defaultValue());
cols.add(field);
@@ -504,6 +505,8 @@ public class DdlStatementsProcessor {
Set<String> notNullFields = null;
+ HashMap<String, Object> dfltValues = new HashMap<>();
+
for (Map.Entry<String, GridSqlColumn> e : createTbl.columns().entrySet()) {
GridSqlColumn gridCol = e.getValue();
@@ -517,8 +520,16 @@ public class DdlStatementsProcessor {
notNullFields.add(e.getKey());
}
+
+ Object dfltVal = gridCol.defaultValue();
+
+ if (dfltVal != null)
+ dfltValues.put(e.getKey(), dfltVal);
}
+ if (!F.isEmpty(dfltValues))
+ res.setDefaultFieldValues(dfltValues);
+
String valTypeName = QueryUtils.createTableValueTypeName(createTbl.schemaName(), createTbl.tableName());
String keyTypeName = QueryUtils.createTableKeyTypeName(valTypeName);
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java
index 6a45c3c..5625e37 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java
@@ -237,6 +237,8 @@ public final class UpdatePlan {
newColVals.put(colName, DmlUtils.convert(row.get(i), rowDesc, expCls, colTypes[i]));
}
+ desc.setDefaults(key, val);
+
// We update columns in the order specified by the table for a reason - table's
// column order preserves their precedence for correct update of nested properties.
Column[] cols = tbl.getColumns();
@@ -274,6 +276,7 @@ public final class UpdatePlan {
*
* @param row Row to process.
* @throws IgniteCheckedException if failed.
+ * @return Tuple contains: [key, old value, new value]
*/
public T3<Object, Object, Object> processRowForUpdate(List<?> row) throws IgniteCheckedException {
GridH2RowDescriptor rowDesc = tbl.rowDescriptor();
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlColumn.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlColumn.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlColumn.java
index ef460e3..bc14ae2 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlColumn.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlColumn.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.query.h2.sql;
import java.util.Collections;
import org.apache.ignite.internal.util.typedef.F;
import org.h2.command.Parser;
+import org.h2.expression.Expression;
import org.h2.table.Column;
/**
@@ -119,6 +120,15 @@ public class GridSqlColumn extends GridSqlElement {
}
/**
+ * @return Default value.
+ */
+ public Object defaultValue() {
+ Expression dfltExpr = col.getDefaultExpression();
+
+ return dfltExpr != null ? col.convert(dfltExpr.getValue(null)).getObject() : null;
+ }
+
+ /**
* @return H2 Column.
*/
public Column column() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index 388231f..61d7510 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -95,6 +95,7 @@ import org.h2.table.Table;
import org.h2.table.TableBase;
import org.h2.table.TableFilter;
import org.h2.table.TableView;
+import org.h2.value.DataType;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.AND;
@@ -1199,9 +1200,23 @@ public class GridSqlQueryParser {
throw new IgniteSQLException("Computed columns are not supported [colName=" + col.getName() + ']',
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
- if (col.getDefaultExpression() != null)
- throw new IgniteSQLException("DEFAULT expressions are not supported [colName=" + col.getName() + ']',
- IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+ if (col.getDefaultExpression() != null) {
+ if (!col.getDefaultExpression().isConstant()) {
+ throw new IgniteSQLException("Non-constant DEFAULT expressions are not supported [colName=" + col.getName() + ']',
+ IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+ }
+
+ DataType colType = DataType.getDataType(col.getType());
+ DataType dfltType = DataType.getDataType(col.getDefaultExpression().getType());
+
+ if ((DataType.isStringType(colType.type) && !DataType.isStringType(dfltType.type))
+ || (DataType.supportsAdd(colType.type) && !DataType.supportsAdd(dfltType.type))) {
+ throw new IgniteSQLException("Invalid default value for column. [colName=" + col.getName()
+ + ", colType=" + colType.name
+ + ", dfltValueType=" + dfltType.name + ']',
+ IgniteQueryErrorCode.UNEXPECTED_ELEMENT_TYPE);
+ }
+ }
if (col.getSequence() != null)
throw new IgniteSQLException("SEQUENCE columns are not supported [colName=" + col.getName() + ']',
@@ -1225,13 +1240,15 @@ public class GridSqlQueryParser {
/**
* Parse {@code ALTER TABLE ... ADD COLUMN} statement.
* @param addCol H2 statement.
+ * @return Grid SQL statement.
+ *
* @see <a href="http://www.h2database.com/html/grammar.html#alter_table_add"></a>
*/
private GridSqlStatement parseAddColumn(AlterTableAlterColumn addCol) {
assert addCol.getType() == CommandInterface.ALTER_TABLE_ADD_COLUMN;
if (ALTER_COLUMN_BEFORE_COL.get(addCol) != null || ALTER_COLUMN_AFTER_COL.get(addCol) != null)
- throw new IgniteSQLException("ALTER TABLE ADD COLUMN BEFORE/AFTER is not supported",
+ throw new IgniteSQLException("ALTER TABLE ADD COLUMN BEFORE/AFTER is not supported" ,
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
GridSqlAlterTableAddColumn res = new GridSqlAlterTableAddColumn();
@@ -1240,8 +1257,15 @@ public class GridSqlQueryParser {
GridSqlColumn[] gridNewCols = new GridSqlColumn[h2NewCols.size()];
- for (int i = 0; i < h2NewCols.size(); i++)
+ for (int i = 0; i < h2NewCols.size(); i++) {
+ Column col = h2NewCols.get(i);
+
+ if (col.getDefaultExpression() != null)
+ throw new IgniteSQLException("ALTER TABLE ADD COLUMN with DEFAULT value is not supported " +
+ "[col=" + col.getName() + ']', IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+
gridNewCols[i] = parseColumn(h2NewCols.get(i));
+ }
res.columns(gridNewCols);
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultValueTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultValueTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultValueTest.java
new file mode 100644
index 0000000..6747e28
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultValueTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.processors.query;
+
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/** */
+@SuppressWarnings("ThrowableNotThrown")
+public class IgniteSqlDefaultValueTest extends GridCommonAbstractTest {
+ /** IP finder. */
+ private static final TcpDiscoveryVmIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** Name of client node. */
+ private static final String NODE_CLIENT = "client";
+
+ /** Number of server nodes. */
+ private static final int NODE_COUNT = 2;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration c = super.getConfiguration(gridName);
+
+ TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+ disco.setIpFinder(IP_FINDER);
+ disco.setForceServerMode(true);
+
+ c.setDiscoverySpi(disco);
+
+ if (gridName.equals(NODE_CLIENT))
+ c.setClientMode(true);
+
+ return c;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGrids(NODE_COUNT);
+
+ startGrid(NODE_CLIENT);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+
+ super.afterTestsStopped();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ Collection<String> tblNames = new ArrayList<>();
+
+ for (String cacheName : grid(0).context().cache().publicCacheNames()) {
+ for (GridQueryTypeDescriptor table : grid(0).context().query().types(cacheName))
+ tblNames.add(table.tableName());
+ }
+
+ for (String tbl : tblNames)
+ sql("DROP TABLE " + tbl);
+
+ super.afterTest();
+ }
+
+ /**
+ */
+ public void testDefaultValueColumn() {
+ sql("CREATE TABLE TEST (id int, val0 varchar DEFAULT 'default-val', primary key (id))");
+ sql("INSERT INTO TEST (id) VALUES (?)", 1);
+ sql("INSERT INTO TEST (id, val0) VALUES (?, ?)", 2, null);
+ sql("INSERT INTO TEST (id, val0) VALUES (?, ?)", 3, "test-val");
+
+ List<List<Object>> exp = Arrays.asList(
+ Arrays.<Object>asList(1, "default-val"),
+ Arrays.<Object>asList(2, null),
+ Arrays.<Object>asList(3, "test-val")
+ );
+
+ List<List<?>> res = sql("select id, val0 from TEST");
+
+ checkResults(exp, res);
+ }
+
+ /**
+ */
+ public void testDefaultValueColumnAfterUpdate() {
+ sql("CREATE TABLE TEST (id int, val0 varchar DEFAULT 'default-val', val1 varchar, primary key (id))");
+ sql("INSERT INTO TEST (id, val1) VALUES (?, ?)", 1, "val-10");
+ sql("INSERT INTO TEST (id, val1) VALUES (?, ?)", 2, "val-20");
+ sql("INSERT INTO TEST (id, val1) VALUES (?, ?)", 3, "val-30");
+
+ List<List<Object>> exp = Arrays.asList(
+ Arrays.<Object>asList(1, "default-val", "val-10"),
+ Arrays.<Object>asList(2, "default-val", "val-20"),
+ Arrays.<Object>asList(3, "default-val", "val-30")
+ );
+
+ List<List<?>> res = sql("select id, val0, val1 from TEST");
+
+ checkResults(exp, res);
+
+ sql("UPDATE TEST SET val1=? where id=?", "val-21", 2);
+
+ List<List<Object>> expAfterUpdate = Arrays.asList(
+ Arrays.<Object>asList(1, "default-val", "val-10"),
+ Arrays.<Object>asList(2, "default-val", "val-21"),
+ Arrays.<Object>asList(3, "default-val", "val-30")
+ );
+
+ List<List<?>> resAfterUpdate = sql("select id, val0, val1 from TEST");
+
+ checkResults(expAfterUpdate, resAfterUpdate);
+ }
+
+ /**
+ */
+ public void testEmptyValueNullDefaults() {
+ sql("CREATE TABLE TEST (id int, val0 varchar, primary key (id))");
+ sql("INSERT INTO TEST (id) VALUES (?)", 1);
+ sql("INSERT INTO TEST (id, val0) VALUES (?, ?)", 2, "test-val");
+
+ List<List<Object>> expected = Arrays.asList(
+ Arrays.<Object>asList(1, null),
+ Arrays.<Object>asList(2, "test-val")
+ );
+
+ List<List<?>> res = sql("select id, val0 from TEST");
+
+ checkResults(expected, res);
+ }
+
+ /**
+ */
+ public void testAddColumnWithDefaults() {
+ sql("CREATE TABLE TEST (id int, val0 varchar, primary key (id))");
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() {
+ sql("ALTER TABLE TEST ADD COLUMN val1 varchar DEFAULT 'default-val'");
+
+ return null;
+ }
+ }, IgniteSQLException.class, "ALTER TABLE ADD COLUMN with DEFAULT value is not supported");
+ }
+
+ /**
+ */
+ public void testDefaultTypes() {
+ assertEquals("Check tinyint", (byte)28, getDefaultObject("TINYINT", "28"));
+ assertEquals("Check smallint", (short)28, getDefaultObject("SMALLINT", "28"));
+ assertEquals("Check int", 28, getDefaultObject("INT", "28"));
+ assertEquals("Check double", 28.25, getDefaultObject("DOUBLE", "28.25"));
+ assertEquals("Check float", 28.25, getDefaultObject("FLOAT", "28.25"));
+ assertEquals("Check decimal", BigDecimal.valueOf(28.25), getDefaultObject("DECIMAL", "28.25"));
+ assertEquals("Check varchar", "test value", getDefaultObject("VARCHAR", "'test value'"));
+ assertEquals("Check time", Time.valueOf("14:01:01"), getDefaultObject("TIME", "'14:01:01'"));
+ assertEquals("Check date", Date.valueOf("2017-12-29"), getDefaultObject("DATE", "'2017-12-29'"));
+ assertEquals("Check timestamp", Timestamp.valueOf("2017-12-29 14:01:01"),
+ getDefaultObject("TIMESTAMP", "'2017-12-29 14:01:01'"));
+ }
+
+ /**
+ * @param sqlType SQL type.
+ * @param dfltVal Value string representation.
+ * @return Object is returned by SELECT query.
+ */
+ private Object getDefaultObject(String sqlType, String dfltVal) {
+ sql(String.format("CREATE TABLE TEST (id int, val %s default %s, primary key (id))",
+ sqlType, dfltVal));
+
+ sql("INSERT INTO TEST (id) VALUES (1)");
+
+ List<List<?>> res = sql("SELECT val FROM TEST WHERE id=1");
+
+ sql("DROP TABLE TEST");
+
+ return res.get(0).get(0);
+ }
+
+ /**
+ * @param exp Expected results.
+ * @param actual Actual results.
+ */
+ @SuppressWarnings("SuspiciousMethodCalls")
+ private void checkResults(Collection<List<Object>> exp, Collection<List<?>> actual) {
+ assertEquals(exp.size(), actual.size());
+
+ for (List<?> row : actual) {
+ if (!exp.contains(row))
+ fail("Unexpected results: [row=" + row + ']');
+ }
+ }
+
+ /**
+ * @param sql SQL query
+ * @param args Query parameters.
+ * @return Results set.
+ */
+ private List<List<?>> sql(String sql, Object ... args) {
+ return grid(NODE_CLIENT).context().query().querySqlFieldsNoCache(
+ new SqlFieldsQuery(sql).setArgs(args), false).getAll();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index 62860c0..1da695b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -560,6 +560,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
@Override public boolean notNull() {
return false;
}
+
+ /** */
+ @Override public Object defaultValue() {
+ return null;
+ }
};
}
@@ -654,6 +659,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
@Override public void validateKeyAndValue(Object key, Object value) throws IgniteCheckedException {
// No-op.
}
+
+ /** {@inheritDoc} */
+ @Override public void setDefaults(Object key, Object val) throws IgniteCheckedException {
+ // No-op.
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index dc72c31..6efb99f 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -634,14 +634,28 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
assertParseThrows("create table Person (id int as age * 2 primary key, age int) WITH \"template=cache\"",
IgniteSQLException.class, "Computed columns are not supported [colName=ID]");
- assertParseThrows("create table Person (id int primary key, age int default 5) WITH \"template=cache\"",
- IgniteSQLException.class, "DEFAULT expressions are not supported [colName=AGE]");
-
assertParseThrows("create table Int (_key int primary key, _val int) WITH \"template=cache\"",
IgniteSQLException.class, "Direct specification of _KEY and _VAL columns is forbidden");
}
/** */
+ public void testParseCreateTableWithDefaults() {
+ assertParseThrows("create table Person (id int primary key, age int, " +
+ "ts TIMESTAMP default CURRENT_TIMESTAMP()) WITH \"template=cache\"",
+ IgniteSQLException.class, "Non-constant DEFAULT expressions are not supported [colName=TS]");
+
+ assertParseThrows("create table Person (id int primary key, age int default 'test') " +
+ "WITH \"template=cache\"",
+ IgniteSQLException.class, "Invalid default value for column. " +
+ "[colName=AGE, colType=INTEGER, dfltValueType=VARCHAR]");
+
+ assertParseThrows("create table Person (id int primary key, name varchar default 1) " +
+ "WITH \"template=cache\"",
+ IgniteSQLException.class, "Invalid default value for column. " +
+ "[colName=NAME, colType=VARCHAR, dfltValueType=INTEGER]");
+ }
+
+ /** */
public void testParseAlterTableAddColumn() throws Exception {
assertAlterTableAddColumnEquals(buildAlterTableAddColumn("SCH2", "Person", false, false,
c("COMPANY", Value.STRING)), "ALTER TABLE SCH2.Person ADD company varchar");
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 55d0b5c..564019a 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -134,6 +134,7 @@ import org.apache.ignite.internal.processors.cache.query.IgniteCacheQueryCacheDe
import org.apache.ignite.internal.processors.cache.query.IndexingSpiQuerySelfTest;
import org.apache.ignite.internal.processors.cache.query.IndexingSpiQueryTxSelfTest;
import org.apache.ignite.internal.processors.client.ClientConnectorConfigurationValidationSelfTest;
+import org.apache.ignite.internal.processors.query.IgniteSqlDefaultValueTest;
import org.apache.ignite.internal.processors.query.IgniteSqlDistributedJoinSelfTest;
import org.apache.ignite.internal.processors.query.IgniteSqlSkipReducerOnUpdateDmlFlagSelfTest;
import org.apache.ignite.internal.processors.query.IgniteSqlParameterizedQueryTest;
@@ -376,6 +377,8 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
suite.addTestSuite(IgniteCheckClusterStateBeforeExecuteQueryTest.class);
suite.addTestSuite(OptimizedMarshallerIndexNameTest.class);
+ suite.addTestSuite(IgniteSqlDefaultValueTest.class);
+
return suite;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/QueryEntityConfigurationParityTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/QueryEntityConfigurationParityTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/QueryEntityConfigurationParityTest.cs
index e186612..98ab084 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/QueryEntityConfigurationParityTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/QueryEntityConfigurationParityTest.cs
@@ -31,7 +31,8 @@ namespace Apache.Ignite.Core.Tests.ApiParity
"findKeyType",
"findValueType",
"KeyFields",
- "NotNullFields"
+ "NotNullFields",
+ "FieldsDefaultValues"
};
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
index 536cb18..fbd8775 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
@@ -550,6 +550,7 @@ namespace Apache.Ignite.Core.Tests.Cache
Assert.AreEqual(x.FieldTypeName, y.FieldTypeName);
Assert.AreEqual(x.IsKeyField, y.IsKeyField);
Assert.AreEqual(x.NotNull, y.NotNull);
+ Assert.AreEqual(x.DefaultValue, y.DefaultValue);
}
/// <summary>
@@ -625,7 +626,7 @@ namespace Apache.Ignite.Core.Tests.Cache
Fields = new[]
{
new QueryField("length", typeof(int)),
- new QueryField("name", typeof(string)) {IsKeyField = true},
+ new QueryField("name", typeof(string)) {IsKeyField = true, DefaultValue = "defName"},
new QueryField("location", typeof(string)) {NotNull = true},
},
Aliases = new [] {new QueryAlias("length", "len") },
@@ -734,7 +735,7 @@ namespace Apache.Ignite.Core.Tests.Cache
TableName = "MyTable",
Fields = new[]
{
- new QueryField("length", typeof(int)),
+ new QueryField("length", typeof(int)) {DefaultValue = -1},
new QueryField("name", typeof(string)),
new QueryField("location", typeof(string)) {IsKeyField = true}
},
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
index f289e56..7ee6695 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
@@ -387,6 +387,46 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
}
/// <summary>
+ /// Tests the QueryField.DefaultValue functionality.
+ /// </summary>
+ [Test]
+ public void TestDefaultValue()
+ {
+ // Attribute-based config.
+ var cfg = new CacheConfiguration("def_value_attr", new QueryEntity(typeof(int), typeof(Foo)));
+ Assert.AreEqual(-1, cfg.QueryEntities.Single().Fields.Single(x => x.Name == "Id").DefaultValue);
+
+ var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);
+ Assert.AreEqual(-1,
+ cache.GetConfiguration().QueryEntities.Single().Fields.Single(x => x.Name == "Id").DefaultValue);
+
+ cache.Query(new SqlFieldsQuery("insert into foo(_key, id, name) values (?, ?, ?)", 1, 2, "John")).GetAll();
+ cache.Query(new SqlFieldsQuery("insert into foo(_key, name) values (?, ?)", 3, "Mary")).GetAll();
+
+ Assert.AreEqual(2, cache[1].Id);
+ Assert.AreEqual(-1, cache[3].Id);
+
+ // QueryEntity-based config.
+ cfg = new CacheConfiguration("def_value_binary", new QueryEntity
+ {
+ KeyType = typeof(int),
+ ValueTypeName = "DefValTest",
+ Fields = new[]
+ {
+ new QueryField("Name", typeof(string)) {DefaultValue = "foo"}
+ }
+ });
+
+ var cache2 = Ignition.GetIgnite().CreateCache<int, int>(cfg).WithKeepBinary<int, IBinaryObject>();
+
+ cache2.Query(new SqlFieldsQuery("insert into DefValTest(_key, name) values (?, ?)", 1, "John")).GetAll();
+ cache2.Query(new SqlFieldsQuery("insert into DefValTest(_key) values (?)", 2)).GetAll();
+
+ Assert.AreEqual("John", cache2[1].GetField<string>("Name"));
+ Assert.AreEqual("foo", cache2[2].GetField<string>("Name"));
+ }
+
+ /// <summary>
/// Key.
/// </summary>
private struct Key
@@ -423,7 +463,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
/// </summary>
private class Foo
{
- [QuerySqlField] public int Id { get; set; }
+ [QuerySqlField(DefaultValue = -1)] public int Id { get; set; }
[QuerySqlField(NotNull = true)] public string Name { get; set; }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml
index aff48f5..29aa704 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml
@@ -57,7 +57,9 @@
<queryEntities>
<queryEntity keyType='System.Int32' valueType='System.String' tableName='myTable'>
<fields>
- <queryField name='length' fieldType='System.Int32' isKeyField='true' notNull='true' />
+ <queryField name='length' fieldType='System.Int32' isKeyField='true' notNull='true'>
+ <defaultValue type="System.Double">3.456</defaultValue>
+ </queryField>
</fields>
<aliases>
<queryAlias fullName='somefield.field' alias='shortField' />
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
index 5512975..1260aa5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
@@ -132,6 +132,7 @@ namespace Apache.Ignite.Core.Tests
Assert.AreEqual(typeof(int), queryEntity.Fields.Single().FieldType);
Assert.IsTrue(queryEntity.Fields.Single().IsKeyField);
Assert.IsTrue(queryEntity.Fields.Single().NotNull);
+ Assert.AreEqual(3.456d, (double)queryEntity.Fields.Single().DefaultValue);
Assert.AreEqual("somefield.field", queryEntity.Aliases.Single().FullName);
Assert.AreEqual("shortField", queryEntity.Aliases.Single().Alias);
@@ -677,7 +678,8 @@ namespace Apache.Ignite.Core.Tests
new QueryField("field", typeof(int))
{
IsKeyField = true,
- NotNull = true
+ NotNull = true,
+ DefaultValue = "foo"
}
},
Indexes = new[]
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
index 4db15eb..a1fb4e0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
@@ -457,7 +457,8 @@ namespace Apache.Ignite.Core.Cache.Configuration
fields.Add(new QueryField(columnName, memberInfo.Value)
{
IsKeyField = isKey,
- NotNull = attr.NotNull
+ NotNull = attr.NotNull,
+ DefaultValue = attr.DefaultValue
});
ScanAttributes(memberInfo.Value, fields, indexes, columnName, visitedTypes, isKey);
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs
index b8142fd..38aeed3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs
@@ -84,6 +84,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
FieldTypeName = reader.ReadString();
IsKeyField = reader.ReadBoolean();
NotNull = reader.ReadBoolean();
+ DefaultValue = reader.ReadObject<object>();
}
/// <summary>
@@ -97,6 +98,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
writer.WriteString(FieldTypeName);
writer.WriteBoolean(IsKeyField);
writer.WriteBoolean(NotNull);
+ writer.WriteObject(DefaultValue);
}
/// <summary>
@@ -147,6 +149,11 @@ namespace Apache.Ignite.Core.Cache.Configuration
public bool NotNull { get; set; }
/// <summary>
+ /// Gets or sets the default value for the field.
+ /// </summary>
+ public object DefaultValue { get; set; }
+
+ /// <summary>
/// Validates this instance and outputs information to the log, if necessary.
/// </summary>
internal void Validate(ILogger log, string logInfo)
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs
index d15cc1a..96912dd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs
@@ -76,5 +76,10 @@ namespace Apache.Ignite.Core.Cache.Configuration
/// Gets or sets a value indicating whether null values are allowed for this field.
/// </summary>
public bool NotNull { get; set; }
+
+ /// <summary>
+ /// Gets or sets the default value for the field (has effect when inserting with DML).
+ /// </summary>
+ public object DefaultValue { get; set; }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78e79e01/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
index 190b3ad..84afdc4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
@@ -308,6 +308,13 @@
<xs:sequence>
<xs:element name="queryField" maxOccurs="unbounded">
<xs:complexType>
+ <xs:all>
+ <xs:element name="defaultValue" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>Default field value.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Cache name.</xs:documentation>