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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9d2d840746 PHOENIX-7358 Upsert select result wrong when use order by 
in query (#2148)
9d2d840746 is described below

commit 9d2d8407467823233ccb45dc852d3010b6e61f7c
Author: chaijunjie0101 <1340011...@qq.com>
AuthorDate: Sat May 31 02:42:11 2025 +0800

    PHOENIX-7358 Upsert select result wrong when use order by in query (#2148)
---
 .../org/apache/phoenix/compile/UpsertCompiler.java |  4 +-
 .../org/apache/phoenix/end2end/UpsertSelectIT.java | 60 ++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git 
a/phoenix-core-client/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
 
b/phoenix-core-client/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index 5529ec08af..854e605583 100644
--- 
a/phoenix-core-client/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ 
b/phoenix-core-client/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -580,10 +580,12 @@ public class UpsertCompiler {
              * 5) no limit clause, as the limit clause requires client-side 
post processing
              * 6) no sequences, as sequences imply that the order of upsert 
must match the order of
              *    selection. TODO: change this and only force client side if 
there's a ORDER BY on the sequence value
+             * 7) no order by, upsert order should same as select order.
              * Otherwise, run the query to pull the data from the server
              * and populate the MutationState (upto a limit).
             */
-            if (! (select.isAggregate() || select.isDistinct() || 
select.getLimit() != null || select.hasSequence()) ) {
+            if (!(select.isAggregate() || select.isDistinct() || 
select.getLimit() != null
+                    || select.hasSequence() || select.haveOrderBy())) {
                 // We can pipeline the upsert select instead of spooling 
everything to disk first,
                 // if we don't have any post processing that's required.
                 parallelIteratorFactoryToBe = new 
UpsertingParallelIteratorFactory(connection, tableRefToBe, 
useServerTimestampToBe);
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectIT.java
index e63ccad707..958af7151c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectIT.java
@@ -842,6 +842,66 @@ public class UpsertSelectIT extends 
ParallelStatsDisabledIT {
         }
     }
 
+    @Test
+    public void testUpsertSelectWithOrderBy() throws Exception {
+        Properties props = new Properties();
+        props.setProperty(QueryServices.ENABLE_SERVER_SIDE_UPSERT_MUTATIONS,
+                allowServerSideMutations);
+        props.setProperty(QueryServices.AUTO_COMMIT_ATTRIB, "true");
+        String uniqueName = generateUniqueName();
+        String tableName1 = uniqueName + "_1";
+        String tableName2 = uniqueName + "_2";
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);
+             Statement stmt = conn.createStatement()) {
+            stmt.execute("create table " + tableName1 +
+                    " (c1 char(3) not null primary key, c2 char(3), c3 
char(3)) SALT_BUCKETS=16");
+            stmt.execute("create table " + tableName2 +
+                    " (cc1 char(3) not null primary key, cc2 char(3), cc3 
char(3)) SALT_BUCKETS=16");
+            conn.commit();
+        }
+
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);
+             Statement stmt = conn.createStatement()) {
+            // c1 c2 c3
+            // 000 a 512
+            // 001 a 511
+            // ...
+            // 512 a 000
+            int maxNums = 512;
+            for (int i = 0; i <= maxNums; i++) {
+                String c1Val = String.format("%03d", i);
+                String c3Val = String.format("%03d", maxNums - i);
+                stmt.execute("upsert into " + tableName1 +
+                        " values ('" + c1Val + "','a','" + c3Val + "')");
+            }
+            conn.commit();
+        }
+
+        // select c2,c1,c3 from tableName1 order by c3
+        // The result should be:
+        // c2 c1 c3
+        // a 512 000
+        // a 511 001
+        // ...
+        // a 000 512
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);
+             Statement stmt = conn.createStatement()) {
+            stmt.execute("upsert into " + tableName2 +
+                    "(cc1,cc2,cc3) select c2,c1,c3 from " + tableName1 + " 
order by c3");
+            conn.commit();
+        }
+
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);
+             Statement stmt = conn.createStatement()) {
+            ResultSet rs = stmt.executeQuery("select * from " + tableName2);
+            assertTrue(rs.next());
+            assertEquals("a", rs.getString(1));
+            assertEquals("000", rs.getString(2));
+            assertEquals("512", rs.getString(3));
+            assertFalse(rs.next());
+        }
+    }
+
     @Test
     public void testUpsertSelectWithSequence() throws Exception {
         Properties props = new Properties();

Reply via email to