Repository: phoenix Updated Branches: refs/heads/calcite 9a79dc99a -> 9a08a9d99
PHOENIX-3147 Support UPDATE STATISTICS in Phoenix-Calcite Integration Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/9a08a9d9 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/9a08a9d9 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/9a08a9d9 Branch: refs/heads/calcite Commit: 9a08a9d9902cd93b192d8a84941fce5e0864edb6 Parents: 9a79dc9 Author: maryannxue <maryann....@gmail.com> Authored: Thu Aug 4 15:58:58 2016 -0400 Committer: maryannxue <maryann....@gmail.com> Committed: Thu Aug 4 15:58:58 2016 -0400 ---------------------------------------------------------------------- .../apache/phoenix/calcite/CalciteDDLIT.java | 7 + phoenix-core/src/main/codegen/data/Parser.tdd | 6 +- .../src/main/codegen/includes/parserImpls.ftl | 87 ++++++++++-- .../org/apache/calcite/sql/SqlOptionNode.java | 71 ++++++++++ .../apache/calcite/sql/SqlTableOptionNode.java | 71 ---------- .../calcite/jdbc/PhoenixPrepareImpl.java | 142 +++++++++++-------- .../calcite/parse/SqlUpdateStatistics.java | 73 ++++++++++ 7 files changed, 313 insertions(+), 144 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDDLIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDDLIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDDLIT.java index 1814516..2a222cd 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDDLIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDDLIT.java @@ -2,6 +2,7 @@ package org.apache.phoenix.calcite; import java.util.Properties; +import org.junit.Ignore; import org.junit.Test; public class CalciteDDLIT extends BaseCalciteIT { @@ -50,4 +51,10 @@ public class CalciteDDLIT extends BaseCalciteIT { start(PROPS).sql("drop table t5").execute().close(); start(PROPS).sql("create table t5(a bigint not null primary key, b varchar)").execute().close(); } + + @Ignore + @Test public void testUpdateStatistics() throws Exception { + start(PROPS).sql("create table stest(a varchar(20) not null primary key, b integer)").execute().close(); + start(PROPS).sql("update statistics stest columns set dummy=2").execute().close(); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/main/codegen/data/Parser.tdd ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/codegen/data/Parser.tdd b/phoenix-core/src/main/codegen/data/Parser.tdd index a3091fd..68a0f43 100644 --- a/phoenix-core/src/main/codegen/data/Parser.tdd +++ b/phoenix-core/src/main/codegen/data/Parser.tdd @@ -23,6 +23,7 @@ imports: [ "org.apache.phoenix.calcite.parse.*", "org.apache.phoenix.schema.SortOrder", + "org.apache.phoenix.schema.stats.StatisticsCollectionScope", "org.apache.phoenix.parse.ColumnName", "org.apache.phoenix.parse.ColumnDef", "org.apache.phoenix.parse.ColumnDefInPkConstraint", @@ -30,7 +31,7 @@ "org.apache.calcite.sql.SqlColumnDefInPkConstraintNode" "org.apache.calcite.sql.SqlIndexExpressionNode" "org.apache.calcite.sql.SqlDataTypeNode" - "org.apache.calcite.sql.SqlTableOptionNode" + "org.apache.calcite.sql.SqlOptionNode" "java.util.*" ] @@ -38,11 +39,13 @@ keywords: [ "ASYNC" "CACHE" + "COLUMNS" "IF" "INCLUDE" "INDEX" "ROW_TIMESTAMP" "SPLIT" + "STATISTICS" ] # List of keywords from "keywords" section that are not reserved. @@ -60,6 +63,7 @@ "SqlDropTableOrDropView()", "SqlDropIndex()", "SqlDropSequence()", + "SqlUpdateStatistics()", ] # List of methods for parsing custom literals. http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/main/codegen/includes/parserImpls.ftl ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/codegen/includes/parserImpls.ftl b/phoenix-core/src/main/codegen/includes/parserImpls.ftl index f501e33..1360b68 100644 --- a/phoenix-core/src/main/codegen/includes/parserImpls.ftl +++ b/phoenix-core/src/main/codegen/includes/parserImpls.ftl @@ -103,7 +103,7 @@ SqlNode SqlCreateView() : } ) ( - tableOptions = TableOptionList() + tableOptions = FamilyOptionList() | { tableOptions = SqlNodeList.EMPTY; @@ -154,7 +154,7 @@ SqlNode SqlCreateTable() : ) <RPAREN> ( - tableOptions = TableOptionList() + tableOptions = FamilyOptionList() | { tableOptions = SqlNodeList.EMPTY; @@ -216,7 +216,7 @@ SqlNode SqlCreateIndex() : <ASYNC> { async = true; } ] [ - indexOptions = TableOptionList() + indexOptions = FamilyOptionList() ] [ <SPLIT> <ON> <LPAREN> @@ -383,6 +383,40 @@ SqlNode SqlDropSequence() : } } +/** + * Parses statement + * UPDATE STATISTICS + */ +SqlNode SqlUpdateStatistics() : +{ + SqlParserPos pos; + SqlIdentifier tableName; + StatisticsCollectionScope scope; + SqlNodeList statsOptions = SqlNodeList.EMPTY; +} +{ + <UPDATE> { pos = getPos(); } <STATISTICS> + tableName = DualIdentifier() + ( + <ALL> { scope = StatisticsCollectionScope.ALL; } + | + <INDEX> { scope = StatisticsCollectionScope.INDEX; } + | + <COLUMNS> { scope = StatisticsCollectionScope.COLUMNS; } + | + { + scope = StatisticsCollectionScope.getDefault(); + } + ) + [ + <SET> + statsOptions = GeneralOptionList() + ] + { + return new SqlUpdateStatistics(pos.plus(getPos()), tableName, scope, statsOptions); + } +} + SqlNodeList ColumnDefList() : { SqlParserPos pos; @@ -451,20 +485,37 @@ SqlNodeList IndexIncludeList() : } } -SqlNodeList TableOptionList() : +SqlNodeList FamilyOptionList() : { SqlParserPos pos; SqlNode e; - List<SqlNode> tableOptionList; + List<SqlNode> familyOptionList; } { { pos = getPos(); } - e = TableOption() { tableOptionList = startList(e); } + e = FamilyOption() { familyOptionList = startList(e); } ( - <COMMA> e = TableOption() { tableOptionList.add(e); } + <COMMA> e = FamilyOption() { familyOptionList.add(e); } ) * { - return new SqlNodeList(tableOptionList, pos.plus(getPos())); + return new SqlNodeList(familyOptionList, pos.plus(getPos())); + } +} + +SqlNodeList GeneralOptionList() : +{ + SqlParserPos pos; + SqlNode e; + List<SqlNode> generalOptionList; +} +{ + { pos = getPos(); } + e = GeneralOption() { generalOptionList = startList(e); } + ( + <COMMA> e = GeneralOption() { generalOptionList.add(e); } + ) * + { + return new SqlNodeList(generalOptionList, pos.plus(getPos())); } } @@ -609,7 +660,7 @@ SqlIndexExpressionNode IndexExpression() : } } -SqlTableOptionNode TableOption() : +SqlOptionNode FamilyOption() : { SqlIdentifier key; SqlNode value; @@ -621,7 +672,23 @@ SqlTableOptionNode TableOption() : value = Literal() { pos = key.getParserPosition().plus(getPos()); - return new SqlTableOptionNode(pos, key, (SqlLiteral) value); + return new SqlOptionNode(pos, key, (SqlLiteral) value); + } +} + +SqlOptionNode GeneralOption() : +{ + SqlIdentifier key; + SqlNode value; + SqlParserPos pos; +} +{ + key = SimpleIdentifier() + <EQ> + value = Literal() + { + pos = key.getParserPosition().plus(getPos()); + return new SqlOptionNode(pos, key, (SqlLiteral) value); } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/main/java/org/apache/calcite/sql/SqlOptionNode.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/calcite/sql/SqlOptionNode.java b/phoenix-core/src/main/java/org/apache/calcite/sql/SqlOptionNode.java new file mode 100644 index 0000000..dc2274e --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/calcite/sql/SqlOptionNode.java @@ -0,0 +1,71 @@ +/* + * 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.calcite.sql; + +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.util.SqlVisitor; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorScope; +import org.apache.calcite.util.Litmus; +import org.apache.calcite.util.NlsString; + +public class SqlOptionNode extends SqlNode { + public final String familyName; + public final String propertyName; + public final Object value; + + public SqlOptionNode(SqlParserPos pos, SqlIdentifier key, SqlLiteral literal) { + super(pos); + if (key.isSimple()) { + familyName = ""; + propertyName = key.getSimple(); + } else { + familyName = key.names.get(0); + propertyName = key.names.get(1); + } + final Object v = SqlLiteral.value(literal); + if (v instanceof NlsString) { + value = ((NlsString) v).toString(); + } else { + value = v; + } + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + // TODO Auto-generated method stub + } + + @Override + public void validate(SqlValidator validator, SqlValidatorScope scope) { + // TODO Auto-generated method stub + } + + @Override + public <R> R accept(SqlVisitor<R> visitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean equalsDeep(SqlNode node, Litmus litmus) { + // TODO Auto-generated method stub + return false; + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/main/java/org/apache/calcite/sql/SqlTableOptionNode.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/calcite/sql/SqlTableOptionNode.java b/phoenix-core/src/main/java/org/apache/calcite/sql/SqlTableOptionNode.java deleted file mode 100644 index 5119565..0000000 --- a/phoenix-core/src/main/java/org/apache/calcite/sql/SqlTableOptionNode.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.calcite.sql; - -import org.apache.calcite.sql.parser.SqlParserPos; -import org.apache.calcite.sql.util.SqlVisitor; -import org.apache.calcite.sql.validate.SqlValidator; -import org.apache.calcite.sql.validate.SqlValidatorScope; -import org.apache.calcite.util.Litmus; -import org.apache.calcite.util.NlsString; - -public class SqlTableOptionNode extends SqlNode { - public final String familyName; - public final String propertyName; - public final Object value; - - public SqlTableOptionNode(SqlParserPos pos, SqlIdentifier key, SqlLiteral literal) { - super(pos); - if (key.isSimple()) { - familyName = ""; - propertyName = key.getSimple(); - } else { - familyName = key.names.get(0); - propertyName = key.names.get(1); - } - final Object v = SqlLiteral.value(literal); - if (v instanceof NlsString) { - value = ((NlsString) v).toString(); - } else { - value = v; - } - } - - @Override - public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { - // TODO Auto-generated method stub - } - - @Override - public void validate(SqlValidator validator, SqlValidatorScope scope) { - // TODO Auto-generated method stub - } - - @Override - public <R> R accept(SqlVisitor<R> visitor) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean equalsDeep(SqlNode node, Litmus litmus) { - // TODO Auto-generated method stub - return false; - } - -} http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java index 0a3baa9..f7e4a45 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java @@ -30,7 +30,7 @@ import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlLiteral; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNodeList; -import org.apache.calcite.sql.SqlTableOptionNode; +import org.apache.calcite.sql.SqlOptionNode; import org.apache.calcite.sql.parser.SqlParser; import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.sql.parser.SqlParserUtil; @@ -38,7 +38,7 @@ import org.apache.calcite.tools.Program; import org.apache.calcite.tools.Programs; import org.apache.calcite.util.Holder; import org.apache.calcite.util.NlsString; -import org.apache.calcite.util.Pair; +import org.apache.hadoop.hbase.util.Pair; import org.apache.phoenix.calcite.PhoenixSchema; import org.apache.phoenix.calcite.parse.SqlCreateIndex; import org.apache.phoenix.calcite.parse.SqlCreateSequence; @@ -46,6 +46,7 @@ import org.apache.phoenix.calcite.parse.SqlCreateTable; import org.apache.phoenix.calcite.parse.SqlDropIndex; import org.apache.phoenix.calcite.parse.SqlDropSequence; import org.apache.phoenix.calcite.parse.SqlDropTable; +import org.apache.phoenix.calcite.parse.SqlUpdateStatistics; import org.apache.phoenix.calcite.parser.PhoenixParserImpl; import org.apache.phoenix.calcite.rel.PhoenixRel; import org.apache.phoenix.calcite.rel.PhoenixServerProject; @@ -83,6 +84,7 @@ import org.apache.phoenix.parse.PrimaryKeyConstraint; import org.apache.phoenix.parse.SQLParser; import org.apache.phoenix.parse.TableName; import org.apache.phoenix.parse.UDFParseNode; +import org.apache.phoenix.parse.UpdateStatisticsStatement; import org.apache.phoenix.schema.MetaDataClient; import org.apache.phoenix.schema.PTable.IndexType; import org.apache.phoenix.schema.PTableType; @@ -177,10 +179,10 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { }); } - Hook.PROGRAM.add(new Function<Pair<List<Materialization>, Holder<Program>>, Object>() { + Hook.PROGRAM.add(new Function<org.apache.calcite.util.Pair<List<Materialization>, Holder<Program>>, Object>() { @Override public Object apply( - Pair<List<Materialization>, Holder<Program>> input) { + org.apache.calcite.util.Pair<List<Materialization>, Holder<Program>> input) { input.getValue().set(Programs.standard(PhoenixRel.METADATA_PROVIDER)); return null; } @@ -205,16 +207,7 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { } else { name = TableName.create(table.tableName.names.get(0), table.tableName.names.get(1)); } - final ListMultimap<String, org.apache.hadoop.hbase.util.Pair<String, Object>> props; - if (SqlNodeList.isEmptyList(table.tableOptions)) { - props = null; - } else { - props = ArrayListMultimap.<String, org.apache.hadoop.hbase.util.Pair<String, Object>>create(); - for (SqlNode tableOption : table.tableOptions) { - SqlTableOptionNode option = (SqlTableOptionNode) tableOption; - props.put(option.familyName, new org.apache.hadoop.hbase.util.Pair<String, Object>(option.propertyName, option.value)); - } - } + final ListMultimap<String, Pair<String, Object>> props = convertOptions(table.tableOptions); final List<ColumnDef> columnDefs = Lists.newArrayList(); for (SqlNode columnDef : table.columnDefs) { columnDefs.add(((SqlColumnDefNode) columnDef).columnDef); @@ -240,27 +233,9 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { } else { baseTableName = TableName.create(table.baseTableName.names.get(0), table.baseTableName.names.get(1)); } - if (table.whereNode == null) { - where = null; - } else { - String sql = THREAD_SQL_STRING.get(); - SqlParserPos wherePos = table.whereNode.getParserPosition(); - int start = SqlParserUtil.lineColToIndex(sql, wherePos.getLineNum(), wherePos.getColumnNum()); - int end = SqlParserUtil.lineColToIndex(sql, wherePos.getEndLineNum(), wherePos.getEndColumnNum()); - String whereString = sql.substring(start, end + 1); - where = new SQLParser(whereString).parseExpression(); - } - } - final List<ParseNode> splitNodes; - if (SqlNodeList.isEmptyList(table.splitKeyList)) { - splitNodes = null; - } else { - splitNodes = Lists.newArrayList(); - for (SqlNode splitKey : table.splitKeyList) { - final SqlLiteral key = (SqlLiteral) splitKey; - splitNodes.add(nodeFactory.literal(((NlsString) key.getValue()).toString())); - } + where = convertSqlNodeToParseNode(table.whereNode); } + final List<ParseNode> splitNodes = convertSplits(table.splitKeyList, nodeFactory); final CreateTableStatement create = nodeFactory.createTable( name, props, columnDefs, pkConstraint, splitNodes, tableType, table.ifNotExists.booleanValue(), @@ -283,16 +258,11 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { dataTableName = TableName.create(index.dataTableName.names.get(0), index.dataTableName.names.get(1)); } final NamedTableNode dataTable = NamedTableNode.create(dataTableName); - final List<org.apache.hadoop.hbase.util.Pair<ParseNode, SortOrder>> indexKeys = Lists.newArrayList(); + final List<Pair<ParseNode, SortOrder>> indexKeys = Lists.newArrayList(); for (SqlNode e : index.expressions) { SqlIndexExpressionNode indexExpression = (SqlIndexExpressionNode) e; - String sql = THREAD_SQL_STRING.get(); - SqlParserPos exprPos = indexExpression.expression.getParserPosition(); - int start = SqlParserUtil.lineColToIndex(sql, exprPos.getLineNum(), exprPos.getColumnNum()); - int end = SqlParserUtil.lineColToIndex(sql, exprPos.getEndLineNum(), exprPos.getEndColumnNum()); - String exprString = sql.substring(start, end + 1); - ParseNode exprNode = new SQLParser(exprString).parseExpression(); - indexKeys.add(new org.apache.hadoop.hbase.util.Pair<ParseNode, SortOrder>(exprNode, indexExpression.sortOrder)); + ParseNode exprNode = convertSqlNodeToParseNode(indexExpression.expression); + indexKeys.add(new Pair<ParseNode, SortOrder>(exprNode, indexExpression.sortOrder)); } final IndexKeyConstraint indexKeyConstraint = nodeFactory.indexKey(indexKeys); final List<ColumnName> includeColumns; @@ -311,26 +281,8 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { includeColumns.add(columnName); } } - final ListMultimap<String, org.apache.hadoop.hbase.util.Pair<String, Object>> props; - if (SqlNodeList.isEmptyList(index.indexOptions)) { - props = null; - } else { - props = ArrayListMultimap.<String, org.apache.hadoop.hbase.util.Pair<String, Object>>create(); - for (SqlNode tableOption : index.indexOptions) { - SqlTableOptionNode option = (SqlTableOptionNode) tableOption; - props.put(option.familyName, new org.apache.hadoop.hbase.util.Pair<String, Object>(option.propertyName, option.value)); - } - } - final List<ParseNode> splitNodes; - if (SqlNodeList.isEmptyList(index.splitKeyList)) { - splitNodes = null; - } else { - splitNodes = Lists.newArrayList(); - for (SqlNode splitKey : index.splitKeyList) { - final SqlLiteral key = (SqlLiteral) splitKey; - splitNodes.add(nodeFactory.literal(((NlsString) key.getValue()).toString())); - } - } + final ListMultimap<String, Pair<String, Object>> props = convertOptions(index.indexOptions); + final List<ParseNode> splitNodes = convertSplits(index.splitKeyList, nodeFactory); // TODO final Map<String, UDFParseNode> udfParseNodes = new HashMap<String, UDFParseNode>(); final CreateIndexStatement create = nodeFactory.createIndex( @@ -408,6 +360,29 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { client.dropSequence(drop); break; } + case OTHER_DDL: { + if (node instanceof SqlUpdateStatistics) { + SqlUpdateStatistics updateStatsNode = (SqlUpdateStatistics) node; + final TableName name; + if (updateStatsNode.tableName.isSimple()) { + name = TableName.create(null, updateStatsNode.tableName.getSimple()); + } else { + name = TableName.create(updateStatsNode.tableName.names.get(0), updateStatsNode.tableName.names.get(1)); + } + final NamedTableNode table = NamedTableNode.create(name); + final Map<String, Object> props = new HashMap<String, Object>(); + for (SqlNode optionNode : updateStatsNode.options) { + SqlOptionNode option = (SqlOptionNode) optionNode; + props.put(option.propertyName, option.value); + } + final UpdateStatisticsStatement updateStatsStmt = nodeFactory.updateStatistics(table, updateStatsNode.scope, props); + MetaDataClient client = new MetaDataClient(connection); + client.updateStatistics(updateStatsStmt); + } else { + throw new AssertionError("unknown DDL node " + node.getClass()); + } + break; + } default: throw new AssertionError("unknown DDL type " + node.getKind() + " " + node.getClass()); } @@ -415,6 +390,49 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { throw new RuntimeException(ex); } } + + private static ParseNode convertSqlNodeToParseNode(SqlNode sqlNode) throws SQLException { + if (sqlNode == null) { + return null; + } + + String sql = THREAD_SQL_STRING.get(); + SqlParserPos pos = sqlNode.getParserPosition(); + int start = SqlParserUtil.lineColToIndex(sql, pos.getLineNum(), pos.getColumnNum()); + int end = SqlParserUtil.lineColToIndex(sql, pos.getEndLineNum(), pos.getEndColumnNum()); + String sqlString = sql.substring(start, end + 1); + return new SQLParser(sqlString).parseExpression(); + } + + private static ListMultimap<String, Pair<String, Object>> convertOptions(SqlNodeList options) { + final ListMultimap<String, Pair<String, Object>> props; + if (SqlNodeList.isEmptyList(options)) { + props = null; + } else { + props = ArrayListMultimap.<String, Pair<String, Object>>create(); + for (SqlNode optionNode : options) { + SqlOptionNode option = (SqlOptionNode) optionNode; + props.put(option.familyName, new Pair<String, Object>(option.propertyName, option.value)); + } + } + + return props; + } + + private static List<ParseNode> convertSplits(SqlNodeList splitKeyList, ParseNodeFactory nodeFactory) { + final List<ParseNode> splits; + if (SqlNodeList.isEmptyList(splitKeyList)) { + splits = null; + } else { + splits = Lists.newArrayList(); + for (SqlNode splitKey : splitKeyList) { + final SqlLiteral key = (SqlLiteral) splitKey; + splits.add(nodeFactory.literal(((NlsString) key.getValue()).toString())); + } + } + + return splits; + } private static PhoenixConnection getPhoenixConnection(SchemaPlus rootSchema) { for (String subSchemaName : rootSchema.getSubSchemaNames()) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/9a08a9d9/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlUpdateStatistics.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlUpdateStatistics.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlUpdateStatistics.java new file mode 100644 index 0000000..7f91ca7 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlUpdateStatistics.java @@ -0,0 +1,73 @@ +/* + * 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.calcite.parse; + +import com.google.common.collect.ImmutableList; + +import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlLiteral; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.SqlOperator; +import org.apache.calcite.sql.SqlWriter; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.phoenix.schema.stats.StatisticsCollectionScope; + +import java.util.List; + +/** + * Parse tree node for SQL {@code UPDATE STATISTICS} command. + */ +public class SqlUpdateStatistics extends SqlCall { + public static final SqlOperator OPERATOR = new SqlDdlOperator("UPDATE STATISTICS", SqlKind.OTHER_DDL); + + public final SqlIdentifier tableName; + public final StatisticsCollectionScope scope; + public final SqlNodeList options; + + private final SqlLiteral scopeLiteral; + + + /** Creates a UPDATE STATISTICS. */ + public SqlUpdateStatistics( + SqlParserPos pos, + SqlIdentifier tableName, + StatisticsCollectionScope scope, + SqlNodeList options) { + super(pos); + this.tableName = tableName; + this.scope = scope; + this.options = options; + this.scopeLiteral = SqlLiteral.createCharString(scope.name(), SqlParserPos.ZERO); + } + + public SqlOperator getOperator() { + return OPERATOR; + } + + public List<SqlNode> getOperandList() { + return ImmutableList.of(tableName, scopeLiteral, options); + } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + // TODO Auto-generated method stub + } +}