-
Notifications
You must be signed in to change notification settings - Fork 181
Use Calcite's validation system for type checking & coercion #4892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1e04df1
229cb1d
b529a35
34b2435
e6e01c8
15e0bef
a1f2f42
7f999df
39e208a
55e8486
dc44f8c
a4dfd3f
9deca8b
11c33ba
a4b0d72
c237041
51c556f
dc3bc41
09f45e7
a30fa3a
a588864
4cd7570
dcb3b8f
c230765
8200cf7
4abc31e
0269692
0118313
4adfa98
4838c4c
545ed04
1aea9e3
9f369b0
9bffce8
96801c6
c3bde24
15f17b3
9b9c07a
443d81e
e1bab21
6a7feae
2d36650
23e611a
6286e90
0736444
53a4118
7f52976
c4de0e4
0667fa7
485c038
d19ba53
330a4e5
f5fda25
657cc6a
b030f41
8caa594
975d21c
bc38f9f
502dbb0
34985c7
c660a69
d9b1453
90b6309
ea06ab0
e548ad2
94c7f33
bab48d7
6a30697
0be7cb4
38e12c6
0990db1
d0195cb
9f6dcd7
d455d35
a2d1955
4a98c3a
aff8541
229ddb7
e6b80e5
cb78ea7
69a2d01
d722baf
d513e17
ff91bdc
32c407b
a6839e2
38ef160
42b89f0
9ecc8ff
907b292
35ac017
7418cda
ebfdffd
8d561a0
fd6251e
f34619a
31dc650
19faa38
1582966
3584c7c
568fc00
6d291b8
199546a
0d299b5
78051d6
3443fae
f70bc97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,9 +44,12 @@ | |
| import java.util.stream.IntStream; | ||
| import java.util.stream.Stream; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.NonNull; | ||
| import org.apache.calcite.adapter.enumerable.RexToLixTranslator; | ||
| import org.apache.calcite.plan.RelOptTable; | ||
| import org.apache.calcite.plan.ViewExpanders; | ||
| import org.apache.calcite.rel.RelCollation; | ||
| import org.apache.calcite.rel.RelFieldCollation; | ||
| import org.apache.calcite.rel.RelNode; | ||
| import org.apache.calcite.rel.core.Aggregate; | ||
| import org.apache.calcite.rel.core.JoinRelType; | ||
|
|
@@ -57,10 +60,14 @@ | |
| import org.apache.calcite.rex.RexBuilder; | ||
| import org.apache.calcite.rex.RexCall; | ||
| import org.apache.calcite.rex.RexCorrelVariable; | ||
| import org.apache.calcite.rex.RexFieldCollation; | ||
| import org.apache.calcite.rex.RexInputRef; | ||
| import org.apache.calcite.rex.RexLiteral; | ||
| import org.apache.calcite.rex.RexNode; | ||
| import org.apache.calcite.rex.RexOver; | ||
| import org.apache.calcite.rex.RexShuttle; | ||
| import org.apache.calcite.rex.RexVisitorImpl; | ||
| import org.apache.calcite.rex.RexWindow; | ||
| import org.apache.calcite.rex.RexWindowBounds; | ||
| import org.apache.calcite.sql.SqlKind; | ||
| import org.apache.calcite.sql.fun.SqlLibraryOperators; | ||
|
|
@@ -740,8 +747,8 @@ public RelNode visitTranspose( | |
| .map( | ||
| f -> | ||
| Map.entry( | ||
| ImmutableList.of(rx.makeLiteral(f)), | ||
| ImmutableList.of((RexNode) rx.makeCast(varchar, b.field(f), true)))) | ||
| ImmutableList.of((RexLiteral) rx.makeLiteral(f, varchar, true)), | ||
| ImmutableList.of(rx.makeCast(varchar, b.field(f), true, true)))) | ||
| .collect(Collectors.toList())); | ||
|
|
||
| // Step 3: Trim spaces from columnName column before pivot | ||
|
|
@@ -1808,6 +1815,7 @@ public RelNode visitStreamWindow(StreamWindow node, CalcitePlanContext context) | |
| // Default: first get rawExpr | ||
| List<RexNode> overExpressions = | ||
| node.getWindowFunctionList().stream().map(w -> rexVisitor.analyze(w, context)).toList(); | ||
| overExpressions = embedExistingCollationsIntoOver(overExpressions, context); | ||
|
|
||
| if (hasGroup) { | ||
| // only build sequence when there is by condition | ||
|
|
@@ -1849,6 +1857,84 @@ public RelNode visitStreamWindow(StreamWindow node, CalcitePlanContext context) | |
| return context.relBuilder.peek(); | ||
| } | ||
|
|
||
| /** | ||
| * Embed existing collation into window function's over clauses. | ||
| * | ||
| * <p>Window functions with frame specifications like {@code ROWS n PRECEDING} require ORDER BY to | ||
| * determine row order. Without it, results are non-deterministic. | ||
| * | ||
| * <p>Without this fix, the initial plan has ORDER BY separate from window functions: | ||
| * | ||
| * <pre> | ||
| * LogicalProject(SUM($5) OVER (ROWS 1 PRECEDING)) ← Missing ORDER BY | ||
| * LogicalSort(sort0=[$5]) | ||
| * </pre> | ||
| * | ||
| * <p>This causes problems during validation as the order is not bound to the window. With this | ||
| * fix, sort collations are embeded into each {@code RexOver} window: | ||
| * | ||
| * <pre> | ||
| * LogicalProject(SUM($5) OVER (ORDER BY $5 ROWS 1 PRECEDING)) ← ORDER BY embedded | ||
| * </pre> | ||
| * | ||
| * @param overExpressions Window function expressions (may contain nested {@link RexOver}) | ||
| * @param context Plan context for building RexNodes | ||
| * @return Expressions with ORDER BY embedded in all window specifications | ||
| */ | ||
| private List<RexNode> embedExistingCollationsIntoOver( | ||
|
Comment on lines
+1861
to
+1884
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this changes fix the issue #5004? |
||
| List<RexNode> overExpressions, CalcitePlanContext context) { | ||
| RelCollation existingCollation = context.relBuilder.peek().getTraitSet().getCollation(); | ||
| List<@NonNull RelFieldCollation> relCollations = | ||
| existingCollation == null ? List.of() : existingCollation.getFieldCollations(); | ||
| ImmutableList<@NonNull RexFieldCollation> rexCollations = | ||
| relCollations.stream() | ||
| .map(f -> relCollationToRexCollation(f, context.relBuilder)) | ||
| .collect(ImmutableList.toImmutableList()); | ||
| return overExpressions.stream() | ||
| .map( | ||
| n -> | ||
| n.accept( | ||
| new RexShuttle() { | ||
| @Override | ||
| public RexNode visitOver(RexOver over) { | ||
| RexWindow window = over.getWindow(); | ||
| return context.rexBuilder.makeOver( | ||
| over.getType(), | ||
| over.getAggOperator(), | ||
| over.getOperands(), | ||
| window.partitionKeys, | ||
| rexCollations, | ||
| window.getLowerBound(), | ||
| window.getUpperBound(), | ||
| window.isRows(), | ||
| true, | ||
| false, | ||
| over.isDistinct(), | ||
| over.ignoreNulls()); | ||
|
Comment on lines
+1899
to
+1913
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's look at the full context around the visitOver method
cat -n core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | sed -n '1880,1930p'Repository: opensearch-project/sql Length of output: 2823 🏁 Script executed: # Search for where rexCollations is defined in the visitOver context
grep -n "rexCollations" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | head -20Repository: opensearch-project/sql Length of output: 180 🏁 Script executed: # Look for the broader method context to understand how rexCollations is populated
ast-grep --pattern 'visitOver($$$) {
$$$
}'Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: # Search for RexWindow.orderKeys references
rg "window\.orderKeys" core/src/main/java/org/opensearch/sql/calcite/Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: # Search for RexWindow creation or usage patterns
rg "RexWindow" core/src/main/java/org/opensearch/sql/calcite/ -A 3 -B 1Repository: opensearch-project/sql Length of output: 14719 🏁 Script executed: # Look for similar patterns of window handling elsewhere in the file
rg "makeOver\(" core/src/main/java/org/opensearch/sql/calcite/ -B 5 -A 5Repository: opensearch-project/sql Length of output: 12259 🏁 Script executed: # Check if there are any imports or usage of RexWindow that show field names
grep -n "import.*RexWindow\|RexWindow\." core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.javaRepository: opensearch-project/sql Length of output: 159 🏁 Script executed: # Search for window.orderKeys usage in the codebase
rg "\.orderKeys" core/src/main/java/ -t javaRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: # Search for window field access patterns
rg "window\.(partition|order|collation)" core/src/main/java/ -t javaRepository: opensearch-project/sql Length of output: 188 🏁 Script executed: # Check pom.xml for Calcite version
cat pom.xml | grep -A 2 "calcite" | head -20Repository: opensearch-project/sql Length of output: 105 🌐 Web query:
💡 Result: In
Each element (
Convenience accessors on
Sources: [1] [2] 🏁 Script executed: # Search for RexBuilder.makeOver method to see its signature
rg "makeOver\(" --type java -B 2 -A 8 | head -100Repository: opensearch-project/sql Length of output: 10225 🏁 Script executed: # Look for patterns where window.orderKeys is checked or used
find . -name "*.java" -type f | xargs grep -l "orderKeys" 2>/dev/null | head -10Repository: opensearch-project/sql Length of output: 322 🏁 Script executed: # Search for the method name "embedExistingCollationsIntoOver" and surrounding context
rg "embedExistingCollationsIntoOver" -B 5 -A 30Repository: opensearch-project/sql Length of output: 8562 🌐 Web query:
💡 Result: In Apache Calcite, Signature (current javadocAggregate): Older/shorter overload (no So the relevant order is: Preserve existing window ORDER BY when embedding plan collations. The 🛠️ Suggested fix- return context.rexBuilder.makeOver(
+ ImmutableList<@NonNull RexFieldCollation> orderKeys =
+ window.orderKeys.isEmpty() ? rexCollations : window.orderKeys;
+ return context.rexBuilder.makeOver(
over.getType(),
over.getAggOperator(),
over.getOperands(),
window.partitionKeys,
- rexCollations,
+ orderKeys,
window.getLowerBound(),
window.getUpperBound(),
window.isRows(),
true,
false,
over.isDistinct(),
over.ignoreNulls());🤖 Prompt for AI Agents |
||
| } | ||
| })) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
Comment on lines
+1860
to
+1917
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Search for RexOver class definition and its methods
rg -n "class RexOver" --type=javaRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Search for makeOver method signature to understand all parameters
rg -n "makeOver\(" --type=java -A 10 | grep -E "makeOver|allowPartial|nullWhenCountZero" | head -50Repository: opensearch-project/sql Length of output: 1319 🏁 Script executed: #!/bin/bash
# Check if RexOver has getters for allowPartial or isNullWhenCountZero
rg -n "getAllowPartial|getNullWhenCountZero|isAllowPartial|isNullWhenCountZero|allowPartial|nullWhenCountZero" --type=java | head -40Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Look at the specific method implementation in CalciteRelNodeVisitor
sed -n '1860,1917p' core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.javaRepository: opensearch-project/sql Length of output: 2631 🏁 Script executed: #!/bin/bash
# Check PlanUtils.makeOver method signature and implementation
sed -n '157,200p' core/src/main/java/org/opensearch/sql/calcite/utils/PlanUtils.javaRepository: opensearch-project/sql Length of output: 2000 🏁 Script executed: #!/bin/bash
# Compare other makeOver calls to see parameter patterns
rg -B2 -A12 "rexBuilder.makeOver|PlanUtils.makeOver" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | head -80Repository: opensearch-project/sql Length of output: 2920 🏁 Script executed: #!/bin/bash
# Check ExtendedRelJson.java usage of makeOver (line 448) for reference
sed -n '440,465p' opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/ExtendedRelJson.javaRepository: opensearch-project/sql Length of output: 1011 🏁 Script executed: #!/bin/bash
# Search for methods called on RexOver objects to see what properties are available
rg -n "over\." core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "over\.[a-zA-Z]+" | head -30Repository: opensearch-project/sql Length of output: 395 🏁 Script executed: #!/bin/bash
# Check if there are imports or references to Calcite's RexOver methods
rg -n "isAllowPartial|isNullWhenCountZero|allowPartial|nullWhenCountZero" core/src/main/java/ opensearch/src/main/java/Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Look at the Calcite version constraints to understand API compatibility
cat pom.xml | grep -A 5 -B 5 "calcite" | head -50Repository: opensearch-project/sql Length of output: 105 🏁 Script executed: #!/bin/bash
# Check if there's any documentation or comments about makeOver parameters
rg -B5 "makeOver" core/src/main/java/org/opensearch/sql/calcite/utils/PlanUtils.java | grep -E "makeOver|//|/\*" | head -40Repository: opensearch-project/sql Length of output: 92 🏁 Script executed: #!/bin/bash
# Search for allowPartial and nullWhenCountZero in the entire codebase
find . -name "*.java" -type f | xargs grep -l "allowPartial\|nullWhenCountZero" 2>/dev/nullRepository: opensearch-project/sql Length of output: 50 🏁 Script executed: #!/bin/bash
# Look at the actual Calcite RexBuilder.makeOver signatures in any comments or docs
rg -B20 "rexBuilder\.makeOver" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "^[0-9]+-.*(\*|makeOver)" | head -40Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Check if other usages in the codebase try to preserve these values from source RexOver
rg -B5 -A15 "makeOver.*over\." core/src/main/java/org/opensearch/sql/calcite/ | grep -E "over\.|makeOver|allowPartial|nullWhenCountZero" | head -50Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Look for the full PlanUtils method to see the sumOver and countOver helper functions
sed -n '157,300p' core/src/main/java/org/opensearch/sql/calcite/utils/PlanUtils.javaRepository: opensearch-project/sql Length of output: 5371 🏁 Script executed: #!/bin/bash
# Search for helper methods that might extract these properties from RexOver
rg -n "getallowPartial|getNullWhenCountZero|getAllowPartial|isNullWhenCountZero" --type=javaRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Check if PlanUtils has a method that wraps makeOver calls with parameter handling
sed -n '200,250p' core/src/main/java/org/opensearch/sql/calcite/utils/PlanUtils.javaRepository: opensearch-project/sql Length of output: 1577 🏁 Script executed: #!/bin/bash
# Look for comments or documentation about the makeOver parameters, especially those two
rg -B10 "true.*false" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "(1910|1911|true|false|allow|null|makeOver)" | head -30Repository: opensearch-project/sql Length of output: 546 🏁 Script executed: #!/bin/bash
# Check what Calcite version this project uses - may help understand the API
find . -name "pom.xml" -type f | xargs grep -h "calcite" | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Look at all pom.xml files in the repo to find Calcite version
find . -type f -name "pom.xml" | xargs grep -l "calcite" | head -5Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Check the gradle files if any
find . -type f -name "build.gradle" -o -name "build.gradle.kts" | xargs grep -l "calcite" 2>/dev/null | head -5Repository: opensearch-project/sql Length of output: 175 🏁 Script executed: #!/bin/bash
# Search for RexBuilder in imports to understand which Calcite version is used
rg -n "import.*RexBuilder|import.*RexOver" --type=java | head -20Repository: opensearch-project/sql Length of output: 2761 🏁 Script executed: #!/bin/bash
# Look at the complete line context for the makeOver call to see if there are inline comments
sed -n '1895,1920p' core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.javaRepository: opensearch-project/sql Length of output: 1128 🏁 Script executed: #!/bin/bash
# Check the core build.gradle for Calcite version
sed -n '1,100p' core/build.gradle | grep -i calciteRepository: opensearch-project/sql Length of output: 168 🏁 Script executed: #!/bin/bash
# Look for any usage of RexStandardizer which imports RexOver
sed -n '1,150p' opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/RexStandardizer.java | head -80Repository: opensearch-project/sql Length of output: 3279 🏁 Script executed: #!/bin/bash
# Search for how RexOver is used elsewhere in the codebase to understand available methods
rg -A5 "visitOver|RexOver" core/src/main/java/org/opensearch/sql/calcite/ | grep -E "over\.|RexOver" | head -40Repository: opensearch-project/sql Length of output: 1447 🏁 Script executed: #!/bin/bash
# Search for tests of embedExistingCollationsIntoOver
rg -n "embedExistingCollationsIntoOver" --type=javaRepository: opensearch-project/sql Length of output: 359 🏁 Script executed: #!/bin/bash
# Check what parameters RexBuilder.makeOver accepts in Calcite 1.41.0
# by looking at all makeOver invocations with their parameter counts
rg -A20 "\.makeOver\(" core/src/main/java/org/opensearch/sql/calcite/ | grep -E "makeOver\(|,\s*\)|over\.|window\." | head -60Repository: opensearch-project/sql Length of output: 2140 🏁 Script executed: #!/bin/bash
# Look for any documentation or comments about what allowPartial and isNullWhenCountZero mean
rg -B5 -A5 "allowPartial|nullWhenCountZero" . --type=java 2>/dev/null | head -40Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Check if RexOver provides any getter methods beyond what we've already seen
rg -n "over\.get|over\.is" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -v "getWindow\|getType\|getAggOperator\|getOperands\|isDistinct\|ignoreNulls"Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Look more carefully at the exact makeOver signature by checking line counts
sed -n '1901,1913p' core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | cat -nRepository: opensearch-project/sql Length of output: 766 🏁 Script executed: #!/bin/bash
# Check if there's an exclude parameter being used elsewhere
rg -n "RexWindowExclusion\|getExclude" --type=java | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Count the parameters in the ExtendedRelJson makeOver call more carefully
sed -n '448,465p' opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/ExtendedRelJson.java | cat -nRepository: opensearch-project/sql Length of output: 814 🏁 Script executed: #!/bin/bash
# Search for documentation or comments about what parameters 9 and 10 represent
rg -B10 "true,\s*false," core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "^\s*\*|makeOver|true.*false" | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# The two makeOver calls have different signatures. Let's search for documentation or other usages
# to determine which is correct. Check if exclude is a newer addition
rg -n "exclude.*EXCLUDE" --type=java | head -20Repository: opensearch-project/sql Length of output: 218 🏁 Script executed: #!/bin/bash
# Search for RexWindowExclusion usage
rg -n "RexWindowExclusion" --type=javaRepository: opensearch-project/sql Length of output: 1408 🏁 Script executed: #!/bin/bash
# Look at the imports in ExtendedRelJson to see if it uses exclude
head -50 opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/ExtendedRelJson.java | grep -E "import|RexWindow"Repository: opensearch-project/sql Length of output: 1888 🏁 Script executed: #!/bin/bash
# Count total parameters by looking at ExtendedRelJson more carefully with all makeOver calls
rg -B5 -A20 "rexBuilder.makeOver" opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/ExtendedRelJson.java | head -80Repository: opensearch-project/sql Length of output: 1048 🏁 Script executed: #!/bin/bash
# Check what RexWindow exposes - does it have getExclude or similar?
rg -n "window\." core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "window\.(get|is)" | head -20Repository: opensearch-project/sql Length of output: 229 🏁 Script executed: #!/bin/bash
# Compare the parameter order and count: ExtendedRelJson has 13 params, CalciteRelNodeVisitor has 12
# Let's check if window has an exclude field
rg -n "getExclude\|exclusion" --type=java | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Let's look at what the original RexOver contains - does it have exclude info?
rg -B5 -A10 "class RexWindow\|RexWindow(" opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/ExtendedRelJson.java | head -40Repository: opensearch-project/sql Length of output: 170 🏁 Script executed: #!/bin/bash
# Critical: Check if parameter mismatch - ExtendedRelJson has exclude param, CalciteRelNodeVisitor doesn't
# Let's see ALL the parameters being passed to understand the order
echo "=== CalciteRelNodeVisitor version ===" && sed -n '1901,1913p' core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java && echo "" && echo "=== ExtendedRelJson version ===" && sed -n '448,461p' opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/ExtendedRelJson.javaRepository: opensearch-project/sql Length of output: 1204 🏁 Script executed: #!/bin/bash
# This is critical - the parameter lists don't match. Let's see if RexWindow has getExclude
rg -n "\.getExclude|Exclusion" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.javaRepository: opensearch-project/sql Length of output: 223 🏁 Script executed: #!/bin/bash
# Check if RexWindow exposes exclusion information
sed -n '1900,1915p' core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "window\."Repository: opensearch-project/sql Length of output: 264 🏁 Script executed: #!/bin/bash
# Look for RexWindow.getExclude or similar in the whole codebase
rg -n "getExclude" --type=javaRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# The signatures don't match - CalciteRelNodeVisitor is missing the exclude parameter
# Let's verify the exact Calcite RexBuilder.makeOver signature by checking javadoc or other hints
# Search for how many parameters makeOver should have in different contexts
rg -n "makeOver" --type=java -A1 | grep -E "makeOver.*\(" | wc -lRepository: opensearch-project/sql Length of output: 68 🏁 Script executed: #!/bin/bash
# Search online Calcite documentation or check if there's version info about when exclude was added
# For now, let's verify whether window object has exclusion info
rg -n "window\.get|RexWindow\." core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | head -20Repository: opensearch-project/sql Length of output: 179 🏁 Script executed: #!/bin/bash
# Check if there are overloaded versions of makeOver in Calcite
# by looking at how it's being called in different ways
rg -B2 -A15 "rexBuilder\.makeOver" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | head -50Repository: opensearch-project/sql Length of output: 886 🏁 Script executed: #!/bin/bash
# Check the git history to see if this code was recently added or if there's a comment about it
git log --oneline -20 core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java 2>/dev/null | head -20Repository: opensearch-project/sql Length of output: 134 🏁 Script executed: #!/bin/bash
# Search for any TODO or FIXME comments near the embedExistingCollationsIntoOver method
sed -n '1850,1920p' core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -E "TODO|FIXME|BUG|XXX"Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Check if the code compiles without errors by looking for any compilation markers
rg -n "PARAM_MISMATCH|parameter.*mismatch" --type=javaRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: web_search
Apache Calcite 1.41.0 RexBuilder.makeOver method signature parametersRepository: opensearch-project/sql Length of output: 161 🏁 Script executed: #!/bin/bash
# Let's try to use web_search properly with the capability
# For now, check if there are any recent changes or PRs related to this
git log --all --oneline --grep="makeOver\|window\|collation" 2>/dev/null | head -20Repository: opensearch-project/sql Length of output: 1400 🏁 Script executed: #!/bin/bash
# Check if RexWindow has an exclusion getter that should be used
rg -n "RexWindow\|class.*Window" core/src/main/java/org/opensearch/sql/calcite/ --type=java | grep -v ".class" | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Critical check: Does RexWindow from over.getWindow() have an exclusion?
# by checking what RexWindow methods are available
rg -n "over\.getWindow\(\)" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java -A5 | head -30Repository: opensearch-project/sql Length of output: 409 🏁 Script executed: #!/bin/bash
# Let's check if there's a variant of makeOver that takes fewer parameters
# by looking at how PlanUtils helper methods wrap it
sed -n '200,250p' core/src/main/java/org/opensearch/sql/calcite/utils/PlanUtils.java | grep -E "makeOver|relBuilder\."Repository: opensearch-project/sql Length of output: 395 🏁 Script executed: #!/bin/bash
# Critical discovery: the parameter lists differ significantly
# ExtendedRelJson has 14 params, CalciteRelNodeVisitor has 12
# AND ExtendedRelJson includes RexWindowExclusion which is missing from CalciteRelNodeVisitor
# Let's verify if the code even compiles by checking for any build errors
find . -name "*.log" -o -name "*error*" 2>/dev/null | head -10Repository: opensearch-project/sql Length of output: 454 🏁 Script executed: #!/bin/bash
# Let's check the git commit that added embedExistingCollationsIntoOver
git log --all -p --follow -- core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -B20 -A20 "embedExistingCollationsIntoOver" | head -100Repository: opensearch-project/sql Length of output: 152 🏁 Script executed: #!/bin/bash
# Check if there's any test that validates this method works correctly
find . -name "*Test.java" -type f | xargs grep -l "embedExistingCollationsIntoOver\|window.*collation" 2>/dev/nullRepository: opensearch-project/sql Length of output: 50 🏁 Script executed: #!/antml:tool_start
```web_search
Calcite 1.41.0 RexBuilder makeOver signature documentation
```
</tool_start>Repository: opensearch-project/sql Length of output: 267 🏁 Script executed: #!/bin/bash
# Let me check the actual failing scenario more carefully
# The parameter mismatch is concerning - let's see if CalciteRelNodeVisitor was recently modified
git log --all --oneline -5 -- core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.javaRepository: opensearch-project/sql Length of output: 367 🏁 Script executed: #!/bin/bash
# Check the PR that added this method
git log --all -p -- core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java | grep -B50 "embedExistingCollationsIntoOver" | grep "^commit\|^Author\|^Date" | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# The critical issue: parameter 8 in CalciteRelNodeVisitor is window.isRows()
# but in ExtendedRelJson it's exclude (RexWindowExclusion)
# Let's verify what RexBuilder.makeOver actually expects
# by checking if window has an exclusion property
rg -n "getExclusion\|getExclude\|exclusion\|Exclusion" core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.javaRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/antml:thinking_start
Looking at the parameter discrepancy:
CalciteRelNodeVisitor version (12 params):
1. type
2. operator
3. operands
4. partitionKeys
5. orderKeys (as rexCollations)
6. lowerBound
7. upperBound
8. isRows (boolean)
9. true
10. false
11. distinct
12. ignoreNulls
ExtendedRelJson version (13 params):
1. type
2. operator
3. operands
4. partitionKeys
5. orderKeys (as orderKeys)
6. lowerBound
7. upperBound
8. exclude (RexWindowExclusion)
9. physical (boolean)
10. true
11. false
12. distinct
13. false
The issue is clear: CalciteRelNodeVisitor is missing the `exclude` parameter and has the parameter types wrong. Parameter 8 should be RexWindowExclusion, not isRows().
This looks like a genuine bug in the embedExistingCollationsIntoOver method - it's missing the exclude parameter which should come from window.getExclusion() or default to EXCLUDE_NO_OTHER.
Let me search for whether RexWindow has a getExclusion method.
</thinking_start>Repository: opensearch-project/sql Length of output: 241 🏁 Script executed: #!/antml:thinking_endRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/bin/bash
# Check if RexWindow class has getExclusion method by looking at how it's used elsewhere
rg -n "window\.getExclusion|RexWindow" core/src/main/java/org/opensearch/sql/calcite/ --type=java | grep -i "exclusion" | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: #!/antml:thinking_start
The user hasn't provided results yet. Let me think about what I know:
1. ExtendedRelJson passes a RexWindowExclusion parameter to makeOver
2. It gets this from window.get("exclude") or defaults to RexWindowExclusion.EXCLUDE_NO_OTHER
3. CalciteRelNodeVisitor doesn't pass any RexWindowExclusion parameter
4. The parameter at position 8 in CalciteRelNodeVisitor is window.isRows() which seems wrong
This is a real bug - the makeOver signature requires RexWindowExclusion but the code doesn't provide it. The question is whether window.getExclusion() exists or if we need to default to EXCLUDE_NO_OTHER like ExtendedRelJson does.
</thinking_end>Repository: opensearch-project/sql Length of output: 287 Fix missing The The correct order should be:
Add the missing exclude parameter (defaulting to return context.rexBuilder.makeOver(
over.getType(),
over.getAggOperator(),
over.getOperands(),
window.partitionKeys,
rexCollations,
window.getLowerBound(),
window.getUpperBound(),
RexWindowExclusion.EXCLUDE_NO_OTHER, // Add this
window.isRows(),
true,
false,
over.isDistinct(),
over.ignoreNulls());The original concern about preserving 🤖 Prompt for AI Agents |
||
|
|
||
| private static RexFieldCollation relCollationToRexCollation( | ||
| RelFieldCollation relCollation, RelBuilder builder) { | ||
| RexNode fieldRef = builder.field(relCollation.getFieldIndex()); | ||
|
|
||
| // Convert direction flags to SqlKind set | ||
| Set<SqlKind> flags = new HashSet<>(); | ||
| if (relCollation.direction == RelFieldCollation.Direction.DESCENDING | ||
| || relCollation.direction == RelFieldCollation.Direction.STRICTLY_DESCENDING) { | ||
| flags.add(SqlKind.DESCENDING); | ||
| } | ||
| if (relCollation.nullDirection == RelFieldCollation.NullDirection.FIRST) { | ||
| flags.add(SqlKind.NULLS_FIRST); | ||
| } else if (relCollation.nullDirection == RelFieldCollation.NullDirection.LAST) { | ||
| flags.add(SqlKind.NULLS_LAST); | ||
| } | ||
|
|
||
| return new RexFieldCollation(fieldRef, flags); | ||
| } | ||
|
|
||
| private List<RexNode> wrapWindowFunctionsWithGroupNotNull( | ||
| List<RexNode> overExpressions, RexNode groupNotNull, CalcitePlanContext context) { | ||
| List<RexNode> wrappedOverExprs = new ArrayList<>(overExpressions.size()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -290,13 +290,28 @@ private static RexNode getFieldsAsMap( | |
| List<String> keys = excludeMetaFields(existingFields); | ||
| keys.removeAll(excluded); | ||
| Collections.sort(keys); | ||
| // Handle empty keys case - Calcite ARRAY[] requires at least 1 element | ||
| if (keys.isEmpty()) { | ||
| return createEmptyMap(context); | ||
| } | ||
| RexNode keysArray = getStringLiteralArray(keys, context); | ||
| List<RexNode> values = | ||
| keys.stream().map(key -> context.relBuilder.field(key)).collect(Collectors.toList()); | ||
| keys.stream() | ||
| .map(key -> context.relBuilder.cast(context.relBuilder.field(key), SqlTypeName.VARCHAR)) | ||
| .collect(Collectors.toList()); | ||
| RexNode valuesArray = makeArray(values, context); | ||
| return context.rexBuilder.makeCall(BuiltinFunctionName.MAP_FROM_ARRAYS, keysArray, valuesArray); | ||
|
Comment on lines
+293
to
303
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cd /repo && find . -name "DynamicFieldsHelper.java" -type fRepository: opensearch-project/sql Length of output: 121 🏁 Script executed: cd /repo && wc -l core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.javaRepository: opensearch-project/sql Length of output: 121 🏁 Script executed: cd /repo && cat -n core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java | sed -n '280,330p'Repository: opensearch-project/sql Length of output: 121 🏁 Script executed: cd /repo && cat -n core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java | sed -n '1,50p'Repository: opensearch-project/sql Length of output: 121 🏁 Script executed: cd /repo && grep -n "createEmptyMap\|MAP_FROM_ARRAYS\|MAP_APPEND" core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.javaRepository: opensearch-project/sql Length of output: 121 🏁 Script executed: cd /repo && find . -path "*/test*" -name "*DynamicFieldsHelperTest*" -type fRepository: opensearch-project/sql Length of output: 121 🏁 Script executed: find . -name "DynamicFieldsHelper.java" -type fRepository: opensearch-project/sql Length of output: 138 🏁 Script executed: wc -l ./core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.javaRepository: opensearch-project/sql Length of output: 142 🏁 Script executed: cat -n ./core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java | sed -n '280,330p'Repository: opensearch-project/sql Length of output: 2638 🏁 Script executed: cat -n ./core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java | sed -n '1,100p'Repository: opensearch-project/sql Length of output: 4829 🏁 Script executed: grep -n "createEmptyMap\|MAP_FROM_ARRAYS\|MAP_APPEND" ./core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.javaRepository: opensearch-project/sql Length of output: 649 🏁 Script executed: find . -path "*/test*" -name "*DynamicFieldsHelperTest*" -type fRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: find . -name "*DynamicFieldsHelper*" -type fRepository: opensearch-project/sql Length of output: 138 🏁 Script executed: find . -path "*/test/*" -name "*DynamicFields*" -type fRepository: opensearch-project/sql Length of output: 157 🏁 Script executed: grep -r "DynamicFieldsHelper" --include="*Test.java" | head -20Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: cat -n ./core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java | sed -n '160,250p'Repository: opensearch-project/sql Length of output: 4505 🏁 Script executed: grep -n "MAP_FROM_ARRAYS\|MAP_APPEND" ./core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java -B 2 -A 2Repository: opensearch-project/sql Length of output: 1275 🏁 Script executed: grep -r "getFieldsAsMap" --include="*.java"Repository: opensearch-project/sql Length of output: 676 🏁 Script executed: find . -path "*/test/*" -name "*.java" -exec grep -l "createEmptyMap\|getFieldsAsMap" {} \;Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: find . -name "pom.xml" -type f | head -5Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: cat ./pom.xml | grep -A 5 "calcite"Repository: opensearch-project/sql Length of output: 107 🏁 Script executed: find . -name "pom.xml" -type f -exec grep -l "calcite" {} \;Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: grep -r "MAP_APPEND\|MAP_FROM_ARRAYS" --include="*.java" | head -30Repository: opensearch-project/sql Length of output: 3167 🏁 Script executed: find . -path "*/test/*" -name "*.java" -exec grep -l "MAP_APPEND\|MAP_FROM_ARRAYS" {} \;Repository: opensearch-project/sql Length of output: 155 🏁 Script executed: grep -r "makeNullLiteral" --include="*.java" | head -20Repository: opensearch-project/sql Length of output: 3067 🏁 Script executed: cat -n ./integ-test/src/test/java/org/opensearch/sql/calcite/standalone/MapAppendFunctionIT.javaRepository: opensearch-project/sql Length of output: 6404 🏁 Script executed: cat -n ./core/src/main/java/org/opensearch/sql/expression/function/CollectionUDF/MapAppendFunctionImpl.javaRepository: opensearch-project/sql Length of output: 4823 🏁 Script executed: find . -name "pom.xml" -type f | xargs grep -l "calcite" | head -1 | xargs cat | grep -A 5 "calcite-core\|calcite.version"Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: find . -name "*.xml" -type f | xargs grep -l "calcite" | head -1Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: find . -name "pom.xml" -type f -exec grep -l "properties\|version" {} \; | head -3Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: cat ./pom.xml 2>/dev/null || find . -maxdepth 2 -name "pom.xml" -type f -exec head -30 {} \;Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: ls -la | grep -i pomRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: find . -maxdepth 3 -name "pom.xml" -type fRepository: opensearch-project/sql Length of output: 48 🏁 Script executed: grep -n "private static RexNode getFieldsAsMap\|private static RexNode createEmptyMap" core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java -A 1Repository: opensearch-project/sql Length of output: 325 🏁 Script executed: find . -path "*/test/*" -name "*.java" -exec grep -l "getFieldsAsMap\|createEmptyMap" {} \;Repository: opensearch-project/sql Length of output: 48 🏁 Script executed: grep -r "excludeMetaFields\|isMetadataField" core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java -B 2 -A 2Repository: opensearch-project/sql Length of output: 1003 🏁 Script executed: find . -path "*/test/*" -name "*.java" | xargs grep -l "DynamicFieldsHelper" 2>/dev/nullRepository: opensearch-project/sql Length of output: 50 🏁 Script executed: grep -n "new DynamicFieldsHelper\|DynamicFieldsHelper\." core/src/main/java/org/opensearch/sql/calcite/*.java | head -20Repository: opensearch-project/sql Length of output: 2272 🏁 Script executed: git log --oneline -20 -- core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java 2>/dev/null | head -10Repository: opensearch-project/sql Length of output: 134 🏁 Script executed: git show HEAD:core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java 2>/dev/null | grep -n "createEmptyMap\|getFieldsAsMap" | head -5Repository: opensearch-project/sql Length of output: 450 🏁 Script executed: cat -n core/src/main/java/org/opensearch/sql/calcite/DynamicFieldsHelper.java | sed -n '287,315p'Repository: opensearch-project/sql Length of output: 1606 Add unit tests for new helper functions per coding guidelines. The coding guidelines require that new functions in Additionally, note that 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| /** Create an empty map by casting NULL to MAP type */ | ||
| private static RexNode createEmptyMap(CalcitePlanContext context) { | ||
| RelDataType varcharType = | ||
| context.rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR); | ||
| RelDataType mapType = | ||
| context.rexBuilder.getTypeFactory().createMapType(varcharType, varcharType); | ||
| return context.rexBuilder.makeNullLiteral(mapType); | ||
| } | ||
|
Comment on lines
+306
to
+313
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add unit test coverage for empty-keys map creation. A new helper function was added to core/src/main/java; please add a unit test that exercises the empty-keys path (and ensures As per coding guidelines: New functions MUST have unit tests in the same commit. 🤖 Prompt for AI Agents |
||
|
|
||
| /** Create string literal array from collection of strings */ | ||
| private static RexNode getStringLiteralArray( | ||
| Collection<String> keys, CalcitePlanContext context) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 1951
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 1377
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 48
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 3043
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 48
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 1868
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 48
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 363
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 48
🏁 Script executed:
# Check the full test file to understand what's covered wc -l core/src/test/java/org/opensearch/sql/calcite/CalciteRexNodeVisitorTest.javaRepository: opensearch-project/sql
Length of output: 146
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 257
🏁 Script executed:
# Read CalciteRexNodeVisitorTest.java to see what's tested cat core/src/test/java/org/opensearch/sql/calcite/CalciteRexNodeVisitorTest.javaRepository: opensearch-project/sql
Length of output: 8794
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 48
🏁 Script executed:
Repository: opensearch-project/sql
Length of output: 50
Add Calcite integration tests for window function collation embedding.
The new
embedExistingCollationsIntoOvermethod (lines 1780–1803) handles critical window function semantics by injecting ORDER BY into OVER clauses. Per coding guidelines, all new business logic requires unit tests in the same commit. Add tests in the Calcite test suite (e.g.,CalciteRexNodeVisitorTest.javaor a new dedicated test class) covering:🤖 Prompt for AI Agents