SQL: Properly handle indices with no/empty mapping (#46775)
When encountering only indices with empty mapping, the IndexResolver throws an exception as it expects to find at least one entry. This commit fixes this case so that an empty mapping is returned. Fix #46757 (cherry picked from commit 5f4f5807acb93b5fab36718c092c328977a396b6)
This commit is contained in:
parent
65dc888623
commit
92e518e789
|
@ -43,6 +43,27 @@ public class DataLoader {
|
|||
loadEmpDatasetIntoEs(client);
|
||||
}
|
||||
|
||||
public static void createEmptyIndex(RestClient client, String index) throws Exception {
|
||||
Request request = new Request("PUT", "/" + index);
|
||||
XContentBuilder createIndex = JsonXContent.contentBuilder().startObject();
|
||||
createIndex.startObject("settings");
|
||||
{
|
||||
createIndex.field("number_of_shards", 1);
|
||||
createIndex.field("number_of_replicas", 1);
|
||||
}
|
||||
createIndex.endObject();
|
||||
createIndex.startObject("mappings");
|
||||
{
|
||||
createIndex.startObject("properties");
|
||||
{
|
||||
}
|
||||
createIndex.endObject();
|
||||
}
|
||||
createIndex.endObject().endObject();
|
||||
request.setJsonEntity(Strings.toString(createIndex));
|
||||
client.performRequest(request);
|
||||
}
|
||||
|
||||
protected static void loadEmpDatasetIntoEs(RestClient client) throws Exception {
|
||||
loadEmpDatasetIntoEs(client, "test_emp", "employees");
|
||||
loadEmpDatasetWithExtraIntoEs(client, "test_emp_copy", "employees");
|
||||
|
|
|
@ -71,6 +71,24 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testGetTablesForEmptyIndices() throws Exception {
|
||||
DataLoader.createEmptyIndex(client(), "test_empty");
|
||||
DataLoader.createEmptyIndex(client(), "test_empty_again");
|
||||
|
||||
try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) {
|
||||
h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_tables_empty.sql'");
|
||||
|
||||
CheckedSupplier<ResultSet, SQLException> all = () -> h2.createStatement()
|
||||
.executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock");
|
||||
assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "%", null));
|
||||
assertResultSets(all.get(), es.getMetaData().getTables("%", "%", "te%", null));
|
||||
assertResultSets(
|
||||
h2.createStatement()
|
||||
.executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock WHERE TABLE_NAME = 'test_empty'"),
|
||||
es.getMetaData().getTables("%", "%", "test_empty", null));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetTypeOfTables() throws Exception {
|
||||
index("test1", body -> body.field("name", "bob"));
|
||||
index("test2", body -> body.field("name", "bob"));
|
||||
|
@ -121,4 +139,13 @@ public class DatabaseMetaDataTestCase extends JdbcIntegrationTestCase {
|
|||
assertResultSets(expected, es.getMetaData().getColumns(null, "%", "%", null));
|
||||
}
|
||||
}
|
||||
|
||||
public void testColumnsForEmptyTable() throws Exception {
|
||||
try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) {
|
||||
h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_metadata_get_columns_empty.sql'");
|
||||
|
||||
ResultSet expected = h2.createStatement().executeQuery("SELECT '" + clusterName() + "' AS TABLE_CAT, * FROM mock");
|
||||
assertResultSets(expected, es.getMetaData().getColumns(null, "%", "%", null));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,4 +37,18 @@ public class ShowTablesTestCase extends JdbcIntegrationTestCase {
|
|||
assertResultSets(expected, es.createStatement().executeQuery("SHOW TABLES"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testEmptyIndex() throws Exception {
|
||||
DataLoader.createEmptyIndex(client(), "test_empty");
|
||||
DataLoader.createEmptyIndex(client(), "test_empty_again");
|
||||
|
||||
try (Connection h2 = LocalH2.anonymousDb(); Connection es = esJdbc()) {
|
||||
h2.createStatement().executeUpdate("RUNSCRIPT FROM 'classpath:/setup_mock_show_tables.sql'");
|
||||
h2.createStatement().executeUpdate("INSERT INTO mock VALUES ('test_empty', 'BASE TABLE', 'INDEX');");
|
||||
h2.createStatement().executeUpdate("INSERT INTO mock VALUES ('test_empty_again', 'BASE TABLE', 'INDEX');");
|
||||
|
||||
ResultSet expected = h2.createStatement().executeQuery("SELECT * FROM mock");
|
||||
assertResultSets(expected, es.createStatement().executeQuery("SHOW TABLES"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public abstract class SpecBaseIntegrationTestCase extends JdbcIntegrationTestCas
|
|||
}
|
||||
|
||||
protected void loadDataset(RestClient client) throws Exception {
|
||||
DataLoader.loadEmpDatasetIntoEs(client);
|
||||
DataLoader.loadDatasetIntoEs(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
CREATE TABLE mock (
|
||||
TABLE_SCHEM VARCHAR,
|
||||
TABLE_NAME VARCHAR,
|
||||
COLUMN_NAME VARCHAR,
|
||||
DATA_TYPE INTEGER,
|
||||
TYPE_NAME VARCHAR,
|
||||
COLUMN_SIZE INTEGER,
|
||||
BUFFER_LENGTH INTEGER,
|
||||
DECIMAL_DIGITS INTEGER,
|
||||
NUM_PREC_RADIX INTEGER,
|
||||
NULLABLE INTEGER,
|
||||
REMARKS VARCHAR,
|
||||
COLUMN_DEF VARCHAR,
|
||||
SQL_DATA_TYPE INTEGER,
|
||||
SQL_DATETIME_SUB INTEGER,
|
||||
CHAR_OCTET_LENGTH INTEGER,
|
||||
ORDINAL_POSITION INTEGER,
|
||||
IS_NULLABLE VARCHAR,
|
||||
SCOPE_CATALOG VARCHAR,
|
||||
SCOPE_SCHEMA VARCHAR,
|
||||
SCOPE_TABLE VARCHAR,
|
||||
SOURCE_DATA_TYPE SMALLINT,
|
||||
IS_AUTOINCREMENT VARCHAR,
|
||||
IS_GENERATEDCOLUMN VARCHAR
|
||||
);
|
|
@ -0,0 +1,15 @@
|
|||
CREATE TABLE mock (
|
||||
TABLE_SCHEM VARCHAR,
|
||||
TABLE_NAME VARCHAR,
|
||||
TABLE_TYPE VARCHAR,
|
||||
REMARKS VARCHAR,
|
||||
TYPE_CAT VARCHAR,
|
||||
TYPE_SCHEM VARCHAR,
|
||||
TYPE_NAME VARCHAR,
|
||||
SELF_REFERENCING_COL_NAME VARCHAR,
|
||||
REF_GENERATION VARCHAR
|
||||
) AS
|
||||
SELECT null, 'test_empty', 'BASE TABLE', '', null, null, null, null, null FROM DUAL
|
||||
UNION ALL
|
||||
SELECT null, 'test_empty_again', 'BASE TABLE', '', null, null, null, null, null FROM DUAL
|
||||
;
|
|
@ -338,12 +338,13 @@ public class IndexResolver {
|
|||
return null;
|
||||
});
|
||||
|
||||
if (indices.size() != 1) {
|
||||
throw new SqlIllegalArgumentException("Incorrect merging of mappings (likely due to a bug) - expect 1 but found [{}]",
|
||||
if (indices.size() > 1) {
|
||||
throw new SqlIllegalArgumentException(
|
||||
"Incorrect merging of mappings (likely due to a bug) - expect at most one but found [{}]",
|
||||
indices.size());
|
||||
}
|
||||
|
||||
return IndexResolution.valid(indices.get(0));
|
||||
return IndexResolution.valid(indices.isEmpty() ? new EsIndex(indexNames[0], emptyMap()) : indices.get(0));
|
||||
}
|
||||
|
||||
private static EsField createField(String fieldName, Map<String, Map<String, FieldCapabilities>> globalCaps,
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
|
||||
|
||||
public class IndexResolverTests extends ESTestCase {
|
||||
|
@ -211,6 +212,12 @@ public class IndexResolverTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testIndexWithNoMapping() {
|
||||
Map<String, Map<String, FieldCapabilities>> versionFC = singletonMap("_version",
|
||||
singletonMap("_index", new FieldCapabilities("_version", "_version", false, false)));
|
||||
assertTrue(IndexResolver.mergedMappings("*", new String[] { "empty" }, versionFC).isValid());
|
||||
}
|
||||
|
||||
public static IndexResolution merge(EsIndex... indices) {
|
||||
return IndexResolver.mergedMappings("*", Stream.of(indices).map(EsIndex::name).toArray(String[]::new), fromMappings(indices));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue