Skip to content

Commit 6da727a

Browse files
committed
Merge remote-tracking branch 'upstream/main' into issues/4836
Signed-off-by: Lantao Jin <ltjin@amazon.com>
2 parents 9919d68 + 52fe8aa commit 6da727a

116 files changed

Lines changed: 1521 additions & 749 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.coderabbit.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
2+
3+
# CodeRabbit Configuration for OpenSearch SQL Project
4+
# This configuration uses .rules/REVIEW_GUIDELINES.md for code review standards
5+
6+
language: "en-US"
7+
early_access: false
8+
9+
reviews:
10+
profile: "chill"
11+
request_changes_workflow: false
12+
high_level_summary: true
13+
high_level_summary_placeholder: "@coderabbitai summary"
14+
poem: false # Keep reviews professional and concise
15+
review_status: true
16+
collapse_walkthrough: false
17+
18+
auto_review:
19+
enabled: false # Disabled auto-review until it becomes stable
20+
auto_incremental_review: false
21+
drafts: false # Don't review draft PRs
22+
ignore_title_keywords:
23+
- "WIP"
24+
- "DO NOT MERGE"
25+
- "DRAFT"
26+
27+
# Path-specific review instructions
28+
path_instructions:
29+
- path: "**/*.java"
30+
instructions: |
31+
- Verify Java naming conventions (PascalCase for classes, camelCase for methods/variables)
32+
- Check for proper JavaDoc on public classes and methods
33+
- Flag redundant comments that restate obvious code
34+
- Ensure methods are under 20 lines with single responsibility
35+
- Verify proper error handling with specific exception types
36+
- Check for Optional<T> usage instead of null returns
37+
- Validate proper use of try-with-resources for resource management
38+
39+
- path: "**/test/**/*.java"
40+
instructions: |
41+
- Verify test coverage for new business logic
42+
- Check test naming follows conventions (*Test.java for unit, *IT.java for integration)
43+
- Ensure tests are independent and don't rely on execution order
44+
- Validate meaningful test data that reflects real-world scenarios
45+
- Check for proper cleanup of test resources
46+
47+
- path: "integ-test/**/*IT.java"
48+
instructions: |
49+
- Verify integration tests are in correct module (integ-test/)
50+
- Check tests can be run with ./gradlew :integ-test:integTest
51+
- Ensure proper test data setup and teardown
52+
- Validate end-to-end scenario coverage
53+
54+
- path: "**/ppl/**/*.java"
55+
instructions: |
56+
- For PPL parser changes, verify grammar tests with positive/negative cases
57+
- Check AST generation for new syntax
58+
- Ensure corresponding AST builder classes are updated
59+
- Validate edge cases and boundary conditions
60+
61+
- path: "**/calcite/**/*.java"
62+
instructions: |
63+
- Follow existing patterns in CalciteRelNodeVisitor and CalciteRexNodeVisitor
64+
- Verify SQL generation and optimization paths
65+
- Document any Calcite-specific workarounds
66+
- Test compatibility with Calcite version constraints
67+
68+
chat:
69+
auto_reply: true
70+
71+
# Knowledge base configuration
72+
knowledge_base:
73+
# Don't opt out - use knowledge base features
74+
opt_out: false
75+
76+
# Code guidelines - reference our custom review guidelines
77+
code_guidelines:
78+
enabled: true
79+
filePatterns:
80+
# Reference our custom review guidelines
81+
- ".rules/REVIEW_GUIDELINES.md"
82+
83+
# Enable web search for additional context
84+
web_search:
85+
enabled: true
86+
87+
# Use repository-specific learnings for this project
88+
learnings:
89+
scope: "local"
90+
91+
# Use repository-specific issues
92+
issues:
93+
scope: "local"
94+
95+
# Use repository-specific pull requests for context
96+
pull_requests:
97+
scope: "local"

.rules/REVIEW_GUIDELINES.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Code Review Guidelines for OpenSearch SQL
2+
3+
This document provides guidelines for code reviews in the OpenSearch SQL project. These guidelines are used by CodeRabbit AI for automated code reviews and serve as a reference for human reviewers.
4+
5+
## Core Review Principles
6+
7+
### Code Quality
8+
- **Simplicity First**: Prefer simpler solutions unless there's significant functional or performance degradation
9+
- **Self-Documenting Code**: Code should be clear through naming and structure, not comments
10+
- **No Redundant Comments**: Avoid comments that merely restate what the code does
11+
- **Concise Implementation**: Keep code, docs, and notes short and focused on essentials
12+
13+
### Java Standards
14+
- **Naming Conventions**:
15+
- Classes: `PascalCase` (e.g., `QueryExecutor`)
16+
- Methods/Variables: `camelCase` (e.g., `executeQuery`)
17+
- Constants: `UPPER_SNAKE_CASE` (e.g., `MAX_RETRY_COUNT`)
18+
- **Method Size**: Keep methods under 20 lines with single responsibility
19+
- **JavaDoc Required**: All public classes and methods must have proper JavaDoc
20+
- **Error Handling**: Use specific exception types with meaningful messages
21+
- **Null Safety**: Prefer `Optional<T>` for nullable returns
22+
23+
### Testing Requirements
24+
- **Test Coverage**: All new business logic requires unit tests
25+
- **Integration Tests**: End-to-end scenarios need integration tests in `integ-test/` module
26+
- **Test Execution**: Verify changes with `./gradlew :integ-test:integTest`
27+
- **No Failing Tests**: All tests must pass before merge; fix or ask for guidance if blocked
28+
29+
### Code Organization
30+
- **Single Responsibility**: Each class should have one clear purpose
31+
- **Package Structure**: Follow existing module organization (core, ppl, sql, opensearch)
32+
- **Separation of Concerns**: Keep parsing, execution, and storage logic separate
33+
- **Composition Over Inheritance**: Prefer composition for code reuse
34+
35+
### Performance & Security
36+
- **Efficient Loops**: Avoid unnecessary object creation in loops
37+
- **String Handling**: Use `StringBuilder` for concatenation in loops
38+
- **Input Validation**: Validate all user inputs, especially queries
39+
- **Logging Safety**: Sanitize data before logging to prevent injection
40+
- **Resource Management**: Use try-with-resources for proper cleanup
41+
42+
## Review Focus Areas
43+
44+
### What to Check
45+
1. **Code Clarity**: Is the code self-explanatory?
46+
2. **Test Coverage**: Are there adequate tests?
47+
3. **Error Handling**: Are errors handled appropriately?
48+
4. **Documentation**: Is JavaDoc complete and accurate?
49+
5. **Performance**: Are there obvious performance issues?
50+
6. **Security**: Are inputs validated and sanitized?
51+
52+
### What to Flag
53+
- Redundant or obvious comments
54+
- Methods longer than 20 lines
55+
- Missing JavaDoc on public APIs
56+
- Generic exception handling
57+
- Unused imports or dead code
58+
- Hard-coded values that should be constants
59+
- Missing or inadequate test coverage
60+
61+
### What to Encourage
62+
- Clear, descriptive naming
63+
- Proper use of Java idioms
64+
- Comprehensive test coverage
65+
- Meaningful error messages
66+
- Efficient algorithms and data structures
67+
- Security-conscious coding practices
68+
69+
## Project-Specific Guidelines
70+
71+
### OpenSearch SQL Context
72+
- **JDK 21**: Required for development
73+
- **Java 11 Compatibility**: Maintain when possible for OpenSearch 2.x
74+
- **Module Structure**: Respect existing module boundaries
75+
- **Integration Tests**: Use `./gradlew :integ-test:integTest` for testing
76+
- **Test Naming**: `*IT.java` for integration tests, `*Test.java` for unit tests
77+
78+
### PPL Parser Changes
79+
- Test new grammar rules with positive and negative cases
80+
- Verify AST generation for new syntax
81+
- Include edge cases and boundary conditions
82+
- Update corresponding AST builder classes
83+
84+
### Calcite Integration
85+
- If the PR is for PPL command, refer docs/dev/ppl-commands.md and verify the PR satisfy the checklist.
86+
- Follow existing patterns in `CalciteRelNodeVisitor` and `CalciteRexNodeVisitor`
87+
- Test SQL generation and optimization paths
88+
- Document Calcite-specific workarounds

async-query/src/main/java/org/opensearch/sql/spark/scheduler/job/ScheduledAsyncQueryJobRunner.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import org.opensearch.jobscheduler.spi.ScheduledJobParameter;
1313
import org.opensearch.jobscheduler.spi.ScheduledJobRunner;
1414
import org.opensearch.plugins.Plugin;
15-
import org.opensearch.sql.legacy.executor.AsyncRestExecutor;
1615
import org.opensearch.sql.spark.asyncquery.AsyncQueryExecutorService;
1716
import org.opensearch.sql.spark.asyncquery.model.NullAsyncQueryRequestContext;
1817
import org.opensearch.sql.spark.rest.model.CreateAsyncQueryRequest;
@@ -21,6 +20,8 @@
2120
import org.opensearch.threadpool.ThreadPool;
2221
import org.opensearch.transport.client.Client;
2322

23+
import static org.opensearch.sql.opensearch.executor.OpenSearchQueryManager.SQL_WORKER_THREAD_POOL_NAME;
24+
2425
/**
2526
* The job runner class for scheduling async query.
2627
*
@@ -37,7 +38,7 @@
3738
public class ScheduledAsyncQueryJobRunner implements ScheduledJobRunner {
3839
// Share SQL plugin thread pool
3940
private static final String ASYNC_QUERY_THREAD_POOL_NAME =
40-
AsyncRestExecutor.SQL_WORKER_THREAD_POOL_NAME;
41+
SQL_WORKER_THREAD_POOL_NAME;
4142
private static final Logger LOGGER = LogManager.getLogger(ScheduledAsyncQueryJobRunner.class);
4243

4344
private static final ScheduledAsyncQueryJobRunner INSTANCE = new ScheduledAsyncQueryJobRunner();

async-query/src/test/java/org/opensearch/sql/spark/scheduler/job/ScheduledAsyncQueryJobRunnerTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import static org.mockito.Mockito.spy;
1616
import static org.mockito.Mockito.verify;
1717
import static org.mockito.Mockito.when;
18+
import static org.opensearch.sql.opensearch.executor.OpenSearchQueryManager.SQL_WORKER_THREAD_POOL_NAME;
1819

1920
import java.time.Instant;
2021
import org.apache.logging.log4j.LogManager;
@@ -87,7 +88,7 @@ public void testRunJobWithCorrectParameter() {
8788
spyJobRunner.runJob(request, context);
8889

8990
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
90-
verify(threadPool.executor(AsyncRestExecutor.SQL_WORKER_THREAD_POOL_NAME))
91+
verify(threadPool.executor(SQL_WORKER_THREAD_POOL_NAME))
9192
.submit(captor.capture());
9293

9394
Runnable runnable = captor.getValue();
@@ -145,7 +146,7 @@ public void testDoRefreshThrowsException() {
145146
spyJobRunner.runJob(request, context);
146147

147148
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
148-
verify(threadPool.executor(AsyncRestExecutor.SQL_WORKER_THREAD_POOL_NAME))
149+
verify(threadPool.executor(SQL_WORKER_THREAD_POOL_NAME))
149150
.submit(captor.capture());
150151

151152
Runnable runnable = captor.getValue();

common/src/main/java/org/opensearch/sql/common/setting/Settings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public enum Key {
2525

2626
/** PPL Settings. */
2727
PPL_ENABLED("plugins.ppl.enabled"),
28+
PPL_QUERY_TIMEOUT("plugins.ppl.query.timeout"),
2829
PATTERN_METHOD("plugins.ppl.pattern.method"),
2930
PATTERN_MODE("plugins.ppl.pattern.mode"),
3031
PATTERN_MAX_SAMPLE_COUNT("plugins.ppl.pattern.max.sample.count"),

core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
import org.opensearch.sql.ast.tree.UnresolvedPlan;
144144
import org.opensearch.sql.ast.tree.Values;
145145
import org.opensearch.sql.ast.tree.Window;
146+
import org.opensearch.sql.calcite.plan.AliasFieldsWrappable;
146147
import org.opensearch.sql.calcite.plan.LogicalSystemLimit;
147148
import org.opensearch.sql.calcite.plan.LogicalSystemLimit.SystemLimitType;
148149
import org.opensearch.sql.calcite.plan.OpenSearchConstants;
@@ -196,7 +197,11 @@ public RelNode visitRelation(Relation node, CalcitePlanContext context) {
196197
throw new CalciteUnsupportedException("information_schema is unsupported in Calcite");
197198
}
198199
context.relBuilder.scan(node.getTableQualifiedName().getParts());
199-
return context.relBuilder.peek();
200+
RelNode scan = context.relBuilder.peek();
201+
if (scan instanceof AliasFieldsWrappable) {
202+
return ((AliasFieldsWrappable) scan).wrapProjectForAliasFields(context.relBuilder);
203+
}
204+
return scan;
200205
}
201206

202207
// This is a tool method to add an existed RelOptTable to builder stack, not used for now
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.calcite.plan;
7+
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.Map.Entry;
11+
import java.util.Set;
12+
import org.apache.calcite.rel.RelNode;
13+
import org.apache.calcite.rex.RexNode;
14+
import org.apache.calcite.tools.RelBuilder;
15+
16+
/**
17+
* Wrapper for TableScan to add alias fields by creating another project with alias upon on it. This
18+
* allows TableScan or Table to emit alias type fields in its schema, while it still supports
19+
* resolving these fields used in the query.
20+
*/
21+
public interface AliasFieldsWrappable {
22+
23+
Map<String, String> getAliasMapping();
24+
25+
default RelNode wrapProjectForAliasFields(RelBuilder relBuilder) {
26+
assert relBuilder.peek() instanceof AliasFieldsWrappable
27+
: "The top node in RelBuilder must be AliasFieldsWrappable";
28+
Set<Entry<String, String>> aliasFieldsSet = this.getAliasMapping().entrySet();
29+
// Adding alias referring to the original field.
30+
List<RexNode> aliasFieldsNew =
31+
aliasFieldsSet.stream()
32+
.map(entry -> relBuilder.alias(relBuilder.field(entry.getValue()), entry.getKey()))
33+
.toList();
34+
return relBuilder.projectPlus(aliasFieldsNew).peek();
35+
}
36+
}

core/src/main/java/org/opensearch/sql/calcite/type/ExprJavaType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
/**
1616
* The JavaType for ExprUDT. The UDT which needs to use self-implemented java class should extend
17-
* this.
17+
* this. Its javaClazz should override equals() and hashCode() methods. For example, {@link
18+
* org.opensearch.sql.data.model.ExprIpValue} (javaClazz of {@link ExprIPType}) overrides the
19+
* equals() and hashCode().
1820
*/
1921
public class ExprJavaType extends AbstractExprRelDataType<JavaType> {
2022
public ExprJavaType(OpenSearchTypeFactory typeFactory, ExprUDT exprUDT, Class<?> javaClazz) {

core/src/main/java/org/opensearch/sql/calcite/utils/OpenSearchTypeFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ public static RelDataType convertSchema(Table table) {
313313
Map<String, ExprType> fieldTypes = new LinkedHashMap<>(table.getFieldTypes());
314314
fieldTypes.putAll(table.getReservedFieldTypes());
315315
for (Entry<String, ExprType> entry : fieldTypes.entrySet()) {
316+
// skip alias type fields when constructing schema
317+
if (entry.getValue().getOriginalPath().isPresent()) continue;
316318
fieldNameList.add(entry.getKey());
317319
typeList.add(OpenSearchTypeFactory.convertExprTypeToRelDataType(entry.getValue()));
318320
}

core/src/main/java/org/opensearch/sql/data/model/ExprIpValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
package org.opensearch.sql.data.model;
77

88
import inet.ipaddr.IPAddress;
9+
import lombok.EqualsAndHashCode;
910
import org.opensearch.sql.data.type.ExprCoreType;
1011
import org.opensearch.sql.data.type.ExprType;
1112
import org.opensearch.sql.utils.IPUtils;
1213

1314
/** Expression IP Address Value. */
15+
@EqualsAndHashCode(callSuper = false)
1416
public class ExprIpValue extends AbstractExprValue {
1517
private final IPAddress value;
1618

0 commit comments

Comments
 (0)