Repository: phoenix
Updated Branches:
  refs/heads/3.0 be6d6f7a8 -> 836140b93


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

Conflicts:
        phoenix-core/src/main/antlr3/PhoenixSQL.g
        phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
        phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
        
phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
        
phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java


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

Branch: refs/heads/3.0
Commit: 951cae0f5487fae8561f6ab2448154efe8def9da
Parents: be6d6f7
Author: James Taylor <jtay...@salesforce.com>
Authored: Wed Oct 8 12:21:06 2014 -0700
Committer: James Taylor <jtay...@salesforce.com>
Committed: Wed Oct 8 14:27:57 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       | 11 +++--
 .../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   | 49 +++++++++-----------
 .../apache/phoenix/schema/stat/PTableStats.java | 34 ++++++++++----
 .../phoenix/schema/stat/PTableStatsImpl.java    | 24 +++++++---
 .../schema/stat/StatisticsCollectionScope.java  | 28 +++++++++++
 .../phoenix/schema/stat/StatisticsUtil.java     |  2 +-
 .../java/org/apache/phoenix/util/TestUtil.java  | 16 +++++--
 17 files changed, 220 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/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 21cfcdd..d2dbda6 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
@@ -92,7 +92,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/951cae0f/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/951cae0f/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 e6c2fc4..bcc2973 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/951cae0f/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 fb12cce..b48e260 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());
@@ -88,9 +88,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");
@@ -113,7 +113,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/951cae0f/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/951cae0f/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 67fd1cc..73bee73 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';
 }
 
 
@@ -148,6 +150,9 @@ import org.apache.phoenix.schema.IllegalDataException;
 import org.apache.phoenix.schema.PDataType;
 import org.apache.phoenix.schema.PIndexState;
 import org.apache.phoenix.schema.PTableType;
+
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
+
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.parse.LikeParseNode.LikeType;
 }
@@ -495,8 +500,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/951cae0f/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 3bd53c5..437027c 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;
@@ -110,6 +110,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.util.ByteUtil;
@@ -665,9 +666,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")
@@ -688,7 +688,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
@@ -862,8 +862,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/951cae0f/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 f5d98d4..1f6d0a4 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
@@ -46,6 +46,7 @@ import org.apache.phoenix.schema.PIndexState;
 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;
@@ -347,8 +348,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/951cae0f/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/951cae0f/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 c0947b6..8bb91b4 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
@@ -471,12 +471,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();
@@ -1176,6 +1195,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/951cae0f/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 5bd2cf2..f818b92 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
@@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.Writable;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
 import org.apache.phoenix.index.IndexMaintainer;
+import org.apache.phoenix.schema.stat.PTableStats;
 
 
 /**
@@ -280,4 +281,6 @@ public interface PTable extends Writable {
     PTableKey getKey();
     
     int getEstimatedSize();
+
+    PTableStats getTableStats();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/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 6feeaa1..c909345 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
@@ -113,6 +113,7 @@ public class PTableImpl implements PTable {
     private Short viewIndexId;
     private int estimatedSize;
     private List<byte[]> guidePosts = Collections.emptyList();
+    private PTableStats tableStats = PTableStats.EMPTY_STATS;
     
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -172,28 +173,33 @@ 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.isImmutableRows(), table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), 
table.getViewIndexId(), 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.getPhysicalNames(), table.getDefaultFamilyName(), 
table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), 
table.getViewType(),
+                table.getViewIndexId(), 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.getPhysicalNames(), table.getDefaultFamilyName(), 
table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(),
+                table.getViewType(), table.getViewIndexId(), 
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());
+                isImmutableRows, table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), 
table.getViewIndexId(), table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, PIndexState state) 
throws SQLException {
@@ -201,14 +207,16 @@ 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.getPhysicalNames(), table.getDefaultFamilyName(), 
table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), 
table.getViewIndexId(), 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) 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);
+                indexes, isImmutableRows, physicalNames, defaultFamilyName, 
viewExpression, disableWAL, multiTenant, viewType, viewIndexId,
+                PTableStats.EMPTY_STATS);
     }
     
     public static PTableImpl makePTable(PName tenantId, PName schemaName, 
PName tableName, PTableType type,
@@ -222,13 +230,6 @@ public class PTableImpl implements PTable {
                 viewExpression, disableWAL, multiTenant, viewType, 
viewIndexId, 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) 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);
-    }
-    
     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,
@@ -285,6 +286,8 @@ public class PTableImpl implements PTable {
         this.multiTenant = multiTenant;
         this.viewType = viewType;
         this.viewIndexId = viewIndexId;
+
+        this.tableStats = stats;
         List<PColumn> pkColumns;
         PColumn[] allColumns;
 
@@ -362,7 +365,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;
@@ -774,17 +776,8 @@ public class PTableImpl implements PTable {
             indexes.add(index);
         }
         boolean isImmutableRows = input.readBoolean();
-        TreeMap<byte[], List<byte[]>> guidePosts = new TreeMap<byte[], 
List<byte[]>>(Bytes.BYTES_COMPARATOR);
-        int size = WritableUtils.readVInt(input);
-        for (int i = 0; i < size; i++) {
-            byte[] key = Bytes.readByteArray(input);
-            int valueSize = WritableUtils.readVInt(input);
-            List<byte[]> value = Lists.newArrayListWithExpectedSize(valueSize);
-            for (int j = 0; j < valueSize; j++) {
-                value.add(j, Bytes.readByteArray(input));
-            }
-            guidePosts.put(key, value);
-        }
+        PTableStats stats = new PTableStatsImpl();
+        stats.readFields(input);
         byte[] dataTableNameBytes = Bytes.readByteArray(input);
         PName dataTableName = dataTableNameBytes.length == 0 ? null : 
PNameFactory.newName(dataTableNameBytes);
         byte[] defaultFamilyNameBytes = Bytes.readByteArray(input);
@@ -807,7 +800,6 @@ public class PTableImpl implements PTable {
                 physicalNames.add(PNameFactory.newName(physicalNameBytes));
             }
         }
-        PTableStats stats = new PTableStatsImpl(guidePosts);
         try {
             init(tenantId, schemaName, tableName, tableType, indexState, 
timeStamp, sequenceNumber,
                  pkName, bucketNum.equals(NO_SALTING) ? null : bucketNum, 
columns, stats,
@@ -993,5 +985,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/951cae0f/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 be6cfd2..6e822c8 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
@@ -17,11 +17,17 @@
  */
 package org.apache.phoenix.schema.stat;
 
+import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.List;
 import java.util.TreeMap;
 
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.io.Writable;
+
+import com.google.common.collect.Maps;
+
 
 /**
  * Interface for Phoenix table statistics. Statistics is collected on the 
server
@@ -30,16 +36,28 @@ import java.util.TreeMap;
  * 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 interface PTableStats extends Writable {
+
+    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;
+        }
+
+        @Override
+        public void write(DataOutput output) throws IOException {
+        }
+
+        @Override
+        public void readFields(DataInput arg0) throws IOException {
+        }
+    };
 
     /**
-     * Given the region info, returns an array of bytes that is the current 
estimate of key
-     * distribution inside that region. The keys should split that region into 
equal chunks.
-     * 
-     * @param region
-     * @return array of keys
+     * TODO: Change from TreeMap to Map
+     * Returns a tree map of the guide posts collected against a column family
+     * @return
      */
     TreeMap<byte[], List<byte[]>> getGuidePosts();
-
-    void write(DataOutput output) throws IOException;
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/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 88ce1fb..36b732a 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
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.stat;
 
+import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.List;
@@ -26,17 +27,14 @@ import java.util.TreeMap;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.WritableUtils;
 
+import com.google.common.collect.Lists;
+
 
 /**
  * Implementation for PTableStats.
  */
 public class PTableStatsImpl implements PTableStats {
-
-    // The map for guide posts should be immutable. We only take the current 
snapshot from outside
-    // method call and store it.
-    
-    public static final PTableStats NO_STATS = new PTableStatsImpl();
-    private TreeMap<byte[], List<byte[]>> guidePosts = new TreeMap<byte[], 
List<byte[]>>(Bytes.BYTES_COMPARATOR);
+    private final TreeMap<byte[], List<byte[]>> guidePosts;
 
     public PTableStatsImpl() {
         this(new TreeMap<byte[], List<byte[]>>(Bytes.BYTES_COMPARATOR));
@@ -67,4 +65,18 @@ public class PTableStatsImpl implements PTableStats {
             }
         }
     }
+
+    @Override
+    public void readFields(DataInput input) throws IOException {
+        int size = WritableUtils.readVInt(input);
+        for (int i = 0; i < size; i++) {
+            byte[] key = Bytes.readByteArray(input);
+            int valueSize = WritableUtils.readVInt(input);
+            List<byte[]> value = Lists.newArrayListWithExpectedSize(valueSize);
+            for (int j = 0; j < valueSize; j++) {
+                value.add(j, Bytes.readByteArray(input));
+            }
+            guidePosts.put(key, value);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/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/951cae0f/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 2086d31..a397a19 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
@@ -106,6 +106,6 @@ public class StatisticsUtil {
         } finally {
             scanner.close();
         }
-        return PTableStatsImpl.NO_STATS;
+        return PTableStats.EMPTY_STATS;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/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 3cf90fe..b832c72 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
@@ -461,7 +461,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);
@@ -483,12 +483,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);
     }
     

Reply via email to