remove Catalog abstraction and rename its package from catalog to index
Given that the Catalog was only ever used to hold a single index, the corresponding abstraction can be removed in favour of the abstraction that it holds, namely `GetIndexResult`. Original commit: elastic/x-pack-elasticsearch@6932db642c
This commit is contained in:
parent
90aee54251
commit
9664363575
|
@ -11,7 +11,7 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.test.rest.FakeRestChannel;
|
||||
import org.elasticsearch.test.rest.FakeRestRequest;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.Proto;
|
||||
import org.elasticsearch.xpack.sql.plugin.RestSqlJdbcAction;
|
||||
import org.elasticsearch.xpack.sql.plugin.SqlLicenseChecker;
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.elasticsearch.common.bytes.BytesReference;
|
|||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
||||
|
||||
import java.io.DataInput;
|
||||
|
|
|
@ -7,8 +7,7 @@ package org.elasticsearch.xpack.sql.analysis.analyzer;
|
|||
|
||||
import org.elasticsearch.xpack.sql.analysis.AnalysisException;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.Verifier.Failure;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.capabilities.Resolvables;
|
||||
import org.elasticsearch.xpack.sql.expression.Alias;
|
||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||
|
@ -253,14 +252,14 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
|
|||
@Override
|
||||
protected LogicalPlan rule(UnresolvedRelation plan) {
|
||||
TableIdentifier table = plan.table();
|
||||
GetIndexResult index = SqlSession.currentContext().catalog.getIndex(table.index());
|
||||
GetIndexResult index = SqlSession.currentContext().getIndexResult;
|
||||
if (index.isValid() == false) {
|
||||
return plan.unresolvedMessage().equals(index.toString()) ? plan : new UnresolvedRelation(plan.location(), plan.table(),
|
||||
plan.alias(), index.toString());
|
||||
}
|
||||
|
||||
LogicalPlan catalogTable = new EsRelation(plan.location(), index.get());
|
||||
SubQueryAlias sa = new SubQueryAlias(plan.location(), catalogTable, table.index());
|
||||
assert index.matches(table.index());
|
||||
LogicalPlan logicalPlan = new EsRelation(plan.location(), index.get());
|
||||
SubQueryAlias sa = new SubQueryAlias(plan.location(), logicalPlan, table.index());
|
||||
|
||||
if (plan.alias() != null) {
|
||||
sa = new SubQueryAlias(plan.location(), sa, plan.alias());
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* 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.analysis.catalog;
|
||||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Index representation that is compatible with SQL ({@link EsIndex}).
|
||||
*/
|
||||
public final class Catalog {
|
||||
|
||||
public static final Catalog EMPTY = new Catalog(GetIndexResult::notFound);
|
||||
|
||||
private final Function<String, GetIndexResult> resultFunction;
|
||||
|
||||
//TODO given that this always holds a single index, we cana probably get rid of the whole idea of Catalog
|
||||
public Catalog(GetIndexResult result) {
|
||||
assert result != null;
|
||||
this.resultFunction = index -> result.matches(index) ? result : GetIndexResult.notFound(index);
|
||||
}
|
||||
|
||||
private Catalog(Function<String, GetIndexResult> resultFunction) {
|
||||
assert resultFunction != null;
|
||||
this.resultFunction = resultFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the information for a table.
|
||||
*/
|
||||
public GetIndexResult getIndex(String index) {
|
||||
return resultFunction.apply(index);
|
||||
}
|
||||
|
||||
public static final class GetIndexResult {
|
||||
public static GetIndexResult valid(EsIndex index) {
|
||||
Objects.requireNonNull(index, "index must not be null if it was found");
|
||||
return new GetIndexResult(index, null);
|
||||
}
|
||||
public static GetIndexResult invalid(String invalid) {
|
||||
Objects.requireNonNull(invalid, "invalid must not be null to signal that the index is invalid");
|
||||
return new GetIndexResult(null, invalid);
|
||||
}
|
||||
public static GetIndexResult notFound(String name) {
|
||||
Objects.requireNonNull(name, "name must not be null");
|
||||
return invalid("Index '" + name + "' does not exist");
|
||||
}
|
||||
|
||||
private final EsIndex index;
|
||||
@Nullable
|
||||
private final String invalid;
|
||||
|
||||
private GetIndexResult(EsIndex index, @Nullable String invalid) {
|
||||
this.index = index;
|
||||
this.invalid = invalid;
|
||||
}
|
||||
|
||||
private boolean matches(String index) {
|
||||
return isValid() && this.index.name().equals(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@linkplain EsIndex} built by the {@linkplain Catalog}.
|
||||
* @throws MappingException if the index is invalid for
|
||||
* use with sql
|
||||
*/
|
||||
public EsIndex get() {
|
||||
if (invalid != null) {
|
||||
throw new MappingException(invalid);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the index valid for use with sql? Returns {@code false} if the
|
||||
* index wasn't found.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return invalid == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
GetIndexResult other = (GetIndexResult) obj;
|
||||
return Objects.equals(index, other.index)
|
||||
&& Objects.equals(invalid, other.invalid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(index, invalid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return invalid != null ? invalid : index.name();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,19 +3,14 @@
|
|||
* 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.analysis.catalog;
|
||||
package org.elasticsearch.xpack.sql.analysis.index;
|
||||
|
||||
import org.elasticsearch.xpack.sql.type.DataType;
|
||||
import org.elasticsearch.xpack.sql.util.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
public class EsIndex {
|
||||
|
||||
public static final EsIndex NOT_FOUND = new EsIndex(StringUtils.EMPTY, emptyMap());
|
||||
|
||||
private final String name;
|
||||
private final Map<String, DataType> mapping;
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.analysis.index;
|
||||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class GetIndexResult {
|
||||
public static GetIndexResult valid(EsIndex index) {
|
||||
Objects.requireNonNull(index, "index must not be null if it was found");
|
||||
return new GetIndexResult(index, null);
|
||||
}
|
||||
public static GetIndexResult invalid(String invalid) {
|
||||
Objects.requireNonNull(invalid, "invalid must not be null to signal that the index is invalid");
|
||||
return new GetIndexResult(null, invalid);
|
||||
}
|
||||
public static GetIndexResult notFound(String name) {
|
||||
Objects.requireNonNull(name, "name must not be null");
|
||||
return invalid("Index '" + name + "' does not exist");
|
||||
}
|
||||
|
||||
private final EsIndex index;
|
||||
@Nullable
|
||||
private final String invalid;
|
||||
|
||||
private GetIndexResult(EsIndex index, @Nullable String invalid) {
|
||||
this.index = index;
|
||||
this.invalid = invalid;
|
||||
}
|
||||
|
||||
public boolean matches(String index) {
|
||||
return isValid() && this.index.name().equals(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@linkplain EsIndex}
|
||||
* @throws MappingException if the index is invalid for use with sql
|
||||
*/
|
||||
public EsIndex get() {
|
||||
if (invalid != null) {
|
||||
throw new MappingException(invalid);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the index valid for use with sql? Returns {@code false} if the
|
||||
* index wasn't found.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return invalid == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
GetIndexResult other = (GetIndexResult) obj;
|
||||
return Objects.equals(index, other.index)
|
||||
&& Objects.equals(invalid, other.invalid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(index, invalid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return invalid != null ? invalid : index.name();
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
* 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.analysis.catalog;
|
||||
package org.elasticsearch.xpack.sql.analysis.index;
|
||||
|
||||
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
|
@ -13,14 +13,12 @@ import org.elasticsearch.action.support.IndicesOptions;
|
|||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.type.DataType;
|
||||
import org.elasticsearch.xpack.sql.type.Types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -33,9 +31,9 @@ public class IndexResolver {
|
|||
}
|
||||
|
||||
/**
|
||||
* Resolves a single catalog by name.
|
||||
* Resolves a single index by name.
|
||||
*/
|
||||
public void asCatalog(final String index, ActionListener<Catalog> listener) {
|
||||
public void asIndex(final String index, ActionListener<GetIndexResult> listener) {
|
||||
GetIndexRequest getIndexRequest = createGetIndexRequest(index);
|
||||
client.admin().indices().getIndex(getIndexRequest, ActionListener.wrap(getIndexResponse -> {
|
||||
GetIndexResult result;
|
||||
|
@ -57,7 +55,7 @@ public class IndexResolver {
|
|||
} else {
|
||||
result = GetIndexResult.notFound(index);
|
||||
}
|
||||
listener.onResponse(new Catalog(result));
|
||||
listener.onResponse(result);
|
||||
}, listener::onFailure));
|
||||
}
|
||||
|
||||
|
@ -67,8 +65,9 @@ public class IndexResolver {
|
|||
public void asList(String index, ActionListener<List<EsIndex>> listener) {
|
||||
GetIndexRequest getIndexRequest = createGetIndexRequest(index);
|
||||
client.admin().indices().getIndex(getIndexRequest, ActionListener.wrap(getIndexResponse -> {
|
||||
Map<String, GetIndexResult> map = new HashMap<>();
|
||||
for (ObjectObjectCursor<String, ImmutableOpenMap<String, MappingMetaData>> indexMappings : getIndexResponse.getMappings()) {
|
||||
ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings = getIndexResponse.getMappings();
|
||||
List<EsIndex> results = new ArrayList<>(mappings.size());
|
||||
for (ObjectObjectCursor<String, ImmutableOpenMap<String, MappingMetaData>> indexMappings : mappings) {
|
||||
/*
|
||||
* We support wildcard expressions here, and it's only for commands that only perform the get index call.
|
||||
* We can and simply have to use the concrete index name and show that to users.
|
||||
|
@ -76,12 +75,9 @@ public class IndexResolver {
|
|||
* and not the concrete index: there is a well known information leak of the concrete index name in the response.
|
||||
*/
|
||||
String concreteIndex = indexMappings.key;
|
||||
map.put(concreteIndex, buildGetIndexResult(concreteIndex, concreteIndex, indexMappings.value));
|
||||
}
|
||||
List<EsIndex> results = new ArrayList<>(map.size());
|
||||
for (GetIndexResult result : map.values()) {
|
||||
if (result.isValid()) {
|
||||
results.add(result.get());
|
||||
GetIndexResult getIndexResult = buildGetIndexResult(concreteIndex, concreteIndex, indexMappings.value);
|
||||
if (getIndexResult.isValid()) {
|
||||
results.add(getIndexResult.get());
|
||||
}
|
||||
}
|
||||
results.sort(Comparator.comparing(EsIndex::name));
|
|
@ -3,7 +3,7 @@
|
|||
* 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.analysis.catalog;
|
||||
package org.elasticsearch.xpack.sql.analysis.index;
|
||||
|
||||
import org.elasticsearch.xpack.sql.ClientSqlException;
|
||||
|
|
@ -10,7 +10,7 @@ import org.elasticsearch.client.Client;
|
|||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.Analyzer;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.PreAnalyzer;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.execution.search.SourceGenerator;
|
||||
import org.elasticsearch.xpack.sql.expression.function.DefaultFunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry;
|
||||
|
@ -31,15 +31,15 @@ public class PlanExecutor {
|
|||
private final FunctionRegistry functionRegistry;
|
||||
|
||||
private final SqlParser parser;
|
||||
private final IndexResolver catalogResolver;
|
||||
private final IndexResolver indexResolver;
|
||||
private final PreAnalyzer preAnalyzer;
|
||||
private final Analyzer analyzer;
|
||||
private final Optimizer optimizer;
|
||||
private final Planner planner;
|
||||
|
||||
public PlanExecutor(Client client, IndexResolver catalogResolver) {
|
||||
public PlanExecutor(Client client, IndexResolver indexResolver) {
|
||||
this.client = client;
|
||||
this.catalogResolver = catalogResolver;
|
||||
this.indexResolver = indexResolver;
|
||||
this.functionRegistry = new DefaultFunctionRegistry();
|
||||
|
||||
this.parser = new SqlParser();
|
||||
|
@ -50,7 +50,7 @@ public class PlanExecutor {
|
|||
}
|
||||
|
||||
private SqlSession newSession(Configuration cfg) {
|
||||
return new SqlSession(cfg, client, functionRegistry, parser, catalogResolver, preAnalyzer, analyzer, optimizer, planner);
|
||||
return new SqlSession(cfg, client, functionRegistry, parser, indexResolver, preAnalyzer, analyzer, optimizer, planner);
|
||||
}
|
||||
|
||||
public void searchSource(String sql, Configuration settings, ActionListener<SearchSourceBuilder> listener) {
|
||||
|
|
|
@ -8,7 +8,7 @@ package org.elasticsearch.xpack.sql.expression;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.MappingException;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.MappingException;
|
||||
import org.elasticsearch.xpack.sql.tree.Location;
|
||||
import org.elasticsearch.xpack.sql.type.DataType;
|
||||
import org.elasticsearch.xpack.sql.type.TextType;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.sql.plan.logical;
|
||||
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.MappingException;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.MappingException;
|
||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||
import org.elasticsearch.xpack.sql.expression.NestedFieldAttribute;
|
||||
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
package org.elasticsearch.xpack.sql.plan.logical.command;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
||||
import org.elasticsearch.xpack.sql.session.Rows;
|
||||
|
@ -47,10 +46,9 @@ public class ShowColumns extends Command {
|
|||
|
||||
@Override
|
||||
public void execute(SqlSession session, ActionListener<SchemaRowSet> listener) {
|
||||
session.indexResolver().asCatalog(index, ActionListener.wrap(
|
||||
c -> {
|
||||
session.indexResolver().asIndex(index, ActionListener.wrap(
|
||||
indexResult -> {
|
||||
List<List<?>> rows = emptyList();
|
||||
GetIndexResult indexResult = c.getIndex(index);
|
||||
if (indexResult.isValid()) {
|
||||
rows = new ArrayList<>();
|
||||
fillInRows(indexResult.get().mapping(), null, rows);
|
||||
|
|
|
@ -14,8 +14,8 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.rest.RestChannel;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.ColumnInfo;
|
||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.InfoResponse;
|
||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.MetaColumnInfo;
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.elasticsearch.common.settings.SettingsFilter;
|
|||
import org.elasticsearch.plugins.ActionPlugin;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestHandler;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
||||
import org.elasticsearch.xpack.sql.plugin.sql.action.TransportSqlAction;
|
||||
|
|
|
@ -11,8 +11,8 @@ import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
|||
import org.elasticsearch.xpack.sql.analysis.analyzer.Analyzer;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.PreAnalyzer;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.PreAnalyzer.PreAnalysis;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver;
|
||||
import org.elasticsearch.xpack.sql.expression.Expression;
|
||||
import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.optimizer.Optimizer;
|
||||
|
@ -43,18 +43,18 @@ public class SqlSession {
|
|||
public static class SessionContext {
|
||||
|
||||
public final Configuration configuration;
|
||||
public final Catalog catalog;
|
||||
public final GetIndexResult getIndexResult;
|
||||
|
||||
SessionContext(Configuration configuration, Catalog catalog) {
|
||||
SessionContext(Configuration configuration, GetIndexResult getIndexResult) {
|
||||
this.configuration = configuration;
|
||||
this.catalog = catalog;
|
||||
this.getIndexResult = getIndexResult;
|
||||
}
|
||||
}
|
||||
|
||||
// thread-local used for sharing settings across the plan compilation
|
||||
// Currently this is used during:
|
||||
// 1. parsing - to set the TZ in date time functions (if they are used)
|
||||
// 2. analysis - to compute the Catalog and share it across the rules
|
||||
// 2. analysis - to compute the ESIndex and share it across the rules
|
||||
// Might be used in
|
||||
// 3. Optimization - to pass in configs around plan hints/settings
|
||||
// 4. Folding/mapping - same as above
|
||||
|
@ -131,7 +131,8 @@ public class SqlSession {
|
|||
private LogicalPlan doParse(String sql) {
|
||||
try {
|
||||
// NB: it's okay for the catalog to be empty - parsing only cares about the configuration
|
||||
CURRENT_CONTEXT.set(new SessionContext(settings, Catalog.EMPTY));
|
||||
//TODO find a better way to replace the empty catalog
|
||||
CURRENT_CONTEXT.set(new SessionContext(settings, GetIndexResult.invalid("_na_")));
|
||||
return parser.createStatement(sql);
|
||||
} finally {
|
||||
CURRENT_CONTEXT.remove();
|
||||
|
@ -160,9 +161,9 @@ public class SqlSession {
|
|||
return;
|
||||
}
|
||||
|
||||
preAnalyze(parsed, c -> {
|
||||
preAnalyze(parsed, getIndexResult -> {
|
||||
try {
|
||||
CURRENT_CONTEXT.set(new SessionContext(settings, c));
|
||||
CURRENT_CONTEXT.set(new SessionContext(settings, getIndexResult));
|
||||
return analyzer.debugAnalyze(parsed);
|
||||
} finally {
|
||||
CURRENT_CONTEXT.remove();
|
||||
|
@ -170,19 +171,18 @@ public class SqlSession {
|
|||
}, listener);
|
||||
}
|
||||
|
||||
private <T> void preAnalyze(LogicalPlan parsed, Function<Catalog, T> action, ActionListener<T> listener) {
|
||||
private <T> void preAnalyze(LogicalPlan parsed, Function<GetIndexResult, T> action, ActionListener<T> listener) {
|
||||
PreAnalysis preAnalysis = preAnalyzer.preAnalyze(parsed);
|
||||
//TODO why do we have a list if we only support one single element? Seems like it's the wrong data structure?
|
||||
if (preAnalysis.indices.size() > 1) {
|
||||
listener.onFailure(new SqlIllegalArgumentException("Queries with multiple indices are not supported"));
|
||||
return;
|
||||
}
|
||||
//TODO why do we have a list if we only support one single element? Seems like it's the wrong data structure?
|
||||
if (preAnalysis.indices.size() == 1) {
|
||||
indexResolver.asCatalog(preAnalysis.indices.get(0),
|
||||
wrap(c -> listener.onResponse(action.apply(c)), listener::onFailure));
|
||||
} else if (preAnalysis.indices.size() == 1) {
|
||||
indexResolver.asIndex(preAnalysis.indices.get(0),
|
||||
wrap(indexResult -> listener.onResponse(action.apply(indexResult)), listener::onFailure));
|
||||
} else {
|
||||
try {
|
||||
listener.onResponse(action.apply(Catalog.EMPTY));
|
||||
//TODO when can this ever happen? shouldn't it be an exception instead?
|
||||
listener.onResponse(action.apply(GetIndexResult.invalid("_na_")));
|
||||
} catch (Exception ex) {
|
||||
listener.onFailure(ex);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ package org.elasticsearch.xpack.sql.type;
|
|||
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.MappingException;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.MappingException;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
|
|
@ -8,8 +8,8 @@ package org.elasticsearch.xpack.sql.analysis.analyzer;
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||
import org.elasticsearch.xpack.sql.analysis.AnalysisException;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.expression.function.DefaultFunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.parser.SqlParser;
|
||||
|
@ -26,8 +26,8 @@ import java.util.Map;
|
|||
public class VerifierErrorMessagesTests extends ESTestCase {
|
||||
|
||||
private SqlParser parser;
|
||||
private GetIndexResult getIndexResult;
|
||||
private FunctionRegistry functionRegistry;
|
||||
private Catalog catalog;
|
||||
private Analyzer analyzer;
|
||||
|
||||
public VerifierErrorMessagesTests() {
|
||||
|
@ -40,13 +40,13 @@ public class VerifierErrorMessagesTests extends ESTestCase {
|
|||
mapping.put("text", DataTypes.TEXT);
|
||||
mapping.put("keyword", DataTypes.KEYWORD);
|
||||
EsIndex test = new EsIndex("test", mapping);
|
||||
catalog = new Catalog(Catalog.GetIndexResult.valid(test));
|
||||
getIndexResult = GetIndexResult.valid(test);
|
||||
analyzer = new Analyzer(functionRegistry);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setupContext() {
|
||||
TestingSqlSession.setCurrentContext(TestingSqlSession.ctx(catalog));
|
||||
TestingSqlSession.setCurrentContext(TestingSqlSession.ctx(getIndexResult));
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -62,6 +62,8 @@ public class VerifierErrorMessagesTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testMissingIndex() {
|
||||
TestingSqlSession.removeCurrentContext();
|
||||
TestingSqlSession.setCurrentContext(TestingSqlSession.ctx(GetIndexResult.notFound("missing")));
|
||||
assertEquals("1:17: Unknown index [missing]", verify("SELECT foo FROM missing"));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@ package org.elasticsearch.xpack.sql.planner;
|
|||
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.Analyzer;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.InMemoryCatalog;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.expression.function.DefaultFunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.optimizer.Optimizer;
|
||||
|
@ -23,13 +22,11 @@ import org.junit.Before;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
public class VerifierErrorMessagesTests extends ESTestCase {
|
||||
|
||||
private SqlParser parser;
|
||||
private FunctionRegistry functionRegistry;
|
||||
private Catalog catalog;
|
||||
private GetIndexResult getIndexResult;
|
||||
private Analyzer analyzer;
|
||||
private Optimizer optimizer;
|
||||
private Planner planner;
|
||||
|
@ -44,7 +41,7 @@ public class VerifierErrorMessagesTests extends ESTestCase {
|
|||
mapping.put("text", DataTypes.TEXT);
|
||||
mapping.put("keyword", DataTypes.KEYWORD);
|
||||
EsIndex test = new EsIndex("test", mapping);
|
||||
catalog = new InMemoryCatalog(singletonList(test));
|
||||
getIndexResult = GetIndexResult.valid(test);
|
||||
analyzer = new Analyzer(functionRegistry);
|
||||
optimizer = new Optimizer();
|
||||
planner = new Planner();
|
||||
|
@ -53,7 +50,7 @@ public class VerifierErrorMessagesTests extends ESTestCase {
|
|||
|
||||
@Before
|
||||
public void setupContext() {
|
||||
TestingSqlSession.setCurrentContext(TestingSqlSession.ctx(catalog));
|
||||
TestingSqlSession.setCurrentContext(TestingSqlSession.ctx(getIndexResult));
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -7,16 +7,16 @@ package org.elasticsearch.xpack.sql.session;
|
|||
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.GetIndexResult;
|
||||
import org.elasticsearch.xpack.sql.session.SqlSession.SessionContext;
|
||||
|
||||
public class TestingSqlSession {
|
||||
|
||||
public static SessionContext ctx(Catalog catalog) {
|
||||
public static SessionContext ctx(GetIndexResult getIndexResult) {
|
||||
Configuration cfg = new Configuration(ESTestCase.randomDateTimeZone(), ESTestCase.between(1, 100),
|
||||
TimeValue.parseTimeValue(ESTestCase.randomPositiveTimeValue(), "test-random"),
|
||||
TimeValue.parseTimeValue(ESTestCase.randomPositiveTimeValue(), "test-random"), null);
|
||||
return new SessionContext(cfg, catalog);
|
||||
return new SessionContext(cfg, getIndexResult);
|
||||
}
|
||||
|
||||
public static void setCurrentContext(SessionContext ctx) {
|
||||
|
|
Loading…
Reference in New Issue