tkalkirill commented on code in PR #13464:
URL: https://github.com/apache/ignite/pull/13464#discussion_r3765743751


##########
modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/LimitOffsetIntegrationTest.java:
##########
@@ -199,6 +197,128 @@ public void testOffsetOutOfRange() throws Exception {
         assertQuery("SELECT (SELECT id FROM TEST_PART ORDER BY id LIMIT 1 
OFFSET 10)").returns(NULL_RESULT).check();
     }
 
+    /** */
+    @Test
+    public void testInvalidFetchExpression() {
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (" + 
bigValue() + ") ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (" + 
bigValue() + " + 1) ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (1 + " + 
bigValue() + ") ROWS ONLY", null);
+
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (-2) 
ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (2 - 3) 
ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (1 + 2 - 
4) ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (-1.5) 
ROWS ONLY", null);
+
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST ('abc') 
ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST 
(SUBSTRING('abc', 1, 1)) ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST 
(CAST(NULL AS INTEGER)) ROWS ONLY", null);
+
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (id) 
ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (id + 1) 
ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST 
(ABS(id)) ROWS ONLY", null);
+
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST (SUM(1)) 
ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST 
(ROW_NUMBER() OVER ()) ROWS ONLY", null);
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST 
(ABS((SELECT 1))) ROWS ONLY", null);
+
+        assertThrowsSqlException("SELECT * FROM TEST_REPL FETCH FIRST SQRT(4) 
ROWS ONLY", null);
+    }
+
+    /** */
+    @Test
+    public void testFetchExpression() throws Exception {
+        fillCache(cacheRepl, 5);
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST (1) ROWS 
ONLY")
+            .returns(0)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST (1 + 5 - 
2) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .returns(2)
+            .returns(3)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST (1 + (2 
- 1) + 1) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .returns(2)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id DESC FETCH FIRST (1 
+ (2 - 1) + 1) ROWS ONLY")
+            .returns(4)
+            .returns(3)
+            .returns(2)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST 
(ABS(-2)) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST (1 + 
ABS(-2)) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .returns(2)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST (SQRT(4) 
+ 1 + 0) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .returns(2)
+            .check();
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST 
(EXTRACT(YEAR FROM CURRENT_DATE)) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .returns(2)
+            .returns(3)
+            .returns(4)
+            .check();
+    }
+
+    /** */
+    @Test
+    public void testFetchExpressionNested() throws Exception {
+        fillCache(cacheRepl, 5);
+
+        assertQuery("SELECT id FROM (SELECT id from TEST_REPL ORDER BY id 
FETCH FIRST (2 + 3) ROWS ONLY) " +
+            "ORDER BY id FETCH NEXT (1 + 1) ROWS ONLY")
+            .returns(0)
+            .returns(1)
+            .check();
+    }
+
+    /** */
+    @Test
+    public void testFetchExpressionWithRewrite() throws Exception {
+        fillCache(cacheRepl, 5);
+
+        assertQuery("SELECT id FROM TEST_REPL ORDER BY id FETCH FIRST (1 + 
NVL(?, 10000)) ROWS ONLY")
+            .withParams(1)
+            .returns(0)
+            .returns(1)
+            .check();
+    }
+
+    /** */
+    @Test
+    public void testFetchExpressionWithoutPushDown() throws Exception {

Review Comment:
   `FETCH` pushdown causes the expression to be evaluated more than once: by 
every local `IgniteSort` and again by the global `IgniteLimit`. `ABS(100)` is 
deterministic and always produces the same value, so the pushdown is safe. 
`RAND_INTEGER(...)` is marked non-deterministic, therefore different 
nodes/evaluations may produce different limits. If a local sort produces a 
smaller value, it may discard rows required by the global limit and change the 
query result. `RAND_INTEGER(1)` is used to keep the test result stable while 
still exercising the non-deterministic-expression path.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to