Skip to content

Commit 083251e

Browse files
committed
fix UT
Signed-off-by: Kai Huang <[email protected]>
1 parent 9aaaed7 commit 083251e

File tree

1 file changed

+131
-57
lines changed

1 file changed

+131
-57
lines changed

ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLReverseTest.java

Lines changed: 131 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@ public void testReverseParserSuccess() {
1919
String ppl = "source=EMP | reverse";
2020
RelNode root = getRelNode(ppl);
2121
String expectedLogical =
22-
""
23-
+ "LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5],"
24-
+ " COMM=[$6], DEPTNO=[$7])\n"
25-
+ " LogicalSort(sort0=[$8], dir0=[DESC])\n"
26-
+ " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],"
27-
+ " SAL=[$5], COMM=[$6], DEPTNO=[$7], __reverse_row_num__=[ROW_NUMBER() OVER ()])\n"
28-
+ " LogicalTableScan(table=[[scott, EMP]])\n";
22+
"LogicalSort(sort0=[$0], dir0=[DESC])\n" + " LogicalTableScan(table=[[scott, EMP]])\n";
2923
verifyLogical(root, expectedLogical);
3024

3125
String expectedResult =
@@ -60,67 +54,47 @@ public void testReverseParserSuccess() {
6054
verifyResult(root, expectedResult);
6155

6256
String expectedSparkSql =
63-
""
64-
+ "SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
65-
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`,"
66-
+ " ROW_NUMBER() OVER () `__reverse_row_num__`\n"
67-
+ "FROM `scott`.`EMP`\n"
68-
+ "ORDER BY 9 DESC NULLS FIRST) `t0`";
57+
"SELECT *\n" + "FROM `scott`.`EMP`\n" + "ORDER BY `EMPNO` DESC NULLS FIRST";
6958
verifyPPLToSparkSQL(root, expectedSparkSql);
7059
}
7160

7261
@Test
7362
public void testReverseWithSortParserSuccess() {
7463
String ppl = "source=EMP | sort ENAME | reverse";
7564
RelNode root = getRelNode(ppl);
65+
// Optimization rule may show double sorts in logical plan but physical execution is optimized
7666
String expectedLogical =
77-
""
78-
+ "LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5],"
79-
+ " COMM=[$6], DEPTNO=[$7])\n"
80-
+ " LogicalSort(sort0=[$8], dir0=[DESC])\n"
81-
+ " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],"
82-
+ " SAL=[$5], COMM=[$6], DEPTNO=[$7], __reverse_row_num__=[ROW_NUMBER() OVER ()])\n"
83-
+ " LogicalSort(sort0=[$1], dir0=[ASC-nulls-first])\n"
84-
+ " LogicalTableScan(table=[[scott, EMP]])\n";
67+
"LogicalSort(sort0=[$1], dir0=[DESC-nulls-last])\n"
68+
+ " LogicalSort(sort0=[$1], dir0=[ASC-nulls-first])\n"
69+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
8570
verifyLogical(root, expectedLogical);
8671

8772
String expectedSparkSql =
88-
""
89-
+ "SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
90-
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`,"
91-
+ " ROW_NUMBER() OVER () `__reverse_row_num__`\n"
73+
"SELECT *\n"
74+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
9275
+ "FROM `scott`.`EMP`\n"
93-
+ "ORDER BY `ENAME`) `t0`\n"
94-
+ "ORDER BY `__reverse_row_num__` DESC NULLS FIRST";
76+
+ "ORDER BY `ENAME`) `t`\n"
77+
+ "ORDER BY `ENAME` DESC";
9578
verifyPPLToSparkSQL(root, expectedSparkSql);
9679
}
9780

9881
@Test
9982
public void testDoubleReverseParserSuccess() {
10083
String ppl = "source=EMP | reverse | reverse";
10184
RelNode root = getRelNode(ppl);
85+
// Without optimization rule, shows consecutive sorts
10286
String expectedLogical =
103-
""
104-
+ "LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5],"
105-
+ " COMM=[$6], DEPTNO=[$7])\n"
106-
+ " LogicalSort(sort0=[$8], dir0=[DESC])\n"
107-
+ " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],"
108-
+ " SAL=[$5], COMM=[$6], DEPTNO=[$7], __reverse_row_num__=[ROW_NUMBER() OVER ()])\n"
109-
+ " LogicalSort(sort0=[$8], dir0=[DESC])\n"
110-
+ " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],"
111-
+ " SAL=[$5], COMM=[$6], DEPTNO=[$7], __reverse_row_num__=[ROW_NUMBER() OVER ()])\n"
112-
+ " LogicalTableScan(table=[[scott, EMP]])\n";
87+
"LogicalSort(sort0=[$0], dir0=[ASC])\n"
88+
+ " LogicalSort(sort0=[$0], dir0=[DESC])\n"
89+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
11390
verifyLogical(root, expectedLogical);
11491

11592
String expectedSparkSql =
116-
"SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
117-
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`,"
118-
+ " ROW_NUMBER() OVER () `__reverse_row_num__`\n"
119-
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`,"
120-
+ " ROW_NUMBER() OVER () `__reverse_row_num__`\n"
93+
"SELECT *\n"
94+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
12195
+ "FROM `scott`.`EMP`\n"
122-
+ "ORDER BY 9 DESC NULLS FIRST) `t0`\n"
123-
+ "ORDER BY 9 DESC NULLS FIRST) `t2`";
96+
+ "ORDER BY `EMPNO` DESC NULLS FIRST) `t`\n"
97+
+ "ORDER BY `EMPNO` NULLS LAST";
12498
verifyPPLToSparkSQL(root, expectedSparkSql);
12599
}
126100

@@ -129,13 +103,8 @@ public void testReverseWithHeadParserSuccess() {
129103
String ppl = "source=EMP | reverse | head 2";
130104
RelNode root = getRelNode(ppl);
131105
String expectedLogical =
132-
""
133-
+ "LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5],"
134-
+ " COMM=[$6], DEPTNO=[$7])\n"
135-
+ " LogicalSort(sort0=[$8], dir0=[DESC], fetch=[2])\n"
136-
+ " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],"
137-
+ " SAL=[$5], COMM=[$6], DEPTNO=[$7], __reverse_row_num__=[ROW_NUMBER() OVER ()])\n"
138-
+ " LogicalTableScan(table=[[scott, EMP]])\n";
106+
"LogicalSort(sort0=[$0], dir0=[DESC], fetch=[2])\n"
107+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
139108
verifyLogical(root, expectedLogical);
140109

141110
String expectedResult =
@@ -146,12 +115,7 @@ public void testReverseWithHeadParserSuccess() {
146115
verifyResult(root, expectedResult);
147116

148117
String expectedSparkSql =
149-
"SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
150-
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`,"
151-
+ " ROW_NUMBER() OVER () `__reverse_row_num__`\n"
152-
+ "FROM `scott`.`EMP`\n"
153-
+ "ORDER BY 9 DESC NULLS FIRST\n"
154-
+ "LIMIT 2) `t0`";
118+
"SELECT *\n" + "FROM `scott`.`EMP`\n" + "ORDER BY `EMPNO` DESC NULLS FIRST\n" + "LIMIT 2";
155119
verifyPPLToSparkSQL(root, expectedSparkSql);
156120
}
157121

@@ -178,4 +142,114 @@ public void testReverseWithExpressionShouldFail() {
178142
String ppl = "source=EMP | reverse EMPNO + 1";
179143
getRelNode(ppl);
180144
}
145+
146+
@Test
147+
public void testMultipleSortsWithReverseParserSuccess() {
148+
String ppl = "source=EMP | sort + SAL | sort - ENAME | reverse";
149+
RelNode root = getRelNode(ppl);
150+
String expectedLogical =
151+
"LogicalSort(sort0=[$1], dir0=[ASC-nulls-first])\n"
152+
+ " LogicalSort(sort0=[$1], dir0=[DESC-nulls-last])\n"
153+
+ " LogicalSort(sort0=[$5], dir0=[ASC-nulls-first])\n"
154+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
155+
verifyLogical(root, expectedLogical);
156+
157+
String expectedSparkSql =
158+
"SELECT *\n"
159+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
160+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
161+
+ "FROM `scott`.`EMP`\n"
162+
+ "ORDER BY `SAL`) `t`\n"
163+
+ "ORDER BY `ENAME` DESC) `t0`\n"
164+
+ "ORDER BY `ENAME`";
165+
verifyPPLToSparkSQL(root, expectedSparkSql);
166+
}
167+
168+
@Test
169+
public void testMultiFieldSortWithReverseParserSuccess() {
170+
String ppl = "source=EMP | sort + SAL, - ENAME | reverse";
171+
RelNode root = getRelNode(ppl);
172+
String expectedLogical =
173+
"LogicalSort(sort0=[$5], sort1=[$1], dir0=[DESC-nulls-last], dir1=[ASC-nulls-first])\n"
174+
+ " LogicalSort(sort0=[$5], sort1=[$1], dir0=[ASC-nulls-first],"
175+
+ " dir1=[DESC-nulls-last])\n"
176+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
177+
verifyLogical(root, expectedLogical);
178+
179+
String expectedSparkSql =
180+
"SELECT *\n"
181+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
182+
+ "FROM `scott`.`EMP`\n"
183+
+ "ORDER BY `SAL`, `ENAME` DESC) `t`\n"
184+
+ "ORDER BY `SAL` DESC, `ENAME`";
185+
verifyPPLToSparkSQL(root, expectedSparkSql);
186+
}
187+
188+
@Test
189+
public void testComplexMultiFieldSortWithReverseParserSuccess() {
190+
String ppl = "source=EMP | sort DEPTNO, + SAL, - ENAME | reverse";
191+
RelNode root = getRelNode(ppl);
192+
String expectedLogical =
193+
"LogicalSort(sort0=[$7], sort1=[$5], sort2=[$1], dir0=[DESC-nulls-last],"
194+
+ " dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n"
195+
+ " LogicalSort(sort0=[$7], sort1=[$5], sort2=[$1], dir0=[ASC-nulls-first],"
196+
+ " dir1=[ASC-nulls-first], dir2=[DESC-nulls-last])\n"
197+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
198+
verifyLogical(root, expectedLogical);
199+
200+
String expectedSparkSql =
201+
"SELECT *\n"
202+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
203+
+ "FROM `scott`.`EMP`\n"
204+
+ "ORDER BY `DEPTNO`, `SAL`, `ENAME` DESC) `t`\n"
205+
+ "ORDER BY `DEPTNO` DESC, `SAL` DESC, `ENAME`";
206+
verifyPPLToSparkSQL(root, expectedSparkSql);
207+
}
208+
209+
@Test
210+
public void testReverseWithFieldsAndSortParserSuccess() {
211+
String ppl = "source=EMP | fields ENAME, SAL, DEPTNO | sort + SAL | reverse";
212+
RelNode root = getRelNode(ppl);
213+
String expectedLogical =
214+
"LogicalSort(sort0=[$1], dir0=[DESC-nulls-last])\n"
215+
+ " LogicalSort(sort0=[$1], dir0=[ASC-nulls-first])\n"
216+
+ " LogicalProject(ENAME=[$1], SAL=[$5], DEPTNO=[$7])\n"
217+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
218+
verifyLogical(root, expectedLogical);
219+
220+
String expectedSparkSql =
221+
"SELECT *\n"
222+
+ "FROM (SELECT `ENAME`, `SAL`, `DEPTNO`\n"
223+
+ "FROM `scott`.`EMP`\n"
224+
+ "ORDER BY `SAL`) `t0`\n"
225+
+ "ORDER BY `SAL` DESC";
226+
verifyPPLToSparkSQL(root, expectedSparkSql);
227+
}
228+
229+
@Test
230+
public void testHeadThenSortReverseNoOpt() {
231+
// Tests fetch limit behavior: head 5 | sort field | reverse
232+
// Should NOT be optimized to preserve "take first 5, then sort" semantics
233+
String ppl = "source=EMP | head 5 | sort + SAL | reverse";
234+
RelNode root = getRelNode(ppl);
235+
236+
// Should have three LogicalSort nodes: fetch=5, sort SAL, reverse
237+
// Calcite's built-in optimization will handle the physical plan optimization
238+
String expectedLogical =
239+
"LogicalSort(sort0=[$5], dir0=[DESC-nulls-last])\n"
240+
+ " LogicalSort(sort0=[$5], dir0=[ASC-nulls-first])\n"
241+
+ " LogicalSort(fetch=[5])\n"
242+
+ " LogicalTableScan(table=[[scott, EMP]])\n";
243+
verifyLogical(root, expectedLogical);
244+
245+
String expectedSparkSql =
246+
"SELECT *\n"
247+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
248+
+ "FROM (SELECT `EMPNO`, `ENAME`, `JOB`, `MGR`, `HIREDATE`, `SAL`, `COMM`, `DEPTNO`\n"
249+
+ "FROM `scott`.`EMP`\n"
250+
+ "LIMIT 5) `t`\n"
251+
+ "ORDER BY `SAL`) `t0`\n"
252+
+ "ORDER BY `SAL` DESC";
253+
verifyPPLToSparkSQL(root, expectedSparkSql);
254+
}
181255
}

0 commit comments

Comments
 (0)