Repository: phoenix
Updated Branches:
  refs/heads/4.x-HBase-1.0 64be3a3d4 -> a05137b2f


PHOENIX-2894 Sort-merge join works incorrectly with DESC columns


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/a05137b2
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/a05137b2
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/a05137b2

Branch: refs/heads/4.x-HBase-1.0
Commit: a05137b2f591874909ef9bbefecdcbb086e7ba86
Parents: 64be3a3
Author: maryannxue <maryann....@gmail.com>
Authored: Fri May 20 13:29:49 2016 -0400
Committer: maryannxue <maryann....@gmail.com>
Committed: Fri May 20 13:29:49 2016 -0400

----------------------------------------------------------------------
 .../apache/phoenix/end2end/HashJoinMoreIT.java  | 185 +++++++++++++++++
 .../phoenix/end2end/SortMergeJoinMoreIT.java    | 199 +++++++++++++++++++
 .../apache/phoenix/compile/JoinCompiler.java    |   9 +-
 3 files changed, 389 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/a05137b2/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinMoreIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinMoreIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinMoreIT.java
index 98264f0..128baf3 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinMoreIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinMoreIT.java
@@ -690,4 +690,189 @@ public class HashJoinMoreIT extends 
BaseHBaseManagedTimeIT {
             conn.close();
         }
     }
+
+    @Test
+    public void testBug2894() throws Exception {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(true);
+        try {
+            conn.createStatement().execute(
+                    "CREATE TABLE IF NOT EXISTS EVENT_COUNT (\n" +
+                    "        BUCKET VARCHAR,\n" +
+                    "        TIMESTAMP_DATE TIMESTAMP,\n" +
+                    "        TIMESTAMP UNSIGNED_LONG NOT NULL,\n" +
+                    "        LOCATION VARCHAR,\n" +
+                    "        A VARCHAR,\n" +
+                    "        B VARCHAR,\n" +
+                    "        C VARCHAR,\n" +
+                    "        D UNSIGNED_LONG,\n" +
+                    "        E FLOAT\n" +
+                    "    CONSTRAINT pk PRIMARY KEY (BUCKET, TIMESTAMP DESC, 
LOCATION, A, B, C)\n" +
+                    ") SALT_BUCKETS=2, COMPRESSION='GZ', TTL=31622400");
+            PreparedStatement stmt = conn.prepareStatement("UPSERT INTO 
EVENT_COUNT(BUCKET, TIMESTAMP, LOCATION, A, B, C) VALUES(?,?,?,?,?,?)");
+            stmt.setString(1, "5SEC");
+            stmt.setString(3, "Tr/Bal");
+            stmt.setString(4, "A1");
+            stmt.setString(5, "B1");
+            stmt.setString(6, "C1");
+            stmt.setLong(2, 1462993520000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993515000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993510000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993505000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993500000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993495000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993490000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993485000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993480000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993475000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993470000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993465000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993460000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993455000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993450000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993445000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993440000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993430000000000L);
+            stmt.execute();
+
+            // We'll test the original version of the user table as well as a 
slightly modified
+            // version, in order to verify that hash join works for columns 
both having DESC
+            // sort order as well as one having ASC order and the other having 
DESC order.
+            String[] t = new String[] {"EVENT_LATENCY", "EVENT_LATENCY_2"};
+            for (int i = 0; i < 2; i++) {
+                conn.createStatement().execute(
+                        "CREATE TABLE IF NOT EXISTS " + t[i] + " (\n" +
+                                "        BUCKET VARCHAR,\n" +
+                                "        TIMESTAMP_DATE TIMESTAMP,\n" +
+                                "        TIMESTAMP UNSIGNED_LONG NOT NULL,\n" +
+                                "        SRC_LOCATION VARCHAR,\n" +
+                                "        DST_LOCATION VARCHAR,\n" +
+                                "        B VARCHAR,\n" +
+                                "        C VARCHAR,\n" +
+                                "        F UNSIGNED_LONG,\n" +
+                                "        G UNSIGNED_LONG,\n" +
+                                "        H UNSIGNED_LONG,\n" +
+                                "        I UNSIGNED_LONG\n" +
+                                "    CONSTRAINT pk PRIMARY KEY (BUCKET, 
TIMESTAMP" + (i == 0 ? " DESC" : "") + ", SRC_LOCATION, DST_LOCATION, B, C)\n" +
+                        ") SALT_BUCKETS=2, COMPRESSION='GZ', TTL=31622400");
+                stmt = conn.prepareStatement("UPSERT INTO " + t[i] + "(BUCKET, 
TIMESTAMP, SRC_LOCATION, DST_LOCATION, B, C) VALUES(?,?,?,?,?,?)");
+                stmt.setString(1, "5SEC");
+                stmt.setString(3, "Tr/Bal");
+                stmt.setString(4, "Tr/Bal");
+                stmt.setString(5, "B1");
+                stmt.setString(6, "C1");
+                stmt.setLong(2, 1462993520000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993515000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993510000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993505000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993490000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993485000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993480000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993475000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993470000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993430000000000L);
+                stmt.execute();
+                
+                String q =
+                        "SELECT C.BUCKET, C.TIMESTAMP FROM (\n" +
+                        "     SELECT E.BUCKET as BUCKET, L.BUCKET as LBUCKET, 
E.TIMESTAMP as TIMESTAMP, L.TIMESTAMP as LTIMESTAMP FROM\n" +
+                        "        (SELECT BUCKET, TIMESTAMP FROM EVENT_COUNT\n" 
+
+                        "             WHERE BUCKET = '5SEC' AND LOCATION = 
'Tr/Bal'\n" +
+                        "                 AND TIMESTAMP <= 1462993520000000000 
AND TIMESTAMP > 1462993420000000000\n" +
+                        "        ) E\n" +
+                        "        JOIN\n" +
+                        "         (SELECT BUCKET, TIMESTAMP FROM "+ t[i] +"\n" 
+
+                        "             WHERE BUCKET = '5SEC' AND SRC_LOCATION = 
'Tr/Bal' AND SRC_LOCATION = DST_LOCATION\n" +
+                        "                 AND TIMESTAMP <= 1462993520000000000 
AND TIMESTAMP > 1462993420000000000\n" +
+                        "         ) L\n" +
+                        "     ON L.BUCKET = E.BUCKET AND L.TIMESTAMP = 
E.TIMESTAMP\n" +
+                        " ) C\n" +
+                        " GROUP BY C.BUCKET, C.TIMESTAMP";
+                    
+                String p = i == 0 ?
+                        "CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES OVER 
EVENT_COUNT [0,'5SEC',~1462993520000000000,'Tr/Bal'] - 
[1,'5SEC',~1462993420000000000,'Tr/Bal']\n" +
+                        "    SERVER FILTER BY FIRST KEY ONLY\n" +
+                        "    SERVER AGGREGATE INTO DISTINCT ROWS BY [E.BUCKET, 
E.TIMESTAMP]\n" +
+                        "CLIENT MERGE SORT\n" +
+                        "    PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)\n" +
+                        "        CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES 
OVER " + t[i] + " [0,'5SEC',~1462993520000000000,'Tr/Bal'] - 
[1,'5SEC',~1462993420000000000,'Tr/Bal']\n" +
+                        "            SERVER FILTER BY FIRST KEY ONLY AND 
SRC_LOCATION = DST_LOCATION\n" +
+                        "        CLIENT MERGE SORT"
+                        :
+                        "CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES OVER 
EVENT_COUNT [0,'5SEC',~1462993520000000000,'Tr/Bal'] - 
[1,'5SEC',~1462993420000000000,'Tr/Bal']\n" +
+                        "    SERVER FILTER BY FIRST KEY ONLY\n" +
+                        "    SERVER AGGREGATE INTO DISTINCT ROWS BY [E.BUCKET, 
E.TIMESTAMP]\n" +
+                        "CLIENT MERGE SORT\n" +
+                        "    PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)\n" +
+                        "        CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES 
OVER " + t[i] + " [0,'5SEC',1462993420000000001,'Tr/Bal'] - 
[1,'5SEC',1462993520000000000,'Tr/Bal']\n" +
+                        "            SERVER FILTER BY FIRST KEY ONLY AND 
SRC_LOCATION = DST_LOCATION\n" +
+                        "        CLIENT MERGE SORT";
+                
+                ResultSet rs = conn.createStatement().executeQuery("explain " 
+ q);
+                assertEquals(p, QueryUtil.getExplainPlan(rs));
+                
+                rs = conn.createStatement().executeQuery(q);
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993520000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993515000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993510000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993505000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993490000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993485000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993480000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993475000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993470000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993430000000000L, rs.getLong(2));
+                assertFalse(rs.next());
+            }
+        } finally {
+            conn.close();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/a05137b2/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinMoreIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinMoreIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinMoreIT.java
index d9016d0..c36b24d 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinMoreIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinMoreIT.java
@@ -32,6 +32,7 @@ import java.util.Properties;
 
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -311,4 +312,202 @@ public class SortMergeJoinMoreIT extends 
BaseHBaseManagedTimeIT {
             conn.close();
         }
     }
+
+    @Test
+    public void testBug2894() throws Exception {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(true);
+        try {
+            conn.createStatement().execute(
+                    "CREATE TABLE IF NOT EXISTS EVENT_COUNT (\n" +
+                    "        BUCKET VARCHAR,\n" +
+                    "        TIMESTAMP_DATE TIMESTAMP,\n" +
+                    "        TIMESTAMP UNSIGNED_LONG NOT NULL,\n" +
+                    "        LOCATION VARCHAR,\n" +
+                    "        A VARCHAR,\n" +
+                    "        B VARCHAR,\n" +
+                    "        C VARCHAR,\n" +
+                    "        D UNSIGNED_LONG,\n" +
+                    "        E FLOAT\n" +
+                    "    CONSTRAINT pk PRIMARY KEY (BUCKET, TIMESTAMP DESC, 
LOCATION, A, B, C)\n" +
+                    ") SALT_BUCKETS=2, COMPRESSION='GZ', TTL=31622400");
+            PreparedStatement stmt = conn.prepareStatement("UPSERT INTO 
EVENT_COUNT(BUCKET, TIMESTAMP, LOCATION, A, B, C) VALUES(?,?,?,?,?,?)");
+            stmt.setString(1, "5SEC");
+            stmt.setString(3, "Tr/Bal");
+            stmt.setString(4, "A1");
+            stmt.setString(5, "B1");
+            stmt.setString(6, "C1");
+            stmt.setLong(2, 1462993520000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993515000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993510000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993505000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993500000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993495000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993490000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993485000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993480000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993475000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993470000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993465000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993460000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993455000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993450000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993445000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993440000000000L);
+            stmt.execute();
+            stmt.setLong(2, 1462993430000000000L);
+            stmt.execute();
+
+            // We'll test the original version of the user table as well as a 
slightly modified
+            // version, in order to verify that sort-merge join works for 
columns both having
+            // DESC sort order as well as one having ASC order and the other 
having DESC order.
+            String[] t = new String[] {"EVENT_LATENCY", "EVENT_LATENCY_2"};
+            for (int i = 0; i < 2; i++) {
+                conn.createStatement().execute(
+                        "CREATE TABLE IF NOT EXISTS " + t[i] + " (\n" +
+                                "        BUCKET VARCHAR,\n" +
+                                "        TIMESTAMP_DATE TIMESTAMP,\n" +
+                                "        TIMESTAMP UNSIGNED_LONG NOT NULL,\n" +
+                                "        SRC_LOCATION VARCHAR,\n" +
+                                "        DST_LOCATION VARCHAR,\n" +
+                                "        B VARCHAR,\n" +
+                                "        C VARCHAR,\n" +
+                                "        F UNSIGNED_LONG,\n" +
+                                "        G UNSIGNED_LONG,\n" +
+                                "        H UNSIGNED_LONG,\n" +
+                                "        I UNSIGNED_LONG\n" +
+                                "    CONSTRAINT pk PRIMARY KEY (BUCKET, 
TIMESTAMP" + (i == 0 ? " DESC" : "") + ", SRC_LOCATION, DST_LOCATION, B, C)\n" +
+                        ") SALT_BUCKETS=2, COMPRESSION='GZ', TTL=31622400");
+                stmt = conn.prepareStatement("UPSERT INTO " + t[i] + "(BUCKET, 
TIMESTAMP, SRC_LOCATION, DST_LOCATION, B, C) VALUES(?,?,?,?,?,?)");
+                stmt.setString(1, "5SEC");
+                stmt.setString(3, "Tr/Bal");
+                stmt.setString(4, "Tr/Bal");
+                stmt.setString(5, "B1");
+                stmt.setString(6, "C1");
+                stmt.setLong(2, 1462993520000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993515000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993510000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993505000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993490000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993485000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993480000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993475000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993470000000000L);
+                stmt.execute();
+                stmt.setLong(2, 1462993430000000000L);
+                stmt.execute();
+                
+                String q =
+                        "SELECT C.BUCKET, C.TIMESTAMP FROM (\n" +
+                        "     SELECT E.BUCKET as BUCKET, L.BUCKET as LBUCKET, 
E.TIMESTAMP as TIMESTAMP, L.TIMESTAMP as LTIMESTAMP FROM\n" +
+                        "        (SELECT BUCKET, TIMESTAMP FROM EVENT_COUNT\n" 
+
+                        "             WHERE BUCKET = '5SEC' AND LOCATION = 
'Tr/Bal'\n" +
+                        "                 AND TIMESTAMP <= 1462993520000000000 
AND TIMESTAMP > 1462993420000000000\n" +
+                        "             GROUP BY BUCKET, TIMESTAMP, LOCATION\n" +
+                        "        ) E\n" +
+                        "        JOIN\n" +
+                        "         (SELECT BUCKET, TIMESTAMP FROM "+ t[i] +"\n" 
+
+                        "             WHERE BUCKET = '5SEC' AND SRC_LOCATION = 
'Tr/Bal' AND SRC_LOCATION = DST_LOCATION\n" +
+                        "                 AND TIMESTAMP <= 1462993520000000000 
AND TIMESTAMP > 1462993420000000000\n" +
+                        "             GROUP BY BUCKET, TIMESTAMP, 
SRC_LOCATION, DST_LOCATION\n" +
+                        "         ) L\n" +
+                        "     ON L.BUCKET = E.BUCKET AND L.TIMESTAMP = 
E.TIMESTAMP\n" +
+                        " ) C\n" +
+                        " GROUP BY C.BUCKET, C.TIMESTAMP";
+                
+                String p = i == 0 ?
+                        "SORT-MERGE-JOIN (INNER) TABLES\n" +
+                        "    CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES OVER 
EVENT_COUNT [0,'5SEC',~1462993520000000000,'Tr/Bal'] - 
[1,'5SEC',~1462993420000000000,'Tr/Bal']\n" +
+                        "        SERVER FILTER BY FIRST KEY ONLY\n" +
+                        "        SERVER AGGREGATE INTO ORDERED DISTINCT ROWS 
BY [BUCKET, TIMESTAMP, LOCATION]\n" +
+                        "    CLIENT MERGE SORT\n" +
+                        "    CLIENT SORTED BY [BUCKET, TIMESTAMP]\n" +
+                        "AND (SKIP MERGE)\n" +
+                        "    CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES OVER 
" + t[i] + " [0,'5SEC',~1462993520000000000,'Tr/Bal'] - 
[1,'5SEC',~1462993420000000000,'Tr/Bal']\n" +
+                        "        SERVER FILTER BY FIRST KEY ONLY AND 
SRC_LOCATION = DST_LOCATION\n" +
+                        "        SERVER AGGREGATE INTO ORDERED DISTINCT ROWS 
BY [BUCKET, TIMESTAMP, SRC_LOCATION, DST_LOCATION]\n" +
+                        "    CLIENT MERGE SORT\n" +
+                        "    CLIENT SORTED BY [BUCKET, TIMESTAMP]\n" +
+                        "CLIENT SORTED BY [E.BUCKET, E.TIMESTAMP]\n" +
+                        "CLIENT AGGREGATE INTO DISTINCT ROWS BY [E.BUCKET, 
E.TIMESTAMP]"
+                        :
+                        "SORT-MERGE-JOIN (INNER) TABLES\n" +
+                        "    CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES OVER 
EVENT_COUNT [0,'5SEC',~1462993520000000000,'Tr/Bal'] - 
[1,'5SEC',~1462993420000000000,'Tr/Bal']\n" +
+                        "        SERVER FILTER BY FIRST KEY ONLY\n" +
+                        "        SERVER AGGREGATE INTO ORDERED DISTINCT ROWS 
BY [BUCKET, TIMESTAMP, LOCATION]\n" +
+                        "    CLIENT MERGE SORT\n" +
+                        "    CLIENT SORTED BY [BUCKET, TIMESTAMP]\n" +
+                        "AND (SKIP MERGE)\n" +
+                        "    CLIENT PARALLEL 2-WAY SKIP SCAN ON 2 RANGES OVER 
" + t[i] + " [0,'5SEC',1462993420000000001,'Tr/Bal'] - 
[1,'5SEC',1462993520000000000,'Tr/Bal']\n" +
+                        "        SERVER FILTER BY FIRST KEY ONLY AND 
SRC_LOCATION = DST_LOCATION\n" +
+                        "        SERVER AGGREGATE INTO ORDERED DISTINCT ROWS 
BY [BUCKET, TIMESTAMP, SRC_LOCATION, DST_LOCATION]\n" +
+                        "    CLIENT MERGE SORT\n" +
+                        "CLIENT SORTED BY [E.BUCKET, E.TIMESTAMP]\n" +
+                        "CLIENT AGGREGATE INTO DISTINCT ROWS BY [E.BUCKET, 
E.TIMESTAMP]";
+                
+                ResultSet rs = conn.createStatement().executeQuery("explain " 
+ q);
+                assertEquals(p, QueryUtil.getExplainPlan(rs));
+                
+                rs = conn.createStatement().executeQuery(q);
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993520000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993515000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993510000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993505000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993490000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993485000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993480000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993475000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993470000000000L, rs.getLong(2));
+                assertTrue(rs.next());
+                assertEquals("5SEC", rs.getString(1));
+                assertEquals(1462993430000000000L, rs.getLong(2));
+                assertFalse(rs.next());
+            }
+        } finally {
+            conn.close();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/a05137b2/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index 4c18bf8..6fab728 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -77,6 +77,7 @@ import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ProjectedColumn;
+import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.types.PBoolean;
 import org.apache.phoenix.schema.types.PDataType;
@@ -500,11 +501,11 @@ public class JoinCompiler {
                 rhsCompiler.reset();
                 Expression right = condition.getRHS().accept(rhsCompiler);
                 PDataType toType = getCommonType(left.getDataType(), 
right.getDataType());
-                if (left.getDataType() != toType) {
-                    left = CoerceExpression.create(left, toType);
+                if (left.getDataType() != toType || left.getSortOrder() == 
SortOrder.DESC) {
+                    left = CoerceExpression.create(left, toType, 
SortOrder.ASC, left.getMaxLength());
                 }
-                if (right.getDataType() != toType) {
-                    right = CoerceExpression.create(right, toType);
+                if (right.getDataType() != toType || right.getSortOrder() == 
SortOrder.DESC) {
+                    right = CoerceExpression.create(right, toType, 
SortOrder.ASC, right.getMaxLength());
                 }
                 compiled.add(new Pair<Expression, Expression>(left, right));
             }

Reply via email to