Return-Path: X-Original-To: apmail-phoenix-commits-archive@minotaur.apache.org Delivered-To: apmail-phoenix-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9DF1E187FC for ; Sat, 4 Jul 2015 07:37:21 +0000 (UTC) Received: (qmail 3533 invoked by uid 500); 4 Jul 2015 07:37:21 -0000 Delivered-To: apmail-phoenix-commits-archive@phoenix.apache.org Received: (qmail 3492 invoked by uid 500); 4 Jul 2015 07:37:21 -0000 Mailing-List: contact commits-help@phoenix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@phoenix.apache.org Delivered-To: mailing list commits@phoenix.apache.org Received: (qmail 3482 invoked by uid 99); 4 Jul 2015 07:37:21 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 04 Jul 2015 07:37:21 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 2F751E04D9; Sat, 4 Jul 2015 07:37:21 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ramkrishna@apache.org To: commits@phoenix.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: phoenix git commit: PHOENIX-2064 ARRAY constructor doesn't work when used in COUNT DISTINCT (Dumindu Buddhika) Date: Sat, 4 Jul 2015 07:37:21 +0000 (UTC) Repository: phoenix Updated Branches: refs/heads/master f579e7256 -> 1c10fda17 PHOENIX-2064 ARRAY constructor doesn't work when used in COUNT DISTINCT (Dumindu Buddhika) Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/1c10fda1 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/1c10fda1 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/1c10fda1 Branch: refs/heads/master Commit: 1c10fda17975bc3c2a13542b0041fe6bd7fee50c Parents: f579e72 Author: ramkrishna Authored: Fri Jul 3 23:44:44 2015 +0530 Committer: ramkrishna Committed: Sat Jul 4 13:07:01 2015 +0530 ---------------------------------------------------------------------- .../org/apache/phoenix/end2end/ArrayIT.java | 119 +++++++++++++++++++ .../expression/ArrayConstructorExpression.java | 19 +-- 2 files changed, 131 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c10fda1/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java index 4b79142..27887e4 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java @@ -1861,4 +1861,123 @@ public class ArrayIT extends BaseClientManagedTimeIT { conn.close(); } } + + @Test + public void testArrayConstructorWithMultipleRows1() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "CREATE TABLE regions1 (region_name VARCHAR PRIMARY KEY, a INTEGER, b INTEGER)"; + conn.createStatement().execute(ddl); + conn.commit(); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO regions1(region_name, a, b) VALUES('a', 6,3)"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions1(region_name, a, b) VALUES('b', 2,4)"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions1(region_name, a, b) VALUES('c', 6,3)"); + stmt.execute(); + conn.commit(); + ResultSet rs; + rs = conn.createStatement().executeQuery("SELECT COUNT(DISTINCT ARRAY[a,b]) from regions1"); + assertTrue(rs.next()); + assertEquals(2, rs.getInt(1)); + } + + @Test + public void testArrayConstructorWithMultipleRows2() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "CREATE TABLE regions2 (region_name VARCHAR PRIMARY KEY, a INTEGER, b INTEGER)"; + conn.createStatement().execute(ddl); + conn.commit(); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO regions2(region_name, a, b) VALUES('a', 6,3)"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions2(region_name, a, b) VALUES('b', 2,4)"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions2(region_name, a, b) VALUES('c', 6,3)"); + stmt.execute(); + conn.commit(); + ResultSet rs; + rs = conn.createStatement().executeQuery("SELECT ARRAY[a,b] from regions2"); + assertTrue(rs.next()); + Array arr = conn.createArrayOf("INTEGER", new Object[]{6, 3}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + arr = conn.createArrayOf("INTEGER", new Object[]{2, 4}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + arr = conn.createArrayOf("INTEGER", new Object[]{6, 3}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + } + + @Test + public void testArrayConstructorWithMultipleRows3() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "CREATE TABLE regions3 (region_name VARCHAR PRIMARY KEY, a VARCHAR, b VARCHAR)"; + conn.createStatement().execute(ddl); + conn.commit(); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO regions3(region_name, a, b) VALUES('a', 'foo', 'abc')"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions3(region_name, a, b) VALUES('b', 'abc', 'dfg')"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions3(region_name, a, b) VALUES('c', 'foo', 'abc')"); + stmt.execute(); + conn.commit(); + ResultSet rs; + rs = conn.createStatement().executeQuery("SELECT ARRAY[a,b] from regions3"); + assertTrue(rs.next()); + Array arr = conn.createArrayOf("VARCHAR", new Object[]{"foo", "abc"}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + arr = conn.createArrayOf("VARCHAR", new Object[]{"abc", "dfg"}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + arr = conn.createArrayOf("VARCHAR", new Object[]{"foo", "abc"}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + } + + @Test + public void testArrayConstructorWithMultipleRows4() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "CREATE TABLE regions4 (region_name VARCHAR PRIMARY KEY, a VARCHAR, b VARCHAR)"; + conn.createStatement().execute(ddl); + conn.commit(); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO regions4(region_name, a, b) VALUES('a', 'foo', 'abc')"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions4(region_name, a, b) VALUES('b', 'abc', 'dfg')"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions4(region_name, a, b) VALUES('c', 'foo', 'abc')"); + stmt.execute(); + conn.commit(); + ResultSet rs; + rs = conn.createStatement().executeQuery("SELECT COUNT(DISTINCT ARRAY[a,b]) from regions4"); + assertTrue(rs.next()); + assertEquals(2, rs.getInt(1)); + } + + @Test + public void testArrayConstructorWithMultipleRows5() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "CREATE TABLE regions5 (region_name VARCHAR PRIMARY KEY, a VARCHAR, b VARCHAR)"; + conn.createStatement().execute(ddl); + conn.commit(); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO regions5(region_name, a, b) VALUES('a', 'foo', 'abc')"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions5(region_name, a, b) VALUES('b', 'abc', 'dfg')"); + stmt.execute(); + stmt = conn.prepareStatement("UPSERT INTO regions5(region_name, a, b) VALUES('c', 'foo', 'abc')"); + stmt.execute(); + conn.commit(); + ResultSet rs; + rs = conn.createStatement().executeQuery("SELECT ARRAY_APPEND(ARRAY[a,b], 'oo') from regions5"); + assertTrue(rs.next()); + Array arr = conn.createArrayOf("VARCHAR", new Object[]{"foo", "abc", "oo"}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + arr = conn.createArrayOf("VARCHAR", new Object[]{"abc", "dfg", "oo"}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + arr = conn.createArrayOf("VARCHAR", new Object[]{"foo", "abc", "oo"}); + assertEquals(arr, rs.getArray(1)); + rs.next(); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c10fda1/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java index 15cd14c..da581ce 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java @@ -23,6 +23,7 @@ import org.apache.phoenix.query.QueryConstants; import org.apache.phoenix.schema.tuple.Tuple; import org.apache.phoenix.schema.types.PArrayDataType; import org.apache.phoenix.schema.types.PDataType; +import org.apache.phoenix.util.ByteUtil; import org.apache.phoenix.util.TrustedByteArrayOutputStream; /** @@ -32,8 +33,7 @@ public class ArrayConstructorExpression extends BaseCompoundExpression { private PDataType baseType; private int position = -1; private Object[] elements; - private TrustedByteArrayOutputStream byteStream = null; - private DataOutputStream oStream = null; + private final ImmutableBytesWritable valuePtr = new ImmutableBytesWritable(); private int estimatedSize = 0; // store the offset postion in this. Later based on the total size move this to a byte[] // and serialize into byte stream @@ -54,13 +54,11 @@ public class ArrayConstructorExpression extends BaseCompoundExpression { private void init(PDataType baseType) { this.baseType = baseType; elements = new Object[getChildren().size()]; + valuePtr.set(ByteUtil.EMPTY_BYTE_ARRAY); estimatedSize = PArrayDataType.estimateSize(this.children.size(), this.baseType); if (!this.baseType.isFixedWidth()) { offsetPos = new int[children.size()]; - byteStream = new TrustedByteArrayOutputStream(estimatedSize); - } else { - byteStream = new TrustedByteArrayOutputStream(estimatedSize); - } + } } @Override @@ -73,14 +71,20 @@ public class ArrayConstructorExpression extends BaseCompoundExpression { super.reset(); position = 0; Arrays.fill(elements, null); + valuePtr.set(ByteUtil.EMPTY_BYTE_ARRAY); } @Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { + if (position == elements.length) { + ptr.set(valuePtr.get(), valuePtr.getOffset(), valuePtr.getLength()); + return true; + } + TrustedByteArrayOutputStream byteStream = new TrustedByteArrayOutputStream(estimatedSize); + DataOutputStream oStream = new DataOutputStream(byteStream); try { int noOfElements = children.size(); int nNulls = 0; - oStream = new DataOutputStream(byteStream); for (int i = position >= 0 ? position : 0; i < elements.length; i++) { Expression child = children.get(i); if (!child.evaluate(tuple, ptr)) { @@ -125,6 +129,7 @@ public class ArrayConstructorExpression extends BaseCompoundExpression { PArrayDataType.serializeHeaderInfoIntoStream(oStream, noOfElements); } ptr.set(byteStream.getBuffer(), 0, byteStream.size()); + valuePtr.set(ptr.get(), ptr.getOffset(), ptr.getLength()); return true; } catch (IOException e) { throw new RuntimeException("Exception while serializing the byte array");