Skip to content

Commit 4b9d635

Browse files
committed
Extended UT Framework for E2E Query conversion (opensearch-project#21060)
Changes to test the end to end DSL query conversion without OpenSearch cluster. Currently adds support for match_all and terms with agg for the initial commit. Signed-off-by: Suresh N S <nssuresh@amazon.com>
1 parent fc04bed commit 4b9d635

9 files changed

Lines changed: 1267 additions & 0 deletions

File tree

sandbox/plugins/dsl-query-executor/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies {
3737

3838
testImplementation project(':test:framework')
3939
testImplementation "org.mockito:mockito-core:${versions.mockito}"
40+
testImplementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}"
4041

4142
internalClusterTestImplementation project(':server')
4243
internalClusterTestImplementation project(':test:framework')

sandbox/plugins/dsl-query-executor/src/test/design.md

Lines changed: 448 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*/
8+
9+
package org.opensearch.dsl.golden;
10+
11+
import org.apache.calcite.config.CalciteConnectionConfigImpl;
12+
import org.apache.calcite.jdbc.CalciteSchema;
13+
import org.apache.calcite.plan.RelOptCluster;
14+
import org.apache.calcite.plan.RelOptTable;
15+
import org.apache.calcite.plan.hep.HepPlanner;
16+
import org.apache.calcite.plan.hep.HepProgram;
17+
import org.apache.calcite.prepare.CalciteCatalogReader;
18+
import org.apache.calcite.rel.type.RelDataType;
19+
import org.apache.calcite.rel.type.RelDataTypeFactory;
20+
import org.apache.calcite.rel.type.RelDataTypeSystem;
21+
import org.apache.calcite.rex.RexBuilder;
22+
import org.apache.calcite.schema.SchemaPlus;
23+
import org.apache.calcite.schema.impl.AbstractTable;
24+
import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
25+
import org.apache.calcite.sql.type.SqlTypeName;
26+
27+
import java.util.Collections;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.Objects;
31+
import java.util.Properties;
32+
33+
/**
34+
* Builds Calcite planning infrastructure from a golden file's index mapping.
35+
*
36+
* <p>Mirrors the pattern in {@code TestUtils} and {@code SearchSourceConverter}'s
37+
* constructor, but constructs the schema dynamically from the golden file's
38+
* {@code indexMapping} field instead of using a hardcoded schema.
39+
*/
40+
public class CalciteTestInfra {
41+
42+
private CalciteTestInfra() {}
43+
44+
/**
45+
* Builds a complete Calcite infrastructure from a golden file's index mapping.
46+
*
47+
* @param indexName the index name to register in the schema
48+
* @param indexMapping field name → SQL type name (e.g. "VARCHAR", "INTEGER")
49+
* @return an {@link InfraResult} containing the cluster, table, and schema
50+
* @throws IllegalArgumentException if indexMapping contains an unsupported type
51+
*/
52+
public static InfraResult buildFromMapping(String indexName, Map<String, String> indexMapping) {
53+
Objects.requireNonNull(indexName, "indexName must not be null");
54+
Objects.requireNonNull(indexMapping, "indexMapping must not be null");
55+
56+
RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
57+
HepPlanner planner = new HepPlanner(HepProgram.builder().build());
58+
RelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory));
59+
60+
SchemaPlus schema = CalciteSchema.createRootSchema(true).plus();
61+
schema.add(indexName, new AbstractTable() {
62+
@Override
63+
public RelDataType getRowType(RelDataTypeFactory tf) {
64+
RelDataTypeFactory.Builder builder = tf.builder();
65+
for (Map.Entry<String, String> entry : indexMapping.entrySet()) {
66+
SqlTypeName sqlType = toSqlTypeName(entry.getValue());
67+
builder.add(entry.getKey(), tf.createTypeWithNullability(tf.createSqlType(sqlType), true));
68+
}
69+
return builder.build();
70+
}
71+
});
72+
73+
CalciteCatalogReader reader = new CalciteCatalogReader(
74+
CalciteSchema.from(schema),
75+
Collections.singletonList(""),
76+
typeFactory,
77+
new CalciteConnectionConfigImpl(new Properties())
78+
);
79+
RelOptTable table = Objects.requireNonNull(
80+
reader.getTable(List.of(indexName)),
81+
"Table not found in schema: " + indexName
82+
);
83+
84+
return new InfraResult(cluster, table, schema);
85+
}
86+
87+
/**
88+
* Maps a golden file type string to a Calcite {@link SqlTypeName}.
89+
*
90+
* @throws IllegalArgumentException for unsupported type strings
91+
*/
92+
private static SqlTypeName toSqlTypeName(String goldenType) {
93+
switch (goldenType) {
94+
case "VARCHAR": return SqlTypeName.VARCHAR;
95+
case "INTEGER": return SqlTypeName.INTEGER;
96+
case "BIGINT": return SqlTypeName.BIGINT;
97+
case "DOUBLE": return SqlTypeName.DOUBLE;
98+
case "FLOAT": return SqlTypeName.FLOAT;
99+
case "BOOLEAN": return SqlTypeName.BOOLEAN;
100+
case "DATE": return SqlTypeName.DATE;
101+
case "TIMESTAMP": return SqlTypeName.TIMESTAMP;
102+
default:
103+
throw new IllegalArgumentException("Unsupported SQL type in golden file indexMapping: " + goldenType);
104+
}
105+
}
106+
107+
/** Result record containing the Calcite infrastructure built from a golden file mapping. */
108+
public record InfraResult(RelOptCluster cluster, RelOptTable table, SchemaPlus schema) {}
109+
}

0 commit comments

Comments
 (0)