You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ra...@apache.org on 2015/07/04 09:37:21 UTC
phoenix git commit: PHOENIX-2064 ARRAY constructor doesn't work when
used in COUNT DISTINCT (Dumindu Buddhika)
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 <ra...@gmail.com>
Authored: Fri Jul 3 23:44:44 2015 +0530
Committer: ramkrishna <ra...@gmail.com>
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");