mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-23 21:38:15 +00:00
(cherry picked from commit f65e4d6ff7b2e00eb6f9c985fbe7cb24de00f045)
This commit is contained in:
parent
a0314ad015
commit
79600eb38b
@ -6,6 +6,7 @@
|
|||||||
package org.elasticsearch.xpack.ql.index;
|
package org.elasticsearch.xpack.ql.index;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.cursors.ObjectCursor;
|
import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchSecurityException;
|
import org.elasticsearch.ElasticsearchSecurityException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
@ -16,12 +17,14 @@ import org.elasticsearch.action.admin.indices.get.GetIndexRequest.Feature;
|
|||||||
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
||||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
|
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
|
||||||
|
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||||
import org.elasticsearch.action.support.IndicesOptions;
|
import org.elasticsearch.action.support.IndicesOptions;
|
||||||
import org.elasticsearch.action.support.IndicesOptions.Option;
|
import org.elasticsearch.action.support.IndicesOptions.Option;
|
||||||
import org.elasticsearch.action.support.IndicesOptions.WildcardStates;
|
import org.elasticsearch.action.support.IndicesOptions.WildcardStates;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||||
import org.elasticsearch.index.IndexNotFoundException;
|
import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
|
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
|
||||||
@ -42,9 +45,11 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@ -164,7 +169,6 @@ public class IndexResolver {
|
|||||||
private final String clusterName;
|
private final String clusterName;
|
||||||
private final DataTypeRegistry typeRegistry;
|
private final DataTypeRegistry typeRegistry;
|
||||||
|
|
||||||
|
|
||||||
public IndexResolver(Client client, String clusterName, DataTypeRegistry typeRegistry) {
|
public IndexResolver(Client client, String clusterName, DataTypeRegistry typeRegistry) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.clusterName = clusterName;
|
this.clusterName = clusterName;
|
||||||
@ -296,7 +300,7 @@ public class IndexResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// merge all indices onto the same one
|
// merge all indices onto the same one
|
||||||
List<EsIndex> indices = buildIndices(typeRegistry, indexNames, null, fieldCaps, i -> indexPattern, (n, types) -> {
|
List<EsIndex> indices = buildIndices(typeRegistry, indexNames, null, fieldCaps, null, i -> indexPattern, (n, types) -> {
|
||||||
StringBuilder errorMessage = new StringBuilder();
|
StringBuilder errorMessage = new StringBuilder();
|
||||||
|
|
||||||
boolean hasUnmapped = types.containsKey(UNMAPPED);
|
boolean hasUnmapped = types.containsKey(UNMAPPED);
|
||||||
@ -473,17 +477,32 @@ public class IndexResolver {
|
|||||||
public void resolveAsSeparateMappings(String indexWildcard, String javaRegex, boolean includeFrozen,
|
public void resolveAsSeparateMappings(String indexWildcard, String javaRegex, boolean includeFrozen,
|
||||||
ActionListener<List<EsIndex>> listener) {
|
ActionListener<List<EsIndex>> listener) {
|
||||||
FieldCapabilitiesRequest fieldRequest = createFieldCapsRequest(indexWildcard, includeFrozen);
|
FieldCapabilitiesRequest fieldRequest = createFieldCapsRequest(indexWildcard, includeFrozen);
|
||||||
client.fieldCaps(fieldRequest,
|
client.fieldCaps(fieldRequest, wrap(response -> {
|
||||||
ActionListener.wrap(
|
client.admin().indices().getAliases(createGetAliasesRequest(response, includeFrozen), wrap(aliases ->
|
||||||
response -> listener.onResponse(
|
listener.onResponse(separateMappings(typeRegistry, javaRegex, response.getIndices(), response.get(), aliases.getAliases())),
|
||||||
separateMappings(typeRegistry, indexWildcard, javaRegex, response.getIndices(), response.get())),
|
ex -> {
|
||||||
listener::onFailure));
|
if (ex instanceof IndexNotFoundException || ex instanceof ElasticsearchSecurityException) {
|
||||||
|
listener.onResponse(separateMappings(typeRegistry, javaRegex, response.getIndices(), response.get(), null));
|
||||||
|
} else {
|
||||||
|
listener.onFailure(ex);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
listener::onFailure));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<EsIndex> separateMappings(DataTypeRegistry typeRegistry, String indexPattern, String javaRegex, String[] indexNames,
|
private GetAliasesRequest createGetAliasesRequest(FieldCapabilitiesResponse response, boolean includeFrozen) {
|
||||||
Map<String, Map<String, FieldCapabilities>> fieldCaps) {
|
return new GetAliasesRequest()
|
||||||
return buildIndices(typeRegistry, indexNames, javaRegex, fieldCaps, Function.identity(), (s, cap) -> null);
|
.local(true)
|
||||||
|
.aliases("*")
|
||||||
|
.indices(response.getIndices())
|
||||||
|
.indicesOptions(includeFrozen ? FIELD_CAPS_FROZEN_INDICES_OPTIONS : FIELD_CAPS_INDICES_OPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<EsIndex> separateMappings(DataTypeRegistry typeRegistry, String javaRegex, String[] indexNames,
|
||||||
|
Map<String, Map<String, FieldCapabilities>> fieldCaps, ImmutableOpenMap<String, List<AliasMetaData>> aliases) {
|
||||||
|
return buildIndices(typeRegistry, indexNames, javaRegex, fieldCaps, aliases, Function.identity(), (s, cap) -> null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Fields {
|
private static class Fields {
|
||||||
@ -496,16 +515,27 @@ public class IndexResolver {
|
|||||||
* each field.
|
* each field.
|
||||||
*/
|
*/
|
||||||
private static List<EsIndex> buildIndices(DataTypeRegistry typeRegistry, String[] indexNames, String javaRegex,
|
private static List<EsIndex> buildIndices(DataTypeRegistry typeRegistry, String[] indexNames, String javaRegex,
|
||||||
Map<String, Map<String, FieldCapabilities>> fieldCaps,
|
Map<String, Map<String, FieldCapabilities>> fieldCaps, ImmutableOpenMap<String, List<AliasMetaData>> aliases,
|
||||||
Function<String, String> indexNameProcessor,
|
Function<String, String> indexNameProcessor,
|
||||||
BiFunction<String, Map<String, FieldCapabilities>, InvalidMappedField> validityVerifier) {
|
BiFunction<String, Map<String, FieldCapabilities>, InvalidMappedField> validityVerifier) {
|
||||||
|
|
||||||
if (indexNames == null || indexNames.length == 0) {
|
if ((indexNames == null || indexNames.length == 0) && (aliases == null || aliases.isEmpty())) {
|
||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> resolvedIndices = asList(indexNames);
|
Set<String> resolvedAliases = new HashSet<>();
|
||||||
Map<String, Fields> indices = new LinkedHashMap<>(resolvedIndices.size());
|
if (aliases != null) {
|
||||||
|
Iterator<ObjectObjectCursor<String, List<AliasMetaData>>> iterator = aliases.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
for (AliasMetaData alias : iterator.next().value) {
|
||||||
|
resolvedAliases.add(alias.getAlias());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> resolvedIndices = new ArrayList<>(asList(indexNames));
|
||||||
|
int mapSize = CollectionUtils.mapSize(resolvedIndices.size() + resolvedAliases.size());
|
||||||
|
Map<String, Fields> indices = new LinkedHashMap<>(mapSize);
|
||||||
Pattern pattern = javaRegex != null ? Pattern.compile(javaRegex) : null;
|
Pattern pattern = javaRegex != null ? Pattern.compile(javaRegex) : null;
|
||||||
|
|
||||||
// sort fields in reverse order to build the field hierarchy
|
// sort fields in reverse order to build the field hierarchy
|
||||||
@ -525,6 +555,8 @@ public class IndexResolver {
|
|||||||
Map<String, FieldCapabilities> types = new LinkedHashMap<>(entry.getValue());
|
Map<String, FieldCapabilities> types = new LinkedHashMap<>(entry.getValue());
|
||||||
// apply verification and possibly remove the "duplicate" CONSTANT_KEYWORD field type
|
// apply verification and possibly remove the "duplicate" CONSTANT_KEYWORD field type
|
||||||
final InvalidMappedField invalidField = validityVerifier.apply(fieldName, types);
|
final InvalidMappedField invalidField = validityVerifier.apply(fieldName, types);
|
||||||
|
// apply verification for fields belonging to index aliases
|
||||||
|
Map<String, InvalidMappedField> invalidFieldsForAliases = getInvalidFieldsForAliases(fieldName, types, aliases);
|
||||||
|
|
||||||
// filter meta fields and unmapped
|
// filter meta fields and unmapped
|
||||||
FieldCapabilities unmapped = types.get(UNMAPPED);
|
FieldCapabilities unmapped = types.get(UNMAPPED);
|
||||||
@ -545,7 +577,7 @@ public class IndexResolver {
|
|||||||
List<String> concreteIndices = null;
|
List<String> concreteIndices = null;
|
||||||
if (capIndices != null) {
|
if (capIndices != null) {
|
||||||
if (unmappedIndices.isEmpty()) {
|
if (unmappedIndices.isEmpty()) {
|
||||||
concreteIndices = asList(capIndices);
|
concreteIndices = new ArrayList<>(asList(capIndices));
|
||||||
} else {
|
} else {
|
||||||
concreteIndices = new ArrayList<>(capIndices.length);
|
concreteIndices = new ArrayList<>(capIndices.length);
|
||||||
for (String capIndex : capIndices) {
|
for (String capIndex : capIndices) {
|
||||||
@ -559,30 +591,55 @@ public class IndexResolver {
|
|||||||
concreteIndices = resolvedIndices;
|
concreteIndices = resolvedIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add to the list of concrete indices the aliases associated with these indices
|
||||||
|
Set<String> uniqueAliases = new LinkedHashSet<>();
|
||||||
|
if (aliases != null) {
|
||||||
|
for (String concreteIndex : concreteIndices) {
|
||||||
|
if (aliases.containsKey(concreteIndex)) {
|
||||||
|
List<AliasMetaData> concreteIndexAliases = aliases.get(concreteIndex);
|
||||||
|
concreteIndexAliases.stream().forEach(e -> uniqueAliases.add(e.alias()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
concreteIndices.addAll(uniqueAliases);
|
||||||
|
}
|
||||||
|
|
||||||
// put the field in their respective mappings
|
// put the field in their respective mappings
|
||||||
for (String index : concreteIndices) {
|
for (String index : concreteIndices) {
|
||||||
if (pattern == null || pattern.matcher(index).matches()) {
|
boolean isIndexAlias = uniqueAliases.contains(index);
|
||||||
String indexName = indexNameProcessor.apply(index);
|
if (pattern == null || pattern.matcher(index).matches() || isIndexAlias) {
|
||||||
|
String indexName = isIndexAlias ? index : indexNameProcessor.apply(index);
|
||||||
Fields indexFields = indices.get(indexName);
|
Fields indexFields = indices.get(indexName);
|
||||||
if (indexFields == null) {
|
if (indexFields == null) {
|
||||||
indexFields = new Fields();
|
indexFields = new Fields();
|
||||||
indices.put(indexName, indexFields);
|
indices.put(indexName, indexFields);
|
||||||
}
|
}
|
||||||
EsField field = indexFields.flattedMapping.get(fieldName);
|
EsField field = indexFields.flattedMapping.get(fieldName);
|
||||||
if (field == null || (invalidField != null && (field instanceof InvalidMappedField) == false)) {
|
boolean createField = false;
|
||||||
|
if (isIndexAlias == false) {
|
||||||
|
if (field == null || (invalidField != null && (field instanceof InvalidMappedField) == false)) {
|
||||||
|
createField = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (field == null && invalidFieldsForAliases.get(index) == null) {
|
||||||
|
createField = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createField) {
|
||||||
int dot = fieldName.lastIndexOf('.');
|
int dot = fieldName.lastIndexOf('.');
|
||||||
/*
|
/*
|
||||||
* Looking up the "tree" at the parent fields here to see if the field is an alias.
|
* Looking up the "tree" at the parent fields here to see if the field is an alias.
|
||||||
* When the upper elements of the "tree" have no elements in fieldcaps, then this is an alias field. But not
|
* When the upper elements of the "tree" have no elements in fieldcaps, then this is an alias field. But not
|
||||||
* always: if there are two aliases - a.b.c.alias1 and a.b.c.alias2 - only one of them will be considered alias.
|
* always: if there are two aliases - a.b.c.alias1 and a.b.c.alias2 - only one of them will be considered alias.
|
||||||
*/
|
*/
|
||||||
Holder<Boolean> isAlias = new Holder<>(false);
|
Holder<Boolean> isAliasFieldType = new Holder<>(false);
|
||||||
if (dot >= 0) {
|
if (dot >= 0) {
|
||||||
String parentName = fieldName.substring(0, dot);
|
String parentName = fieldName.substring(0, dot);
|
||||||
if (indexFields.flattedMapping.get(parentName) == null) {
|
if (indexFields.flattedMapping.get(parentName) == null) {
|
||||||
// lack of parent implies the field is an alias
|
// lack of parent implies the field is an alias
|
||||||
if (fieldCaps.get(parentName) == null) {
|
if (fieldCaps.get(parentName) == null) {
|
||||||
isAlias.set(true);
|
isAliasFieldType.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -590,7 +647,7 @@ public class IndexResolver {
|
|||||||
createField(typeRegistry, fieldName, fieldCaps, indexFields.hierarchicalMapping, indexFields.flattedMapping,
|
createField(typeRegistry, fieldName, fieldCaps, indexFields.hierarchicalMapping, indexFields.flattedMapping,
|
||||||
s -> invalidField != null ? invalidField :
|
s -> invalidField != null ? invalidField :
|
||||||
createField(typeRegistry, s, typeCap.getType(), emptyMap(), typeCap.isAggregatable(),
|
createField(typeRegistry, s, typeCap.getType(), emptyMap(), typeCap.isAggregatable(),
|
||||||
isAlias.get()));
|
isAliasFieldType.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -605,4 +662,141 @@ public class IndexResolver {
|
|||||||
foundIndices.sort(Comparator.comparing(EsIndex::name));
|
foundIndices.sort(Comparator.comparing(EsIndex::name));
|
||||||
return foundIndices;
|
return foundIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the field is valid (same type and same capabilities - searchable/aggregatable) across indices belonging to a list
|
||||||
|
* of aliases.
|
||||||
|
* A field can look like the example below (generated by field_caps API).
|
||||||
|
* "name": {
|
||||||
|
* "text": {
|
||||||
|
* "type": "text",
|
||||||
|
* "searchable": false,
|
||||||
|
* "aggregatable": false,
|
||||||
|
* "indices": [
|
||||||
|
* "bar",
|
||||||
|
* "foo"
|
||||||
|
* ],
|
||||||
|
* "non_searchable_indices": [
|
||||||
|
* "foo"
|
||||||
|
* ]
|
||||||
|
* },
|
||||||
|
* "keyword": {
|
||||||
|
* "type": "keyword",
|
||||||
|
* "searchable": false,
|
||||||
|
* "aggregatable": true,
|
||||||
|
* "non_aggregatable_indices": [
|
||||||
|
* "bar", "baz"
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
private static Map<String, InvalidMappedField> getInvalidFieldsForAliases(String fieldName, Map<String, FieldCapabilities> types,
|
||||||
|
ImmutableOpenMap<String, List<AliasMetaData>> aliases) {
|
||||||
|
if (aliases == null || aliases.isEmpty()) {
|
||||||
|
return emptyMap();
|
||||||
|
}
|
||||||
|
Map<String, InvalidMappedField> invalidFields = new HashMap<>();
|
||||||
|
Map<String, Set<String>> typesErrors = new HashMap<>(); // map holding aliases and a list of unique field types across its indices
|
||||||
|
Map<String, Set<String>> aliasToIndices = new HashMap<>(); // map with aliases and their list of indices
|
||||||
|
|
||||||
|
Iterator<ObjectObjectCursor<String, List<AliasMetaData>>> iter = aliases.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
ObjectObjectCursor<String, List<AliasMetaData>> index = iter.next();
|
||||||
|
for (AliasMetaData aliasMetaData : index.value) {
|
||||||
|
String aliasName = aliasMetaData.alias();
|
||||||
|
aliasToIndices.putIfAbsent(aliasName, new HashSet<>());
|
||||||
|
aliasToIndices.get(aliasName).add(index.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate over each type
|
||||||
|
for (Entry<String, FieldCapabilities> type : types.entrySet()) {
|
||||||
|
String esFieldType = type.getKey();
|
||||||
|
if (esFieldType == UNMAPPED) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] indices = type.getValue().indices();
|
||||||
|
// if there is a list of indices where this field type is defined
|
||||||
|
if (indices != null) {
|
||||||
|
// Look at all these indices' aliases and add the type of the field to a list (Set) with unique elements.
|
||||||
|
// A valid mapping for a field in an index alias should contain only one type. If it doesn't, this means that field
|
||||||
|
// is mapped as different types across the indices in this index alias.
|
||||||
|
for (String index : indices) {
|
||||||
|
List<AliasMetaData> indexAliases = aliases.get(index);
|
||||||
|
if (indexAliases == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (AliasMetaData aliasMetaData : indexAliases) {
|
||||||
|
String aliasName = aliasMetaData.alias();
|
||||||
|
if (typesErrors.containsKey(aliasName)) {
|
||||||
|
typesErrors.get(aliasName).add(esFieldType);
|
||||||
|
} else {
|
||||||
|
Set<String> fieldTypes = new HashSet<>();
|
||||||
|
fieldTypes.add(esFieldType);
|
||||||
|
typesErrors.put(aliasName, fieldTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String aliasName : aliasToIndices.keySet()) {
|
||||||
|
// if, for the same index alias, there are multiple field types for this fieldName ie the index alias has indices where the same
|
||||||
|
// field name is of different types
|
||||||
|
Set<String> esFieldTypes = typesErrors.get(aliasName);
|
||||||
|
if (esFieldTypes != null && esFieldTypes.size() > 1) {
|
||||||
|
// consider the field as invalid, for the currently checked index alias
|
||||||
|
// the error message doesn't actually matter
|
||||||
|
invalidFields.put(aliasName, new InvalidMappedField(fieldName));
|
||||||
|
} else {
|
||||||
|
// if the field type is the same across all this alias' indices, check the field's capabilities (searchable/aggregatable)
|
||||||
|
for (Entry<String, FieldCapabilities> type : types.entrySet()) {
|
||||||
|
if (type.getKey() == UNMAPPED) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FieldCapabilities f = type.getValue();
|
||||||
|
|
||||||
|
// the existence of a list of non_aggregatable_indices is an indication that not all indices have the same capabilities
|
||||||
|
// but this list can contain indices belonging to other aliases, so we need to check only for this alias
|
||||||
|
if (f.nonAggregatableIndices() != null) {
|
||||||
|
Set<String> aliasIndices = aliasToIndices.get(aliasName);
|
||||||
|
int nonAggregatableCount = 0;
|
||||||
|
// either all or none of the non-aggregatable indices belonging to a certain alias should be in this list
|
||||||
|
for (String nonAggIndex : f.nonAggregatableIndices()) {
|
||||||
|
if (aliasIndices.contains(nonAggIndex)) {
|
||||||
|
nonAggregatableCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nonAggregatableCount > 0 && nonAggregatableCount != aliasIndices.size()) {
|
||||||
|
invalidFields.put(aliasName, new InvalidMappedField(fieldName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform the same check for non_searchable_indices list
|
||||||
|
if (f.nonSearchableIndices() != null) {
|
||||||
|
Set<String> aliasIndices = aliasToIndices.get(aliasName);
|
||||||
|
int nonSearchableCount = 0;
|
||||||
|
// either all or none of the non-searchable indices belonging to a certain alias should be in this list
|
||||||
|
for (String nonSearchIndex : f.nonSearchableIndices()) {
|
||||||
|
if (aliasIndices.contains(nonSearchIndex)) {
|
||||||
|
nonSearchableCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nonSearchableCount > 0 && nonSearchableCount != aliasIndices.size()) {
|
||||||
|
invalidFields.put(aliasName, new InvalidMappedField(fieldName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidFields.size() > 0) {
|
||||||
|
return invalidFields;
|
||||||
|
}
|
||||||
|
// everything checks
|
||||||
|
return emptyMap();
|
||||||
|
}
|
||||||
}
|
}
|
@ -25,6 +25,11 @@ public class InvalidMappedField extends EsField {
|
|||||||
this.errorMessage = errorMessage;
|
this.errorMessage = errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InvalidMappedField(String name) {
|
||||||
|
super(name, DataTypes.UNSUPPORTED, emptyMap(), false);
|
||||||
|
this.errorMessage = StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
public String errorMessage() {
|
public String errorMessage() {
|
||||||
return errorMessage;
|
return errorMessage;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.xpack.sql.qa.single_node;
|
||||||
|
|
||||||
|
import org.elasticsearch.xpack.sql.qa.jdbc.SysColumnsTestCase;
|
||||||
|
|
||||||
|
public class SysColumnsIT extends SysColumnsTestCase {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,358 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.xpack.sql.qa.jdbc;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Request;
|
||||||
|
import org.elasticsearch.common.CheckedConsumer;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import static org.elasticsearch.xpack.sql.qa.jdbc.ResultSetTestCase.updateMapping;
|
||||||
|
|
||||||
|
public class SysColumnsTestCase extends JdbcIntegrationTestCase {
|
||||||
|
|
||||||
|
public void testAliasWithIncompatibleTypes() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("value").field("type", "double").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").endObject();
|
||||||
|
builder.startObject("value").field("type", "double").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"KEYWORD"},
|
||||||
|
{"test1" ,"value" ,"DOUBLE"},
|
||||||
|
{"test2" ,"id" ,"TEXT"},
|
||||||
|
{"test2" ,"value" ,"DOUBLE"},
|
||||||
|
{"test_alias" ,"value" ,"DOUBLE"}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAliasWithIncompatibleSearchableProperty() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("value").field("type", "boolean").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").field("index", false).endObject();
|
||||||
|
builder.startObject("value").field("type", "boolean").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test3", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").field("index", false).endObject();
|
||||||
|
builder.startObject("value").field("type", "boolean").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test4", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").field("index", false).endObject();
|
||||||
|
builder.startObject("value").field("type", "boolean").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test3").field("alias", "test_alias2").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test4").field("alias", "test_alias2").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"KEYWORD"},
|
||||||
|
{"test1" ,"value" ,"BOOLEAN"},
|
||||||
|
{"test2" ,"id" ,"KEYWORD"},
|
||||||
|
{"test2" ,"value" ,"BOOLEAN"},
|
||||||
|
{"test3" ,"id" ,"KEYWORD"},
|
||||||
|
{"test3" ,"value" ,"BOOLEAN"},
|
||||||
|
{"test4" ,"id" ,"KEYWORD"},
|
||||||
|
{"test4" ,"value" ,"BOOLEAN"},
|
||||||
|
{"test_alias" ,"value" ,"BOOLEAN"},
|
||||||
|
{"test_alias2" ,"id" ,"KEYWORD"},
|
||||||
|
{"test_alias2" ,"value" ,"BOOLEAN"}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAliasWithIncompatibleAggregatableProperty() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").field("fielddata", true).endObject();
|
||||||
|
builder.startObject("value").field("type", "date").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").endObject();
|
||||||
|
builder.startObject("value").field("type", "date").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test3", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").field("fielddata", true).endObject();
|
||||||
|
builder.startObject("value").field("type", "date").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test4", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").field("fielddata", true).endObject();
|
||||||
|
builder.startObject("value").field("type", "date").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test3").field("alias", "test_alias2").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test4").field("alias", "test_alias2").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"TEXT"},
|
||||||
|
{"test1" ,"value" ,"DATETIME"},
|
||||||
|
{"test2" ,"id" ,"TEXT"},
|
||||||
|
{"test2" ,"value" ,"DATETIME"},
|
||||||
|
{"test3" ,"id" ,"TEXT"},
|
||||||
|
{"test3" ,"value" ,"DATETIME"},
|
||||||
|
{"test4" ,"id" ,"TEXT"},
|
||||||
|
{"test4" ,"value" ,"DATETIME"},
|
||||||
|
{"test_alias" ,"value" ,"DATETIME"},
|
||||||
|
{"test_alias2","id" ,"TEXT"},
|
||||||
|
{"test_alias2","value" ,"DATETIME"},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAliasWithIncompatibleTypesInSubfield() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "keyword")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"TEXT"},
|
||||||
|
{"test1" ,"id.raw" ,"KEYWORD"},
|
||||||
|
{"test1" ,"value" ,"DATETIME"},
|
||||||
|
{"test1" ,"value.raw","LONG"},
|
||||||
|
{"test2" ,"id" ,"TEXT"},
|
||||||
|
{"test2" ,"id.raw" ,"INTEGER"},
|
||||||
|
{"test2" ,"value" ,"DATETIME"},
|
||||||
|
{"test2" ,"value.raw","LONG"},
|
||||||
|
{"test_alias" ,"id" ,"TEXT"},
|
||||||
|
{"test_alias" ,"value" ,"DATETIME"},
|
||||||
|
{"test_alias" ,"value.raw","LONG"},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAliasWithIncompatibleSearchablePropertyInSubfield() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer")
|
||||||
|
.field("index", false).endObject().endObject().endObject();
|
||||||
|
builder.startObject("value").field("type", "date").startObject("fields").startObject("raw").field("type", "long")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"TEXT"},
|
||||||
|
{"test1" ,"id.raw" ,"INTEGER"},
|
||||||
|
{"test1" ,"value" ,"DATETIME"},
|
||||||
|
{"test1" ,"value.raw","LONG"},
|
||||||
|
{"test2" ,"id" ,"TEXT"},
|
||||||
|
{"test2" ,"id.raw" ,"INTEGER"},
|
||||||
|
{"test2" ,"value" ,"DATETIME"},
|
||||||
|
{"test2" ,"value.raw","LONG"},
|
||||||
|
{"test_alias" ,"id" ,"TEXT"},
|
||||||
|
{"test_alias" ,"value" ,"DATETIME"},
|
||||||
|
{"test_alias" ,"value.raw","LONG"},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAliasWithIncompatibleAggregatablePropertyInSubfield() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer")
|
||||||
|
.field("doc_values", false).endObject().endObject().endObject();
|
||||||
|
builder.startObject("value").field("type", "ip").startObject("fields").startObject("raw").field("type", "text")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "text").startObject("fields").startObject("raw").field("type", "integer")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
builder.startObject("value").field("type", "ip").startObject("fields").startObject("raw").field("type", "text")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"TEXT"},
|
||||||
|
{"test1" ,"id.raw" ,"INTEGER"},
|
||||||
|
{"test1" ,"value" ,"IP"},
|
||||||
|
{"test1" ,"value.raw","TEXT"},
|
||||||
|
{"test2" ,"id" ,"TEXT"},
|
||||||
|
{"test2" ,"id.raw" ,"INTEGER"},
|
||||||
|
{"test2" ,"value" ,"IP"},
|
||||||
|
{"test2" ,"value.raw","TEXT"},
|
||||||
|
{"test_alias" ,"id" ,"TEXT"},
|
||||||
|
{"test_alias" ,"value" ,"IP"},
|
||||||
|
{"test_alias" ,"value.raw","TEXT"},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/53445")
|
||||||
|
public void testAliasWithSubfieldsAndDifferentRootFields() throws Exception {
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("name").field("type", "text").startObject("fields").startObject("raw").field("type", "keyword")
|
||||||
|
.endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("name").field("type", "keyword").field("index", false).startObject("fields").startObject("raw")
|
||||||
|
.field("type", "keyword").endObject().endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "test_alias").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "test_alias").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"test1" ,"id" ,"KEYWORD"},
|
||||||
|
{"test1" ,"name" ,"TEXT"},
|
||||||
|
{"test1" ,"name.raw","KEYWORD"},
|
||||||
|
{"test2" ,"id" ,"KEYWORD"},
|
||||||
|
{"test2" ,"name" ,"KEYWORD"},
|
||||||
|
{"test2" ,"name.raw","KEYWORD"},
|
||||||
|
{"test_alias" ,"id" ,"KEYWORD"}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiIndicesMultiAlias() throws Exception {
|
||||||
|
createIndexWithMapping("test2", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("name").field("type", "text").endObject();
|
||||||
|
});
|
||||||
|
createIndexWithMapping("test4", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("name").field("type", "text").field("index", false).endObject();
|
||||||
|
});
|
||||||
|
createIndexWithMapping("test1", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("name").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("number").field("type", "long").endObject();
|
||||||
|
});
|
||||||
|
createIndexWithMapping("test3", builder -> {
|
||||||
|
builder.startObject("id").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("name").field("type", "keyword").endObject();
|
||||||
|
builder.startObject("number").field("type", "long").endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
createAliases(builder -> {
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "alias1").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test1").field("alias", "alias2").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "alias2").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test2").field("alias", "alias3").endObject().endObject();
|
||||||
|
builder.startObject().startObject("add").field("index", "test4").field("alias", "alias3").endObject().endObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertResultsForQuery("SYS COLUMNS", new String[][] {
|
||||||
|
{"alias1","id" ,"KEYWORD"},
|
||||||
|
{"alias1","name" ,"KEYWORD"},
|
||||||
|
{"alias1","number","LONG"},
|
||||||
|
{"alias2","id" ,"KEYWORD"},
|
||||||
|
{"alias2","number","LONG"},
|
||||||
|
{"alias3","id" ,"KEYWORD"},
|
||||||
|
{"test1" ,"id" ,"KEYWORD"},
|
||||||
|
{"test1" ,"name" ,"KEYWORD"},
|
||||||
|
{"test1" ,"number","LONG"},
|
||||||
|
{"test2" ,"id" ,"KEYWORD"},
|
||||||
|
{"test2" ,"name" ,"TEXT"},
|
||||||
|
{"test3" ,"id" ,"KEYWORD"},
|
||||||
|
{"test3" ,"name" ,"KEYWORD"},
|
||||||
|
{"test3" ,"number","LONG"},
|
||||||
|
{"test4" ,"id" ,"KEYWORD"},
|
||||||
|
{"test4" ,"name" ,"TEXT"}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createIndexWithMapping(String indexName, CheckedConsumer<XContentBuilder, IOException> mapping) throws Exception {
|
||||||
|
ResultSetTestCase.createIndex(indexName);
|
||||||
|
updateMapping(indexName, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doWithQuery(String query, CheckedConsumer<ResultSet, SQLException> consumer) throws SQLException {
|
||||||
|
try (Connection connection = esJdbc()) {
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
try (ResultSet results = statement.executeQuery()) {
|
||||||
|
consumer.accept(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createAliases(CheckedConsumer<XContentBuilder, IOException> definitions) throws Exception {
|
||||||
|
Request request = new Request("POST", "/_aliases");
|
||||||
|
XContentBuilder createAliases = JsonXContent.contentBuilder().startObject();
|
||||||
|
createAliases.startArray("actions");
|
||||||
|
{
|
||||||
|
definitions.accept(createAliases);
|
||||||
|
}
|
||||||
|
createAliases.endArray();
|
||||||
|
createAliases.endObject();
|
||||||
|
request.setJsonEntity(Strings.toString(createAliases));
|
||||||
|
client().performRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertResultsForQuery(String query, String[][] rows) throws Exception {
|
||||||
|
doWithQuery(query, (results) -> {
|
||||||
|
for (String[] row : rows) {
|
||||||
|
results.next();
|
||||||
|
assertEquals(row[0], results.getString(3)); // table name
|
||||||
|
assertEquals(row[1], results.getString(4)); // column name
|
||||||
|
assertEquals(row[2], results.getString(6)); // type name
|
||||||
|
}
|
||||||
|
assertFalse(results.next());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -90,38 +90,66 @@ integTest |null |test_alias |salary |4 |I
|
|||||||
sysColumnsAllTables
|
sysColumnsAllTables
|
||||||
SYS COLUMNS TABLE LIKE '%';
|
SYS COLUMNS TABLE LIKE '%';
|
||||||
|
|
||||||
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i| BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
|
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i|BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
|
||||||
---------------+---------------+---------------+------------------+---------------+----------------+---------------+----------------+----------------+-----------------+-----------+---------------+---------------+---------------+------------------+-------------------+------------------+-------------+---------------+---------------+---------------+----------------+------------------+------------------
|
-----------------+---------------+---------------+------------------+---------------+----------------+---------------+---------------+----------------+---------------+---------------+---------------+---------------+---------------+----------------+-----------------+----------------+---------------+---------------+---------------+---------------+----------------+----------------+------------------
|
||||||
integTest |null |logs |@timestamp |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |@timestamp |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |bytes_in |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |2 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |bytes_in |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |2 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |bytes_out |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |bytes_out |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |client_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |4 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |client_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |4 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |client_port |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |5 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |client_port |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |5 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |dest_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |6 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |dest_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |6 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |id |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |7 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |id |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |7 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |logs |status |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |8 |YES |null |null |null |null |NO |NO
|
integTest |null |logs |status |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |8 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |4 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |5 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |7 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |8 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |11 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
|
||||||
integTest |null |test_emp_copy |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
|
integTest |null |test_alias_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_alias_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_alias_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_alias_emp |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_alias_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |4 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |5 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |7 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |8 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |11 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
|
||||||
|
integTest |null |test_emp_copy |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
|
||||||
;
|
;
|
||||||
|
@ -375,7 +375,7 @@ public class IndexResolverTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<EsIndex> separate(EsIndex... indices) {
|
public static List<EsIndex> separate(EsIndex... indices) {
|
||||||
return separateMappings("*", null, Stream.of(indices).map(EsIndex::name).toArray(String[]::new),
|
return separateMappings(null, Stream.of(indices).map(EsIndex::name).toArray(String[]::new),
|
||||||
fromMappings(indices));
|
fromMappings(indices));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,8 +484,8 @@ public class IndexResolverTests extends ESTestCase {
|
|||||||
return IndexResolver.mergedMappings(SqlDataTypeRegistry.INSTANCE, indexPattern, indexNames, fieldCaps);
|
return IndexResolver.mergedMappings(SqlDataTypeRegistry.INSTANCE, indexPattern, indexNames, fieldCaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<EsIndex> separateMappings(String indexPattern, String javaRegex, String[] indexNames,
|
private static List<EsIndex> separateMappings(String javaRegex, String[] indexNames,
|
||||||
Map<String, Map<String, FieldCapabilities>> fieldCaps) {
|
Map<String, Map<String, FieldCapabilities>> fieldCaps) {
|
||||||
return IndexResolver.separateMappings(SqlDataTypeRegistry.INSTANCE, indexPattern, javaRegex, indexNames, fieldCaps);
|
return IndexResolver.separateMappings(SqlDataTypeRegistry.INSTANCE, javaRegex, indexNames, fieldCaps, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user