This is an automated email from the ASF dual-hosted git repository.
amashenkov 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 4b3d155 IGNITE-13075 NPE on request JDBC metadata. (#7851)
4b3d155 is described below
commit 4b3d155f4f38f5cf0d520752a440cc43ebfe42cd
Author: korlov42 <[email protected]>
AuthorDate: Fri May 29 16:25:33 2020 +0300
IGNITE-13075 NPE on request JDBC metadata. (#7851)
---
.../ignite/jdbc/thin/JdbcThinMetadataSelfTest.java | 105 +++++++++++++++++++++
.../internal/processors/query/QueryUtils.java | 26 ++---
.../apache/ignite/internal/util/lang/GridFunc.java | 14 +++
3 files changed, 126 insertions(+), 19 deletions(-)
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 e8aeb58..a2c1eff 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
@@ -62,7 +62,10 @@ import static java.sql.Types.VARCHAR;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
import static
org.apache.ignite.internal.processors.query.QueryUtils.DFLT_SCHEMA;
+import static
org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
import static
org.apache.ignite.internal.processors.query.QueryUtils.SCHEMA_SYS;
+import static
org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
+import static org.apache.ignite.internal.util.lang.GridFunc.asMap;
/**
* Metadata tests.
@@ -204,6 +207,84 @@ public class JdbcThinMetadataSelfTest extends
JdbcThinAbstractSelfTest {
}
/**
+ * Ensure metadata returned for cache without explicit query entities: <ul>
+ * <li>create a cache with indexed types and without explicit query
entities</li>
+ * <li>request metadata for columns from the cache</li>
+ * <li>verify returned result</li>
+ * </ul>
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void testMetadataPresentedForAutogeneratedColumns() throws
SQLException {
+ final String cacheName = "testCache";
+
+ IgniteCache<?, ?> cache = grid(0).createCache(
+ new CacheConfiguration<>(cacheName).setIndexedTypes(Integer.class,
String.class)
+ );
+
+ try (Connection conn = DriverManager.getConnection(URL)) {
+ DatabaseMetaData meta = conn.getMetaData();
+
+ ResultSet rs = meta.getColumns(null, cacheName, null, null);
+
+ assertTrue(rs.next());
+ assertEquals(cacheName,
rs.getString(MetadataColumn.TABLE_SCHEMA.columnName()));
+ assertEquals(KEY_FIELD_NAME,
rs.getString(MetadataColumn.COLUMN_NAME.columnName()));
+
+ assertTrue(rs.next());
+ assertEquals(cacheName,
rs.getString(MetadataColumn.TABLE_SCHEMA.columnName()));
+ assertEquals(VAL_FIELD_NAME,
rs.getString(MetadataColumn.COLUMN_NAME.columnName()));
+
+ assertFalse(rs.next());
+ }
+ finally {
+ cache.destroy();
+ }
+ }
+
+ /**
+ * Ensure metadata returned for cache with explicit query entities has no
duplicate columns: <ul>
+ * <li>create a cache with indexed types and explicit query entity</li>
+ * <li>request metadata for columns from the cache</li>
+ * <li>verify returned result</li>
+ * </ul>
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void testMetadataNotDublicatedIfFieldsSetExplicitly() throws
SQLException {
+ final String cacheName = "testCache";
+
+ IgniteCache<?, ?> cache = grid(0).createCache(
+ new CacheConfiguration<>(cacheName)
+ .setQueryEntities(Collections.singleton(
+ new QueryEntity()
+ .setKeyType(Integer.class.getName())
+ .setKeyFieldName("my_key")
+ .setValueType(String.class.getName())
+ .setFields(new LinkedHashMap<>(asMap("my_key",
Integer.class.getName())))
+ ))
+ .setIndexedTypes(Integer.class, String.class)
+ );
+
+ try (Connection conn = DriverManager.getConnection(URL)) {
+ DatabaseMetaData meta = conn.getMetaData();
+
+ ResultSet rs = meta.getColumns(null, cacheName, null, null);
+
+ assertTrue(rs.next());
+ assertEquals(cacheName,
rs.getString(MetadataColumn.TABLE_SCHEMA.columnName()));
+ assertEquals("MY_KEY",
rs.getString(MetadataColumn.COLUMN_NAME.columnName()));
+
+ assertFalse(rs.next());
+ }
+ finally {
+ cache.destroy();
+ }
+ }
+
+ /**
* @throws Exception If failed.
*/
@Test
@@ -1341,4 +1422,28 @@ public class JdbcThinMetadataSelfTest extends
JdbcThinAbstractSelfTest {
this.name = name;
}
}
+
+ /** */
+ private enum MetadataColumn {
+ /** */
+ TABLE_SCHEMA("TABLE_SCHEM"),
+
+ /** */
+ COLUMN_NAME("COLUMN_NAME");
+
+ /** Column name. */
+ private final String colName;
+
+ /**
+ * @param colName Column name.
+ */
+ MetadataColumn(String colName) {
+ this.colName = colName;
+ }
+
+ /** */
+ public String columnName() {
+ return colName;
+ }
+ }
}
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 8487d78..5edb492 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
@@ -625,25 +625,13 @@ public class QueryUtils {
}
// Sql-typed key/value doesn't have field property, but they may have
precision and scale constraints.
- String keyFieldName = qryEntity.getKeyFieldName();
+ // Also if fields are not set then _KEY and _VAL will be created as
visible,
+ // so we have to add binary properties for them
+ if ((qryEntity.getKeyFieldName() == null &&
F.mapContainsKey(precision, KEY_FIELD_NAME)) || F.isEmpty(fields))
+ addKeyValueProperty(ctx, qryEntity, d, KEY_FIELD_NAME, true);
- if (keyFieldName == null)
- keyFieldName = KEY_FIELD_NAME;
-
- if (!F.isEmpty(precision) && precision.containsKey(keyFieldName) &&
- !fields.containsKey(keyFieldName)) {
- addKeyValueValidationProperty(ctx, qryEntity, d, keyFieldName,
true);
- }
-
- String valFieldName = qryEntity.getValueFieldName();
-
- if (valFieldName == null)
- valFieldName = VAL_FIELD_NAME;
-
- if (!F.isEmpty(precision) && precision.containsKey(valFieldName) &&
- !fields.containsKey(valFieldName)) {
- addKeyValueValidationProperty(ctx, qryEntity, d, valFieldName,
false);
- }
+ if ((qryEntity.getValueFieldName() == null &&
F.mapContainsKey(precision, VAL_FIELD_NAME)) || F.isEmpty(fields))
+ addKeyValueProperty(ctx, qryEntity, d, VAL_FIELD_NAME, false);
processIndexes(qryEntity, d);
}
@@ -657,7 +645,7 @@ public class QueryUtils {
* @param name Field name.
* @throws IgniteCheckedException
*/
- private static void addKeyValueValidationProperty(GridKernalContext ctx,
QueryEntity qryEntity, QueryTypeDescriptorImpl d,
+ private static void addKeyValueProperty(GridKernalContext ctx, QueryEntity
qryEntity, QueryTypeDescriptorImpl d,
String name, boolean isKey) throws IgniteCheckedException {
Map<String, Object> dfltVals = qryEntity.getDefaultFieldValues();
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
index e8d156c..cb53ac4 100755
---
a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
@@ -2799,6 +2799,20 @@ public class GridFunc {
}
/**
+ * Checks if key is contained in the map passed in. If the map
+ * is {@code null}, then {@code false} is returned.
+ *
+ * @param m Map to check.
+ * @param k Key to check for containment.
+ * @param <T> Key type.
+ * @return {@code true} if map is not {@code null} and contains given
+ * key, {@code false} otherwise.
+ */
+ public static <T> boolean mapContainsKey(@Nullable final Map<T, ?> m,
final T k) {
+ return m != null && m.containsKey(k);
+ }
+
+ /**
* Check's that {@code val} contains ignore case in collection {@code col}.
*
* @param col Collection of values.