You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by th...@apache.org on 2021/07/30 14:47:47 UTC
[solr] branch main updated: SOLR-15570: Include declared but unused
fields from the schema in table metadata (#241)
This is an automated email from the ASF dual-hosted git repository.
thelabdude pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 6056b68 SOLR-15570: Include declared but unused fields from the schema in table metadata (#241)
6056b68 is described below
commit 6056b6814de1a93cfbf14858bfa5e6026e86d16d
Author: Timothy Potter <th...@gmail.com>
AuthorDate: Fri Jul 30 08:47:41 2021 -0600
SOLR-15570: Include declared but unused fields from the schema in table metadata (#241)
---
.../org/apache/solr/handler/sql/SolrSchema.java | 29 +++++++++++++---------
.../org/apache/solr/handler/TestSQLHandler.java | 16 ++++++++++++
.../solr-ref-guide/src/parallel-sql-interface.adoc | 2 +-
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
index 413bbf7..d527018 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
@@ -23,6 +23,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import com.google.common.collect.ImmutableMap;
import org.apache.calcite.rel.type.RelDataType;
@@ -111,33 +113,40 @@ class SolrSchema extends AbstractSchema implements Closeable {
}
}
- private Map<String, LukeResponse.FieldTypeInfo> getFieldTypeInfo(final String collection) {
+ private LukeResponse getSchema(final String collection) {
final String zk = this.properties.getProperty("zk");
PKIAuthenticationPlugin.withServerIdentity(true);
try {
LukeRequest lukeRequest = new LukeRequest();
- lukeRequest.setShowSchema(true); // for custom type info ...
+ lukeRequest.setShowSchema(true); // for empty fields and custom type info ...
lukeRequest.setNumTerms(0);
- return lukeRequest.process(solrClientCache.getCloudSolrClient(zk), collection).getFieldTypeInfo();
+ return lukeRequest.process(solrClientCache.getCloudSolrClient(zk), collection);
} catch (SolrServerException | IOException e) {
throw new RuntimeException(e);
} finally {
PKIAuthenticationPlugin.withServerIdentity(false);
}
}
-
+
RelProtoDataType getRelDataType(String collection) {
// Temporary type factory, just for the duration of this method. Allowable
// because we're creating a proto-type, not a type; before being used, the
// proto-type will be copied into a real type factory.
final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
final RelDataTypeFactory.Builder fieldInfo = typeFactory.builder();
- Map<String, LukeResponse.FieldInfo> luceneFieldInfoMap = getFieldInfo(collection);
+
+ // Get fields that have data, including dynamic field instances
+ Map<String, LukeResponse.FieldInfo> fieldsInUseMap = getFieldInfo(collection);
+
+ LukeResponse schema = getSchema(collection);
+ // merge the actual fields in use returned by Luke with the declared fields in the schema that are empty
+ Map<String, LukeResponse.FieldInfo> combinedFields = Stream.of(fieldsInUseMap, schema.getFieldInfo())
+ .flatMap(map -> map.entrySet().stream())
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
- Map<String, LukeResponse.FieldTypeInfo> fieldTypeInfoMap = null; // loaded lazily if needed
Map<String, Class<?>> javaClassForTypeMap = new HashMap<>(); // local cache for custom field types we've already resolved
- for (Map.Entry<String, LukeResponse.FieldInfo> entry : luceneFieldInfoMap.entrySet()) {
+ for (Map.Entry<String, LukeResponse.FieldInfo> entry : combinedFields.entrySet()) {
LukeResponse.FieldInfo luceneFieldInfo = entry.getValue();
String luceneFieldType = luceneFieldInfo.getType();
@@ -173,11 +182,7 @@ class SolrSchema extends AbstractSchema implements Closeable {
default:
Class<?> javaClass = javaClassForTypeMap.get(luceneFieldType);
if (javaClass == null) {
- if (fieldTypeInfoMap == null) {
- // lazily go to luke for the field type info ...
- fieldTypeInfoMap = getFieldTypeInfo(collection);
- }
- javaClass = guessJavaClassForFieldType(fieldTypeInfoMap.get(luceneFieldType));
+ javaClass = guessJavaClassForFieldType(schema.getFieldTypeInfo().get(luceneFieldType));
javaClassForTypeMap.put(luceneFieldType, javaClass);
}
type = typeFactory.createJavaType(javaClass);
diff --git a/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java b/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java
index c3420fd..f7209a1 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java
@@ -2232,4 +2232,20 @@ public class TestSQLHandler extends SolrCloudTestCase {
// select * w/o limit is not supported by Solr SQL
expectThrows(IOException.class, () -> expectResults("SELECT * FROM $ALIAS", -1));
}
+
+ @Test
+ public void testSelectEmptyField() throws Exception {
+ new UpdateRequest()
+ .add("id", "01")
+ .add("id", "02")
+ .add("id", "03")
+ .add("id", "04")
+ .add("id", "05")
+ .commit(cluster.getSolrClient(), COLLECTIONORALIAS);
+
+ // stringx is declared in the schema but has no docs
+ expectResults("SELECT id, stringx FROM $ALIAS", 5);
+ // notafield_i matches a dynamic field pattern but has no docs, so don't allow this
+ expectThrows(IOException.class, () -> expectResults("SELECT id, stringx, notafield_i FROM $ALIAS", 5));
+ }
}
diff --git a/solr/solr-ref-guide/src/parallel-sql-interface.adoc b/solr/solr-ref-guide/src/parallel-sql-interface.adoc
index 7837b95..68caf06 100644
--- a/solr/solr-ref-guide/src/parallel-sql-interface.adoc
+++ b/solr/solr-ref-guide/src/parallel-sql-interface.adoc
@@ -40,7 +40,7 @@ Column names in the SQL query map directly to fields in the Solr index for the c
These identifiers are case sensitive.
Aliases are supported, and can be referenced in the `ORDER BY` clause.
-The `*` syntax to indicate all fields is not supported in either limited or unlimited queries.
+The `SELECT *` syntax to indicate all fields is only supported for queries with a `LIMIT` clause.
The `score` field can be used only with queries that contain a `LIMIT` clause.
For example, we could index Solr's sample documents and then construct an SQL query like this: