phoenix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamestay...@apache.org
Subject git commit: PHOENIX-1328 Update ANALYZE syntax to collect stats on index tables and all tables (ramkrishna.s.vasudevan)
Date Wed, 08 Oct 2014 19:23:28 GMT
Repository: phoenix
Updated Branches:
  refs/heads/master bc530f206 -> 3bd9d888b


PHOENIX-1328 Update ANALYZE syntax to collect stats on index tables and all tables (ramkrishna.s.vasudevan)


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

Branch: refs/heads/master
Commit: 3bd9d888b522b443e87e00e107a29ad3c88ab052
Parents: bc530f2
Author: James Taylor <jtaylor@salesforce.com>
Authored: Wed Oct 8 12:21:06 2014 -0700
Committer: James Taylor <jtaylor@salesforce.com>
Committed: Wed Oct 8 12:21:06 2014 -0700

----------------------------------------------------------------------
 .../org/apache/phoenix/end2end/ArrayIT.java     |  2 +-
 .../phoenix/end2end/ParallelIteratorsIT.java    | 40 ++++++++++++++++++--
 .../org/apache/phoenix/end2end/QueryIT.java     |  2 +-
 .../phoenix/end2end/StatsCollectorIT.java       | 10 ++---
 .../salted/SaltedTableUpsertSelectIT.java       |  2 +-
 phoenix-core/src/main/antlr3/PhoenixSQL.g       |  9 +++--
 .../apache/phoenix/jdbc/PhoenixStatement.java   | 14 +++----
 .../apache/phoenix/parse/ParseNodeFactory.java  |  5 ++-
 .../parse/UpdateStatisticsStatement.java        | 25 +++++++++++-
 .../apache/phoenix/schema/MetaDataClient.java   | 26 +++++++++++--
 .../java/org/apache/phoenix/schema/PTable.java  |  3 +-
 .../org/apache/phoenix/schema/PTableImpl.java   | 38 +++++++++++--------
 .../apache/phoenix/schema/stat/PTableStats.java | 13 +++++++
 .../phoenix/schema/stat/PTableStatsImpl.java    |  2 -
 .../schema/stat/StatisticsCollectionScope.java  | 28 ++++++++++++++
 .../phoenix/schema/stat/StatisticsUtil.java     |  2 +-
 .../java/org/apache/phoenix/util/TestUtil.java  | 16 ++++++--
 17 files changed, 185 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/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 ab2ad48..3fb276c 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
@@ -171,7 +171,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
 	}
 
     private void analyzeTable(Connection conn, String tableWithArray) throws SQLException
{
-        String analyse = "ANALYZE  "+tableWithArray;
+        String analyse = "UPDATE STATISTICS  "+tableWithArray;
 		PreparedStatement statement = conn.prepareStatement(analyse);
         statement.execute();
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
index dd5b661..a1c6217 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
@@ -20,6 +20,8 @@ package org.apache.phoenix.end2end;
 import static org.apache.phoenix.util.TestUtil.STABLE_NAME;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 import static org.apache.phoenix.util.TestUtil.analyzeTable;
+import static org.apache.phoenix.util.TestUtil.analyzeTableColumns;
+import static org.apache.phoenix.util.TestUtil.analyzeTableIndex;
 import static org.apache.phoenix.util.TestUtil.getAllSplits;
 import static org.apache.phoenix.util.TestUtil.getSplits;
 import static org.junit.Assert.assertEquals;
@@ -43,6 +45,7 @@ import com.google.common.collect.Maps;
 @Category(NeedsOwnMiniClusterTest.class)
 public class ParallelIteratorsIT extends BaseOwnClusterHBaseManagedTimeIT {
 
+    private static final String STABLE_INDEX = "STABLE_INDEX";
     protected static final byte[] KMIN  = new byte[] {'!'};
     protected static final byte[] KMIN2  = new byte[] {'.'};
     protected static final byte[] K1  = new byte[] {'a'};
@@ -72,7 +75,7 @@ public class ParallelIteratorsIT extends BaseOwnClusterHBaseManagedTimeIT
{
         Connection conn = DriverManager.getConnection(getUrl(), TEST_PROPERTIES);
         initTableValues(conn);
         
-        PreparedStatement stmt = conn.prepareStatement("ANALYZE STABLE");
+        PreparedStatement stmt = conn.prepareStatement("UPDATE STATISTICS STABLE");
         stmt.execute();
         
         List<KeyRange> keyRanges;
@@ -108,19 +111,48 @@ public class ParallelIteratorsIT extends BaseOwnClusterHBaseManagedTimeIT
{
         Connection conn = DriverManager.getConnection(getUrl(), TEST_PROPERTIES);
         byte[][] splits = new byte[][] { K3, K9, KR };
         ensureTableCreated(getUrl(), STABLE_NAME, splits);
-
+        // create index
+        conn.createStatement().execute("CREATE INDEX " + STABLE_INDEX + " ON " + STABLE_NAME
+ "( \"value\")");
+        // before upserting
         List<KeyRange> keyRanges = getAllSplits(conn);
         assertEquals(4, keyRanges.size());
         upsert(conn, new byte[][] { KMIN, K4, K11 });
-        analyzeTable(conn);
+        // Analyze table alone
+        analyzeTableColumns(conn);
+        keyRanges = getAllSplits(conn);
+        assertEquals(7, keyRanges.size());
+        // Get all splits on the index table before calling analyze on the index table
+        List<KeyRange> indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(1, indexSplits.size());
+        // Analyze the index table alone
+        analyzeTableIndex(conn, STABLE_NAME);
+        // check the splits of the main table 
         keyRanges = getAllSplits(conn);
         assertEquals(7, keyRanges.size());
+        // check the splits on the index table
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(4, indexSplits.size());
         upsert(conn, new byte[][] { KMIN2, K5, K12 });
+        // Update the stats for both the table and the index table
         analyzeTable(conn);
         keyRanges = getAllSplits(conn);
         assertEquals(10, keyRanges.size());
+        // the above analyze should have udpated the index splits also
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(7, indexSplits.size());
         upsert(conn, new byte[][] { K1, K6, KP });
-        analyzeTable(conn);
+        // Update only the table
+        analyzeTableColumns(conn);
+        keyRanges = getAllSplits(conn);
+        assertEquals(13, keyRanges.size());
+        // No change to the index splits
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(7, indexSplits.size());
+        analyzeTableIndex(conn, STABLE_NAME);
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        // the above analyze should have udpated the index splits only
+        assertEquals(10, indexSplits.size());
+        // No change in main table splits
         keyRanges = getAllSplits(conn);
         assertEquals(13, keyRanges.size());
         conn.close();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
index 674009b..07cb624 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
@@ -855,7 +855,7 @@ public class QueryIT extends BaseQueryIT {
     }
 
     private void analyzeTable(Connection conn, String tableName) throws IOException, SQLException
{
-        String query = "ANALYZE " + tableName;
+        String query = "UPDATE STATISTICS " + tableName;
         conn.createStatement().execute(query);
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/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 03ff316..49def02 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
@@ -48,7 +48,7 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         Array array;
         conn = upsertValues(props, "t");
         // CAll the update statistics query here. If already major compaction has run this
will not get executed.
-        stmt = conn.prepareStatement("ANALYZE T");
+        stmt = conn.prepareStatement("UPDATE STATISTICS T");
         stmt.execute();
         stmt = upsertStmt(conn, "t");
         stmt.setString(1, "z");
@@ -62,7 +62,7 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         conn.close();
         conn = DriverManager.getConnection(getUrl(), props);
         // This analyze would not work
-        stmt = conn.prepareStatement("ANALYZE T");
+        stmt = conn.prepareStatement("UPDATE STATISTICS T");
         stmt.execute();
         rs = conn.createStatement().executeQuery("SELECT k FROM T");
         assertTrue(rs.next());
@@ -89,9 +89,9 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         conn = upsertValues(props, "x");
         conn = upsertValues(props, "z");
         // CAll the update statistics query here
-        stmt = conn.prepareStatement("ANALYZE X");
+        stmt = conn.prepareStatement("UPDATE STATISTICS X");
         stmt.execute();
-        stmt = conn.prepareStatement("ANALYZE Z");
+        stmt = conn.prepareStatement("UPDATE STATISTICS Z");
         stmt.execute();
         stmt = upsertStmt(conn, "x");
         stmt.setString(1, "z");
@@ -114,7 +114,7 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT
{
         conn.close();
         conn = DriverManager.getConnection(getUrl(), props);
         // This analyze would not work
-        stmt = conn.prepareStatement("ANALYZE Z");
+        stmt = conn.prepareStatement("UPDATE STATISTICS Z");
         stmt.execute();
         rs = conn.createStatement().executeQuery("SELECT k FROM Z");
         assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
index 690b15c..8015cbc 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
@@ -115,7 +115,7 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT
{
     }
     
     private void analyzeTable(Connection conn, String tableName) throws IOException, SQLException
{
-        String query = "ANALYZE " + tableName;
+        String query = "UPDATE STATISTICS " + tableName;
         conn.createStatement().execute(query);
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 980ec8b..4a28d9d 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -104,7 +104,9 @@ tokens
     MAXVALUE='maxvalue';
     CYCLE='cycle';
     CASCADE='cascade';
-    ANALYZE='analyze';
+    UPDATE='update';
+    STATISTICS='statistics';    
+    COLUMNS='columns';
 }
 
 
@@ -149,6 +151,7 @@ import org.apache.phoenix.schema.PDataType;
 import org.apache.phoenix.schema.PIndexState;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.PTable.IndexType;
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.parse.LikeParseNode.LikeType;
 }
@@ -496,8 +499,8 @@ alter_table_node returns [AlterTableStatement ret]
     ;
 
 update_statistics_node returns [UpdateStatisticsStatement ret]
-	:   ANALYZE t=from_table_name
-		{ret = factory.updateStatistics(factory.namedTable(null, t));}
+	:   UPDATE STATISTICS t=from_table_name (s=INDEX | s=ALL | s=COLUMNS)?
+		{ret = factory.updateStatistics(factory.namedTable(null, t), s == null ? StatisticsCollectionScope.getDefault()
: StatisticsCollectionScope.valueOf(SchemaUtil.normalizeIdentifier(s.getText())));}
 	;
 
 prop_name returns [String ret]

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index 30376e7..76fff24 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@ -45,7 +45,6 @@ import org.apache.phoenix.compile.DropSequenceCompiler;
 import org.apache.phoenix.compile.ExplainPlan;
 import org.apache.phoenix.compile.ExpressionProjector;
 import org.apache.phoenix.compile.FromCompiler;
-import org.apache.phoenix.compile.SubqueryRewriter;
 import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
 import org.apache.phoenix.compile.MutationPlan;
 import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
@@ -55,6 +54,7 @@ import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.compile.StatementNormalizer;
 import org.apache.phoenix.compile.StatementPlan;
+import org.apache.phoenix.compile.SubqueryRewriter;
 import org.apache.phoenix.compile.SubselectRewriter;
 import org.apache.phoenix.compile.UpsertCompiler;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
@@ -111,6 +111,7 @@ import org.apache.phoenix.schema.RowKeyValueAccessor;
 import org.apache.phoenix.schema.Sequence;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
 import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.trace.util.Tracing;
@@ -671,9 +672,8 @@ public class PhoenixStatement implements Statement, SQLCloseable, org.apache.pho
     
     private static class ExecutableUpdateStatisticsStatement extends UpdateStatisticsStatement
implements
             CompilableStatement {
-
-        public ExecutableUpdateStatisticsStatement(NamedTableNode table) {
-            super(table);
+        public ExecutableUpdateStatisticsStatement(NamedTableNode table, StatisticsCollectionScope
scope) {
+            super(table, scope);
         }
 
         @SuppressWarnings("unchecked")
@@ -694,7 +694,7 @@ public class PhoenixStatement implements Statement, SQLCloseable, org.apache.pho
 
                 @Override
                 public ExplainPlan getExplainPlan() throws SQLException {
-                    return new ExplainPlan(Collections.singletonList("ANALYZE"));
+                    return new ExplainPlan(Collections.singletonList("UPDATE STATISTICS"));
                 }
 
                 @Override
@@ -869,8 +869,8 @@ public class PhoenixStatement implements Statement, SQLCloseable, org.apache.pho
         }
 
         @Override
-        public UpdateStatisticsStatement updateStatistics(NamedTableNode table) {
-            return new ExecutableUpdateStatisticsStatement(table);
+        public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope
scope) {
+            return new ExecutableUpdateStatisticsStatement(table, scope);
         }
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index 951098e..51f3a36 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -47,6 +47,7 @@ import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
 import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.ListMultimap;
@@ -348,8 +349,8 @@ public class ParseNodeFactory {
         return new DivideParseNode(children);
     }
 
-    public UpdateStatisticsStatement updateStatistics(NamedTableNode table) {
-      return new UpdateStatisticsStatement(table);
+    public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope
scope) {
+      return new UpdateStatisticsStatement(table, scope);
     }
 
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
index 9eff74a..db8b7b5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
@@ -17,10 +17,31 @@
  */
 package org.apache.phoenix.parse;
 
-public class UpdateStatisticsStatement extends SingleTableStatement {
+import static org.apache.phoenix.schema.stat.StatisticsCollectionScope.ALL;
+import static org.apache.phoenix.schema.stat.StatisticsCollectionScope.COLUMNS;
+import static org.apache.phoenix.schema.stat.StatisticsCollectionScope.INDEX;
+
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
+
+import com.sun.istack.NotNull;
 
-    public UpdateStatisticsStatement(NamedTableNode table) {
+
+public class UpdateStatisticsStatement extends SingleTableStatement {
+    private final StatisticsCollectionScope scope;
+    public UpdateStatisticsStatement(NamedTableNode table, @NotNull StatisticsCollectionScope
scope) {
         super(table, 0);
+        this.scope = scope;
+    }
+
+    public boolean updateColumns() {
+        return scope == COLUMNS || scope == ALL;
+    }
+
+    public boolean updateIndex() {
+        return scope == INDEX || scope == ALL;
     }
 
+    public boolean updateAll() {
+        return scope == ALL;
+    };
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 18ea16d..70a7de1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -478,12 +478,31 @@ public class MetaDataClient {
         return connection.getQueryServices().updateData(plan);
     }
 
-    public MutationState updateStatistics(UpdateStatisticsStatement updateStatisticsStmt)
throws SQLException {
+    public MutationState updateStatistics(UpdateStatisticsStatement updateStatisticsStmt)
+            throws SQLException {
         // Check before updating the stats if we have reached the configured time to reupdate
the stats once again
-        long msMinBetweenUpdates = connection.getQueryServices().getProps()
-                .getLong(QueryServices.MIN_STATS_UPDATE_FREQ_MS_ATTRIB, QueryServicesOptions.DEFAULT_MIN_STATS_UPDATE_FREQ_MS);
+        final long msMinBetweenUpdates = connection
+                .getQueryServices()
+                .getProps()
+                .getLong(QueryServices.MIN_STATS_UPDATE_FREQ_MS_ATTRIB,
+                        QueryServicesOptions.DEFAULT_MIN_STATS_UPDATE_FREQ_MS);
         ColumnResolver resolver = FromCompiler.getResolver(updateStatisticsStmt, connection);
         PTable table = resolver.getTables().get(0).getTable();
+        List<PTable> indexes = table.getIndexes();
+        List<PTable> tables = Lists.newArrayListWithExpectedSize(1 + indexes.size());
+        if (updateStatisticsStmt.updateColumns()) {
+            tables.add(table);
+        }
+        if (updateStatisticsStmt.updateIndex()) {
+            tables.addAll(indexes);
+        }
+        for(PTable pTable : tables) {
+            updateStatisticsInternal(msMinBetweenUpdates, pTable);
+        }
+        return new MutationState(1, connection);
+    }
+
+    private MutationState updateStatisticsInternal(long msMinBetweenUpdates, PTable table)
throws SQLException {
         PName physicalName = table.getPhysicalName();
         byte[] tenantIdBytes = ByteUtil.EMPTY_BYTE_ARRAY;
         Long scn = connection.getSCN();
@@ -1268,6 +1287,7 @@ public class MetaDataClient {
             
             // Bootstrapping for our SYSTEM.TABLE that creates itself before it exists 
             if (SchemaUtil.isMetaTable(schemaName,tableName)) {
+                // TODO: what about stats for system catalog?
                 PTable table = PTableImpl.makePTable(tenantId,PNameFactory.newName(schemaName),
PNameFactory.newName(tableName), tableType,
                         null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                         PNameFactory.newName(QueryConstants.SYSTEM_TABLE_PK_NAME), null,
columns, null, Collections.<PTable>emptyList(), 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index 374b10c..a76bc2d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -23,6 +23,7 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
 import org.apache.phoenix.index.IndexMaintainer;
+import org.apache.phoenix.schema.stat.PTableStats;
 
 
 /**
@@ -316,5 +317,5 @@ public interface PTable {
     
     int getEstimatedSize();
     IndexType getIndexType();
-    
+    PTableStats getTableStats();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 41faaf2..e26a694 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -114,6 +114,7 @@ public class PTableImpl implements PTable {
     private int estimatedSize;
     private IndexType indexType;
     private List<byte[]> guidePosts = Collections.emptyList();
+    private PTableStats tableStats = PTableStats.EMPTY_STATS;
     
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -173,28 +174,32 @@ public class PTableImpl implements PTable {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(),
table.getIndexState(), timeStamp, 
                 table.getSequenceNumber() + 1, table.getPKName(), table.getBucketNum(), getColumnsToClone(table),
table.getParentTableName(), indexes,
-                table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(),
table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(),
table.getViewIndexId(), table.getIndexType());
+                table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(),
table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws
SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(),
table.getIndexState(), table.getTimeStamp(), 
-                table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns,
table.getParentTableName(), table.getIndexes(), table.isImmutableRows(),
-                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId(),
table.getIndexType());
+                table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns,
table.getParentTableName(), table.getIndexes(),
+                table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(),
table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber,
List<PColumn> columns) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(),
table.getIndexState(), timeStamp, 
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentTableName(),
table.getIndexes(), table.isImmutableRows(),
-                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId(),
table.getIndexType());
+                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(),
+                table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber,
List<PColumn> columns, boolean isImmutableRows) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(),
table.getIndexState(), timeStamp, 
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentTableName(),
table.getIndexes(),
-                isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(),
table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(),
table.getViewIndexId(), table.getIndexType());
+                isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(),
table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException
{
@@ -202,14 +207,17 @@ public class PTableImpl implements PTable {
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(),
state, table.getTimeStamp(), 
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table),

                 table.getParentTableName(), table.getIndexes(), table.isImmutableRows(),
-                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId(),
table.getIndexType());
+                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
table.isWALDisabled(), 
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
table.getTableStats());
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName,
PTableType type, PIndexState state, long timeStamp, long sequenceNumber,
             PName pkName, Integer bucketNum, List<PColumn> columns, PName dataTableName,
List<PTable> indexes, boolean isImmutableRows,
-            List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
boolean disableWAL, boolean multiTenant, ViewType viewType, Short viewIndexId, IndexType indexType)
throws SQLException {
+            List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
boolean disableWAL, boolean multiTenant, ViewType viewType,
+            Short viewIndexId, IndexType indexType) throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber,
pkName, bucketNum, columns, dataTableName,
-                indexes, isImmutableRows, physicalNames, defaultFamilyName, viewExpression,
disableWAL, multiTenant, viewType, viewIndexId, indexType);
+                indexes, isImmutableRows, physicalNames, defaultFamilyName, viewExpression,
disableWAL, multiTenant, viewType, viewIndexId, indexType,
+                PTableStats.EMPTY_STATS);
     }
     
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName,
PTableType type,
@@ -223,13 +231,6 @@ public class PTableImpl implements PTable {
                 viewExpression, disableWAL, multiTenant, viewType, viewIndexId, indexType,
stats);
     }
 
-    private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type,
PIndexState state, long timeStamp, long sequenceNumber,
-            PName pkName, Integer bucketNum, List<PColumn> columns, PName dataTableName,
List<PTable> indexes, boolean isImmutableRows,
-            List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
boolean disableWAL, boolean multiTenant, ViewType viewType, Short viewIndexId, IndexType indexType)
throws SQLException {
-        init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName,
bucketNum, columns,
-                new PTableStatsImpl(), dataTableName, indexes, isImmutableRows, physicalNames,
defaultFamilyName, viewExpression, disableWAL, multiTenant, viewType, viewIndexId, indexType);
-    }
-    
     private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type,
PIndexState state,
             long timeStamp, long sequenceNumber, PName pkName, Integer bucketNum, List<PColumn>
columns,
             PName dataTableName, List<PTable> indexes, boolean isImmutableRows, List<PName>
physicalNames,
@@ -287,6 +288,7 @@ public class PTableImpl implements PTable {
         this.viewType = viewType;
         this.viewIndexId = viewIndexId;
         this.indexType = indexType;
+        this.tableStats = stats;
         List<PColumn> pkColumns;
         PColumn[] allColumns;
 
@@ -364,7 +366,6 @@ public class PTableImpl implements PTable {
                 if (stats.getGuidePosts().get(defaultFamilyNameBytes) != null) {
                     guidePosts = stats.getGuidePosts().get(defaultFamilyNameBytes);
                     if (guidePosts != null) {
-                        Collections.sort(guidePosts, Bytes.BYTES_COMPARATOR);
                         estimatedSize += SizedUtil.sizeOfArrayList(guidePosts.size());
                         for (byte[] gps : guidePosts) {
                             estimatedSize += gps.length;
@@ -1035,5 +1036,10 @@ public class PTableImpl implements PTable {
     public PTableKey getKey() {
         return key;
     }
+
+    @Override
+    public PTableStats getTableStats() {
+        return tableStats;
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
index dfda457..6efd6f0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
@@ -20,13 +20,26 @@ package org.apache.phoenix.schema.stat;
 import java.util.List;
 import java.util.TreeMap;
 
+import org.apache.hadoop.hbase.util.Bytes;
+
+import com.google.common.collect.Maps;
+
 
 /*
  * The table is defined on the client side, but it is populated on the server side. The client
should not populate any data to the
  * statistics object.
  */
 public interface PTableStats {
+    public static final PTableStats EMPTY_STATS = new PTableStats() {
+        private final TreeMap<byte[], List<byte[]>> EMPTY_TREE_MAP = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
+        @Override
+        public TreeMap<byte[], List<byte[]>> getGuidePosts() {
+            return EMPTY_TREE_MAP;
+        }
+    };
+
     /**
+     * TODO: Change from TreeMap to Map
      * Returns a tree map of the guide posts collected against a column family
      * @return
      */

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
index 3e8f1e9..b20f1ec 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
@@ -26,8 +26,6 @@ import org.apache.hadoop.hbase.util.Bytes;
  */
 public class PTableStatsImpl implements PTableStats {
 
-    public static final PTableStats NO_STATS = new PTableStatsImpl();
-
     private TreeMap<byte[], List<byte[]>> guidePosts = new TreeMap<byte[],
List<byte[]>>(Bytes.BYTES_COMPARATOR);
 
     public PTableStatsImpl() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
new file mode 100644
index 0000000..8a020d2
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * 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 maynot 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 applicablelaw 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.schema.stat;
+
+public enum StatisticsCollectionScope {
+    COLUMNS, INDEX, ALL;
+
+    public static StatisticsCollectionScope getDefault() {
+        return ALL;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
index c48d62f..3749636 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
@@ -112,6 +112,6 @@ public class StatisticsUtil {
             }
             return new PTableStatsImpl(guidePostsPerCf);
         }
-        return PTableStatsImpl.NO_STATS;
+        return PTableStats.EMPTY_STATS;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3bd9d888/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
index 65bc7b2..cb0a287 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
@@ -471,7 +471,7 @@ public class TestUtil {
                     " WHERE " + ((lowerRange != null ? (pkCol + " >= ? " + (upperRange
!= null ? " AND " : "")) : "") 
                               + (upperRange != null ? (pkCol + " < ?") : "" )));
         String whereClause = whereClauseSuffix == null ? whereClauseStart : whereClauseStart.length()
== 0 ? (" WHERE " + whereClauseSuffix) : (" AND " + whereClauseSuffix);
-        String query = "SELECT COUNT(*) FROM " + tableName + whereClause;
+        String query = "SELECT /*+ NO_INDEX */ COUNT(*) FROM " + tableName + whereClause;
         PhoenixPreparedStatement pstmt = conn.prepareStatement(query).unwrap(PhoenixPreparedStatement.class);
         if (lowerRange != null) {
             pstmt.setBytes(1, lowerRange);
@@ -493,12 +493,22 @@ public class TestUtil {
     }
 
     public static void analyzeTable(Connection conn, String tableName) throws IOException,
SQLException {
-        String query = "ANALYZE " + tableName;
+        String query = "UPDATE STATISTICS " + tableName;
+        conn.createStatement().execute(query);
+    }
+    
+    public static void analyzeTableIndex(Connection conn, String tableName) throws IOException,
SQLException {
+        String query = "UPDATE STATISTICS " + tableName+ " INDEX";
+        conn.createStatement().execute(query);
+    }
+    
+    public static void analyzeTableColumns(Connection conn) throws IOException, SQLException
{
+        String query = "UPDATE STATISTICS " + STABLE_NAME+ " COLUMNS";
         conn.createStatement().execute(query);
     }
     
     public static void analyzeTable(Connection conn) throws IOException, SQLException {
-        String query = "ANALYZE " + STABLE_NAME;
+        String query = "UPDATE STATISTICS " + STABLE_NAME;
         conn.createStatement().execute(query);
     }
     


Mime
View raw message