phoenix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ramkris...@apache.org
Subject [4/4] phoenix git commit: Phoenix-1453 - Collect row counts per region in stats table (Ramkrishna)
Date Wed, 14 Jan 2015 04:19:56 GMT
Phoenix-1453 - Collect row counts per region in stats table (Ramkrishna)


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

Branch: refs/heads/4.0
Commit: 2fb019a2fa35f3a3d7ccee667fbe4b703d8deaa2
Parents: ba3fa34
Author: Ramkrishna <ramkrishna.s.vasudevan@intel.com>
Authored: Wed Jan 14 09:48:51 2015 +0530
Committer: Ramkrishna <ramkrishna.s.vasudevan@intel.com>
Committed: Wed Jan 14 09:48:51 2015 +0530

----------------------------------------------------------------------
 .../end2end/StatsCollectorAbstractIT.java       |   77 +
 .../phoenix/end2end/StatsCollectorIT.java       |  108 +-
 .../StatsCollectorWithSplitsAndMultiCFIT.java   |  254 +++
 .../coprocessor/MetaDataEndpointImpl.java.orig  | 1793 ++++++++++++++++++
 .../phoenix/coprocessor/MetaDataProtocol.java   |    2 +-
 .../generated/PGuidePostsProtos.java            |  732 +++++++
 .../coprocessor/generated/PTableProtos.java     |  259 ++-
 .../org/apache/phoenix/execute/ScanPlan.java    |    3 +-
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |    2 +
 .../query/ConnectionQueryServicesImpl.java      |    8 +-
 .../query/ConnectionlessQueryServicesImpl.java  |    1 -
 .../apache/phoenix/query/QueryConstants.java    |    2 +
 .../org/apache/phoenix/schema/PTableImpl.java   |   24 +-
 .../phoenix/schema/stats/GuidePostsInfo.java    |  174 +-
 .../schema/stats/StatisticsCollector.java       |   97 +-
 .../phoenix/schema/stats/StatisticsScanner.java |   29 +-
 .../phoenix/schema/stats/StatisticsUtil.java    |   51 +-
 .../phoenix/schema/stats/StatisticsWriter.java  |   98 +-
 .../java/org/apache/phoenix/util/TestUtil.java  |   37 +-
 phoenix-protocol/src/main/PGuidePosts.proto     |   10 +
 phoenix-protocol/src/main/PTable.proto          |    3 +
 21 files changed, 3471 insertions(+), 293 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorAbstractIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorAbstractIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorAbstractIT.java
new file mode 100644
index 0000000..ab337d6
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorAbstractIT.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.end2end;
+
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.ConnectionQueryServices;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Maps;
+@Category(NeedsOwnMiniClusterTest.class)
+public abstract class StatsCollectorAbstractIT extends BaseOwnClusterHBaseManagedTimeIT {
+    protected static final String STATS_TEST_TABLE_NAME = "S";
+    protected static final String STATS_TEST_TABLE_NAME_NEW = "S_NEW";
+    protected static final byte[] STATS_TEST_TABLE_BYTES = Bytes.toBytes(STATS_TEST_TABLE_NAME);
+    protected static final byte[] STATS_TEST_TABLE_BYTES_NEW = Bytes.toBytes(STATS_TEST_TABLE_NAME_NEW);
+
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        Map<String,String> props = Maps.newHashMapWithExpectedSize(3);
+        // Must update config before starting server
+        props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(20));
+        props.put(QueryServices.EXPLAIN_CHUNK_COUNT_ATTRIB, Boolean.TRUE.toString());
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
+    
+    protected void splitTable(Connection conn, byte[] splitPoint, byte[] tabName) throws
IOException, InterruptedException, SQLException {
+        ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
+        int nRegionsNow = services.getAllTableRegions(tabName).size();
+        HBaseAdmin admin = services.getAdmin();
+        try {
+            admin.split(tabName, splitPoint);
+            int nTries = 0;
+            int nRegions;
+            do {
+                Thread.sleep(2000);
+                services.clearTableRegionCache(tabName);
+                nRegions = services.getAllTableRegions(tabName).size();
+                nTries++;
+            } while (nRegions == nRegionsNow && nTries < 10);
+            if (nRegions == nRegionsNow) {
+                fail();
+            }
+            // FIXME: I see the commit of the stats finishing before this with a lower timestamp
that the scan timestamp,
+            // yet without this sleep, the query finds the old data. Seems like an HBase
bug and a potentially serious one.
+            Thread.sleep(8000);
+        } finally {
+            admin.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
index 8b3bdee..6d3eca5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
@@ -20,10 +20,8 @@ package org.apache.phoenix.end2end;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 import static org.apache.phoenix.util.TestUtil.getAllSplits;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.sql.Array;
@@ -37,27 +35,22 @@ import java.util.Map;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.HColumnDescriptor;
-import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
-import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.ConnectionQueryServices;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
 import org.apache.phoenix.util.PropertiesUtil;
-import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
-import org.apache.phoenix.util.TestUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.google.common.collect.Maps;
 
 
-public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
+public class StatsCollectorIT extends StatsCollectorAbstractIT {
     private static final String STATS_TEST_TABLE_NAME = "S";
-    private static final byte[] STATS_TEST_TABLE_BYTES = Bytes.toBytes(STATS_TEST_TABLE_NAME);
         
     @BeforeClass
     public static void doSetup() throws Exception {
@@ -308,103 +301,4 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT
{
         assertEquals(nRows/2+1, keyRanges.size());
         
     }
-
-
-    private void splitTable(Connection conn, byte[] splitPoint) throws IOException, InterruptedException,
SQLException {
-        ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
-        int nRegionsNow = services.getAllTableRegions(STATS_TEST_TABLE_BYTES).size();
-        HBaseAdmin admin = services.getAdmin();
-        try {
-            admin.split(STATS_TEST_TABLE_BYTES, splitPoint);
-            int nTries = 0;
-            int nRegions;
-            do {
-                Thread.sleep(2000);
-                services.clearTableRegionCache(STATS_TEST_TABLE_BYTES);
-                nRegions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES).size();
-                nTries++;
-            } while (nRegions == nRegionsNow && nTries < 10);
-            if (nRegions == nRegionsNow) {
-                fail();
-            }
-            // FIXME: I see the commit of the stats finishing before this with a lower timestamp
that the scan timestamp,
-            // yet without this sleep, the query finds the old data. Seems like an HBase
bug and a potentially serious one.
-            Thread.sleep(8000);
-        } finally {
-            admin.close();
-        }
-    }
-    
-    @Test
-    public void testSplitUpdatesStats() throws Exception {
-        int nRows = 10;
-        Connection conn;
-        PreparedStatement stmt;
-        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
-        conn = DriverManager.getConnection(getUrl(), props);
-        conn.createStatement().execute("CREATE TABLE " + STATS_TEST_TABLE_NAME + "(k VARCHAR
PRIMARY KEY, v INTEGER) " + HColumnDescriptor.KEEP_DELETED_CELLS + "=" + Boolean.FALSE);
-        stmt = conn.prepareStatement("UPSERT INTO " + STATS_TEST_TABLE_NAME + " VALUES(?,?)");
-        for (int i = 0; i < nRows; i++) {
-            stmt.setString(1, Character.toString((char) ('a' + i)));
-            stmt.setInt(2, i);
-            stmt.executeUpdate();
-        }
-        conn.commit();
-        
-        ResultSet rs;
-        TestUtil.analyzeTable(conn, STATS_TEST_TABLE_NAME);
-        List<KeyRange>keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME);
-        assertEquals(nRows+1, keyRanges.size());
-        rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + STATS_TEST_TABLE_NAME);
-        assertEquals("CLIENT " + (nRows+1) + "-CHUNK " + "PARALLEL 1-WAY FULL SCAN OVER "
+ STATS_TEST_TABLE_NAME, QueryUtil.getExplainPlan(rs));
-
-        ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
-        List<HRegionLocation> regions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES);
-        assertEquals(1, regions.size());
- 
-        rs = conn.createStatement().executeQuery("SELECT GUIDE_POSTS_COUNT, REGION_NAME FROM
SYSTEM.STATS WHERE PHYSICAL_NAME='"+STATS_TEST_TABLE_NAME+"' AND REGION_NAME IS NOT NULL");
-        assertTrue(rs.next());
-        assertEquals(nRows, rs.getLong(1));
-        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
-        assertFalse(rs.next());
-
-        byte[] midPoint = Bytes.toBytes(Character.toString((char) ('a' + (nRows/2))));
-        splitTable(conn, midPoint);
-        
-        keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME);
-        assertEquals(nRows+1, keyRanges.size()); // Same number as before because split was
at guidepost
-        
-        regions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES);
-        assertEquals(2, regions.size());
-        rs = conn.createStatement().executeQuery("SELECT GUIDE_POSTS_COUNT, REGION_NAME FROM
SYSTEM.STATS WHERE PHYSICAL_NAME='"+STATS_TEST_TABLE_NAME+"' AND REGION_NAME IS NOT NULL");
-        assertTrue(rs.next());
-        assertEquals(nRows/2, rs.getLong(1));
-        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
-        assertTrue(rs.next());
-        assertEquals(nRows/2 - 1, rs.getLong(1));
-        assertEquals(regions.get(1).getRegionInfo().getRegionNameAsString(), rs.getString(2));
-        assertFalse(rs.next());
-
-        byte[] midPoint2 = Bytes.toBytes("cj");
-        splitTable(conn, midPoint2);
-        
-        keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME);
-        assertEquals(nRows+2, keyRanges.size()); // One extra due to split between guideposts
-        
-        regions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES);
-        assertEquals(3, regions.size());
-        rs = conn.createStatement().executeQuery("SELECT GUIDE_POSTS_COUNT, REGION_NAME FROM
SYSTEM.STATS WHERE PHYSICAL_NAME='"+STATS_TEST_TABLE_NAME+"' AND REGION_NAME IS NOT NULL");
-        assertTrue(rs.next());
-        assertEquals(3, rs.getLong(1));
-        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
-        assertTrue(rs.next());
-        assertEquals(2, rs.getLong(1));
-        assertEquals(regions.get(1).getRegionInfo().getRegionNameAsString(), rs.getString(2));
-        assertTrue(rs.next());
-        assertEquals(nRows/2 - 1, rs.getLong(1));
-        assertEquals(regions.get(2).getRegionInfo().getRegionNameAsString(), rs.getString(2));
-        assertFalse(rs.next());
-        
-        conn.close();
-    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
new file mode 100644
index 0000000..e1497c1
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.apache.phoenix.util.TestUtil.getAllSplits;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.ConnectionQueryServices;
+import org.apache.phoenix.query.KeyRange;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.stats.GuidePostsInfo;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class StatsCollectorWithSplitsAndMultiCFIT extends StatsCollectorAbstractIT {
+    private static final String STATS_TEST_TABLE_NAME_NEW = "S_NEW";
+    private static final byte[] STATS_TEST_TABLE_NEW_BYTES = Bytes.toBytes(STATS_TEST_TABLE_NAME_NEW);
+
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        Map<String, String> props = Maps.newHashMapWithExpectedSize(3);
+        // Must update config before starting server
+        props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(1000));
+        props.put(QueryServices.EXPLAIN_CHUNK_COUNT_ATTRIB, Boolean.TRUE.toString());
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
+
+    @Test
+    public void testWithMultiCF() throws Exception {
+        int nRows = 20;
+        Connection conn;
+        PreparedStatement stmt;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute(
+                "CREATE TABLE " + STATS_TEST_TABLE_NAME_NEW
+                        + "(k VARCHAR PRIMARY KEY, a.v INTEGER, b.v INTEGER, c.v INTEGER
NULL, d.v INTEGER NULL) ");
+        stmt = conn.prepareStatement("UPSERT INTO " + STATS_TEST_TABLE_NAME_NEW + " VALUES(?,?,
?, ?, ?)");
+        byte[] val = new byte[250];
+        for (int i = 0; i < nRows; i++) {
+            stmt.setString(1, Character.toString((char)('a' + i)) + Bytes.toString(val));
+            stmt.setInt(2, i);
+            stmt.setInt(3, i);
+            stmt.setInt(4, i);
+            stmt.setInt(5, i);
+            stmt.executeUpdate();
+        }
+        conn.commit();
+        stmt = conn.prepareStatement("UPSERT INTO " + STATS_TEST_TABLE_NAME_NEW + "(k, c.v,
d.v) VALUES(?,?,?)");
+        for (int i = 0; i < 5; i++) {
+            stmt.setString(1, Character.toString((char)('a' + 'z' + i)) + Bytes.toString(val));
+            stmt.setInt(2, i);
+            stmt.setInt(3, i);
+            stmt.executeUpdate();
+        }
+        conn.commit();
+
+        ResultSet rs;
+        TestUtil.analyzeTable(conn, STATS_TEST_TABLE_NAME_NEW);
+        List<KeyRange> keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME_NEW);
+        assertEquals(12, keyRanges.size());
+        rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + STATS_TEST_TABLE_NAME_NEW);
+        assertEquals("CLIENT " + (12) + "-CHUNK " + "PARALLEL 1-WAY FULL SCAN OVER " + STATS_TEST_TABLE_NAME_NEW,
+                QueryUtil.getExplainPlan(rs));
+
+        ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
+        List<HRegionLocation> regions = services.getAllTableRegions(STATS_TEST_TABLE_NEW_BYTES);
+        assertEquals(1, regions.size());
+
+        rs = conn.createStatement().executeQuery(
+                "SELECT GUIDE_POSTS_COUNT, REGION_NAME, GUIDE_POSTS_ROW_COUNT FROM SYSTEM.STATS
WHERE PHYSICAL_NAME='"
+                        + STATS_TEST_TABLE_NAME_NEW + "' AND REGION_NAME IS NOT NULL");
+        assertTrue(rs.next());
+        assertEquals(11, (rs.getLong(1)));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        // I get 25 here because for A there is an entry added with the default col
+        assertEquals(25, rs.getLong(3));
+        assertTrue(rs.next());
+        assertEquals(5, (rs.getLong(1)));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        // for b the count is lesser by 5
+        assertEquals(20, rs.getLong(3));
+        assertTrue(rs.next());
+        assertEquals(6, (rs.getLong(1)));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(25, rs.getLong(3));
+        assertTrue(rs.next());
+        assertEquals(6, (rs.getLong(1)));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(25, rs.getLong(3));
+        assertFalse(rs.next());
+        Collection<GuidePostsInfo> infos = TestUtil.getGuidePostsList(conn, STATS_TEST_TABLE_NAME_NEW);
+        long[] rowCountArr = new long[]{25, 20, 25, 25};
+        // CF A alone has double the bytecount because it has column qualifier A and column
qualifier _0
+        long[] byteCountArr = new long[]{12120, 5540, 6652, 6652};
+        int i = 0;
+        for(GuidePostsInfo info : infos) {
+            assertRowCountAndByteCount(info, rowCountArr[i], byteCountArr[i]);
+            i++;
+        }
+    }
+
+    protected void assertRowCountAndByteCount(GuidePostsInfo info, long rowCount, long byteCount)
{
+        assertEquals(info.getRowCount(), rowCount);
+        assertEquals(info.getByteCount(), byteCount);
+    }
+
+    @Test
+    public void testSplitUpdatesStats() throws Exception {
+        int nRows = 20;
+        Connection conn;
+        PreparedStatement stmt;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute(
+                "CREATE TABLE " + STATS_TEST_TABLE_NAME + "(k VARCHAR PRIMARY KEY, v INTEGER)
"
+                        + HColumnDescriptor.KEEP_DELETED_CELLS + "=" + Boolean.FALSE);
+        stmt = conn.prepareStatement("UPSERT INTO " + STATS_TEST_TABLE_NAME + " VALUES(?,?)");
+        byte[] val = new byte[250];
+        for (int i = 0; i < nRows; i++) {
+            stmt.setString(1, Character.toString((char)('a' + i)) + Bytes.toString(val));
+            stmt.setInt(2, i);
+            stmt.executeUpdate();
+        }
+        conn.commit();
+
+        ResultSet rs;
+        TestUtil.analyzeTable(conn, STATS_TEST_TABLE_NAME);
+        Collection<GuidePostsInfo> infos = TestUtil.getGuidePostsList(conn, STATS_TEST_TABLE_NAME);
+        for (GuidePostsInfo info : infos) {
+            assertEquals(20, info.getRowCount());
+            assertEquals(11020, info.getByteCount());
+            break;
+        }
+        List<KeyRange> keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME);
+        assertEquals((nRows / 2) + 1, keyRanges.size());
+        rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + STATS_TEST_TABLE_NAME);
+        assertEquals("CLIENT " + ((nRows / 2) + 1) + "-CHUNK " + "PARALLEL 1-WAY FULL SCAN
OVER "
+                + STATS_TEST_TABLE_NAME, QueryUtil.getExplainPlan(rs));
+
+        ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
+        List<HRegionLocation> regions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES);
+        assertEquals(1, regions.size());
+
+        rs = conn.createStatement().executeQuery(
+                "SELECT GUIDE_POSTS_COUNT, REGION_NAME, GUIDE_POSTS_ROW_COUNT FROM SYSTEM.STATS
WHERE PHYSICAL_NAME='"
+                        + STATS_TEST_TABLE_NAME + "' AND REGION_NAME IS NOT NULL");
+        assertTrue(rs.next());
+        assertEquals(nRows / 2, (rs.getLong(1)));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        //PhoenixArray arr = (PhoenixArray)rs.getArray(3);
+        assertEquals(20, rs.getLong(3));
+        assertFalse(rs.next());
+
+        byte[] midPoint = Bytes.toBytes(Character.toString((char)('a' + (5))));
+        splitTable(conn, midPoint, STATS_TEST_TABLE_BYTES);
+
+        keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME);
+        assertEquals(12, keyRanges.size()); // Same number as before because split was at
guidepost
+
+        regions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES);
+        assertEquals(2, regions.size());
+        rs = conn.createStatement().executeQuery(
+                "SELECT GUIDE_POSTS_COUNT, REGION_NAME, "
+                        + "GUIDE_POSTS_ROW_COUNT FROM SYSTEM.STATS WHERE PHYSICAL_NAME='"
+ STATS_TEST_TABLE_NAME
+                        + "' AND REGION_NAME IS NOT NULL");
+        assertTrue(rs.next());
+        assertEquals(2, rs.getLong(1));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(6, rs.getLong(3));
+        assertTrue(rs.next());
+        assertEquals(8, rs.getLong(1));
+        assertEquals(regions.get(1).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(14, rs.getLong(3));
+        assertFalse(rs.next());
+
+        byte[] midPoint2 = Bytes.toBytes("cj");
+        splitTable(conn, midPoint2, STATS_TEST_TABLE_BYTES);
+
+        keyRanges = getAllSplits(conn, STATS_TEST_TABLE_NAME);
+        assertEquals((nRows / 2) + 3, keyRanges.size()); // One extra due to split between
guideposts
+
+        regions = services.getAllTableRegions(STATS_TEST_TABLE_BYTES);
+        assertEquals(3, regions.size());
+        rs = conn.createStatement().executeQuery(
+                "SELECT GUIDE_POSTS_COUNT, REGION_NAME, GUIDE_POSTS_ROW_COUNT FROM SYSTEM.STATS
WHERE PHYSICAL_NAME='"
+                        + STATS_TEST_TABLE_NAME + "' AND REGION_NAME IS NOT NULL");
+        assertTrue(rs.next());
+        assertEquals(1, rs.getLong(1));
+        assertEquals(regions.get(0).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(4, rs.getLong(3));
+        assertTrue(rs.next());
+        assertEquals(1, rs.getLong(1));
+        assertEquals(regions.get(1).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(3, rs.getLong(3));
+        assertTrue(rs.next());
+        assertEquals(8, rs.getLong(1));
+        assertEquals(regions.get(2).getRegionInfo().getRegionNameAsString(), rs.getString(2));
+        assertEquals(14, rs.getLong(3));
+        assertFalse(rs.next());
+        rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + STATS_TEST_TABLE_NAME);
+        assertEquals("CLIENT " + ((nRows / 2) + 3) + "-CHUNK " + "PARALLEL 1-WAY FULL SCAN
OVER "
+                + STATS_TEST_TABLE_NAME, QueryUtil.getExplainPlan(rs));
+
+        TestUtil.analyzeTable(conn, STATS_TEST_TABLE_NAME);
+        rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + STATS_TEST_TABLE_NAME);
+        assertEquals("CLIENT " + ((nRows / 2) + 2) + "-CHUNK " + "PARALLEL 1-WAY FULL SCAN
OVER "
+                + STATS_TEST_TABLE_NAME, QueryUtil.getExplainPlan(rs));
+        infos = TestUtil.getGuidePostsList(conn, STATS_TEST_TABLE_NAME);
+        for (GuidePostsInfo info : infos) {
+            assertEquals(20, info.getRowCount());
+            assertEquals(9918, info.getByteCount());
+            break;
+        }
+        conn.close();
+    }
+}


Mime
View raw message