Skip to content

Commit

Permalink
Merge branch 'main' into esql-refactor-date-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
not-napoleon authored Dec 3, 2024
2 parents 8308c52 + f2addbc commit d4b9aa6
Show file tree
Hide file tree
Showing 26 changed files with 1,294 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
Expand All @@ -47,6 +49,8 @@

public abstract class ElasticsearchBuildCompletePlugin implements Plugin<Project> {

private static final Logger log = LoggerFactory.getLogger(ElasticsearchBuildCompletePlugin.class);

@Inject
protected abstract FlowScope getFlowScope();

Expand Down Expand Up @@ -241,8 +245,11 @@ private static void createBuildArchiveTar(List<File> files, File projectDir, Fil
tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
tOut.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR);
for (Path path : files.stream().map(File::toPath).toList()) {
if (!Files.isRegularFile(path)) {
throw new IOException("Support only file!");
if (Files.exists(path) == false) {
log.warn("File disappeared before it could be added to CI archive: " + path);
continue;
} else if (!Files.isRegularFile(path)) {
throw new IOException("Support only file!: " + path);
}

long entrySize = Files.size(path);
Expand Down
5 changes: 5 additions & 0 deletions docs/changelog/116755.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 116755
summary: Smarter field caps with subscribable listener
area: ES|QL
type: enhancement
issues: []
6 changes: 6 additions & 0 deletions docs/changelog/117762.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 117762
summary: "Parse the contents of dynamic objects for [subobjects:false]"
area: Mapping
type: bug
issues:
- 117544
5 changes: 5 additions & 0 deletions docs/changelog/117865.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 117865
summary: Fix BWC for ES|QL cluster request
area: ES|QL
type: bug
issues: []
6 changes: 3 additions & 3 deletions muted-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,11 @@ tests:
issue: https://github.com/elastic/elasticsearch/issues/117815
- class: org.elasticsearch.xpack.ml.integration.DatafeedJobsRestIT
issue: https://github.com/elastic/elasticsearch/issues/111319
- class: org.elasticsearch.xpack.test.rest.XPackRestIT
method: test {p0=esql/60_usage/Basic ESQL usage output (telemetry) non-snapshot version}
issue: https://github.com/elastic/elasticsearch/issues/117862
- class: org.elasticsearch.validation.DotPrefixClientYamlTestSuiteIT
issue: https://github.com/elastic/elasticsearch/issues/117893
- class: org.elasticsearch.xpack.core.ml.search.SparseVectorQueryBuilderTests
method: testToQuery
issue: https://github.com/elastic/elasticsearch/issues/117904

# Examples:
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1177,3 +1177,121 @@ fetch geo_point:
- is_false: hits.hits.0.fields.message
- match: { hits.hits.0._source.message.foo: 10 }
- match: { hits.hits.0._source.message.foo\.bar: 20 }

---
root with subobjects false and dynamic false:
- requires:
cluster_features: mapper.fix_parsing_subobjects_false_dynamic_false
reason: bug fix

- do:
indices.create:
index: test
body:
mappings:
subobjects: false
dynamic: false
properties:
id:
type: integer
my.keyword.field:
type: keyword

- do:
bulk:
index: test
refresh: true
body:
- '{ "index": { } }'
- '{ "id": 1, "my": { "keyword.field": "abc" } }'
- match: { errors: false }

# indexing a dynamically-mapped field still fails (silently)
- do:
bulk:
index: test
refresh: true
body:
- '{ "index": { } }'
- '{ "id": 2, "my": { "random.field": "abc" } }'
- match: { errors: false }

- do:
search:
index: test
body:
sort: id
fields: [ "*" ]

- match: { hits.hits.0.fields: { my.keyword.field: [ abc ], id: [ 1 ] } }
- match: { hits.hits.1.fields: { id: [ 2 ] } }

- do:
search:
index: test
body:
query:
match:
my.keyword.field: abc

- match: { hits.total.value: 1 }

---
object with subobjects false and dynamic false:
- requires:
cluster_features: mapper.fix_parsing_subobjects_false_dynamic_false
reason: bug fix

- do:
indices.create:
index: test
body:
mappings:
properties:
my:
subobjects: false
dynamic: false
properties:
id:
type: integer
nested.keyword.field:
type: keyword

- do:
bulk:
index: test
refresh: true
body:
- '{ "index": { } }'
- '{ "id": 1, "my": { "nested": { "keyword.field": "abc" } } }'
- match: { errors: false }

# indexing a dynamically-mapped field still fails (silently)
- do:
bulk:
index: test
refresh: true
body:
- '{ "index": { } }'
- '{ "id": 2, "my": { "nested": { "random.field": "abc" } } }'
- match: { errors: false }

- do:
search:
index: test
body:
sort: id
fields: [ "*" ]

- match: { hits.hits.0.fields: { my.nested.keyword.field: [ abc ], id: [ 1 ] } }
- match: { hits.hits.1.fields: { id: [ 2 ] } }

- do:
search:
index: test
body:
query:
match:
my.nested.keyword.field: abc

- match: { hits.total.value: 1 }
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.features.NodeFeature;
import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.index.fielddata.FieldDataContext;
Expand Down Expand Up @@ -53,6 +54,9 @@
public final class DocumentParser {

public static final IndexVersion DYNAMICALLY_MAP_DENSE_VECTORS_INDEX_VERSION = IndexVersions.FIRST_DETACHED_INDEX_VERSION;
static final NodeFeature FIX_PARSING_SUBOBJECTS_FALSE_DYNAMIC_FALSE = new NodeFeature(
"mapper.fix_parsing_subobjects_false_dynamic_false"
);

private final XContentParserConfiguration parserConfiguration;
private final MappingParserContext mappingParserContext;
Expand Down Expand Up @@ -531,7 +535,8 @@ private static void doParseObject(DocumentParserContext context, String currentF

private static void parseObjectDynamic(DocumentParserContext context, String currentFieldName) throws IOException {
ensureNotStrict(context, currentFieldName);
if (context.dynamic() == ObjectMapper.Dynamic.FALSE) {
// For [subobjects:false], intermediate objects get flattened so we can't skip parsing children.
if (context.dynamic() == ObjectMapper.Dynamic.FALSE && context.parent().subobjects() != ObjectMapper.Subobjects.DISABLED) {
failIfMatchesRoutingPath(context, currentFieldName);
if (context.canAddIgnoredField()) {
context.addIgnoredField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public Set<NodeFeature> getTestFeatures() {
IgnoredSourceFieldMapper.IGNORED_SOURCE_AS_TOP_LEVEL_METADATA_ARRAY_FIELD,
IgnoredSourceFieldMapper.ALWAYS_STORE_OBJECT_ARRAYS_IN_NESTED_OBJECTS,
MapperService.LOGSDB_DEFAULT_IGNORE_DYNAMIC_BEYOND_LIMIT,
DocumentParser.FIX_PARSING_SUBOBJECTS_FALSE_DYNAMIC_FALSE,
CONSTANT_KEYWORD_SYNTHETIC_SOURCE_WRITE_FIX,
META_FETCH_FIELDS_ERROR_CODE_CHANGED
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,38 @@ public void testSubobjectsFalseWithInnerDottedObject() throws Exception {
assertNotNull(doc.rootDoc().getField("metrics.service.test.with.dots.max"));
}

public void testSubobjectsFalseWithInnerDottedObjectDynamicFalse() throws Exception {
DocumentMapper mapper = createDocumentMapper(mapping(b -> {
b.startObject("metrics").field("type", "object").field("subobjects", false).field("dynamic", randomFrom("false", "runtime"));
b.startObject("properties").startObject("service.test.with.dots").field("type", "keyword").endObject().endObject();
b.endObject();
}));

ParsedDocument doc = mapper.parse(source("""
{ "metrics": { "service": { "test.with.dots": "foo" } } }"""));
assertNotNull(doc.rootDoc().getField("metrics.service.test.with.dots"));

doc = mapper.parse(source("""
{ "metrics": { "service.test": { "with.dots": "foo" } } }"""));
assertNotNull(doc.rootDoc().getField("metrics.service.test.with.dots"));

doc = mapper.parse(source("""
{ "metrics": { "service": { "test": { "with.dots": "foo" } } } }"""));
assertNotNull(doc.rootDoc().getField("metrics.service.test.with.dots"));

doc = mapper.parse(source("""
{ "metrics": { "service": { "test.other.dots": "foo" } } }"""));
assertNull(doc.rootDoc().getField("metrics.service.test.other.dots"));

doc = mapper.parse(source("""
{ "metrics": { "service.test": { "other.dots": "foo" } } }"""));
assertNull(doc.rootDoc().getField("metrics.service.test.other.dots"));

doc = mapper.parse(source("""
{ "metrics": { "service": { "test": { "other.dots": "foo" } } } }"""));
assertNull(doc.rootDoc().getField("metrics.service.test.other.dots"));
}

public void testSubobjectsFalseRoot() throws Exception {
DocumentMapper mapper = createDocumentMapper(mappingNoSubobjects(xContentBuilder -> {}));
ParsedDocument doc = mapper.parse(source("""
Expand All @@ -2074,6 +2106,37 @@ public void testSubobjectsFalseRoot() throws Exception {
assertNotNull(doc.rootDoc().getField("metrics.service.test.with.dots"));
}

public void testSubobjectsFalseRootWithInnerDottedObjectDynamicFalse() throws Exception {
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.field("subobjects", false).field("dynamic", randomFrom("false", "runtime"));
b.startObject("properties").startObject("service.test.with.dots").field("type", "keyword").endObject().endObject();
}));

ParsedDocument doc = mapper.parse(source("""
{ "service": { "test.with.dots": "foo" } }"""));
assertNotNull(doc.rootDoc().getField("service.test.with.dots"));

doc = mapper.parse(source("""
{ "service.test": { "with.dots": "foo" } }"""));
assertNotNull(doc.rootDoc().getField("service.test.with.dots"));

doc = mapper.parse(source("""
{ "service": { "test": { "with.dots": "foo" } } }"""));
assertNotNull(doc.rootDoc().getField("service.test.with.dots"));

doc = mapper.parse(source("""
{ "service": { "test.other.dots": "foo" } }"""));
assertNull(doc.rootDoc().getField("service.test.other.dots"));

doc = mapper.parse(source("""
{ "service.test": { "other.dots": "foo" } }"""));
assertNull(doc.rootDoc().getField("service.test.other.dots"));

doc = mapper.parse(source("""
{ "service": { "test": { "other.dots": "foo" } } }"""));
assertNull(doc.rootDoc().getField("service.test.other.dots"));
}

public void testSubobjectsFalseStructuredPath() throws Exception {
DocumentMapper mapper = createDocumentMapper(
mapping(b -> b.startObject("metrics.service").field("type", "object").field("subobjects", false).endObject())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ public <T> T getAnyMasterNodeInstance(Class<T> clazz) {
return getInstance(clazz, MASTER_NODE_PREDICATE);
}

private synchronized <T> T getInstance(Class<T> clazz, Predicate<NodeAndClient> predicate) {
private <T> T getInstance(Class<T> clazz, Predicate<NodeAndClient> predicate) {
NodeAndClient randomNodeAndClient = getRandomNodeAndClient(predicate);
if (randomNodeAndClient == null) {
throw new AssertionError("no node matches [" + predicate + "]");
Expand Down
17 changes: 15 additions & 2 deletions x-pack/plugin/esql/qa/server/multi-clusters/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,22 @@ def supportedVersion = bwcVersion -> {
}

buildParams.bwcVersions.withWireCompatible(supportedVersion) { bwcVersion, baseName ->
tasks.register(bwcTaskName(bwcVersion), StandaloneRestIntegTestTask) {
tasks.register("${baseName}#newToOld", StandaloneRestIntegTestTask) {
usesBwcDistribution(bwcVersion)
systemProperty("tests.version.remote_cluster", bwcVersion)
maxParallelForks = 1
}

tasks.register("${baseName}#oldToNew", StandaloneRestIntegTestTask) {
usesBwcDistribution(bwcVersion)
systemProperty("tests.old_cluster_version", bwcVersion)
systemProperty("tests.version.local_cluster", bwcVersion)
maxParallelForks = 1
}

// TODO: avoid running tests twice with the current version
tasks.register(bwcTaskName(bwcVersion), StandaloneRestIntegTestTask) {
dependsOn tasks.named("${baseName}#oldToNew")
dependsOn tasks.named("${baseName}#newToOld")
maxParallelForks = 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static ElasticsearchCluster remoteCluster() {
return ElasticsearchCluster.local()
.name(REMOTE_CLUSTER_NAME)
.distribution(DistributionType.DEFAULT)
.version(Version.fromString(System.getProperty("tests.old_cluster_version")))
.version(distributionVersion("tests.version.remote_cluster"))
.nodes(2)
.setting("node.roles", "[data,ingest,master]")
.setting("xpack.security.enabled", "false")
Expand All @@ -34,7 +34,7 @@ public static ElasticsearchCluster localCluster(ElasticsearchCluster remoteClust
return ElasticsearchCluster.local()
.name(LOCAL_CLUSTER_NAME)
.distribution(DistributionType.DEFAULT)
.version(Version.CURRENT)
.version(distributionVersion("tests.version.local_cluster"))
.nodes(2)
.setting("xpack.security.enabled", "false")
.setting("xpack.license.self_generated.type", "trial")
Expand All @@ -46,7 +46,18 @@ public static ElasticsearchCluster localCluster(ElasticsearchCluster remoteClust
.build();
}

public static org.elasticsearch.Version oldVersion() {
return org.elasticsearch.Version.fromString(System.getProperty("tests.old_cluster_version"));
public static org.elasticsearch.Version localClusterVersion() {
String prop = System.getProperty("tests.version.local_cluster");
return prop != null ? org.elasticsearch.Version.fromString(prop) : org.elasticsearch.Version.CURRENT;
}

public static org.elasticsearch.Version remoteClusterVersion() {
String prop = System.getProperty("tests.version.remote_cluster");
return prop != null ? org.elasticsearch.Version.fromString(prop) : org.elasticsearch.Version.CURRENT;
}

private static Version distributionVersion(String key) {
final String val = System.getProperty(key);
return val != null ? Version.fromString(val) : Version.CURRENT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;

import org.apache.http.HttpHost;
import org.elasticsearch.Version;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.core.IOUtils;
import org.elasticsearch.test.TestClustersThreadFilter;
import org.elasticsearch.test.cluster.ElasticsearchCluster;
import org.elasticsearch.xpack.esql.qa.rest.EsqlRestValidationTestCase;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
Expand Down Expand Up @@ -78,4 +80,9 @@ private RestClient remoteClusterClient() throws IOException {
}
return remoteClient;
}

@Before
public void skipTestOnOldVersions() {
assumeTrue("skip on old versions", Clusters.localClusterVersion().equals(Version.V_8_16_0));
}
}
Loading

0 comments on commit d4b9aa6

Please sign in to comment.