|
@@ -20,6 +20,7 @@ import org.elasticsearch.xpack.ql.expression.Attribute;
|
|
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
|
|
import org.elasticsearch.xpack.ql.expression.FieldAttribute;
|
|
|
import org.elasticsearch.xpack.ql.expression.Literal;
|
|
|
+import org.elasticsearch.xpack.ql.expression.ReferenceAttribute;
|
|
|
import org.elasticsearch.xpack.ql.expression.function.FunctionDefinition;
|
|
|
import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunction;
|
|
|
import org.elasticsearch.xpack.ql.expression.function.aggregate.Count;
|
|
@@ -68,6 +69,7 @@ import org.elasticsearch.xpack.sql.plan.physical.EsQueryExec;
|
|
|
import org.elasticsearch.xpack.sql.plan.physical.PhysicalPlan;
|
|
|
import org.elasticsearch.xpack.sql.planner.QueryFolder.FoldAggregate.GroupingContext;
|
|
|
import org.elasticsearch.xpack.sql.planner.QueryTranslator.QueryTranslation;
|
|
|
+import org.elasticsearch.xpack.sql.proto.SqlTypedParamValue;
|
|
|
import org.elasticsearch.xpack.sql.querydsl.agg.AggFilter;
|
|
|
import org.elasticsearch.xpack.sql.querydsl.agg.GroupByDateHistogram;
|
|
|
import org.elasticsearch.xpack.sql.querydsl.container.MetricAggRef;
|
|
@@ -100,6 +102,7 @@ import static org.elasticsearch.xpack.sql.type.SqlDataTypes.DATE;
|
|
|
import static org.elasticsearch.xpack.sql.util.DateUtils.UTC;
|
|
|
import static org.hamcrest.CoreMatchers.containsString;
|
|
|
import static org.hamcrest.Matchers.endsWith;
|
|
|
+import static org.hamcrest.Matchers.everyItem;
|
|
|
import static org.hamcrest.Matchers.instanceOf;
|
|
|
import static org.hamcrest.Matchers.startsWith;
|
|
|
|
|
@@ -133,7 +136,11 @@ public class QueryTranslatorTests extends ESTestCase {
|
|
|
}
|
|
|
|
|
|
private PhysicalPlan optimizeAndPlan(String sql) {
|
|
|
- return planner.plan(optimizer.optimize(plan(sql)), true);
|
|
|
+ return optimizeAndPlan(plan(sql));
|
|
|
+ }
|
|
|
+
|
|
|
+ private PhysicalPlan optimizeAndPlan(LogicalPlan plan) {
|
|
|
+ return planner.plan(optimizer.optimize(plan),true);
|
|
|
}
|
|
|
|
|
|
private QueryTranslation translate(Expression condition) {
|
|
@@ -144,6 +151,10 @@ public class QueryTranslatorTests extends ESTestCase {
|
|
|
return QueryTranslator.toQuery(condition, true);
|
|
|
}
|
|
|
|
|
|
+ private LogicalPlan parameterizedSql(String sql, SqlTypedParamValue... params) {
|
|
|
+ return analyzer.analyze(parser.createStatement(sql, Arrays.asList(params), org.elasticsearch.xpack.ql.type.DateUtils.UTC), true);
|
|
|
+ }
|
|
|
+
|
|
|
public void testTermEqualityAnalyzer() {
|
|
|
LogicalPlan p = plan("SELECT some.string FROM test WHERE some.string = 'value'");
|
|
|
assertTrue(p instanceof Project);
|
|
@@ -2239,4 +2250,52 @@ public class QueryTranslatorTests extends ESTestCase {
|
|
|
+ "InternalSqlScriptUtils.asDateTime(params.a0),InternalSqlScriptUtils.asDateTime(params.v0)))\",\"lang\":\"painless\","
|
|
|
+ "\"params\":{\"v0\":\"2020-05-03T00:00:00.000Z\"}},\"gap_policy\":\"skip\"}}}}}}"));
|
|
|
}
|
|
|
+
|
|
|
+ public void testFoldingWithParamsWithoutIndex() {
|
|
|
+ PhysicalPlan p = optimizeAndPlan(parameterizedSql("SELECT ?, ?, ? FROM test",
|
|
|
+ new SqlTypedParamValue("integer", 100),
|
|
|
+ new SqlTypedParamValue("integer", 100),
|
|
|
+ new SqlTypedParamValue("integer", 200)));
|
|
|
+ assertThat(p.output(), everyItem(instanceOf(ReferenceAttribute.class)));
|
|
|
+ assertThat(p.output().get(0).toString(), startsWith("?{r}#"));
|
|
|
+ assertThat(p.output().get(1).toString(), startsWith("?{r}#"));
|
|
|
+ assertThat(p.output().get(2).toString(), startsWith("?{r}#"));
|
|
|
+ assertNotEquals(p.output().get(1).id(), p.output().get(2).id());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testSameAliasForParamAndField() {
|
|
|
+ PhysicalPlan p = optimizeAndPlan(parameterizedSql("SELECT ?, int as \"?\" FROM test",
|
|
|
+ new SqlTypedParamValue("integer", 100)));
|
|
|
+ assertThat(p.output(), everyItem(instanceOf(ReferenceAttribute.class)));
|
|
|
+ assertThat(p.output().get(0).toString(), startsWith("?{r}#"));
|
|
|
+ assertThat(p.output().get(1).toString(), startsWith("?{r}#"));
|
|
|
+ assertNotEquals(p.output().get(0).id(), p.output().get(1).id());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testSameAliasOnSameField() {
|
|
|
+ PhysicalPlan p = optimizeAndPlan(parameterizedSql("SELECT int as \"int\", int as \"int\" FROM test"));
|
|
|
+ assertThat(p.output(), everyItem(instanceOf(ReferenceAttribute.class)));
|
|
|
+ assertThat(p.output().get(0).toString(), startsWith("int{r}#"));
|
|
|
+ assertThat(p.output().get(1).toString(), startsWith("int{r}#"));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testFoldingWithMixedParamsWithoutAlias() {
|
|
|
+ PhysicalPlan p = optimizeAndPlan(parameterizedSql("SELECT ?, ? FROM test",
|
|
|
+ new SqlTypedParamValue("integer", 100),
|
|
|
+ new SqlTypedParamValue("text", "200")));
|
|
|
+ assertThat(p.output(), everyItem(instanceOf(ReferenceAttribute.class)));
|
|
|
+ assertThat(p.output().get(0).toString(), startsWith("?{r}#"));
|
|
|
+ assertThat(p.output().get(1).toString(), startsWith("?{r}#"));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testSameExpressionWithoutAlias() {
|
|
|
+ PhysicalPlan physicalPlan = optimizeAndPlan("SELECT 100, 100 FROM test");
|
|
|
+ assertEquals(EsQueryExec.class, physicalPlan.getClass());
|
|
|
+ EsQueryExec eqe = (EsQueryExec) physicalPlan;
|
|
|
+ assertEquals(2, eqe.output().size());
|
|
|
+ assertThat(eqe.output().get(0).toString(), startsWith("100{r}#"));
|
|
|
+ assertThat(eqe.output().get(1).toString(), startsWith("100{r}#"));
|
|
|
+ // these two should be semantically different reference attributes
|
|
|
+ assertNotEquals(eqe.output().get(0).id(), eqe.output().get(1).id());
|
|
|
+ }
|
|
|
}
|