Skip to content

Commit 4e0718f

Browse files
Merge branch 'main' into move-sql-content-from-explore-anayze-to-reference
2 parents 0fb6936 + a399e29 commit 4e0718f

File tree

55 files changed

+1624
-511
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1624
-511
lines changed

docs/changelog/133405.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 133405
2+
summary: Fix wrong pruning of plans with no output columns
3+
area: ES|QL
4+
type: bug
5+
issues: []
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
navigation_title: "KQL"
3+
mapped_pages:
4+
- https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-kql-query.html
5+
applies_to:
6+
stack: preview 9.0, ga 9.1
7+
serverless: all
8+
---
9+
10+
# KQL query [query-dsl-kql-query]
11+
12+
Returns documents matching a provided KQL expression. The value of the `query` parameter is parsed using the
13+
[Kibana Query Language (KQL)](/reference/query-languages/kql.md) and rewritten
14+
into standard Query DSL.
15+
16+
Use this query when you want to accept KQL input (for example from a Kibana search bar) directly in Elasticsearch.
17+
18+
## Example request [kql-query-example]
19+
20+
The following example returns documents where `service.name` is `"checkout-service"` and `http.response.status_code` is `200`.
21+
22+
```console
23+
GET /_search
24+
{
25+
"query": {
26+
"kql": {
27+
"query": "service.name: \"checkout-service\" AND http.response.status_code: 200"
28+
}
29+
}
30+
}
31+
```
32+
33+
## Top-level parameters for `kql` [kql-top-level-params]
34+
35+
`query`
36+
: (Required, string) The KQL expression to parse. See the
37+
[KQL language reference](/reference/query-languages/kql.md) for supported
38+
syntax.
39+
40+
`case_insensitive`
41+
: (Optional, boolean) If `true`, performs case-insensitive matching for field names and keyword / text terms.
42+
Defaults to `false`.
43+
44+
`default_field`
45+
: (Optional, string) Default field (or field pattern with wildcards) to target when a bare term in the query
46+
string does not specify a field. Supports wildcards (`*`).
47+
48+
Defaults to the [`index.query.default_field`](/reference/elasticsearch/index-settings/index-modules.md#index-query-default-field)
49+
index setting (default value is `*`). The value `*` expands to all fields that are eligible for term queries
50+
(metadata fields excluded). Searching *all* eligible fields can be expensive on mappings with many fields and
51+
is subject to the `indices.query.bool.max_clause_count` limit.
52+
53+
Like other queries, this implicit expansion does not traverse [nested](/reference/elasticsearch/mapping-reference/nested.md)
54+
documents.
55+
56+
`time_zone`
57+
: (Optional, string) [UTC offset](https://en.wikipedia.org/wiki/List_of_UTC_time_offsets) or
58+
[IANA time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used to interpret date literals
59+
(for example `@timestamp > now-2d`). Does not change the value of `now` (which is always system UTC) but affects
60+
rounding and the interpretation of explicit date strings.
61+
62+
`boost`
63+
: (Optional, float) Standard query *boost*. Defaults to `1.0`.
64+
65+
`_name`
66+
: (Optional, string) A name to identify this query in the response's `matched_queries`.
67+
68+
## Syntax reference
69+
70+
The `kql` query accepts a single KQL expression string in the `query` parameter. All language elements (field matching,
71+
wildcards, boolean logic, ranges, nested scoping) are defined in the
72+
[KQL language reference](/reference/query-languages/kql.md). This page does not
73+
duplicate that syntax.
74+
75+
## Additional examples [kql-examples]
76+
77+
### Case-insensitive matching (log level)
78+
79+
```console
80+
GET /_search
81+
{
82+
"query": {
83+
"kql": {
84+
"query": "log.level: ErRoR",
85+
"case_insensitive": true
86+
}
87+
}
88+
}
89+
```
90+
91+
### Using a default field pattern
92+
93+
Search any field under the `logs` object for the term `timeout`:
94+
95+
```console
96+
GET /_search
97+
{
98+
"query": {
99+
"kql": {
100+
"query": "timeout",
101+
"default_field": "logs.*"
102+
}
103+
}
104+
}
105+
```
106+
107+
### Date range with time zone
108+
109+
```console
110+
GET /_search
111+
{
112+
"query": {
113+
"kql": {
114+
"query": "@timestamp >= ""2025-10-01"" AND @timestamp < ""2025-10-02""",
115+
"time_zone": "Europe/Paris"
116+
}
117+
}
118+
}
119+
```
120+
121+
### Nested field query
122+
```console
123+
GET /_search
124+
{
125+
"query": {
126+
"kql": {
127+
"query": "events.stack:{ file: \"app.js\" AND line: 42 }"
128+
}
129+
}
130+
}
131+
```
132+
133+
## When to use `kql` vs `query_string`
134+
135+
Use `kql` for user-facing search boxes where you want a concise, filter-oriented syntax and to avoid Lucene’s
136+
advanced operators (fuzzy, regexp, proximity, inline boosting). Use [`query_string`](./query-dsl-query-string-query.md)
137+
or [`simple_query_string`](./query-dsl-simple-query-string-query.md) when those advanced features are required.
138+
139+
## Notes and limitations
140+
141+
* The parsed KQL expression is rewritten into standard Query DSL and participates in scoring unless wrapped in a
142+
filter context (for example inside a `bool.filter`). Adjust relevance with `boost` if needed.
143+
* Large wildcard expansions (in field names or terms) can hit the `indices.query.bool.max_clause_count` safeguard.
144+
* Nested documents require the KQL nested syntax (`path:{ ... }`); terms are not correlated across separate nested
145+
objects automatically.
146+
* Unsupported syntax (such as fuzzy operators) results in a parse error.
147+
148+
## See also [kql-see-also]
149+
150+
* [KQL language reference](/reference/query-languages/kql.md)
151+
* [Default field setting](/reference/elasticsearch/index-settings/index-modules.md#index-query-default-field)

docs/reference/query-languages/toc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ toc:
2222
- file: query-dsl/query-dsl-multi-match-query.md
2323
- file: query-dsl/query-dsl-query-string-query.md
2424
- file: query-dsl/query-dsl-simple-query-string-query.md
25+
- file: query-dsl/query-dsl-kql-query.md
2526
- file: query-dsl/geo-queries.md
2627
children:
2728
- file: query-dsl/query-dsl-geo-bounding-box-query.md

libs/entitlement/tools/jdk-api-extractor/src/main/java/org/elasticsearch/entitlement/tools/jdkapi/JdkApiExtractor.java

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ public class JdkApiExtractor {
4646
// exclude both final and non-final variants of these
4747
private static final Set<AccessibleMethod> EXCLUDES = Set.of(
4848
new AccessibleMethod("toString", "()Ljava/lang/String;", true, false, false),
49+
new AccessibleMethod("toString", "()Ljava/lang/String;", true, true, false),
4950
new AccessibleMethod("hashCode", "()I", true, false, false),
51+
new AccessibleMethod("hashCode", "()I", true, true, false),
5052
new AccessibleMethod("equals", "(Ljava/lang/Object;)Z", true, false, false),
51-
new AccessibleMethod("close", "()V", true, false, false),
52-
new AccessibleMethod("toString", "()Ljava/lang/String;", true, true, false),
53-
new AccessibleMethod("hashCode", "()I", true, false, true),
5453
new AccessibleMethod("equals", "(Ljava/lang/Object;)Z", true, true, false),
55-
new AccessibleMethod("close", "()V", true, false, true)
54+
new AccessibleMethod("close", "()V", true, false, false),
55+
new AccessibleMethod("close", "()V", true, true, false)
5656
);
5757

5858
private static String DEPRECATIONS_ONLY = "--deprecations-only";
@@ -66,7 +66,7 @@ public static void main(String[] args) throws IOException {
6666

6767
final Map<String, String> moduleNameByClass = new HashMap<>();
6868
final Map<ModuleClass, Set<AccessibleMethod>> accessibleImplementationsByClass = new TreeMap<>(ModuleClass.COMPARATOR);
69-
final Map<ModuleClass, Set<AccessibleMethod>> accessibleForOverridesByClass = new TreeMap<>(ModuleClass.COMPARATOR);
69+
final Map<ModuleClass, Set<AccessibleMethod>> inheritableAccessByClass = new TreeMap<>(ModuleClass.COMPARATOR);
7070
final Map<ModuleClass, Set<AccessibleMethod>> deprecationsByClass = new TreeMap<>(ModuleClass.COMPARATOR);
7171

7272
final Map<String, Set<String>> exportsByModule = Utils.findModuleExports();
@@ -84,7 +84,7 @@ public static void main(String[] args) throws IOException {
8484
moduleNameByClass,
8585
exportsByModule,
8686
accessibleImplementationsByClass,
87-
accessibleForOverridesByClass,
87+
inheritableAccessByClass,
8888
deprecationsByClass
8989
);
9090
Predicate<String> modulePredicate = Utils.DEFAULT_MODULE_PREDICATE.or(
@@ -206,11 +206,11 @@ static class AccessibleClassVisitor extends ClassVisitor {
206206
private final Map<String, String> moduleNameByClass;
207207
private final Map<String, Set<String>> exportsByModule;
208208
private final Map<ModuleClass, Set<AccessibleMethod>> accessibleImplementationsByClass;
209-
private final Map<ModuleClass, Set<AccessibleMethod>> accessibleForOverridesByClass;
209+
private final Map<ModuleClass, Set<AccessibleMethod>> inheritableAccessByClass;
210210
private final Map<ModuleClass, Set<AccessibleMethod>> deprecationsByClass;
211211

212212
private Set<AccessibleMethod> accessibleImplementations;
213-
private Set<AccessibleMethod> accessibleForOverrides;
213+
private Set<AccessibleMethod> inheritableAccess;
214214
private Set<AccessibleMethod> deprecations;
215215

216216
private ModuleClass moduleClass;
@@ -223,14 +223,14 @@ static class AccessibleClassVisitor extends ClassVisitor {
223223
Map<String, String> moduleNameByClass,
224224
Map<String, Set<String>> exportsByModule,
225225
Map<ModuleClass, Set<AccessibleMethod>> accessibleImplementationsByClass,
226-
Map<ModuleClass, Set<AccessibleMethod>> accessibleForOverridesByClass,
226+
Map<ModuleClass, Set<AccessibleMethod>> inheritableAccessByClass,
227227
Map<ModuleClass, Set<AccessibleMethod>> deprecationsByClass
228228
) {
229229
super(ASM9);
230230
this.moduleNameByClass = moduleNameByClass;
231231
this.exportsByModule = exportsByModule;
232232
this.accessibleImplementationsByClass = accessibleImplementationsByClass;
233-
this.accessibleForOverridesByClass = accessibleForOverridesByClass;
233+
this.inheritableAccessByClass = inheritableAccessByClass;
234234
this.deprecationsByClass = deprecationsByClass;
235235
}
236236

@@ -240,21 +240,21 @@ private static Set<AccessibleMethod> newSortedSet() {
240240

241241
@Override
242242
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
243-
final Set<AccessibleMethod> currentAccessibleForOverrides = newSortedSet();
243+
final Set<AccessibleMethod> currentInheritedAccess = newSortedSet();
244244
if (superName != null) {
245245
var superModuleClass = getModuleClass(superName);
246246
if (accessibleImplementationsByClass.containsKey(superModuleClass) == false) {
247247
visitSuperClass(superName);
248248
}
249-
currentAccessibleForOverrides.addAll(accessibleForOverridesByClass.getOrDefault(superModuleClass, emptySet()));
249+
currentInheritedAccess.addAll(inheritableAccessByClass.getOrDefault(superModuleClass, emptySet()));
250250
}
251251
if (interfaces != null && interfaces.length > 0) {
252252
for (var interfaceName : interfaces) {
253253
var interfaceModuleClass = getModuleClass(interfaceName);
254254
if (accessibleImplementationsByClass.containsKey(interfaceModuleClass) == false) {
255255
visitInterface(interfaceName);
256256
}
257-
currentAccessibleForOverrides.addAll(accessibleForOverridesByClass.getOrDefault(interfaceModuleClass, emptySet()));
257+
currentInheritedAccess.addAll(inheritableAccessByClass.getOrDefault(interfaceModuleClass, emptySet()));
258258
}
259259
}
260260
// only initialize local state AFTER visiting all dependencies above!
@@ -264,7 +264,7 @@ public void visit(int version, int access, String name, String signature, String
264264
this.isPublicClass = (access & ACC_PUBLIC) != 0;
265265
this.isFinalClass = (access & ACC_FINAL) != 0;
266266
this.isDeprecatedClass = (access & ACC_DEPRECATED) != 0;
267-
this.accessibleForOverrides = currentAccessibleForOverrides;
267+
this.inheritableAccess = currentInheritedAccess;
268268
this.accessibleImplementations = newSortedSet();
269269
this.deprecations = newSortedSet();
270270
}
@@ -289,7 +289,7 @@ private Set<String> getModuleExports(String module) {
289289
public void visitEnd() {
290290
super.visitEnd();
291291
if (accessibleImplementationsByClass.put(moduleClass, unmodifiableSet(accessibleImplementations)) != null
292-
|| accessibleForOverridesByClass.put(moduleClass, unmodifiableSet(accessibleForOverrides)) != null
292+
|| inheritableAccessByClass.put(moduleClass, unmodifiableSet(inheritableAccess)) != null
293293
|| deprecationsByClass.put(moduleClass, unmodifiableSet(deprecations)) != null) {
294294
throw new IllegalStateException("Class " + moduleClass.clazz + " was already visited!");
295295
}
@@ -337,18 +337,21 @@ public final MethodVisitor visitMethod(int access, String name, String descripto
337337

338338
var method = new AccessibleMethod(name, descriptor, isPublic, isFinal, isStatic);
339339
if (isPublicClass && isExported && EXCLUDES.contains(method) == false) {
340-
// class is public and exported, for final classes skip non-public methods
340+
// class is public and exported, to be accessible outside the JDK the method must be either:
341+
// - public or
342+
// - protected if not a final class
341343
if (isPublic || isFinalClass == false) {
342344
accessibleImplementations.add(method);
343-
// if not static, the method is accessible for overrides
344-
if (isStatic == false) {
345-
accessibleForOverrides.add(method);
345+
// if public and not static, the method can be accessible on non-public and non-exported subclasses,
346+
// but skip constructors
347+
if (isPublic && isStatic == false && name.equals("<init>") == false) {
348+
inheritableAccess.add(method);
346349
}
347350
if (isDeprecatedClass || isDeprecated) {
348351
deprecations.add(method);
349352
}
350353
}
351-
} else if (accessibleForOverrides.contains(method)) {
354+
} else if (inheritableAccess.contains(method)) {
352355
accessibleImplementations.add(method);
353356
if (isDeprecatedClass || isDeprecated) {
354357
deprecations.add(method);

server/src/main/java/org/elasticsearch/cluster/NotMasterException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public NotMasterException(StreamInput in) throws IOException {
3434
super(in);
3535
}
3636

37+
public NotMasterException(String msg, Throwable cause, Object... args) {
38+
super(msg, cause, args);
39+
}
40+
3741
@Override
3842
public Throwable fillInStackTrace() {
3943
return this;

server/src/main/java/org/elasticsearch/cluster/service/MasterService.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ public String toString() {
12831283
if (lifecycle.started()) {
12841284
nextBatch.run(batchCompletionListener);
12851285
} else {
1286-
nextBatch.onRejection(new FailedToCommitClusterStateException("node closed", getRejectionException()));
1286+
nextBatch.onRejection(new NotMasterException("node closed", getRejectionException()));
12871287
batchCompletionListener.onResponse(null);
12881288
}
12891289
});
@@ -1309,7 +1309,7 @@ private void onCompletion() {
13091309
@Override
13101310
public void onRejection(Exception e) {
13111311
assert e instanceof EsRejectedExecutionException esre && esre.isExecutorShutdown() : e;
1312-
drainQueueOnRejection(new FailedToCommitClusterStateException("node closed", e));
1312+
drainQueueOnRejection(new NotMasterException("node closed", e));
13131313
}
13141314

13151315
@Override
@@ -1336,7 +1336,7 @@ private Batch takeNextBatch() {
13361336
private void forkQueueProcessor() {
13371337
// single-threaded: started when totalQueueSize transitions from 0 to 1 and keeps calling itself until the queue is drained.
13381338
if (lifecycle.started() == false) {
1339-
drainQueueOnRejection(new FailedToCommitClusterStateException("node closed", getRejectionException()));
1339+
drainQueueOnRejection(new NotMasterException("node closed", getRejectionException()));
13401340
return;
13411341
}
13421342

@@ -1353,7 +1353,7 @@ private EsRejectedExecutionException getRejectionException() {
13531353
return new EsRejectedExecutionException("master service is in state [" + lifecycleState() + "]", true);
13541354
}
13551355

1356-
private void drainQueueOnRejection(FailedToCommitClusterStateException e) {
1356+
private void drainQueueOnRejection(NotMasterException e) {
13571357
assert totalQueueSize.get() > 0;
13581358
do {
13591359
assert currentlyExecutingBatch == null;
@@ -1407,12 +1407,11 @@ private interface Batch {
14071407
/**
14081408
* Called when the batch is rejected due to the master service shutting down.
14091409
*
1410-
* @param e is a {@link FailedToCommitClusterStateException} to cause things like {@link TransportMasterNodeAction} to retry after
1410+
* @param e is a {@link NotMasterException} to cause things like {@link TransportMasterNodeAction} to retry after
14111411
* submitting a task to a master which shut down. {@code e.getCause()} is the rejection exception, which should be a
14121412
* {@link EsRejectedExecutionException} with {@link EsRejectedExecutionException#isExecutorShutdown()} true.
14131413
*/
1414-
// Should really be a NodeClosedException instead, but this exception type doesn't trigger retries today.
1415-
void onRejection(FailedToCommitClusterStateException e);
1414+
void onRejection(NotMasterException e);
14161415

14171416
/**
14181417
* @return number of tasks in this batch if the batch is pending, or {@code 0} if the batch is not pending.
@@ -1634,7 +1633,7 @@ T acquireForExecution() {
16341633
return task;
16351634
}
16361635

1637-
void onRejection(FailedToCommitClusterStateException e) {
1636+
void onRejection(NotMasterException e) {
16381637
final var task = acquireForExecution();
16391638
if (task != null) {
16401639
try (var ignored = storedContextSupplier.get()) {
@@ -1654,7 +1653,7 @@ boolean isPending() {
16541653

16551654
private class Processor implements Batch {
16561655
@Override
1657-
public void onRejection(FailedToCommitClusterStateException e) {
1656+
public void onRejection(NotMasterException e) {
16581657
final var items = queueSize.getAndSet(0);
16591658
for (int i = 0; i < items; i++) {
16601659
final var entry = queue.poll();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9186000
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
initial_9.2.0,9185000
1+
esql_plan_with_no_columns,9186000

0 commit comments

Comments
 (0)