|
84 | 84 | import org.elasticsearch.xpack.esql.plan.logical.Eval; |
85 | 85 | import org.elasticsearch.xpack.esql.plan.logical.Filter; |
86 | 86 | import org.elasticsearch.xpack.esql.plan.logical.Fork; |
| 87 | +import org.elasticsearch.xpack.esql.plan.logical.InlineStats; |
87 | 88 | import org.elasticsearch.xpack.esql.plan.logical.Insist; |
88 | 89 | import org.elasticsearch.xpack.esql.plan.logical.Limit; |
89 | 90 | import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; |
@@ -4989,6 +4990,138 @@ public void testMixedDataTypesWithExplicitCastingInSubquery() { |
4989 | 4990 | assertEquals("test_mixed_types", subqueryIndex.indexPattern()); |
4990 | 4991 | } |
4991 | 4992 |
|
| 4993 | + public void testSubqueryWithTimeSeriesIndexInMainQuery() { |
| 4994 | + assumeTrue("Requires subquery in FROM command support", EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND.isEnabled()); |
| 4995 | + LogicalPlan plan = analyze(""" |
| 4996 | + FROM k8s, (FROM sample_data), (FROM sample_data | WHERE client_ip == "127.0.0.1") |
| 4997 | + | WHERE @timestamp > "2025-10-07" |
| 4998 | + """, "k8s-downsampled-mappings.json"); |
| 4999 | + |
| 5000 | + Limit limit = as(plan, Limit.class); |
| 5001 | + Filter filter = as(limit.child(), Filter.class); |
| 5002 | + UnionAll unionAll = as(filter.child(), UnionAll.class); |
| 5003 | + List<Attribute> output = unionAll.output(); |
| 5004 | + // all fields from the three indices |
| 5005 | + assertEquals(24, output.size()); |
| 5006 | + assertEquals(3, unionAll.children().size()); |
| 5007 | + |
| 5008 | + limit = as(unionAll.children().get(0), Limit.class); |
| 5009 | + EsqlProject esqlProject = as(limit.child(), EsqlProject.class); |
| 5010 | + Eval eval = as(esqlProject.child(), Eval.class); |
| 5011 | + eval = as(eval.child(), Eval.class); |
| 5012 | + EsRelation relation = as(eval.child(), EsRelation.class); |
| 5013 | + assertEquals("k8s", relation.indexPattern()); |
| 5014 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5015 | + |
| 5016 | + limit = as(unionAll.children().get(1), Limit.class); |
| 5017 | + esqlProject = as(limit.child(), EsqlProject.class); |
| 5018 | + eval = as(esqlProject.child(), Eval.class); |
| 5019 | + Subquery subquery = as(eval.child(), Subquery.class); |
| 5020 | + relation = as(subquery.child(), EsRelation.class); |
| 5021 | + assertEquals("sample_data", relation.indexPattern()); |
| 5022 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5023 | + |
| 5024 | + limit = as(unionAll.children().get(2), Limit.class); |
| 5025 | + esqlProject = as(limit.child(), EsqlProject.class); |
| 5026 | + eval = as(esqlProject.child(), Eval.class); |
| 5027 | + subquery = as(eval.child(), Subquery.class); |
| 5028 | + filter = as(subquery.child(), Filter.class); |
| 5029 | + relation = as(filter.child(), EsRelation.class); |
| 5030 | + assertEquals("sample_data", relation.indexPattern()); |
| 5031 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5032 | + } |
| 5033 | + |
| 5034 | + public void testSubqueryWithTimeSeriesIndexInSubquery() { |
| 5035 | + assumeTrue("Requires subquery in FROM command support", EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND.isEnabled()); |
| 5036 | + LogicalPlan plan = analyze(""" |
| 5037 | + FROM sample_data, |
| 5038 | + (FROM k8s | EVAL a = TO_AGGREGATE_METRIC_DOUBLE(1) | INLINE STATS tx_max = MAX(network.eth0.tx) BY pod), |
| 5039 | + (FROM sample_data | WHERE client_ip == "127.0.0.1") |
| 5040 | + | WHERE @timestamp > "2025-10-07" |
| 5041 | + """, "mapping-sample_data.json"); |
| 5042 | + |
| 5043 | + Limit limit = as(plan, Limit.class); |
| 5044 | + Filter filter = as(limit.child(), Filter.class); |
| 5045 | + UnionAll unionAll = as(filter.child(), UnionAll.class); |
| 5046 | + List<Attribute> output = unionAll.output(); |
| 5047 | + assertEquals(26, output.size()); |
| 5048 | + assertEquals(3, unionAll.children().size()); |
| 5049 | + |
| 5050 | + limit = as(unionAll.children().get(0), Limit.class); |
| 5051 | + EsqlProject esqlProject = as(limit.child(), EsqlProject.class); |
| 5052 | + Eval eval = as(esqlProject.child(), Eval.class); |
| 5053 | + EsRelation relation = as(eval.child(), EsRelation.class); |
| 5054 | + assertEquals("sample_data", relation.indexPattern()); |
| 5055 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5056 | + |
| 5057 | + limit = as(unionAll.children().get(1), Limit.class); |
| 5058 | + esqlProject = as(limit.child(), EsqlProject.class); |
| 5059 | + eval = as(esqlProject.child(), Eval.class); |
| 5060 | + eval = as(eval.child(), Eval.class); |
| 5061 | + Subquery subquery = as(eval.child(), Subquery.class); |
| 5062 | + InlineStats inlineStats = as(subquery.child(), InlineStats.class); |
| 5063 | + Aggregate aggregate = as(inlineStats.child(), Aggregate.class); |
| 5064 | + eval = as(aggregate.child(), Eval.class); |
| 5065 | + relation = as(eval.child(), EsRelation.class); |
| 5066 | + assertEquals("k8s", relation.indexPattern()); |
| 5067 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5068 | + |
| 5069 | + limit = as(unionAll.children().get(2), Limit.class); |
| 5070 | + esqlProject = as(limit.child(), EsqlProject.class); |
| 5071 | + eval = as(esqlProject.child(), Eval.class); |
| 5072 | + subquery = as(eval.child(), Subquery.class); |
| 5073 | + filter = as(subquery.child(), Filter.class); |
| 5074 | + relation = as(filter.child(), EsRelation.class); |
| 5075 | + assertEquals("sample_data", relation.indexPattern()); |
| 5076 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5077 | + } |
| 5078 | + |
| 5079 | + public void testSubqueryWithTimeSeriesIndexInMainQueryAndSubquery() { |
| 5080 | + assumeTrue("Requires subquery in FROM command support", EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND.isEnabled()); |
| 5081 | + LogicalPlan plan = analyze(""" |
| 5082 | + FROM k8s, |
| 5083 | + (FROM k8s | EVAL a = TO_AGGREGATE_METRIC_DOUBLE(1) | INLINE STATS tx_max = MAX(network.eth0.tx) BY pod), |
| 5084 | + (FROM sample_data | WHERE client_ip == "127.0.0.1") |
| 5085 | + | WHERE @timestamp > "2025-10-07" |
| 5086 | + """, "k8s-downsampled-mappings.json"); |
| 5087 | + |
| 5088 | + Limit limit = as(plan, Limit.class); |
| 5089 | + Filter filter = as(limit.child(), Filter.class); |
| 5090 | + UnionAll unionAll = as(filter.child(), UnionAll.class); |
| 5091 | + List<Attribute> output = unionAll.output(); |
| 5092 | + assertEquals(26, output.size()); |
| 5093 | + assertEquals(3, unionAll.children().size()); |
| 5094 | + |
| 5095 | + limit = as(unionAll.children().get(0), Limit.class); |
| 5096 | + EsqlProject esqlProject = as(limit.child(), EsqlProject.class); |
| 5097 | + Eval eval = as(esqlProject.child(), Eval.class); |
| 5098 | + eval = as(eval.child(), Eval.class); |
| 5099 | + EsRelation relation = as(eval.child(), EsRelation.class); |
| 5100 | + assertEquals("k8s", relation.indexPattern()); |
| 5101 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5102 | + |
| 5103 | + limit = as(unionAll.children().get(1), Limit.class); |
| 5104 | + esqlProject = as(limit.child(), EsqlProject.class); |
| 5105 | + eval = as(esqlProject.child(), Eval.class); |
| 5106 | + eval = as(eval.child(), Eval.class); |
| 5107 | + Subquery subquery = as(eval.child(), Subquery.class); |
| 5108 | + InlineStats inlineStats = as(subquery.child(), InlineStats.class); |
| 5109 | + Aggregate aggregate = as(inlineStats.child(), Aggregate.class); |
| 5110 | + eval = as(aggregate.child(), Eval.class); |
| 5111 | + relation = as(eval.child(), EsRelation.class); |
| 5112 | + assertEquals("k8s", relation.indexPattern()); |
| 5113 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5114 | + |
| 5115 | + limit = as(unionAll.children().get(2), Limit.class); |
| 5116 | + esqlProject = as(limit.child(), EsqlProject.class); |
| 5117 | + eval = as(esqlProject.child(), Eval.class); |
| 5118 | + subquery = as(eval.child(), Subquery.class); |
| 5119 | + filter = as(subquery.child(), Filter.class); |
| 5120 | + relation = as(filter.child(), EsRelation.class); |
| 5121 | + assertEquals("sample_data", relation.indexPattern()); |
| 5122 | + assertEquals(IndexMode.STANDARD, relation.indexMode()); |
| 5123 | + } |
| 5124 | + |
4992 | 5125 | private void verifyNameAndType(String actualName, DataType actualType, String expectedName, DataType expectedType) { |
4993 | 5126 | assertEquals(expectedName, actualName); |
4994 | 5127 | assertEquals(expectedType, actualType); |
|
0 commit comments