Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
4aa7ae0
Introduce PromQL command
costin Sep 16, 2025
ebfa9c3
Support cross series aggregations without grouping
felixbarny Oct 14, 2025
2475e8b
Spotless apply
felixbarny Oct 15, 2025
aaec649
Add PromQL parameter support with parenthesized query syntax
costin Oct 17, 2025
987d958
Remove unnecessary files
costin Oct 23, 2025
8cce028
Merge remote-tracking branch 'remotes/upstream/main' into esql/promql
costin Oct 23, 2025
a8b2e19
Regen grammar
costin Oct 23, 2025
c602a60
Pick up latest changes in main
costin Oct 27, 2025
0c05606
Rename stop parameter to end
felixbarny Oct 28, 2025
daf1560
Rename LogicalPlanBuilder to PromqlLogicalPlanBuilder
felixbarny Oct 28, 2025
d44915b
More renaming from stop to end
felixbarny Oct 28, 2025
bd93fac
Handle grammar issues
costin Oct 28, 2025
4cf5cc2
Merge remote-tracking branch 'remotes/upstream/main' into esql/promql
costin Oct 28, 2025
f9deb4f
Pick up TimestampAware interface from main
costin Oct 29, 2025
cd4466e
Make Vector ops LogicalPlans
costin Oct 29, 2025
1875ece
Adjust source with offsets (#137260)
felixbarny Oct 29, 2025
943757a
Add Promql prefix to classes in esql.parser.promql
felixbarny Oct 29, 2025
d221e6a
Fix PromqlParserUtils#adjustColumn
felixbarny Oct 29, 2025
2c74e70
Verify PromqlCommand and throw on currently unsupported queries (#137…
felixbarny Oct 29, 2025
2775c2d
Fix label filter for proper prefix/suffix regex (#136588)
felixbarny Oct 29, 2025
377b47d
Simplify verification rules
felixbarny Oct 29, 2025
6963c07
Consolidate grammar/ast tests
costin Oct 29, 2025
d68175c
Fix subquery parsing
costin Oct 30, 2025
d0bfd4c
Refactor time arithmetic
costin Oct 31, 2025
5aca3d7
Replace TimeValue with Duration
costin Oct 31, 2025
2351e39
Add comparison folding for literals
costin Oct 31, 2025
8272dcd
Parse start/end/time/step parameters (#137472)
felixbarny Nov 3, 2025
6cb2ea3
Support for quoted strings and ?params (#137502)
felixbarny Nov 3, 2025
38af83b
Merge remote-tracking branch 'origin/main' into esql/promql
felixbarny Nov 5, 2025
1b3cc8d
Improve parser
costin Nov 6, 2025
c35ff51
Improve parsing of label matchers
costin Nov 6, 2025
bea6edf
Improve parsing of Duration to pass more tests
costin Nov 6, 2025
364f623
Update tests
costin Nov 6, 2025
0b88a04
Avoid forbidden apis
felixbarny Nov 7, 2025
5d53dc2
Apply spotless suggestions
felixbarny Nov 7, 2025
4fab0c4
Avoid forbidden apis in tests
felixbarny Nov 7, 2025
8359992
PromQL telemetry
felixbarny Nov 7, 2025
a2570d3
Merge remote-tracking branch 'origin/main' into esql/promql
felixbarny Nov 10, 2025
e7798b1
Only skip verification for PromQL
felixbarny Nov 10, 2025
dab226c
Add support for cross series aggregations on instant vector (#137513)
felixbarny Nov 11, 2025
cb1810d
Normalize functionName on lookup rather than when initializing the fu…
felixbarny Nov 11, 2025
468d0a4
Fix AST tests
costin Nov 12, 2025
f095f9c
PromQL: Plug ESQL capability (#137938)
costin Nov 12, 2025
2ffbd0f
Ignore valid extra promql queries in ast tests
felixbarny Nov 12, 2025
78cd4c7
Use Literals rather that Instant and Duration (#137887)
felixbarny Nov 12, 2025
9eaedc8
Update docs/changelog/137988.yaml
costin Nov 12, 2025
edae6ea
Merge branch 'main' into esql/promql
costin Nov 12, 2025
c16ecf7
Remove unneeded file
costin Nov 12, 2025
2a3f551
Add PromQL related assets to .gitignore
costin Nov 12, 2025
2a60fd5
Delete docs/changelog/137988.yaml
costin Nov 13, 2025
c6a336e
Prefer static factory method over constructor for Literal
felixbarny Nov 13, 2025
941ecd5
Merge remote-tracking branch 'origin/main' into esql/promql
felixbarny Nov 13, 2025
833681b
[CI] Auto commit changes from spotless
Nov 13, 2025
28c56ea
Wire missing functions
felixbarny Nov 13, 2025
05cb77d
Remove wired functions from NOT_IMPLEMENTED
felixbarny Nov 13, 2025
ba6f46e
[CI] Auto commit changes from spotless
Nov 13, 2025
ac63e70
Enable a few more tests
costin Nov 13, 2025
3fbe7b7
Merge branch 'main' into esql/promql
costin Nov 13, 2025
0d86516
PromQL: Sort results by timestamp
costin Nov 14, 2025
a819253
[CI] Auto commit changes from spotless
Nov 14, 2025
35f7107
PromQL: Fix javadoc checkstyle error
costin Nov 14, 2025
62e5d3d
Merge branch 'main' into esql/promql
costin Nov 14, 2025
c2a83f5
Merge branch 'main' into esql/promql
costin Nov 17, 2025
0390231
Move Vector plans into the correct package
costin Nov 17, 2025
2e18d98
Pick-up changes from main
costin Nov 18, 2025
fabd69d
Merge remote-tracking branch 'remotes/upstream/main' into esql/promql
costin Nov 18, 2025
2b6e3d3
[CI] Auto commit changes from spotless
Nov 18, 2025
bedd411
PromQL: Pick window changes for TS Aggregate function
costin Nov 18, 2025
d07906d
Add basic csv tests
felixbarny Nov 18, 2025
46dcdbf
Merge branch 'main' into esql/promql
costin Nov 18, 2025
cf2a9ac
PromQL: Fix avg_over_time param passing
costin Nov 18, 2025
d6f9d3a
PromQL: Disable GenerativeFork for PromQL
costin Nov 19, 2025
53436ac
[CI] Auto commit changes from spotless
Nov 19, 2025
82e0447
Merge branch 'main' into esql/promql
felixbarny Nov 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ CHANGELOG.asciidoc merge=union
# Windows
build-tools-internal/src/test/resources/org/elasticsearch/gradle/internal/release/*.asciidoc text eol=lf

# ESQL parsing and source generated related assets
x-pack/plugin/esql/compute/src/main/generated/** linguist-generated=true
x-pack/plugin/esql/compute/src/main/generated-src/** linguist-generated=true
x-pack/plugin/esql/src/main/antlr/*.tokens linguist-generated=true
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/*.interp linguist-generated=true
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer*.java linguist-generated=true
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser*.java linguist-generated=true
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/*BaseLexer*.java linguist-generated=true
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/*BaseParser*.java linguist-generated=true
x-pack/plugin/esql/src/main/generated/** linguist-generated=true
x-pack/plugin/esql/src/main/generated-src/** linguist-generated=true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<suppress files="modules[/\\]lang-painless[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]painless[/\\]antlr[/\\]SuggestLexer\.java" checks="." />
<suppress files="plugin[/\\]sql[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]sql[/\\]parser[/\\]SqlBase(Base(Listener|Visitor)|Lexer|Listener|Parser|Visitor).java" checks="." />
<suppress files="plugin[/\\]eql[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]eql[/\\]parser[/\\]EqlBase(Base(Listener|Visitor)|Lexer|Listener|Parser|Visitor).java" checks="." />
<suppress files="plugin[/\\]esql[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]esql[/\\]parser[/\\]EsqlBase(Parser|Lexer).*.java" checks="." />
<suppress files="plugin[/\\]esql[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]esql[/\\]parser[/\\](EsqlBase|PromqlBase)(Parser|Lexer).*.java" checks="." />
<suppress files="x-pack[/\\]plugin[/\\]otel-data[/\\]build[/\\]generated[/\\]sources[/\\]" checks="." />

<!-- JNA requires the no-argument constructor on JNAKernel32Library.SizeT to be public-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Objects;

Expand Down Expand Up @@ -217,6 +218,10 @@ public static Literal timeDuration(Source source, Duration literal) {
return new Literal(source, literal, DataType.TIME_DURATION);
}

public static Literal dateTime(Source source, Instant literal) {
return new Literal(source, literal, DataType.DATETIME);
}

public static Literal integer(Source source, Integer literal) {
return new Literal(source, literal, INTEGER);
}
Expand All @@ -229,6 +234,10 @@ public static Literal fromLong(Source source, Long literal) {
return new Literal(source, literal, LONG);
}

public static Expression fromBoolean(Source source, Boolean literal) {
return new Literal(source, literal, DataType.BOOLEAN);
}

private static BytesRef longAsWKB(DataType dataType, long encoded) {
return dataType == GEO_POINT ? GEO.longAsWkb(encoded) : CARTESIAN.longAsWkb(encoded);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public static Number mod(Number l, Number r) {
return l.intValue() % r.intValue();
}

static Number negate(Number n) {
public static Number negate(Number n) {
if (n == null) {
return null;
}
Expand Down
62 changes: 53 additions & 9 deletions x-pack/plugin/esql/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ pluginManager.withPlugin('com.diffplug.spotless') {
// for some reason "${outputPath}/EsqlBaseParser*.java" does not match the same files...
targetExclude "src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer*.java",
"src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser*.java",
"src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer*.java",
"src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser*.java",
"src/main/generated/**/*.java",
"src/main/generated-src/generated/**/*.java"
toggleOffOn('begin generated imports', 'end generated imports')
Expand All @@ -345,6 +347,7 @@ tasks.register("cleanGenerated", Delete) {
}
delete fileTree(outputPath) {
include 'EsqlBase*.java'
include 'PromqlBase*.java'
}
}

Expand Down Expand Up @@ -384,52 +387,93 @@ tasks.register("regenParser", JavaExec) {
"${file(grammarPath)}/EsqlBaseParser.g4"
}

tasks.register("regenPromqlLexer", JavaExec) {
dependsOn "cleanGenerated"
mainClass = 'org.antlr.v4.Tool'
classpath = configurations.regenerate
systemProperty 'file.encoding', 'UTF-8'
systemProperty 'user.language', 'en'
systemProperty 'user.country', 'US'
systemProperty 'user.variant', ''
args '-Werror',
'-package', 'org.elasticsearch.xpack.esql.parser',
'-listener',
'-visitor',
'-lib', "${file(grammarPath)}",
'-o', outputPath,
"${file(grammarPath)}/PromqlBaseLexer.g4"
}

tasks.register("regenPromqlParser", JavaExec) {
dependsOn "cleanGenerated"
dependsOn "regenPromqlLexer"
mainClass = 'org.antlr.v4.Tool'
classpath = configurations.regenerate
systemProperty 'file.encoding', 'UTF-8'
systemProperty 'user.language', 'en'
systemProperty 'user.country', 'US'
systemProperty 'user.variant', ''
args '-Werror',
'-package', 'org.elasticsearch.xpack.esql.parser',
'-listener',
'-visitor',
'-lib', outputPath,
'-lib', "${file(grammarPath)}",
'-o', outputPath,
"${file(grammarPath)}/PromqlBaseParser.g4"
}

tasks.register("regen") {
dependsOn "regenParser"
dependsOn "regenPromqlParser"
doLast {
// moves token files to grammar directory for use with IDE's
ant.move(file: "${outputPath}/EsqlBaseLexer.tokens", toDir: grammarPath)
ant.move(file: "${outputPath}/EsqlBaseParser.tokens", toDir: grammarPath)
ant.move(file: "${outputPath}/PromqlBaseLexer.tokens", toDir: grammarPath)
ant.move(file: "${outputPath}/PromqlBaseParser.tokens", toDir: grammarPath)

// make the generated classes package private
ant.replaceregexp(
match: 'public ((interface|class) \\QEsqlBase(Parser|Lexer)\\E\\w+)',
match: 'public ((interface|class) \\Q(Es|Prom)qlBase(Parser|Lexer)\\E\\w+)',
replace: '\\1',
encoding: 'UTF-8'
) {
fileset(dir: outputPath, includes: 'EsqlBase*.java')
fileset(dir: outputPath, includes: '*qlBase*.java')
}
// nuke timestamps/filenames in generated files
ant.replaceregexp(
match: '\\Q// Generated from \\E.*',
replace: '\\/\\/ ANTLR GENERATED CODE: DO NOT EDIT',
encoding: 'UTF-8'
) {
fileset(dir: outputPath, includes: 'EsqlBase*.java')
fileset(dir: outputPath, includes: '*qlBase*.java')
}
// remove tabs in antlr generated files
ant.replaceregexp(match: '\t', flags: 'g', replace: ' ', encoding: 'UTF-8') {
fileset(dir: outputPath, includes: 'EsqlBase*.java')
fileset(dir: outputPath, includes: '*qlBase*.java')
}
// suppress this-escape warnings on EsqlBaseLexer
ant.replaceregexp(
match: 'public EsqlBaseLexer',
replace: '@SuppressWarnings("this-escape")${line.separator} public EsqlBaseLexer',
match: 'public ((Es|Prom)qlBaseLexer)',
replace: '@SuppressWarnings("this-escape")${line.separator} public \\1',
encoding: 'UTF-8'
) {
fileset(dir: outputPath, includes: 'EsqlBaseLexer.java')
fileset(dir: outputPath, includes: '*qlBaseLexer.java')
}

// suppress this-escape warnings on all internal EsqlBaseParser class constructores
ant.replaceregexp(
match: '([ ]+)public ([A-Z][a-z]+[a-z,A-Z]+\\()',
flags: 'g',
replace: '\\1@SuppressWarnings("this-escape")${line.separator}\\1public \\2',
encoding: 'UTF-8'
) {
fileset(dir: outputPath, includes: 'EsqlBaseParser.java')
fileset(dir: outputPath, includes: '*qlBaseParser.java')
}
// fix line endings
ant.fixcrlf(srcdir: outputPath, eol: 'lf') {
patternset(includes: 'EsqlBase*.java')
patternset(includes: '*qlBase*.java')
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ protected void shouldSkipTest(String testName) throws IOException {
testCase.requiredCapabilities.contains(SUBQUERY_IN_FROM_COMMAND.capabilityName())
);

assumeFalse("Tests using PROMQL are not supported for now", testCase.requiredCapabilities.contains(PROMQL_V0.capabilityName()));

assumeTrue("Cluster needs to support FORK", hasCapabilities(adminClient(), List.of(FORK_V9.capabilityName())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ cost:double | time_bucket:datetime
36.375 | 2024-05-10T00:11:00.000Z
;

avg_over_time_of_double_no_grouping_single_bucket
required_capability: ts_command_v0
required_capability: tbucket
TS k8s
| STATS cost=sum(avg_over_time(network.cost)) BY time_bucket = tbucket(1h);

cost:double | time_bucket:datetime
56.32254035241995 | 2024-05-10T00:00:00.000Z
;

avg_over_time_of_double_no_grouping_single_bucket_promql
required_capability: promql_v0
TS k8s
| PROMQL step 1h (sum(avg_over_time(network.cost[1h])));

sum(avg_over_time(network.cost[1h])):double | TBUCKET:date
56.32254035241995 | 2024-05-10T00:00:00.000Z
;

avg_over_time_of_integer
required_capability: ts_command_v0
TS k8s | STATS clients = avg(avg_over_time(network.eth0.currently_connected_clients)) BY time_bucket = bucket(@timestamp,1minute) | SORT time_bucket | LIMIT 10;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,25 @@ max(rate(network.total_bytes_in)): double | time_bucket:date
23.702205882352942 | 2024-05-10T00:15:00.000Z
;

oneRateWithSingleTBucket
required_capability: ts_command_v0
required_capability: tbucket
TS k8s
| STATS max(rate(network.total_bytes_in)) BY time_bucket = tbucket(1h);

max(rate(network.total_bytes_in)): double | time_bucket:date
4.379885057471264 | 2024-05-10T00:00:00.000Z
;

oneRateWithSingleTBucketPromql
required_capability: promql_v0
TS k8s
| PROMQL step 1h (max(rate(network.total_bytes_in[1h])));

max(rate(network.total_bytes_in[1h])):double | TBUCKET:date
4.379885057471264 | 2024-05-10T00:00:00.000Z
;

twoRatesWithBucket
required_capability: ts_command_v0
TS k8s | STATS max(rate(network.total_bytes_in)), sum(rate(network.total_bytes_in)) BY time_bucket = bucket(@timestamp,5minute) | SORT time_bucket DESC | LIMIT 3;
Expand Down
Loading