diff --git a/api/README.md b/api/README.md index c380a1a7128..486a2a9f58a 100644 --- a/api/README.md +++ b/api/README.md @@ -17,19 +17,34 @@ Together, these components enable a complete workflow: parse PPL queries into lo ## Usage -### UnifiedQueryPlanner +### UnifiedQueryContext + +`UnifiedQueryContext` is a reusable abstraction shared across unified query components (planner, compiler, etc.). It bundles `CalcitePlanContext` and `Settings` into a single object, centralizing configuration for all unified query operations. -Use the declarative, fluent builder API to initialize the `UnifiedQueryPlanner`. +Create a context with catalog configuration, query type, and optional settings: ```java -UnifiedQueryPlanner planner = UnifiedQueryPlanner.builder() +UnifiedQueryContext context = UnifiedQueryContext.builder() .language(QueryType.PPL) - .catalog("opensearch", schema) + .catalog("opensearch", opensearchSchema) + .catalog("spark_catalog", sparkSchema) .defaultNamespace("opensearch") .cacheMetadata(true) + .setting("plugins.query.size_limit", 200) .build(); +``` + +### UnifiedQueryPlanner -RelNode plan = planner.plan("source = opensearch.test"); +Use `UnifiedQueryPlanner` to parse and analyze PPL queries into Calcite logical plans. The planner accepts a `UnifiedQueryContext` and can be reused for multiple queries. + +```java +// Create planner with context +UnifiedQueryPlanner planner = new UnifiedQueryPlanner(context); + +// Plan multiple queries (context is reused) +RelNode plan1 = planner.plan("source = logs | where status = 200"); +RelNode plan2 = planner.plan("source = metrics | stats avg(cpu)"); ``` ### UnifiedQueryTranspiler @@ -46,25 +61,28 @@ String sql = transpiler.toSql(plan); ### Complete Workflow Example -Combining both components to transpile PPL queries into target database SQL: +Combining all components to transpile PPL queries into target database SQL: ```java -// Step 1: Initialize planner -UnifiedQueryPlanner planner = UnifiedQueryPlanner.builder() +// Step 1: Create reusable context (shared across components) +UnifiedQueryContext context = UnifiedQueryContext.builder() .language(QueryType.PPL) .catalog("catalog", schema) .defaultNamespace("catalog") .build(); -// Step 2: Parse PPL query into logical plan +// Step 2: Create planner with context +UnifiedQueryPlanner planner = new UnifiedQueryPlanner(context); + +// Step 3: Plan PPL query into logical plan RelNode plan = planner.plan("source = employees | where age > 30"); -// Step 3: Initialize transpiler with target dialect +// Step 4: Create transpiler with target dialect UnifiedQueryTranspiler transpiler = UnifiedQueryTranspiler.builder() .dialect(SparkSqlDialect.DEFAULT) .build(); -// Step 4: Transpile to target SQL +// Step 5: Transpile to target SQL String sparkSql = transpiler.toSql(plan); // Result: SELECT * FROM `catalog`.`employees` WHERE `age` > 30 ``` diff --git a/api/src/main/java/org/opensearch/sql/api/UnifiedQueryContext.java b/api/src/main/java/org/opensearch/sql/api/UnifiedQueryContext.java new file mode 100644 index 00000000000..029eb2218ae --- /dev/null +++ b/api/src/main/java/org/opensearch/sql/api/UnifiedQueryContext.java @@ -0,0 +1,189 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.sql.api; + +import static org.opensearch.sql.common.setting.Settings.Key.PPL_JOIN_SUBSEARCH_MAXOUT; +import static org.opensearch.sql.common.setting.Settings.Key.PPL_SUBSEARCH_MAXOUT; +import static org.opensearch.sql.common.setting.Settings.Key.QUERY_SIZE_LIMIT; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import lombok.Value; +import org.apache.calcite.jdbc.CalciteSchema; +import org.apache.calcite.plan.RelTraitDef; +import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider; +import org.apache.calcite.schema.Schema; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.tools.FrameworkConfig; +import org.apache.calcite.tools.Frameworks; +import org.apache.calcite.tools.Programs; +import org.opensearch.sql.calcite.CalcitePlanContext; +import org.opensearch.sql.calcite.SysLimit; +import org.opensearch.sql.common.setting.Settings; +import org.opensearch.sql.executor.QueryType; + +/** + * A reusable abstraction shared across unified query components (planner, compiler, etc.). This + * centralizes configuration for catalog schemas, query type, execution limits, and other settings, + * enabling consistent behavior across all unified query operations. + */ +@Value +public class UnifiedQueryContext { + + /** CalcitePlanContext containing Calcite framework configuration and query type. */ + CalcitePlanContext planContext; + + /** Settings containing execution limits and feature flags used by parsers and planners. */ + Settings settings; + + /** Creates a new builder for UnifiedQueryContext. */ + public static Builder builder() { + return new Builder(); + } + + /** Builder that constructs UnifiedQueryContext. */ + public static class Builder { + private QueryType queryType; + private final Map catalogs = new HashMap<>(); + private String defaultNamespace; + private boolean cacheMetadata = false; + + /** + * Setting values with defaults from SysLimit.DEFAULT. Only includes planning-required settings + * to avoid coupling with OpenSearchSettings. + */ + private final Map settings = + new HashMap( + Map.of( + QUERY_SIZE_LIMIT, SysLimit.DEFAULT.querySizeLimit(), + PPL_SUBSEARCH_MAXOUT, SysLimit.DEFAULT.subsearchLimit(), + PPL_JOIN_SUBSEARCH_MAXOUT, SysLimit.DEFAULT.joinSubsearchLimit())); + + /** + * Sets the query language frontend to be used. + * + * @param queryType the {@link QueryType}, such as PPL + * @return this builder instance + */ + public Builder language(QueryType queryType) { + this.queryType = queryType; + return this; + } + + /** + * Registers a catalog with the specified name and its associated schema. The schema can be a + * flat or nested structure (e.g., catalog → schema → table), depending on how data is + * organized. + * + * @param name the name of the catalog to register + * @param schema the schema representing the structure of the catalog + * @return this builder instance + */ + public Builder catalog(String name, Schema schema) { + catalogs.put(name, schema); + return this; + } + + /** + * Sets the default namespace path for resolving unqualified table names. + * + * @param namespace dot-separated path (e.g., "spark_catalog.default" or "opensearch") + * @return this builder instance + */ + public Builder defaultNamespace(String namespace) { + this.defaultNamespace = namespace; + return this; + } + + /** + * Enables or disables catalog metadata caching in the root schema. + * + * @param cache whether to enable metadata caching + * @return this builder instance + */ + public Builder cacheMetadata(boolean cache) { + this.cacheMetadata = cache; + return this; + } + + /** + * Sets a specific setting value by name. + * + * @param name the setting key name (e.g., "plugins.query.size_limit") + * @param value the setting value + * @throws IllegalArgumentException if the setting name is not recognized + */ + public Builder setting(String name, Object value) { + Settings.Key key = + Settings.Key.of(name) + .orElseThrow(() -> new IllegalArgumentException("Unknown setting name: " + name)); + settings.put(key, value); + return this; + } + + /** + * Builds a {@link UnifiedQueryContext} with the configuration. + * + * @return a new instance of {@link UnifiedQueryContext} + */ + public UnifiedQueryContext build() { + Objects.requireNonNull(queryType, "Must specify language before build"); + + Settings settings = buildSettings(); + CalcitePlanContext planContext = + CalcitePlanContext.create( + buildFrameworkConfig(), SysLimit.fromSettings(settings), queryType); + return new UnifiedQueryContext(planContext, settings); + } + + private Settings buildSettings() { + return new Settings() { + @Override + @SuppressWarnings("unchecked") + public T getSettingValue(Key key) { + return (T) settings.get(key); + } + + @Override + public List getSettings() { + return List.copyOf(settings.entrySet()); + } + }; + } + + @SuppressWarnings({"rawtypes"}) + private FrameworkConfig buildFrameworkConfig() { + SchemaPlus rootSchema = CalciteSchema.createRootSchema(true, cacheMetadata).plus(); + catalogs.forEach(rootSchema::add); + + SchemaPlus defaultSchema = findSchemaByPath(rootSchema, defaultNamespace); + return Frameworks.newConfigBuilder() + .parserConfig(SqlParser.Config.DEFAULT) + .defaultSchema(defaultSchema) + .traitDefs((List) null) + .programs(Programs.calc(DefaultRelMetadataProvider.INSTANCE)) + .build(); + } + + private SchemaPlus findSchemaByPath(SchemaPlus rootSchema, String defaultPath) { + if (defaultPath == null) { + return rootSchema; + } + + SchemaPlus current = rootSchema; + for (String part : defaultPath.split("\\.")) { + current = current.getSubSchema(part); + if (current == null) { + throw new IllegalArgumentException("Invalid default catalog path: " + defaultPath); + } + } + return current; + } + } +} diff --git a/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java b/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java index 6a524ec307a..91e35335e20 100644 --- a/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java +++ b/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java @@ -5,31 +5,16 @@ package org.opensearch.sql.api; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; import org.antlr.v4.runtime.tree.ParseTree; -import org.apache.calcite.jdbc.CalciteSchema; -import org.apache.calcite.plan.RelTraitDef; import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelCollations; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Sort; import org.apache.calcite.rel.logical.LogicalSort; -import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.SchemaPlus; -import org.apache.calcite.sql.parser.SqlParser; -import org.apache.calcite.tools.FrameworkConfig; -import org.apache.calcite.tools.Frameworks; -import org.apache.calcite.tools.Programs; import org.opensearch.sql.ast.statement.Query; import org.opensearch.sql.ast.statement.Statement; import org.opensearch.sql.ast.tree.UnresolvedPlan; -import org.opensearch.sql.calcite.CalcitePlanContext; import org.opensearch.sql.calcite.CalciteRelNodeVisitor; -import org.opensearch.sql.calcite.SysLimit; import org.opensearch.sql.common.antlr.Parser; import org.opensearch.sql.common.antlr.SyntaxCheckException; import org.opensearch.sql.executor.QueryType; @@ -43,30 +28,24 @@ * such as Spark or command-line tools, abstracting away Calcite internals. */ public class UnifiedQueryPlanner { - /** The type of query language being used (e.g., PPL). */ - private final QueryType queryType; - /** The parser instance responsible for converting query text into a parse tree. */ private final Parser parser; - /** Calcite framework configuration used during logical plan construction. */ - private final FrameworkConfig config; + /** Unified query context containing CalcitePlanContext with all configuration. */ + private final UnifiedQueryContext context; /** AST-to-RelNode visitor that builds logical plans from the parsed AST. */ private final CalciteRelNodeVisitor relNodeVisitor = new CalciteRelNodeVisitor(new EmptyDataSourceService()); /** - * Constructs a UnifiedQueryPlanner for a given query type and schema root. + * Constructs a UnifiedQueryPlanner with a unified query context. * - * @param queryType the query language type (e.g., PPL) - * @param rootSchema the root Calcite schema containing all catalogs and tables - * @param defaultPath dot-separated path of schema to set as default schema + * @param context the unified query context containing CalcitePlanContext */ - public UnifiedQueryPlanner(QueryType queryType, SchemaPlus rootSchema, String defaultPath) { - this.queryType = queryType; - this.parser = buildQueryParser(queryType); - this.config = buildCalciteConfig(rootSchema, defaultPath); + public UnifiedQueryPlanner(UnifiedQueryContext context) { + this.parser = buildQueryParser(context.getPlanContext().queryType); + this.context = context; } /** @@ -94,37 +73,12 @@ private Parser buildQueryParser(QueryType queryType) { throw new IllegalArgumentException("Unsupported query type: " + queryType); } - private FrameworkConfig buildCalciteConfig(SchemaPlus rootSchema, String defaultPath) { - SchemaPlus defaultSchema = findSchemaByPath(rootSchema, defaultPath); - return Frameworks.newConfigBuilder() - .parserConfig(SqlParser.Config.DEFAULT) - .defaultSchema(defaultSchema) - .traitDefs((List) null) - .programs(Programs.calc(DefaultRelMetadataProvider.INSTANCE)) - .build(); - } - - private static SchemaPlus findSchemaByPath(SchemaPlus rootSchema, String defaultPath) { - if (defaultPath == null) { - return rootSchema; - } - - // Find schema by the path recursively - SchemaPlus current = rootSchema; - for (String part : defaultPath.split("\\.")) { - current = current.getSubSchema(part); - if (current == null) { - throw new IllegalArgumentException("Invalid default catalog path: " + defaultPath); - } - } - return current; - } - private UnresolvedPlan parse(String query) { ParseTree cst = parser.parse(query); AstStatementBuilder astStmtBuilder = new AstStatementBuilder( - new AstBuilder(query), AstStatementBuilder.StatementBuilderContext.builder().build()); + new AstBuilder(query, context.getSettings()), + AstStatementBuilder.StatementBuilderContext.builder().build()); Statement statement = cst.accept(astStmtBuilder); if (statement instanceof Query) { @@ -135,10 +89,7 @@ private UnresolvedPlan parse(String query) { } private RelNode analyze(UnresolvedPlan ast) { - // TODO: Hardcoded query size limit (10000) for now as only logical plan is generated. - CalcitePlanContext calcitePlanContext = - CalcitePlanContext.create(config, new SysLimit(10000, 10000, 10000), queryType); - return relNodeVisitor.analyze(ast, calcitePlanContext); + return relNodeVisitor.analyze(ast, context.getPlanContext()); } private RelNode preserveCollation(RelNode logical) { @@ -149,79 +100,4 @@ private RelNode preserveCollation(RelNode logical) { } return calcitePlan; } - - /** Builder for {@link UnifiedQueryPlanner}, supporting declarative fluent API. */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builder for {@link UnifiedQueryPlanner}, supporting both declarative and dynamic schema - * registration for use in query planning. - */ - public static class Builder { - private final Map catalogs = new HashMap<>(); - private String defaultNamespace; - private QueryType queryType; - private boolean cacheMetadata; - - /** - * Sets the query language frontend to be used by the planner. - * - * @param queryType the {@link QueryType}, such as PPL - * @return this builder instance - */ - public Builder language(QueryType queryType) { - this.queryType = queryType; - return this; - } - - /** - * Registers a catalog with the specified name and its associated schema. The schema can be a - * flat or nested structure (e.g., catalog → schema → table), depending on how data is - * organized. - * - * @param name the name of the catalog to register - * @param schema the schema representing the structure of the catalog - * @return this builder instance - */ - public Builder catalog(String name, Schema schema) { - catalogs.put(name, schema); - return this; - } - - /** - * Sets the default namespace path for resolving unqualified table names. - * - * @param namespace dot-separated path (e.g., "spark_catalog.default" or "opensearch") - * @return this builder instance - */ - public Builder defaultNamespace(String namespace) { - this.defaultNamespace = namespace; - return this; - } - - /** - * Enables or disables catalog metadata caching in the root schema. - * - * @param cache whether to enable metadata caching - * @return this builder instance - */ - public Builder cacheMetadata(boolean cache) { - this.cacheMetadata = cache; - return this; - } - - /** - * Builds a {@link UnifiedQueryPlanner} with the configuration. - * - * @return a new instance of {@link UnifiedQueryPlanner} - */ - public UnifiedQueryPlanner build() { - Objects.requireNonNull(queryType, "Must specify language before build"); - SchemaPlus rootSchema = CalciteSchema.createRootSchema(true, cacheMetadata).plus(); - catalogs.forEach(rootSchema::add); - return new UnifiedQueryPlanner(queryType, rootSchema, defaultNamespace); - } - } } diff --git a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryContextTest.java b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryContextTest.java new file mode 100644 index 00000000000..3be36ee435e --- /dev/null +++ b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryContextTest.java @@ -0,0 +1,82 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.sql.api; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.opensearch.sql.common.setting.Settings.Key.*; + +import org.junit.Test; +import org.opensearch.sql.calcite.SysLimit; +import org.opensearch.sql.executor.QueryType; + +public class UnifiedQueryContextTest extends UnifiedQueryTestBase { + + @Test + public void testContextCreationWithDefaults() { + UnifiedQueryContext context = + UnifiedQueryContext.builder() + .language(QueryType.PPL) + .catalog("opensearch", testSchema) + .defaultNamespace("opensearch") + .build(); + + assertNotNull("Context should be created", context); + assertNotNull("PlanContext should be created", context.getPlanContext()); + assertNotNull("Settings should be created", context.getSettings()); + assertEquals( + "Settings should have default system limits", + SysLimit.DEFAULT, + SysLimit.fromSettings(context.getSettings())); + } + + @Test + public void testContextCreationWithCustomConfig() { + UnifiedQueryContext context = + UnifiedQueryContext.builder() + .language(QueryType.PPL) + .catalog("opensearch", testSchema) + .cacheMetadata(true) + .setting("plugins.query.size_limit", 200) + .build(); + + Integer querySizeLimit = context.getSettings().getSettingValue(QUERY_SIZE_LIMIT); + assertEquals("Custom setting should be applied", Integer.valueOf(200), querySizeLimit); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidSettingName() { + UnifiedQueryContext.builder() + .language(QueryType.PPL) + .catalog("opensearch", testSchema) + .setting("invalid.setting.name", 123) + .build(); + } + + @Test(expected = NullPointerException.class) + public void testMissingQueryType() { + UnifiedQueryContext.builder().catalog("opensearch", testSchema).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testUnsupportedQueryType() { + UnifiedQueryContext context = + UnifiedQueryContext.builder() + .language(QueryType.SQL) // only PPL is supported for now + .catalog("opensearch", testSchema) + .build(); + new UnifiedQueryPlanner(context); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidDefaultNamespace() { + UnifiedQueryContext.builder() + .language(QueryType.PPL) + .catalog("opensearch", testSchema) + .defaultNamespace("nonexistent") + .build(); + } +} diff --git a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java index 754e36c092e..9ad7aa42155 100644 --- a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java +++ b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java @@ -29,24 +29,28 @@ protected Map getSubSchemaMap() { @Test public void testPPLQueryPlanning() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() - .language(QueryType.PPL) - .catalog("opensearch", testSchema) - .build(); - - RelNode plan = planner.plan("source = opensearch.employees | eval f = abs(id)"); + RelNode plan = planner.plan("source = catalog.employees | eval f = abs(id)"); assertNotNull("Plan should be created", plan); } + @Test + public void testPPLJoinQueryPlanning() { + RelNode plan = + planner.plan( + "source = catalog.employees | join left = l right = r on l.id = r.age" + + " catalog.employees"); + assertNotNull("Join query should be created", plan); + } + @Test public void testPPLQueryPlanningWithDefaultNamespace() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() + UnifiedQueryContext context = + UnifiedQueryContext.builder() .language(QueryType.PPL) .catalog("opensearch", testSchema) .defaultNamespace("opensearch") .build(); + UnifiedQueryPlanner planner = new UnifiedQueryPlanner(context); assertNotNull("Plan should be created", planner.plan("source = opensearch.employees")); assertNotNull("Plan should be created", planner.plan("source = employees")); @@ -54,12 +58,13 @@ public void testPPLQueryPlanningWithDefaultNamespace() { @Test public void testPPLQueryPlanningWithDefaultNamespaceMultiLevel() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() + UnifiedQueryContext context = + UnifiedQueryContext.builder() .language(QueryType.PPL) .catalog("catalog", testDeepSchema) .defaultNamespace("catalog.opensearch") .build(); + UnifiedQueryPlanner planner = new UnifiedQueryPlanner(context); assertNotNull("Plan should be created", planner.plan("source = catalog.opensearch.employees")); assertNotNull("Plan should be created", planner.plan("source = employees")); @@ -71,12 +76,13 @@ public void testPPLQueryPlanningWithDefaultNamespaceMultiLevel() { @Test public void testPPLQueryPlanningWithMultipleCatalogs() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() + UnifiedQueryContext context = + UnifiedQueryContext.builder() .language(QueryType.PPL) .catalog("catalog1", testSchema) .catalog("catalog2", testSchema) .build(); + UnifiedQueryPlanner planner = new UnifiedQueryPlanner(context); RelNode plan = planner.plan( @@ -86,73 +92,27 @@ public void testPPLQueryPlanningWithMultipleCatalogs() { @Test public void testPPLQueryPlanningWithMultipleCatalogsAndDefaultNamespace() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() + UnifiedQueryContext context = + UnifiedQueryContext.builder() .language(QueryType.PPL) .catalog("catalog1", testSchema) .catalog("catalog2", testSchema) .defaultNamespace("catalog2") .build(); + UnifiedQueryPlanner planner = new UnifiedQueryPlanner(context); RelNode plan = planner.plan("source = catalog1.employees | lookup employees id | eval f = abs(id)"); assertNotNull("Plan should be created with multiple catalogs", plan); } - @Test - public void testPPLQueryPlanningWithMetadataCaching() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() - .language(QueryType.PPL) - .catalog("opensearch", testSchema) - .cacheMetadata(true) - .build(); - - RelNode plan = planner.plan("source = opensearch.employees"); - assertNotNull("Plan should be created", plan); - } - - @Test(expected = NullPointerException.class) - public void testMissingQueryLanguage() { - UnifiedQueryPlanner.builder().catalog("opensearch", testSchema).build(); - } - - @Test(expected = IllegalArgumentException.class) - public void testUnsupportedQueryLanguage() { - UnifiedQueryPlanner.builder() - .language(QueryType.SQL) // only PPL is supported for now - .catalog("opensearch", testSchema) - .build(); - } - - @Test(expected = IllegalArgumentException.class) - public void testInvalidDefaultNamespacePath() { - UnifiedQueryPlanner.builder() - .language(QueryType.PPL) - .catalog("opensearch", testSchema) - .defaultNamespace("nonexistent") // nonexistent namespace path - .build(); - } - @Test(expected = IllegalStateException.class) public void testUnsupportedStatementType() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() - .language(QueryType.PPL) - .catalog("opensearch", testSchema) - .build(); - - planner.plan("explain source = employees"); // explain statement + planner.plan("explain source = catalog.employees"); // explain statement } @Test(expected = SyntaxCheckException.class) public void testPlanPropagatingSyntaxCheckException() { - UnifiedQueryPlanner planner = - UnifiedQueryPlanner.builder() - .language(QueryType.PPL) - .catalog("opensearch", testSchema) - .build(); - - planner.plan("source = employees | eval"); // Trigger syntax error from parser + planner.plan("source = catalog.employees | eval"); // Trigger syntax error from parser } } diff --git a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryTestBase.java b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryTestBase.java index f63bfed09ec..6064e3d768f 100644 --- a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryTestBase.java +++ b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryTestBase.java @@ -22,7 +22,10 @@ public abstract class UnifiedQueryTestBase { /** Test schema containing sample tables for testing */ protected AbstractSchema testSchema; - /** Unified query planner configured with test schema */ + /** Unified query context configured with test schema */ + protected UnifiedQueryContext context; + + /** Unified query planner configured with test context */ protected UnifiedQueryPlanner planner; @Before @@ -35,12 +38,12 @@ protected Map getTableMap() { } }; - planner = - UnifiedQueryPlanner.builder() + context = + UnifiedQueryContext.builder() .language(QueryType.PPL) .catalog("catalog", testSchema) - .defaultNamespace("catalog") .build(); + planner = new UnifiedQueryPlanner(context); } protected Table createEmployeesTable() { diff --git a/api/src/test/java/org/opensearch/sql/api/transpiler/UnifiedQueryTranspilerTest.java b/api/src/test/java/org/opensearch/sql/api/transpiler/UnifiedQueryTranspilerTest.java index f0ad4133c92..ebec4da7ed5 100644 --- a/api/src/test/java/org/opensearch/sql/api/transpiler/UnifiedQueryTranspilerTest.java +++ b/api/src/test/java/org/opensearch/sql/api/transpiler/UnifiedQueryTranspilerTest.java @@ -26,7 +26,7 @@ public void setUp() { @Test public void testToSql() { - String pplQuery = "source = employees"; + String pplQuery = "source = catalog.employees"; RelNode plan = planner.plan(pplQuery); String actualSql = transpiler.toSql(plan); @@ -37,7 +37,7 @@ public void testToSql() { @Test public void testToSqlWithCustomDialect() { - String pplQuery = "source = employees | where name = 123"; + String pplQuery = "source = catalog.employees | where name = 123"; RelNode plan = planner.plan(pplQuery); UnifiedQueryTranspiler customTranspiler =