This is an automated email from the ASF dual-hosted git repository.

tkhurana pushed a commit to branch 5.2
in repository https://gitbox.apache.org/repos/asf/phoenix.git


The following commit(s) were added to refs/heads/5.2 by this push:
     new d06eebfb58 PHOENIX-7302 Server Paging doesn't work on scans with limit
d06eebfb58 is described below

commit d06eebfb58401e5585b012751c68ce5cdac4607f
Author: tkhurana <khurana.ta...@gmail.com>
AuthorDate: Mon Apr 8 12:40:15 2024 -0700

    PHOENIX-7302 Server Paging doesn't work on scans with limit
    
    Fix paging for scans with limit but no other filter
    
    Co-authored-by: Tanuj Khurana <tkhur...@apache.org>
---
 .../apache/phoenix/iterate/SerialIterators.java    | 13 +++-
 .../java/org/apache/phoenix/util/ScanUtil.java     | 11 +++-
 .../org/apache/phoenix/end2end/ServerPagingIT.java | 74 ++++++++++++++++++++++
 3 files changed, 95 insertions(+), 3 deletions(-)

diff --git 
a/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
 
b/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
index e439086686..a783c3558a 100644
--- 
a/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
+++ 
b/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
@@ -44,10 +44,13 @@ import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.util.EnvironmentEdgeManager;
+import org.apache.phoenix.util.LogUtil;
 import org.apache.phoenix.util.QueryUtil;
 
 import org.apache.phoenix.thirdparty.com.google.common.base.Preconditions;
 import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
+import org.apache.phoenix.util.ScanUtil;
 
 
 /**
@@ -188,7 +191,15 @@ public class SerialIterators extends BaseResultIterators {
                                 renewLeaseThreshold, plan, scanGrouper, 
caches, maxQueryEndTime);
                 PeekingResultIterator peekingItr = 
iteratorFactory.newIterator(context, itr, currentScan, tableName, plan);
                 Tuple tuple;
-                if ((tuple = peekingItr.peek()) == null) {
+                long startTime = EnvironmentEdgeManager.currentTimeMillis();
+                tuple = peekingItr.peek();
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug(LogUtil.addCustomAnnotations("Id: " + scanId 
+ ", Time: " +
+                                    
(EnvironmentEdgeManager.currentTimeMillis() - startTime) +
+                                    "ms, Table: " + tableName + ", Scan: " + 
currentScan,
+                            ScanUtil.getCustomAnnotations(currentScan)));
+                }
+                if (tuple == null) {
                     peekingItr.close();
                     continue;
                 } else if ((remainingOffset = 
QueryUtil.getRemainingOffset(tuple)) != null) {
diff --git 
a/phoenix-core-client/src/main/java/org/apache/phoenix/util/ScanUtil.java 
b/phoenix-core-client/src/main/java/org/apache/phoenix/util/ScanUtil.java
index 0718066d9f..c978acf6f6 100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/util/ScanUtil.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/util/ScanUtil.java
@@ -1614,14 +1614,21 @@ public class ScanUtil {
     public static PageFilter removePageFilter(Scan scan) {
         Filter filter = scan.getFilter();
         if (filter != null) {
+            PagingFilter pagingFilter = null;
             if (filter instanceof PagingFilter) {
-                filter = ((PagingFilter) filter).getDelegateFilter();
+                pagingFilter = (PagingFilter) filter;
+                filter = pagingFilter.getDelegateFilter();
                 if (filter == null) {
                     return null;
                 }
             }
             if (filter instanceof PageFilter) {
-                scan.setFilter(null);
+                if (pagingFilter != null) {
+                    pagingFilter.setDelegateFilter(null);
+                    scan.setFilter(pagingFilter);
+                } else {
+                    scan.setFilter(null);
+                }
                 return (PageFilter) filter;
             } else if (filter instanceof FilterList) {
                 return removePageFilterFromFilterList((FilterList) filter);
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerPagingIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerPagingIT.java
index db19a06ee7..b82ac71454 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerPagingIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerPagingIT.java
@@ -36,6 +36,7 @@ import java.util.Map;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.jdbc.PhoenixResultSet;
 import org.apache.phoenix.monitoring.MetricType;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.types.PDate;
@@ -44,6 +45,7 @@ import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.DateUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -77,6 +79,78 @@ public class ServerPagingIT extends ParallelStatsDisabledIT {
         assertTrue(GLOBAL_PAGED_ROWS_COUNTER.getMetric().getValue() > 0);
     }
 
+    @Test
+    public void testScanWithLimit() throws Exception {
+        final String tablename = "T_" + generateUniqueName();
+        final String indexName = "I_" + generateUniqueName();
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+            String ddl = "create table " + tablename +
+                    "(id1 integer not null, id2 integer not null, val varchar 
constraint pk primary key (id1, id2))";
+            conn.createStatement().execute(ddl);
+            conn.commit();
+            PreparedStatement stmt = conn.prepareStatement("upsert into " + 
tablename + " VALUES(?, ?, ?)");
+            // upsert 50 rows
+            for (int i = 0; i < 5; ++i) {
+                for (int j = 0; j < 10; ++j) {
+                    stmt.setInt(1, i);
+                    stmt.setInt(2, j);
+                    stmt.setString(3, "abcdefghijklmnopqrstuvwxyz");
+                    stmt.executeUpdate();
+                }
+                conn.commit();
+            }
+            // delete first 40 rows
+            stmt = conn.prepareStatement("delete from " + tablename + " where 
id1 = ? and id2 = ?");
+            for (int i = 0; i < 4; ++i) {
+                for (int j = 0; j < 10; ++j) {
+                    stmt.setInt(1, i);
+                    stmt.setInt(2, j);
+                    stmt.executeUpdate();
+                }
+                conn.commit();
+            }
+            int limit = 10;
+            stmt = conn.prepareStatement("select * from " + tablename + " 
where id1 >= 3 limit " + limit);
+            try (ResultSet rs = stmt.executeQuery()) {
+                int expectedRowCount = 0;
+                int expectedId1 = 4;
+                int expectedId2 = 0;
+                while (rs.next()) {
+                    ++expectedRowCount;
+                    assertEquals(expectedId1, rs.getInt(1));
+                    assertEquals(expectedId2, rs.getInt(2));
+                    expectedId2++;
+                }
+                assertEquals(expectedRowCount, limit);
+                assertServerPagingMetric(tablename, rs, true);
+            }
+
+            ddl = "create index " + indexName + " ON " + tablename + " (id2, 
id1) INCLUDE (val)";
+            conn.createStatement().execute(ddl);
+            conn.commit();
+
+            stmt = conn.prepareStatement("select * from " + tablename + " 
limit " + limit);
+            try (ResultSet rs = stmt.executeQuery()) {
+                PhoenixResultSet prs = rs.unwrap(PhoenixResultSet.class);
+                String explainPlan = 
QueryUtil.getExplainPlan(prs.getUnderlyingIterator());
+                assertTrue(explainPlan.contains(indexName));
+                int expectedRowCount = 0;
+                int expectedId1 = 4;
+                int expectedId2 = 0;
+                while (rs.next()) {
+                    ++expectedRowCount;
+                    assertEquals(expectedId1, rs.getInt(1));
+                    assertEquals(expectedId2, rs.getInt(2));
+                    expectedId2++;
+                }
+                assertEquals(expectedRowCount, limit);
+                assertServerPagingMetric(indexName, rs, true);
+            }
+        }
+    }
+
     @Test
     public void testOrderByNonAggregation() throws Exception {
         final String tablename = generateUniqueName();

Reply via email to