You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2020/12/25 13:04:51 UTC
[ignite] branch master updated: IGNITE-13908: ODBC nullability info
for columns
This is an automated email from the ASF dual-hosted git repository.
isapego pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new eb77c8a IGNITE-13908: ODBC nullability info for columns
eb77c8a is described below
commit eb77c8af710995237e69c8946e2fc5fa20d7c7a1
Author: Igor Sapego <is...@apache.org>
AuthorDate: Fri Dec 25 16:03:49 2020 +0300
IGNITE-13908: ODBC nullability info for columns
This closes #8610
---
.../processors/odbc/odbc/OdbcColumnMeta.java | 39 ++++++++++---------
.../odbc/odbc/OdbcConnectionContext.java | 6 ++-
.../processors/odbc/odbc/OdbcMessageParser.java | 4 +-
.../processors/odbc/odbc/OdbcRequestHandler.java | 7 +++-
.../processors/odbc/odbc/OdbcResultSet.java | 2 +-
.../internal/processors/odbc/odbc/OdbcUtils.java | 7 +---
.../processors/query/GridQueryFieldMetadata.java | 9 +++++
.../processors/query/h2/H2SqlFieldMetadata.java | 11 +++++-
.../internal/processors/query/h2/H2Utils.java | 7 +++-
.../cpp/odbc-test/src/attributes_test.cpp | 24 ++++++++++++
.../cpp/odbc-test/src/meta_queries_test.cpp | 44 +++++++++++-----------
.../odbc/include/ignite/odbc/meta/column_meta.h | 41 +++++++++++++++++++-
.../odbc/include/ignite/odbc/protocol_version.h | 3 ++
.../platforms/cpp/odbc/src/meta/column_meta.cpp | 28 +++++++++++++-
.../platforms/cpp/odbc/src/protocol_version.cpp | 6 ++-
15 files changed, 179 insertions(+), 59 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcColumnMeta.java
index a8f749e..58ae98f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcColumnMeta.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcColumnMeta.java
@@ -35,19 +35,19 @@ public class OdbcColumnMeta {
private final String tableName;
/** Column name. */
- public final String columnName;
+ private final String columnName;
/** Data type. */
private final Class<?> dataType;
/** Precision. */
- public final int precision;
+ private final int precision;
/** Scale. */
- public final int scale;
+ private final int scale;
- /** Client version. */
- private final ClientListenerProtocolVersion ver;
+ /** Nullability. See {@link java.sql.ResultSetMetaData#isNullable(int)} for more info. */
+ private final int nullability;
/**
* @param schemaName Cache name.
@@ -56,30 +56,30 @@ public class OdbcColumnMeta {
* @param dataType Data type.
* @param precision Precision.
* @param scale Scale.
- * @param ver Client version.
+ * @param nullability Nullability.
*/
public OdbcColumnMeta(String schemaName, String tableName, String columnName, Class<?> dataType,
- int precision, int scale, ClientListenerProtocolVersion ver) {
+ int precision, int scale, int nullability) {
this.schemaName = OdbcUtils.addQuotationMarksIfNeeded(schemaName);
this.tableName = tableName;
this.columnName = columnName;
this.dataType = dataType;
this.precision = precision;
this.scale = scale;
- this.ver = ver;
+ this.nullability = nullability;
}
/**
+ * Constructor for result set column.
* @param info Field metadata.
- * @param ver Client version.
*/
- public OdbcColumnMeta(GridQueryFieldMetadata info, ClientListenerProtocolVersion ver) {
- this.schemaName = OdbcUtils.addQuotationMarksIfNeeded(info.schemaName());
- this.tableName = info.typeName();
- this.columnName = info.fieldName();
- this.precision = info.precision();
- this.scale = info.scale();
- this.ver = ver;
+ public OdbcColumnMeta(GridQueryFieldMetadata info) {
+ schemaName = OdbcUtils.addQuotationMarksIfNeeded(info.schemaName());
+ tableName = info.typeName();
+ columnName = info.fieldName();
+ precision = info.precision();
+ scale = info.scale();
+ nullability = info.nullability();
Class<?> type;
@@ -123,8 +123,9 @@ public class OdbcColumnMeta {
* Write in a binary format.
*
* @param writer Binary writer.
+ * @param ver Client version.
*/
- public void write(BinaryRawWriter writer) {
+ public void write(BinaryRawWriter writer, ClientListenerProtocolVersion ver) {
writer.writeString(schemaName);
writer.writeString(tableName);
writer.writeString(columnName);
@@ -137,6 +138,10 @@ public class OdbcColumnMeta {
writer.writeInt(precision);
writer.writeInt(scale);
}
+
+ if (ver.compareTo(OdbcConnectionContext.VER_2_8_0) >= 0) {
+ writer.writeByte((byte)nullability);
+ }
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
index 74def0d..5b78b6e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
@@ -56,8 +56,11 @@ public class OdbcConnectionContext extends ClientListenerAbstractConnectionConte
/** Version 2.7.0: added precision and scale. */
public static final ClientListenerProtocolVersion VER_2_7_0 = ClientListenerProtocolVersion.create(2, 7, 0);
+ /** Version 2.8.0: added column nullability info. */
+ public static final ClientListenerProtocolVersion VER_2_8_0 = ClientListenerProtocolVersion.create(2, 8, 0);
+
/** Current version. */
- private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_7_0;
+ private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_8_0;
/** Supported versions. */
private static final Set<ClientListenerProtocolVersion> SUPPORTED_VERS = new HashSet<>();
@@ -79,6 +82,7 @@ public class OdbcConnectionContext extends ClientListenerAbstractConnectionConte
static {
SUPPORTED_VERS.add(CURRENT_VER);
+ SUPPORTED_VERS.add(VER_2_7_0);
SUPPORTED_VERS.add(VER_2_5_0);
SUPPORTED_VERS.add(VER_2_3_0);
SUPPORTED_VERS.add(VER_2_3_2);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
index 33f1c4b..2d0d2d4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
@@ -419,13 +419,13 @@ public class OdbcMessageParser implements ClientListenerMessageParser {
* @param writer Writer.
* @param meta Metadata
*/
- private static void writeResultsetMeta(BinaryWriterExImpl writer, Collection<OdbcColumnMeta> meta) {
+ private void writeResultsetMeta(BinaryWriterExImpl writer, Collection<OdbcColumnMeta> meta) {
assert meta != null;
writer.writeInt(meta.size());
for (OdbcColumnMeta columnMeta : meta)
- columnMeta.write(writer);
+ columnMeta.write(writer, ver);
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
index a21caeb..8cc24a1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
@@ -69,6 +69,8 @@ import org.apache.ignite.transactions.TransactionMixedModeException;
import org.apache.ignite.transactions.TransactionSerializationException;
import org.apache.ignite.transactions.TransactionUnsupportedConcurrencyException;
+import static java.sql.ResultSetMetaData.columnNoNulls;
+import static java.sql.ResultSetMetaData.columnNullable;
import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.META_COLS;
import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.META_PARAMS;
import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.META_RESULTSET;
@@ -696,7 +698,8 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
GridQueryProperty prop = table.property(field.getKey());
OdbcColumnMeta columnMeta = new OdbcColumnMeta(table.schemaName(), table.tableName(),
- field.getKey(), field.getValue(), prop.precision(), prop.scale(), ver);
+ field.getKey(), field.getValue(), prop.precision(), prop.scale(),
+ prop.notNull() ? columnNoNulls : columnNullable);
if (!meta.contains(columnMeta))
meta.add(columnMeta);
@@ -802,7 +805,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
SqlFieldsQueryEx qry = makeQuery(schema, sql);
List<GridQueryFieldMetadata> columns = ctx.query().getIndexing().resultMetaData(schema, qry);
- Collection<OdbcColumnMeta> meta = OdbcUtils.convertMetadata(columns, ver);
+ Collection<OdbcColumnMeta> meta = OdbcUtils.convertMetadata(columns);
OdbcQueryGetResultsetMetaResult res = new OdbcQueryGetResultsetMetaResult(meta);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcResultSet.java
index 1eba63d..879acde 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcResultSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcResultSet.java
@@ -54,7 +54,7 @@ public class OdbcResultSet {
if (this.cursor.isQuery()) {
iter = this.cursor.iterator();
- meta = OdbcUtils.convertMetadata(this.cursor.fieldsMeta(), ver);
+ meta = OdbcUtils.convertMetadata(this.cursor.fieldsMeta());
}
else {
iter = null;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
index 80fab2e..926524a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
@@ -25,7 +25,6 @@ import org.apache.ignite.IgniteException;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
-import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion;
import org.apache.ignite.internal.processors.odbc.SqlListenerDataTypes;
import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
@@ -252,16 +251,14 @@ public class OdbcUtils {
* {@link OdbcColumnMeta}.
*
* @param meta Internal query field metadata.
- * @param ver Client version.
* @return Odbc query field metadata.
*/
- public static Collection<OdbcColumnMeta> convertMetadata(Collection<GridQueryFieldMetadata> meta,
- ClientListenerProtocolVersion ver) {
+ public static Collection<OdbcColumnMeta> convertMetadata(Collection<GridQueryFieldMetadata> meta) {
List<OdbcColumnMeta> res = new ArrayList<>();
if (meta != null) {
for (GridQueryFieldMetadata info : meta)
- res.add(new OdbcColumnMeta(info, ver));
+ res.add(new OdbcColumnMeta(info));
}
return res;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryFieldMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryFieldMetadata.java
index f9df499..3c28e38 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryFieldMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryFieldMetadata.java
@@ -65,4 +65,13 @@ public interface GridQueryFieldMetadata extends Externalizable {
* @return Field scale.
*/
public int scale();
+
+ /**
+ * Gets field nullability.
+ *
+ * See {@link java.sql.ResultSetMetaData#isNullable(int)} for more info.
+ *
+ * @return Field nullability.
+ */
+ public int nullability();
}
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2SqlFieldMetadata.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2SqlFieldMetadata.java
index a42771e..08cf1b3 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2SqlFieldMetadata.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2SqlFieldMetadata.java
@@ -51,6 +51,9 @@ public class H2SqlFieldMetadata implements GridQueryFieldMetadata {
/** Scale. */
private int scale;
+ /** Nullability. See {@link java.sql.ResultSetMetaData#isNullable(int)} */
+ private int nullability;
+
/**
* Required by {@link Externalizable}.
*/
@@ -67,7 +70,7 @@ public class H2SqlFieldMetadata implements GridQueryFieldMetadata {
* @param scale Scale.
*/
H2SqlFieldMetadata(@Nullable String schemaName, @Nullable String typeName, String name, String type,
- int precision, int scale) {
+ int precision, int scale, int nullability) {
assert name != null && type != null : schemaName + " | " + typeName + " | " + name + " | " + type;
this.schemaName = schemaName;
@@ -76,6 +79,7 @@ public class H2SqlFieldMetadata implements GridQueryFieldMetadata {
this.type = type;
this.precision = precision;
this.scale = scale;
+ this.nullability = nullability;
}
/** {@inheritDoc} */
@@ -109,6 +113,11 @@ public class H2SqlFieldMetadata implements GridQueryFieldMetadata {
}
/** {@inheritDoc} */
+ @Override public int nullability() {
+ return nullability;
+ }
+
+ /** {@inheritDoc} */
@Override public void writeExternal(ObjectOutput out) throws IOException {
U.writeString(out, schemaName);
U.writeString(out, typeName);
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
index f766de9..e55e6ef 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
@@ -105,6 +105,7 @@ import org.h2.value.ValueUuid;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import static java.sql.ResultSetMetaData.columnNullableUnknown;
import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_COL;
import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
@@ -136,7 +137,8 @@ public class H2Utils {
/** Dummy metadata for update result. */
public static final List<GridQueryFieldMetadata> UPDATE_RESULT_META =
- Collections.singletonList(new H2SqlFieldMetadata(null, null, "UPDATED", Long.class.getName(), -1, -1));
+ Collections.singletonList(new H2SqlFieldMetadata(null, null, "UPDATED", Long.class.getName(), -1, -1,
+ columnNullableUnknown));
/** Spatial index class name. */
private static final String SPATIAL_IDX_CLS =
@@ -375,11 +377,12 @@ public class H2Utils {
String type = rsMeta.getColumnClassName(i);
int precision = rsMeta.getPrecision(i);
int scale = rsMeta.getScale(i);
+ int nullability = rsMeta.isNullable(i);
if (type == null) // Expression always returns NULL.
type = Void.class.getName();
- meta.add(new H2SqlFieldMetadata(schemaName, typeName, name, type, precision, scale));
+ meta.add(new H2SqlFieldMetadata(schemaName, typeName, name, type, precision, scale, nullability));
}
return meta;
diff --git a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
index 278a066..8d6f6e3 100644
--- a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
@@ -116,6 +116,30 @@ BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_2_3_2)
InsertTestBatch(11, 20, 9);
}
+BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_2_5_0)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache;PROTOCOL_VERSION=2.5.0");
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_2_7_0)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache;PROTOCOL_VERSION=2.7.0");
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_2_8_0)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache;PROTOCOL_VERSION=2.8.0");
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 20, 9);
+}
+
BOOST_AUTO_TEST_CASE(TestConnectionRangeBegin)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110..11115;SCHEMA=cache");
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index 05a0e46..696c878 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -189,7 +189,7 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite
" dec3 decimal,"
" char1 char(3),"
" char2 char(42),"
- " char3 char,"
+ " char3 char not null,"
" vchar varchar"
")");
@@ -218,14 +218,14 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite
BOOST_CHECK_EQUAL(columnCount, 8);
- CheckColumnMetaWithSQLDescribeCol(stmt, 1, "ID", SQL_INTEGER, 10, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 2, "DEC1", SQL_DECIMAL, 3, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 3, "DEC2", SQL_DECIMAL, 42, 12, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 4, "DEC3", SQL_DECIMAL, 65535, 32767, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 5, "CHAR1", SQL_VARCHAR, 3, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 6, "CHAR2", SQL_VARCHAR, 42, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 7, "CHAR3", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLDescribeCol(stmt, 8, "VCHAR", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE_UNKNOWN);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 1, "ID", SQL_INTEGER, 10, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 2, "DEC1", SQL_DECIMAL, 3, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 3, "DEC2", SQL_DECIMAL, 42, 12, SQL_NULLABLE);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 4, "DEC3", SQL_DECIMAL, 65535, 32767, SQL_NULLABLE);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 5, "CHAR1", SQL_VARCHAR, 3, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 6, "CHAR2", SQL_VARCHAR, 42, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 7, "CHAR3", SQL_VARCHAR, 2147483647, 0, SQL_NO_NULLS);
+ CheckColumnMetaWithSQLDescribeCol(stmt, 8, "VCHAR", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE);
}
/**
@@ -298,7 +298,7 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite
" dec3 decimal,"
" char1 char(3),"
" char2 char(42),"
- " char3 char,"
+ " char3 char not null,"
" vchar varchar"
")");
@@ -327,14 +327,14 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite
BOOST_CHECK_EQUAL(columnCount, 8);
- CheckColumnMetaWithSQLColAttribute(stmt, 1, "ID", SQL_INTEGER, 10, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 2, "DEC1", SQL_DECIMAL, 3, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 3, "DEC2", SQL_DECIMAL, 42, 12, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 4, "DEC3", SQL_DECIMAL, 65535, 32767, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 5, "CHAR1", SQL_VARCHAR, 3, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 6, "CHAR2", SQL_VARCHAR, 42, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 7, "CHAR3", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE_UNKNOWN);
- CheckColumnMetaWithSQLColAttribute(stmt, 8, "VCHAR", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE_UNKNOWN);
+ CheckColumnMetaWithSQLColAttribute(stmt, 1, "ID", SQL_INTEGER, 10, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLColAttribute(stmt, 2, "DEC1", SQL_DECIMAL, 3, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLColAttribute(stmt, 3, "DEC2", SQL_DECIMAL, 42, 12, SQL_NULLABLE);
+ CheckColumnMetaWithSQLColAttribute(stmt, 4, "DEC3", SQL_DECIMAL, 65535, 32767, SQL_NULLABLE);
+ CheckColumnMetaWithSQLColAttribute(stmt, 5, "CHAR1", SQL_VARCHAR, 3, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLColAttribute(stmt, 6, "CHAR2", SQL_VARCHAR, 42, 0, SQL_NULLABLE);
+ CheckColumnMetaWithSQLColAttribute(stmt, 7, "CHAR3", SQL_VARCHAR, 2147483647, 0, SQL_NO_NULLS);
+ CheckColumnMetaWithSQLColAttribute(stmt, 8, "VCHAR", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE);
}
/**
@@ -883,7 +883,7 @@ BOOST_AUTO_TEST_CASE(TestSQLNumResultColsAfterSQLPrepare)
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Prepare statement.
- * 5. Check presicion and scale of every column using SQLDescribeCol.
+ * 5. Check precision and scale of every column using SQLDescribeCol.
*/
BOOST_AUTO_TEST_CASE(TestSQLDescribeColPrecisionAndScaleAfterPrepare)
{
@@ -897,7 +897,7 @@ BOOST_AUTO_TEST_CASE(TestSQLDescribeColPrecisionAndScaleAfterPrepare)
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Execute statement.
- * 5. Check presicion and scale of every column using SQLDescribeCol. */
+ * 5. Check precision and scale of every column using SQLDescribeCol. */
BOOST_AUTO_TEST_CASE(TestSQLDescribeColPrecisionAndScaleAfterExec)
{
CheckSQLDescribeColPrecisionAndScale(&OdbcTestSuite::ExecQuery);
@@ -910,7 +910,7 @@ BOOST_AUTO_TEST_CASE(TestSQLDescribeColPrecisionAndScaleAfterExec)
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Prepare statement.
- * 5. Check presicion and scale of every column using SQLColAttribute.
+ * 5. Check precision and scale of every column using SQLColAttribute.
*/
BOOST_AUTO_TEST_CASE(TestSQLColAttributePrecisionAndScaleAfterPrepare)
{
@@ -924,7 +924,7 @@ BOOST_AUTO_TEST_CASE(TestSQLColAttributePrecisionAndScaleAfterPrepare)
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Execute statement.
- * 5. Check presicion and scale of every column using SQLColAttribute. */
+ * 5. Check precision and scale of every column using SQLColAttribute. */
BOOST_AUTO_TEST_CASE(TestSQLColAttributePrecisionAndScaleAfterExec)
{
CheckSQLColAttributePrecisionAndScale(&OdbcTestSuite::ExecQuery);
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/meta/column_meta.h b/modules/platforms/cpp/odbc/include/ignite/odbc/meta/column_meta.h
index c4aeae0..5144fa3 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/meta/column_meta.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/meta/column_meta.h
@@ -33,6 +33,29 @@ namespace ignite
{
namespace meta
{
+ /**
+ * Nullability type.
+ */
+ struct Nullability
+ {
+ enum Type
+ {
+ NO_NULL = 0,
+
+ NULLABLE = 1,
+
+ NULLABILITY_UNKNOWN = 2
+ };
+
+ /**
+ * Convert to SQL constant.
+ *
+ * @param nullability Nullability.
+ * @return SQL constant.
+ */
+ static SqlLen ToSql(int32_t nullability);
+ };
+
using namespace ignite::odbc;
/**
@@ -69,7 +92,7 @@ namespace ignite
ColumnMeta(const std::string& schemaName, const std::string& tableName,
const std::string& columnName, int8_t dataType) :
schemaName(schemaName), tableName(tableName), columnName(columnName), dataType(dataType),
- precision(-1), scale(-1)
+ precision(-1), scale(-1), nullability(Nullability::NULLABILITY_UNKNOWN)
{
// No-op.
}
@@ -91,7 +114,8 @@ namespace ignite
columnName(other.columnName),
dataType(other.dataType),
precision(other.precision),
- scale(other.scale)
+ scale(other.scale),
+ nullability(other.nullability)
{
// No-op.
}
@@ -107,6 +131,7 @@ namespace ignite
dataType = other.dataType;
precision = other.precision;
scale = other.scale;
+ nullability = other.nullability;
return *this;
}
@@ -173,6 +198,15 @@ namespace ignite
}
/**
+ * Get column nullability.
+ * @return Column nullability.
+ */
+ int32_t GetNullability() const
+ {
+ return nullability;
+ }
+
+ /**
* Try to get attribute of a string type.
*
* @param fieldId Field ID.
@@ -208,6 +242,9 @@ namespace ignite
/** Column scale. */
int32_t scale;
+
+ /** Column nullability. */
+ int32_t nullability;
};
/** Column metadata vector alias. */
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
index 1a722e3..f4c0e92 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
@@ -49,6 +49,9 @@ namespace ignite
/** Version 2.7.0: added fields precision and scale. */
static const ProtocolVersion VERSION_2_7_0;
+ /** Version 2.8.0: added column nullability info. */
+ static const ProtocolVersion VERSION_2_8_0;
+
typedef std::set<ProtocolVersion> VersionSet;
/**
diff --git a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
index 203b4ad..0270888 100644
--- a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
+++ b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
@@ -74,6 +74,27 @@ namespace ignite
#undef DBG_STR_CASE
+ SqlLen Nullability::ToSql(int32_t nullability)
+ {
+ switch (nullability)
+ {
+ case Nullability::NO_NULL:
+ return SQL_NO_NULLS;
+
+ case Nullability::NULLABLE:
+ return SQL_NULLABLE;
+
+ case Nullability::NULLABILITY_UNKNOWN:
+ return SQL_NULLABLE_UNKNOWN;
+
+ default:
+ break;
+ }
+
+ assert(false);
+ return SQL_NULLABLE_UNKNOWN;
+ }
+
void ColumnMeta::Read(ignite::impl::binary::BinaryReaderImpl& reader, const ProtocolVersion& ver)
{
utility::ReadString(reader, schemaName);
@@ -87,6 +108,9 @@ namespace ignite
precision = reader.ReadInt32();
scale = reader.ReadInt32();
}
+
+ if (ver >= ProtocolVersion::VERSION_2_8_0)
+ nullability = reader.ReadInt8();
}
bool ColumnMeta::GetAttribute(uint16_t fieldId, std::string& value) const
@@ -235,7 +259,7 @@ namespace ignite
case SQL_DESC_NULLABLE:
{
- value = type_traits::BinaryTypeNullability(dataType);
+ value = Nullability::ToSql(nullability);
break;
}
@@ -312,7 +336,7 @@ namespace ignite
}
void ReadColumnMetaVector(ignite::impl::binary::BinaryReaderImpl& reader, ColumnMetaVector& meta,
- const ProtocolVersion& ver)
+ const ProtocolVersion& ver)
{
int32_t metaNum = reader.ReadInt32();
diff --git a/modules/platforms/cpp/odbc/src/protocol_version.cpp b/modules/platforms/cpp/odbc/src/protocol_version.cpp
index 01937e2..a073ab2 100644
--- a/modules/platforms/cpp/odbc/src/protocol_version.cpp
+++ b/modules/platforms/cpp/odbc/src/protocol_version.cpp
@@ -32,6 +32,7 @@ namespace ignite
const ProtocolVersion ProtocolVersion::VERSION_2_3_2(2, 3, 2);
const ProtocolVersion ProtocolVersion::VERSION_2_5_0(2, 5, 0);
const ProtocolVersion ProtocolVersion::VERSION_2_7_0(2, 7, 0);
+ const ProtocolVersion ProtocolVersion::VERSION_2_8_0(2, 8, 0);
ProtocolVersion::VersionSet::value_type supportedArray[] = {
ProtocolVersion::VERSION_2_1_0,
@@ -39,7 +40,8 @@ namespace ignite
ProtocolVersion::VERSION_2_3_0,
ProtocolVersion::VERSION_2_3_2,
ProtocolVersion::VERSION_2_5_0,
- ProtocolVersion::VERSION_2_7_0
+ ProtocolVersion::VERSION_2_7_0,
+ ProtocolVersion::VERSION_2_8_0
};
const ProtocolVersion::VersionSet ProtocolVersion::supported(supportedArray,
@@ -68,7 +70,7 @@ namespace ignite
const ProtocolVersion& ProtocolVersion::GetCurrent()
{
- return VERSION_2_7_0;
+ return VERSION_2_8_0;
}
void ThrowParseError()