From c66ab61ae0cf66f42fc44fbdd4394f87ec5b5700 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Thu, 9 Jul 2015 11:55:30 +0900 Subject: [PATCH 01/26] Add msck repair table statment. --- .../org/apache/tajo/algebra/MsckTable.java | 77 +++++++++++++ .../apache/tajo/algebra/MsckTableOpType.java | 22 ++++ .../java/org/apache/tajo/algebra/OpType.java | 1 + .../org/apache/tajo/engine/parser/SQLLexer.g4 | 2 + .../apache/tajo/engine/parser/SQLParser.g4 | 7 ++ .../tajo/engine/parser/SQLAnalyzer.java | 14 +++ .../apache/tajo/master/exec/DDLExecutor.java | 38 ++++++- .../tajo/engine/parser/TestSQLAnalyzer.java | 10 ++ .../engine/planner/TestLogicalPlanner.java | 20 ++++ .../queries/default/msck_repair_table.sql | 1 + .../tajo/plan/LogicalPlanPreprocessor.java | 9 +- .../org/apache/tajo/plan/LogicalPlanner.java | 9 ++ .../tajo/plan/algebra/AlgebraVisitor.java | 1 + .../tajo/plan/algebra/BaseAlgebraVisitor.java | 9 ++ .../tajo/plan/logical/MsckTableNode.java | 104 ++++++++++++++++++ .../apache/tajo/plan/logical/NodeType.java | 2 + .../plan/serder/LogicalNodeDeserializer.java | 21 ++++ .../plan/serder/LogicalNodeSerializer.java | 22 ++++ .../apache/tajo/plan/util/PlannerUtil.java | 3 +- .../plan/visitor/BasicLogicalPlanVisitor.java | 9 ++ .../tajo/plan/visitor/LogicalPlanVisitor.java | 3 + tajo-plan/src/main/proto/Plan.proto | 12 ++ 22 files changed, 388 insertions(+), 8 deletions(-) create mode 100644 tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java create mode 100644 tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java create mode 100644 tajo-core/src/test/resources/queries/default/msck_repair_table.sql create mode 100644 tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java new file mode 100644 index 0000000000..830f9d5137 --- /dev/null +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java @@ -0,0 +1,77 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.algebra; + + +import com.google.common.base.Objects; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import org.apache.tajo.util.TUtil; + +public class MsckTable extends Expr { + + @Expose @SerializedName("TableName") + private String tableName; + + @Expose @SerializedName("MsckTableOpType") + private MsckTableOpType MsckTableOpType; + + + public MsckTable(final String tableName) { + super(OpType.MsckTable); + this.tableName = tableName; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public MsckTableOpType getMsckTableOpType() { + return MsckTableOpType; + } + + public void setMsckTableOpType(MsckTableOpType MsckTableOpType) { + this.MsckTableOpType = MsckTableOpType; + } + + @Override + public int hashCode() { + return Objects.hashCode(tableName, MsckTableOpType); + } + + @Override + boolean equalsTo(Expr expr) { + MsckTable another = (MsckTable) expr; + return tableName.equals(another.tableName) && + TUtil.checkEquals(MsckTableOpType, another.MsckTableOpType) + ; + } + + @Override + public Object clone() throws CloneNotSupportedException { + MsckTable alter = (MsckTable) super.clone(); + alter.setTableName(tableName); + alter.setMsckTableOpType(MsckTableOpType); + return alter; + } +} diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java new file mode 100644 index 0000000000..ac85f40b6a --- /dev/null +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java @@ -0,0 +1,22 @@ +/** + * 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.tajo.algebra; + +public enum MsckTableOpType { + REPAIR_TABLE +} diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java index 3e7d2779dc..a3bed771ac 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java @@ -54,6 +54,7 @@ public enum OpType { AlterTablespace(AlterTablespace.class), AlterTable(AlterTable.class), TruncateTable(TruncateTable.class), + MsckTable(MsckTable.class), // Insert or Update Insert(Insert.class), diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 index d1daeb6cf9..b2a80a9619 100644 --- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 +++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 @@ -266,6 +266,7 @@ MILLISECONDS : M I L L I S E C O N D S; MIN : M I N; MINUTE : M I N U T E; MONTH : M O N T H; +MSCK : M S C K; NATIONAL : N A T I O N A L; NULLIF : N U L L I F; @@ -289,6 +290,7 @@ RANK : R A N K; RECORD : R E C O R D; REGEXP : R E G E X P; RENAME : R E N A M E; +REPAIR : R E P A I R; RESET : R E S E T; RLIKE : R L I K E; ROLLUP : R O L L U P; diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 index 469b2a2f08..38de56ef56 100644 --- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 +++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 @@ -73,6 +73,7 @@ schema_statement | drop_table_statement | alter_tablespace_statement | alter_table_statement + | msck_table_statement | truncate_table_statement ; @@ -281,6 +282,7 @@ nonreserved_keywords | MIN | MINUTE | MONTH + | MSCK | NATIONAL | NO | NULLIF @@ -298,6 +300,7 @@ nonreserved_keywords | RECORD | REGEXP | RENAME + | REPAIR | RESET | RLIKE | ROLLUP @@ -1607,6 +1610,10 @@ alter_table_statement | ALTER TABLE table_name SET PROPERTY property_list ; +msck_table_statement + : MSCK REPAIR TABLE table_name + ; + partition_column_value_list : partition_column_value (COMMA partition_column_value)* ; diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java index 62bb0f9533..e2c128b8fc 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java @@ -1935,4 +1935,18 @@ private AlterTableOpType evaluateAlterTableOperationTye(final int value) { return null; } } + + @Override + public Expr visitMsck_table_statement(@NotNull Msck_table_statementContext ctx) { + MsckTable msck = new MsckTable(ctx.table_name().getText()); + + for (int i = 1; i < ctx.getChildCount(); i++) { + if (ctx.getChild(i) instanceof TerminalNode) { + if (((TerminalNode) ctx.getChild(i)).getSymbol().getType() == REPAIR) { + msck.setMsckTableOpType(MsckTableOpType.REPAIR_TABLE); + } + } + } + return msck; + } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 7104412db2..0ab68fe56b 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -70,8 +70,6 @@ public boolean execute(QueryContext queryContext, LogicalPlan plan) throws IOExc AlterTablespaceNode alterTablespace = (AlterTablespaceNode) root; alterTablespace(context, queryContext, alterTablespace); return true; - - case CREATE_DATABASE: CreateDatabaseNode createDatabase = (CreateDatabaseNode) root; createDatabase(queryContext, createDatabase.getDatabaseName(), null, createDatabase.isIfNotExists()); @@ -80,8 +78,6 @@ public boolean execute(QueryContext queryContext, LogicalPlan plan) throws IOExc DropDatabaseNode dropDatabaseNode = (DropDatabaseNode) root; dropDatabase(queryContext, dropDatabaseNode.getDatabaseName(), dropDatabaseNode.isIfExists()); return true; - - case CREATE_TABLE: CreateTableNode createTable = (CreateTableNode) root; createTable(queryContext, createTable, createTable.isIfNotExists()); @@ -94,12 +90,14 @@ public boolean execute(QueryContext queryContext, LogicalPlan plan) throws IOExc TruncateTableNode truncateTable = (TruncateTableNode) root; truncateTable(queryContext, truncateTable); return true; - case ALTER_TABLE: AlterTableNode alterTable = (AlterTableNode) root; alterTable(context, queryContext, alterTable); return true; - + case MSCK_TABLE: + MsckTableNode msckTableNode = (MsckTableNode) root; + msckTable(context, queryContext, msckTableNode); + return true; default: throw new InternalError("updateQuery cannot handle such query: \n" + root.toJson()); } @@ -451,6 +449,34 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer } } + public void msckTable(TajoMaster.MasterContext context, final QueryContext queryContext, + final MsckTableNode msckTable) throws IOException { + + final CatalogService catalog = context.getCatalog(); + final String tableName = msckTable.getTableName(); + + String databaseName; + String simpleTableName; + if (CatalogUtil.isFQTableName(tableName)) { + String[] split = CatalogUtil.splitFQTableName(tableName); + databaseName = split[0]; + simpleTableName = split[1]; + } else { + databaseName = queryContext.getCurrentDatabase(); + simpleTableName = tableName; + } + final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName); + + if (!catalog.existsTable(databaseName, simpleTableName)) { + throw new NoSuchTableException(qualifiedName); + } + + TableDesc tableDesc = catalog.getTableDesc(databaseName, simpleTableName); + Path tablePath = new Path(tableDesc.getUri()); + + // TODO: Implement to make directories recursively comparing partition column name. + } + private boolean existColumnName(String tableName, String columnName) { final TableDesc tableDesc = catalog.getTableDesc(tableName); return tableDesc.getSchema().containsByName(columnName) ? true : false; diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java index f698ed5978..97bb13e01c 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java @@ -523,6 +523,16 @@ public void testAlterTableSetProperty3() throws IOException { assertEquals("org.apache.hadoop.io.compress.SnappyCodec", alterTable.getParams().get("compression.codec")); } + @Test + public void testMsckRepairTable() throws IOException { + String sql = FileUtil.readTextFileFromResource("queries/default/msck_repair_table.sql"); + Expr expr = parseQuery(sql); + assertEquals(OpType.MsckTable, expr.getType()); + MsckTable msck = (MsckTable)expr; + assertEquals(msck.getMsckTableOpType(), MsckTableOpType.REPAIR_TABLE); + assertEquals(msck.getTableName(), "table1"); + } + @Test public void testTableSubQuery1() throws IOException { String sql = FileUtil.readTextFileFromResource("queries/default/table_subquery1.sql"); diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java index 0f377630de..f7023e7c3f 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java @@ -27,6 +27,7 @@ import org.apache.tajo.TajoTestingCluster; import org.apache.tajo.algebra.Expr; import org.apache.tajo.algebra.JoinType; +import org.apache.tajo.algebra.MsckTableOpType; import org.apache.tajo.benchmark.TPCH; import org.apache.tajo.catalog.*; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType; @@ -1230,4 +1231,23 @@ private static InsertNode getInsertNode(LogicalPlan plan) { assertEquals(NodeType.INSERT, root.getChild().getType()); return root.getChild(); } + + @Test + public final void testMsckRepairTable() throws PlanningException { + QueryContext qc = createQueryContext(); + + String sql = "MSCK REPAIR TABLE table1"; + Expr expr = sqlAnalyzer.parse(sql); + LogicalPlan rootNode = planner.createPlan(qc, expr); + LogicalNode plan = rootNode.getRootBlock().getRoot(); + testJsonSerDerObject(plan); + assertEquals(NodeType.ROOT, plan.getType()); + LogicalRootNode root = (LogicalRootNode) plan; + assertEquals(NodeType.MSCK_TABLE, root.getChild().getType()); + + MsckTableNode msckNode = root.getChild(); + + assertEquals(msckNode.getMsckTableOpType(), MsckTableOpType.REPAIR_TABLE); + assertEquals(msckNode.getTableName(), "table1"); + } } \ No newline at end of file diff --git a/tajo-core/src/test/resources/queries/default/msck_repair_table.sql b/tajo-core/src/test/resources/queries/default/msck_repair_table.sql new file mode 100644 index 0000000000..6c94870988 --- /dev/null +++ b/tajo-core/src/test/resources/queries/default/msck_repair_table.sql @@ -0,0 +1 @@ +MSCK REPAIR TABLE table1 \ No newline at end of file diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java index dced4d32c8..e857ad9e20 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java @@ -477,7 +477,14 @@ public LogicalNode visitTruncateTable(LogicalPlanner.PlanContext ctx, Stack stack, + MsckTable expr) throws PlanningException { + MsckTableNode msckTableNode = ctx.plan.createNode(MsckTableNode.class); + return msckTableNode; + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// // Insert or Update Section /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java index c51d068f90..f01791dd71 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java @@ -2016,6 +2016,15 @@ public LogicalNode visitTruncateTable(PlanContext context, Stack stack, Tr return truncateTableNode; } + @Override + public LogicalNode visitMsckTable(PlanContext context, Stack stack, MsckTable msck) + throws PlanningException { + MsckTableNode msckTableNode = context.queryBlock.getNodeFromExpr(msck); + msckTableNode.setTableName(msck.getTableName()); + msckTableNode.setMsckTableOpType(msck.getMsckTableOpType()); + return msckTableNode; + } + /*=============================================================================================== Util SECTION ===============================================================================================*/ diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java index 1ac12c240c..90111d9f62 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java @@ -53,6 +53,7 @@ public interface AlgebraVisitor { RESULT visitAlterTablespace(CONTEXT ctx, Stack stack, AlterTablespace expr) throws PlanningException; RESULT visitAlterTable(CONTEXT ctx, Stack stack, AlterTable expr) throws PlanningException; RESULT visitTruncateTable(CONTEXT ctx, Stack stack, TruncateTable expr) throws PlanningException; + RESULT visitMsckTable(CONTEXT ctx, Stack stack, MsckTable expr) throws PlanningException; // Insert or Update RESULT visitInsert(CONTEXT ctx, Stack stack, Insert expr) throws PlanningException; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java index eb11f33e3c..843d69190e 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java @@ -125,6 +125,9 @@ public RESULT visit(CONTEXT ctx, Stack stack, Expr expr) throws PlanningEx case TruncateTable: current = visitTruncateTable(ctx, stack, (TruncateTable)expr); break; + case MsckTable: + current = visitMsckTable(ctx, stack, (MsckTable)expr); + break; case Insert: current = visitInsert(ctx, stack, (Insert) expr); @@ -484,6 +487,12 @@ public RESULT visitAlterTable(CONTEXT ctx, Stack stack, AlterTable expr) t public RESULT visitTruncateTable(CONTEXT ctx, Stack stack, TruncateTable expr) throws PlanningException { return null; } + + @Override + public RESULT visitMsckTable(CONTEXT ctx, Stack stack, MsckTable expr) throws PlanningException { + return null; + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Insert or Update Section /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java new file mode 100644 index 0000000000..5c372daaf0 --- /dev/null +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java @@ -0,0 +1,104 @@ +/** + * 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.tajo.plan.logical; + + +import com.google.common.base.Objects; +import com.google.gson.annotations.Expose; +import org.apache.tajo.algebra.MsckTableOpType; +import org.apache.tajo.plan.PlanString; + +public class MsckTableNode extends LogicalNode implements Cloneable { + + @Expose private String tableName; + @Expose private MsckTableOpType msckTableOpType; + + + public MsckTableNode(int pid) { + super(pid, NodeType.MSCK_TABLE); + } + + @Override + public int childNum() { + return 0; + } + + @Override + public LogicalNode getChild(int idx) { + return null; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public MsckTableOpType getMsckTableOpType() { + return msckTableOpType; + } + + public void setMsckTableOpType(MsckTableOpType msckTableOpType) { + this.msckTableOpType = msckTableOpType; + } + + @Override + public PlanString getPlanString() { + return new PlanString(this); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MsckTableNode) { + MsckTableNode other = (MsckTableNode) obj; + return super.equals(other); + } else { + return false; + } + } + + public int hashCode() { + return Objects.hashCode(tableName, msckTableOpType); + } + + @Override + public Object clone() throws CloneNotSupportedException { + MsckTableNode msck = (MsckTableNode) super.clone(); + msck.tableName = tableName; + msck.msckTableOpType = msckTableOpType; + return msck; + } + + @Override + public String toString() { + return "Msck (table=" + tableName + ", opType = " + msckTableOpType.name().toString() + ")"; + } + + @Override + public void preOrder(LogicalNodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public void postOrder(LogicalNodeVisitor visitor) { + visitor.visit(this); + } +} diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java index 75ae3b7271..7876faf452 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java @@ -22,6 +22,7 @@ package org.apache.tajo.plan.logical; + /** * This indicates a logical node type. */ @@ -55,6 +56,7 @@ public enum NodeType { DROP_TABLE(DropTableNode.class), ALTER_TABLESPACE (AlterTablespaceNode.class), ALTER_TABLE (AlterTableNode.class), + MSCK_TABLE (MsckTableNode.class), TRUNCATE_TABLE (TruncateTableNode.class); private final Class baseClass; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java index c1d9f9a11b..6fcc187a1b 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java @@ -23,6 +23,7 @@ import org.apache.hadoop.fs.Path; import org.apache.tajo.OverridableConf; import org.apache.tajo.algebra.JoinType; +import org.apache.tajo.algebra.MsckTableOpType; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.Schema; @@ -151,6 +152,9 @@ public int compare(PlanProto.LogicalNode o1, PlanProto.LogicalNode o2) { case TRUNCATE_TABLE: current = convertTruncateTable(protoNode); break; + case MSCK_TABLE: + current = convertMsckTable(protoNode); + break; default: throw new RuntimeException("Unknown NodeType: " + protoNode.getType().name()); @@ -609,6 +613,23 @@ private static TruncateTableNode convertTruncateTable(PlanProto.LogicalNode prot return truncateTable; } + private static MsckTableNode convertMsckTable(PlanProto.LogicalNode protoNode) { + MsckTableNode msckTableNode = new MsckTableNode(protoNode.getNodeId()); + + PlanProto.MsckTableNode protoNodeMsckNode = protoNode.getMsckTableNode(); + msckTableNode.setTableName(protoNodeMsckNode.getTableName()); + + switch (protoNodeMsckNode.getSetType()) { + case REPAIR_TABLE: + msckTableNode.setMsckTableOpType(MsckTableOpType.REPAIR_TABLE); + break; + default: + throw new UnimplementedException("Unknown SET type in MSCK TABLE: " + protoNodeMsckNode.getSetType().name()); + } + + return msckTableNode; + } + private static AggregationFunctionCallEval [] convertAggFuncCallEvals(OverridableConf context, EvalContext evalContext, List evalTrees) { AggregationFunctionCallEval [] aggFuncs = new AggregationFunctionCallEval[evalTrees.size()]; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java index 6737756c65..ecf4f89f2e 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java @@ -593,6 +593,28 @@ public LogicalNode visitTruncateTable(SerializeContext context, LogicalPlan plan return node; } + @Override + public LogicalNode visitMsckTable(SerializeContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, + MsckTableNode node, Stack stack) throws PlanningException { + PlanProto.MsckTableNode.Builder msckTableBuilder = PlanProto.MsckTableNode.newBuilder(); + msckTableBuilder.setTableName(node.getTableName()); + + switch (node.getMsckTableOpType()) { + case REPAIR_TABLE: + msckTableBuilder.setSetType(PlanProto.MsckTableNode.Type.REPAIR_TABLE); + break; + + default: + throw new UnimplementedException("Unknown SET type in MSCK TABLE: " + node.getMsckTableOpType().name()); + } + + PlanProto.LogicalNode.Builder nodeBuilder = createNodeBuilder(context, node); + nodeBuilder.setMsckTableNode(msckTableBuilder); + context.treeBuilder.addNodes(nodeBuilder); + + return node; + } + public LogicalNode visitInsert(SerializeContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, InsertNode node, Stack stack) throws PlanningException { super.visitInsert(context, plan, block, node, stack); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java index 19e6ad1076..fb49b84cb5 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java @@ -70,7 +70,8 @@ public static boolean checkIfDDLPlan(LogicalNode node) { baseNode.getType() == NodeType.DROP_TABLE || baseNode.getType() == NodeType.ALTER_TABLESPACE || baseNode.getType() == NodeType.ALTER_TABLE || - baseNode.getType() == NodeType.TRUNCATE_TABLE; + baseNode.getType() == NodeType.TRUNCATE_TABLE || + baseNode.getType() == NodeType.MSCK_TABLE; } /** diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java index ecf9050ab2..29bb36756e 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java @@ -137,6 +137,9 @@ public RESULT visit(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock bl case TRUNCATE_TABLE: current = visitTruncateTable(context, plan, block, (TruncateTableNode) node, stack); break; + case MSCK_TABLE: + current = visitMsckTable(context, plan, block, (MsckTableNode) node, stack); + break; default: throw new PlanningException("Unknown logical node type: " + node.getType()); } @@ -378,4 +381,10 @@ public RESULT visitTruncateTable(CONTEXT context, LogicalPlan plan, LogicalPlan. TruncateTableNode node, Stack stack) throws PlanningException { return null; } + + @Override + public RESULT visitMsckTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, + MsckTableNode node, Stack stack) throws PlanningException { + return null; + } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java index 5be2eec6fa..1da1e26327 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java @@ -104,4 +104,7 @@ RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock RESULT visitTruncateTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, TruncateTableNode node, Stack stack) throws PlanningException; + + RESULT visitMsckTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, MsckTableNode node, + Stack stack) throws PlanningException; } diff --git a/tajo-plan/src/main/proto/Plan.proto b/tajo-plan/src/main/proto/Plan.proto index 40b789118c..149b3a01c9 100644 --- a/tajo-plan/src/main/proto/Plan.proto +++ b/tajo-plan/src/main/proto/Plan.proto @@ -56,6 +56,7 @@ enum NodeType { ALTER_TABLESPACE = 25; ALTER_TABLE = 26; TRUNCATE_TABLE = 27; + MSCK_TABLE = 28; } message LogicalNodeTree { @@ -96,6 +97,7 @@ message LogicalNode { optional AlterTablespaceNode alterTablespace = 28; optional AlterTableNode alterTable = 29; optional TruncateTableNode truncateTableNode = 30; + optional MsckTableNode msckTableNode = 31; } message ScanNode { @@ -303,6 +305,16 @@ message AlterTableNode { optional KeyValueSetProto properties = 6; } +message MsckTableNode { + enum Type { + REPAIR_TABLE = 0; + } + + required string tableName = 1; + required Type setType = 2; +} + + enum EvalType { NOT = 0; AND = 1; From e3bd88f661722e38667f83b8d6cdafda03934a3b Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Fri, 10 Jul 2015 00:39:55 +0900 Subject: [PATCH 02/26] Implement msck repair table on DDLExecutor. --- .../exception/NoPartitionFoundException.java | 28 ++++++++ .../NoPartitionedTableException.java | 2 +- .../apache/tajo/master/exec/DDLExecutor.java | 54 +++++++++++++++- .../tajo/engine/query/TestMsckTable.java | 64 +++++++++++++++++++ .../rules/PartitionedTableRewriter.java | 4 +- 5 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionFoundException.java create mode 100644 tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionFoundException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionFoundException.java new file mode 100644 index 0000000000..ba5cf540c2 --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionFoundException.java @@ -0,0 +1,28 @@ +/** + * 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.tajo.catalog.exception; + +public class NoPartitionFoundException extends CatalogException { + + public NoPartitionFoundException() {} + + public NoPartitionFoundException(String databaseName, String relName) { + super(String.format("ERROR: No partition found in \"%s.%s\"", databaseName, relName)); + } +} diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java index faa8bc407a..efcfcf3655 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/NoPartitionedTableException.java @@ -18,7 +18,7 @@ package org.apache.tajo.catalog.exception; -public class NoPartitionedTableException extends Exception { +public class NoPartitionedTableException extends CatalogException { public NoPartitionedTableException() {} diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 0ab68fe56b..9f241f6935 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -24,6 +24,7 @@ import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.PathFilter; import org.apache.tajo.algebra.AlterTablespaceSetType; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.*; @@ -35,6 +36,7 @@ import org.apache.tajo.master.TajoMaster; import org.apache.tajo.plan.LogicalPlan; import org.apache.tajo.plan.logical.*; +import org.apache.tajo.plan.rewrite.rules.PartitionedTableRewriter; import org.apache.tajo.plan.util.PlannerUtil; import org.apache.tajo.storage.TablespaceManager; import org.apache.tajo.storage.Tablespace; @@ -96,7 +98,7 @@ public boolean execute(QueryContext queryContext, LogicalPlan plan) throws IOExc return true; case MSCK_TABLE: MsckTableNode msckTableNode = (MsckTableNode) root; - msckTable(context, queryContext, msckTableNode); + msckRepairTable(context, queryContext, msckTableNode); return true; default: throw new InternalError("updateQuery cannot handle such query: \n" + root.toJson()); @@ -449,7 +451,17 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer } } - public void msckTable(TajoMaster.MasterContext context, final QueryContext queryContext, + /** + * Run MSCK REPAIR TABLE table_name statement. + * This will recovery all partitions which exists on table directory. + * + * + * @param context + * @param queryContext + * @param msckTable + * @throws IOException + */ + public void msckRepairTable(TajoMaster.MasterContext context, final QueryContext queryContext, final MsckTableNode msckTable) throws IOException { final CatalogService catalog = context.getCatalog(); @@ -472,9 +484,45 @@ public void msckTable(TajoMaster.MasterContext context, final QueryContext query } TableDesc tableDesc = catalog.getTableDesc(databaseName, simpleTableName); + + if(!tableDesc.hasPartition()) { + throw new NoPartitionedTableException(databaseName, simpleTableName); + } + + if(tableDesc.getPartitionMethod() == null) { + throw new NoPartitionFoundException(databaseName, simpleTableName); + } + Path tablePath = new Path(tableDesc.getUri()); + FileSystem fs = tablePath.getFileSystem(context.getConf()); + + PartitionMethodDesc partitionDesc = tableDesc.getPartitionMethod(); + Schema partitionColumns = new Schema(); + for (Column column : partitionDesc.getExpressionSchema().getRootColumns()) { + partitionColumns.addColumn(column); + } + + // Get the array of path filter, accepting all partition paths. + PathFilter[] filters = PartitionedTableRewriter.buildAllAcceptingPathFilters(partitionColumns); + + // loop from one to the number of partition columns + Path [] filteredPaths = PartitionedTableRewriter.toPathArray(fs.listStatus(tablePath, filters[0])); + + // Get all file status matched to a ith level path filter. + for (int i = 1; i < partitionColumns.size(); i++) { + filteredPaths = PartitionedTableRewriter.toPathArray(fs.listStatus(filteredPaths, filters[i])); + } + + int partitionCount = 0; + for(Path filteredPath : filteredPaths) { + String partitionPath = filteredPath.toString(); + int startIndex = partitionPath.indexOf(simpleTableName); + String partitionName = partitionPath.substring(startIndex + simpleTableName.length() + 1, partitionPath.length()); + // TODO: check partition --> add partition + partitionCount++; + } - // TODO: Implement to make directories recursively comparing partition column name. + LOG.info("Added partition directories: " + partitionCount); } private boolean existColumnName(String tableName, String columnName) { diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java new file mode 100644 index 0000000000..cbaf43e063 --- /dev/null +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java @@ -0,0 +1,64 @@ +/** + * 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.tajo.engine.query; + +import org.apache.tajo.QueryTestCaseBase; +import org.apache.tajo.TajoConstants; +import org.apache.tajo.catalog.CatalogUtil; +import org.junit.Test; + +import java.sql.ResultSet; + +import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class TestMsckTable extends QueryTestCaseBase { + + public TestMsckTable() { + super(TajoConstants.DEFAULT_DATABASE_NAME); + } + + @Test + public final void testMsckRepairTable1() throws Exception { + ResultSet res = null; + String tableName = CatalogUtil.normalizeIdentifier("testMsckRepairTable1"); + + res = executeString( + "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) "); + res.close(); + + assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName)); + assertEquals(2, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getSchema().size()); + assertEquals(3, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size()); + + res = testBase.execute( + "insert overwrite into " + tableName + " select l_orderkey, l_partkey, " + + "l_quantity from lineitem"); + res.close(); + + // TODO: drop all partitions to test msck. + + res = testBase.execute("MSCK REPAIR TABLE " + tableName); + res.close(); + + + } +} + diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java b/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java index 3b1f1a8fc5..489d73c19a 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/rewrite/rules/PartitionedTableRewriter.java @@ -196,7 +196,7 @@ public String toString() { * @param partitionColumns The partition columns schema * @return The array of path filter, accpeting all partition paths. */ - private static PathFilter [] buildAllAcceptingPathFilters(Schema partitionColumns) { + public static PathFilter [] buildAllAcceptingPathFilters(Schema partitionColumns) { Column target; PathFilter [] filters = new PathFilter[partitionColumns.size()]; List accumulatedFilters = Lists.newArrayList(); @@ -211,7 +211,7 @@ public String toString() { return filters; } - private static Path [] toPathArray(FileStatus[] fileStatuses) { + public static Path [] toPathArray(FileStatus[] fileStatuses) { Path [] paths = new Path[fileStatuses.length]; for (int j = 0; j < fileStatuses.length; j++) { paths[j] = fileStatuses[j].getPath(); From 4ab75f05c669d3d99fcfd2e7510d4cf2aa3bc9c5 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 14 Jul 2015 15:59:00 +0900 Subject: [PATCH 03/26] Update MSCK TABLE statement to ALTER TABLE REPAIR TABLE statement. --- .../apache/tajo/algebra/AlterTableOpType.java | 2 +- .../org/apache/tajo/algebra/MsckTable.java | 77 ------------- .../apache/tajo/algebra/MsckTableOpType.java | 22 ---- .../java/org/apache/tajo/algebra/OpType.java | 1 - .../org/apache/tajo/engine/parser/SQLLexer.g4 | 1 - .../apache/tajo/engine/parser/SQLParser.g4 | 7 +- .../tajo/engine/parser/SQLAnalyzer.java | 22 ++-- .../apache/tajo/master/exec/DDLExecutor.java | 18 ++- .../tajo/engine/parser/TestSQLAnalyzer.java | 12 +- .../engine/planner/TestLogicalPlanner.java | 12 +- .../alter_table_repair_partition_1.sql | 1 + .../tajo/plan/LogicalPlanPreprocessor.java | 7 -- .../org/apache/tajo/plan/LogicalPlanner.java | 9 -- .../tajo/plan/algebra/AlgebraVisitor.java | 1 - .../tajo/plan/algebra/BaseAlgebraVisitor.java | 9 -- .../tajo/plan/logical/MsckTableNode.java | 104 ------------------ .../apache/tajo/plan/logical/NodeType.java | 2 - .../plan/serder/LogicalNodeDeserializer.java | 21 ---- .../plan/serder/LogicalNodeSerializer.java | 22 ---- .../apache/tajo/plan/util/PlannerUtil.java | 3 +- .../plan/visitor/BasicLogicalPlanVisitor.java | 9 -- .../tajo/plan/visitor/LogicalPlanVisitor.java | 3 - 22 files changed, 32 insertions(+), 333 deletions(-) delete mode 100644 tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java delete mode 100644 tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java create mode 100644 tajo-core/src/test/resources/queries/default/alter_table_repair_partition_1.sql delete mode 100644 tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java index 679ab4bb9e..89daef033e 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.java @@ -18,5 +18,5 @@ package org.apache.tajo.algebra; public enum AlterTableOpType { - RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN, ADD_PARTITION, DROP_PARTITION, SET_PROPERTY + RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN, ADD_PARTITION, DROP_PARTITION, SET_PROPERTY, REPAIR_PARTITION } diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java deleted file mode 100644 index 830f9d5137..0000000000 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTable.java +++ /dev/null @@ -1,77 +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.tajo.algebra; - - -import com.google.common.base.Objects; -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; -import org.apache.tajo.util.TUtil; - -public class MsckTable extends Expr { - - @Expose @SerializedName("TableName") - private String tableName; - - @Expose @SerializedName("MsckTableOpType") - private MsckTableOpType MsckTableOpType; - - - public MsckTable(final String tableName) { - super(OpType.MsckTable); - this.tableName = tableName; - } - - public String getTableName() { - return tableName; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public MsckTableOpType getMsckTableOpType() { - return MsckTableOpType; - } - - public void setMsckTableOpType(MsckTableOpType MsckTableOpType) { - this.MsckTableOpType = MsckTableOpType; - } - - @Override - public int hashCode() { - return Objects.hashCode(tableName, MsckTableOpType); - } - - @Override - boolean equalsTo(Expr expr) { - MsckTable another = (MsckTable) expr; - return tableName.equals(another.tableName) && - TUtil.checkEquals(MsckTableOpType, another.MsckTableOpType) - ; - } - - @Override - public Object clone() throws CloneNotSupportedException { - MsckTable alter = (MsckTable) super.clone(); - alter.setTableName(tableName); - alter.setMsckTableOpType(MsckTableOpType); - return alter; - } -} diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java deleted file mode 100644 index ac85f40b6a..0000000000 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/MsckTableOpType.java +++ /dev/null @@ -1,22 +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.tajo.algebra; - -public enum MsckTableOpType { - REPAIR_TABLE -} diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java index a3bed771ac..3e7d2779dc 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java @@ -54,7 +54,6 @@ public enum OpType { AlterTablespace(AlterTablespace.class), AlterTable(AlterTable.class), TruncateTable(TruncateTable.class), - MsckTable(MsckTable.class), // Insert or Update Insert(Insert.class), diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 index b2a80a9619..48c67f46a1 100644 --- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 +++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 @@ -266,7 +266,6 @@ MILLISECONDS : M I L L I S E C O N D S; MIN : M I N; MINUTE : M I N U T E; MONTH : M O N T H; -MSCK : M S C K; NATIONAL : N A T I O N A L; NULLIF : N U L L I F; diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 index 38de56ef56..bd730e80df 100644 --- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 +++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 @@ -73,7 +73,6 @@ schema_statement | drop_table_statement | alter_tablespace_statement | alter_table_statement - | msck_table_statement | truncate_table_statement ; @@ -282,7 +281,6 @@ nonreserved_keywords | MIN | MINUTE | MONTH - | MSCK | NATIONAL | NO | NULLIF @@ -1608,10 +1606,7 @@ alter_table_statement | ALTER TABLE table_name (if_not_exists)? ADD PARTITION LEFT_PAREN partition_column_value_list RIGHT_PAREN (LOCATION path=Character_String_Literal)? | ALTER TABLE table_name (if_exists)? DROP PARTITION LEFT_PAREN partition_column_value_list RIGHT_PAREN | ALTER TABLE table_name SET PROPERTY property_list - ; - -msck_table_statement - : MSCK REPAIR TABLE table_name + | ALTER TABLE table_name REPAIR PARTITION ; partition_column_value_list diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java index e2c128b8fc..6e8754b9a5 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java @@ -1815,6 +1815,8 @@ public Expr visitAlter_table_statement(SQLParser.Alter_table_statementContext ct if (tables.size() == 2) { alterTable.setNewTableName(tables.get(1).getText()); + } else if (tables.size() == 1) { + alterTable.setTableName(tables.get(0).getText()); } if (checkIfExist(ctx.column_name()) && ctx.column_name().size() == 2) { @@ -1877,6 +1879,7 @@ private AlterTableOpType determineAlterTableType(SQLParser.Alter_table_statement final int PARTITION_MASK = 00000020; final int SET_MASK = 00000002; final int PROPERTY_MASK = 00010000; + final int REPAIR_MASK = 00000003; int val = 00000000; @@ -1908,6 +1911,9 @@ private AlterTableOpType determineAlterTableType(SQLParser.Alter_table_statement case PROPERTY: val = val | PROPERTY_MASK; break; + case REPAIR: + val = val | REPAIR_MASK; + break; default: break; } @@ -1919,6 +1925,8 @@ private AlterTableOpType determineAlterTableType(SQLParser.Alter_table_statement private AlterTableOpType evaluateAlterTableOperationTye(final int value) { switch (value) { + case 19: + return AlterTableOpType.REPAIR_PARTITION; case 65: return AlterTableOpType.RENAME_TABLE; case 73: @@ -1935,18 +1943,4 @@ private AlterTableOpType evaluateAlterTableOperationTye(final int value) { return null; } } - - @Override - public Expr visitMsck_table_statement(@NotNull Msck_table_statementContext ctx) { - MsckTable msck = new MsckTable(ctx.table_name().getText()); - - for (int i = 1; i < ctx.getChildCount(); i++) { - if (ctx.getChild(i) instanceof TerminalNode) { - if (((TerminalNode) ctx.getChild(i)).getSymbol().getType() == REPAIR) { - msck.setMsckTableOpType(MsckTableOpType.REPAIR_TABLE); - } - } - } - return msck; - } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 9f241f6935..e3648e913c 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -96,10 +96,6 @@ public boolean execute(QueryContext queryContext, LogicalPlan plan) throws IOExc AlterTableNode alterTable = (AlterTableNode) root; alterTable(context, queryContext, alterTable); return true; - case MSCK_TABLE: - MsckTableNode msckTableNode = (MsckTableNode) root; - msckRepairTable(context, queryContext, msckTableNode); - return true; default: throw new InternalError("updateQuery cannot handle such query: \n" + root.toJson()); } @@ -446,26 +442,28 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer case SET_PROPERTY: catalog.alterTable(CatalogUtil.setProperty(qualifiedName, alterTable.getProperties(), AlterTableType.SET_PROPERTY)); break; - default: + case REPAIR_PARTITION: + repairPartition(context, queryContext, alterTable); + default: //TODO } } /** - * Run MSCK REPAIR TABLE table_name statement. + * Run ALTER TABLE table_name REPAIR TABLE statement. * This will recovery all partitions which exists on table directory. * * * @param context * @param queryContext - * @param msckTable + * @param alterTable * @throws IOException */ - public void msckRepairTable(TajoMaster.MasterContext context, final QueryContext queryContext, - final MsckTableNode msckTable) throws IOException { + public void repairPartition(TajoMaster.MasterContext context, final QueryContext queryContext, + final AlterTableNode alterTable) throws IOException { final CatalogService catalog = context.getCatalog(); - final String tableName = msckTable.getTableName(); + final String tableName = alterTable.getTableName(); String databaseName; String simpleTableName; diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java index 97bb13e01c..2a18794695 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java @@ -524,13 +524,13 @@ public void testAlterTableSetProperty3() throws IOException { } @Test - public void testMsckRepairTable() throws IOException { - String sql = FileUtil.readTextFileFromResource("queries/default/msck_repair_table.sql"); + public void testAlterTableRepairPartition1() throws IOException { + String sql = FileUtil.readTextFileFromResource("queries/default/alter_table_repair_partition_1.sql"); Expr expr = parseQuery(sql); - assertEquals(OpType.MsckTable, expr.getType()); - MsckTable msck = (MsckTable)expr; - assertEquals(msck.getMsckTableOpType(), MsckTableOpType.REPAIR_TABLE); - assertEquals(msck.getTableName(), "table1"); + assertEquals(OpType.AlterTable, expr.getType()); + AlterTable alterTable = (AlterTable)expr; + assertEquals(alterTable.getAlterTableOpType(), AlterTableOpType.REPAIR_PARTITION); + assertEquals(alterTable.getTableName(), "table1"); } @Test diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java index f7023e7c3f..2a797a546b 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java @@ -25,9 +25,9 @@ import org.apache.tajo.QueryVars; import org.apache.tajo.TajoConstants; import org.apache.tajo.TajoTestingCluster; +import org.apache.tajo.algebra.AlterTableOpType; import org.apache.tajo.algebra.Expr; import org.apache.tajo.algebra.JoinType; -import org.apache.tajo.algebra.MsckTableOpType; import org.apache.tajo.benchmark.TPCH; import org.apache.tajo.catalog.*; import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType; @@ -1233,21 +1233,21 @@ private static InsertNode getInsertNode(LogicalPlan plan) { } @Test - public final void testMsckRepairTable() throws PlanningException { + public final void testAlterTableRepairPartiton() throws PlanningException { QueryContext qc = createQueryContext(); - String sql = "MSCK REPAIR TABLE table1"; + String sql = "ALTER TABLE table1 REPAIR PARTITION"; Expr expr = sqlAnalyzer.parse(sql); LogicalPlan rootNode = planner.createPlan(qc, expr); LogicalNode plan = rootNode.getRootBlock().getRoot(); testJsonSerDerObject(plan); assertEquals(NodeType.ROOT, plan.getType()); LogicalRootNode root = (LogicalRootNode) plan; - assertEquals(NodeType.MSCK_TABLE, root.getChild().getType()); + assertEquals(NodeType.ALTER_TABLE, root.getChild().getType()); - MsckTableNode msckNode = root.getChild(); + AlterTableNode msckNode = root.getChild(); - assertEquals(msckNode.getMsckTableOpType(), MsckTableOpType.REPAIR_TABLE); + assertEquals(msckNode.getAlterTableOpType(), AlterTableOpType.REPAIR_PARTITION); assertEquals(msckNode.getTableName(), "table1"); } } \ No newline at end of file diff --git a/tajo-core/src/test/resources/queries/default/alter_table_repair_partition_1.sql b/tajo-core/src/test/resources/queries/default/alter_table_repair_partition_1.sql new file mode 100644 index 0000000000..b65b0e616f --- /dev/null +++ b/tajo-core/src/test/resources/queries/default/alter_table_repair_partition_1.sql @@ -0,0 +1 @@ +ALTER TABLE table1 REPAIR PARTITION \ No newline at end of file diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java index e857ad9e20..d8cd854060 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java @@ -477,13 +477,6 @@ public LogicalNode visitTruncateTable(LogicalPlanner.PlanContext ctx, Stack stack, - MsckTable expr) throws PlanningException { - MsckTableNode msckTableNode = ctx.plan.createNode(MsckTableNode.class); - return msckTableNode; - } - /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Insert or Update Section /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java index f01791dd71..c51d068f90 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java @@ -2016,15 +2016,6 @@ public LogicalNode visitTruncateTable(PlanContext context, Stack stack, Tr return truncateTableNode; } - @Override - public LogicalNode visitMsckTable(PlanContext context, Stack stack, MsckTable msck) - throws PlanningException { - MsckTableNode msckTableNode = context.queryBlock.getNodeFromExpr(msck); - msckTableNode.setTableName(msck.getTableName()); - msckTableNode.setMsckTableOpType(msck.getMsckTableOpType()); - return msckTableNode; - } - /*=============================================================================================== Util SECTION ===============================================================================================*/ diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java index 90111d9f62..1ac12c240c 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java @@ -53,7 +53,6 @@ public interface AlgebraVisitor { RESULT visitAlterTablespace(CONTEXT ctx, Stack stack, AlterTablespace expr) throws PlanningException; RESULT visitAlterTable(CONTEXT ctx, Stack stack, AlterTable expr) throws PlanningException; RESULT visitTruncateTable(CONTEXT ctx, Stack stack, TruncateTable expr) throws PlanningException; - RESULT visitMsckTable(CONTEXT ctx, Stack stack, MsckTable expr) throws PlanningException; // Insert or Update RESULT visitInsert(CONTEXT ctx, Stack stack, Insert expr) throws PlanningException; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java index 843d69190e..eb11f33e3c 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java @@ -125,9 +125,6 @@ public RESULT visit(CONTEXT ctx, Stack stack, Expr expr) throws PlanningEx case TruncateTable: current = visitTruncateTable(ctx, stack, (TruncateTable)expr); break; - case MsckTable: - current = visitMsckTable(ctx, stack, (MsckTable)expr); - break; case Insert: current = visitInsert(ctx, stack, (Insert) expr); @@ -487,12 +484,6 @@ public RESULT visitAlterTable(CONTEXT ctx, Stack stack, AlterTable expr) t public RESULT visitTruncateTable(CONTEXT ctx, Stack stack, TruncateTable expr) throws PlanningException { return null; } - - @Override - public RESULT visitMsckTable(CONTEXT ctx, Stack stack, MsckTable expr) throws PlanningException { - return null; - } - /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Insert or Update Section /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java deleted file mode 100644 index 5c372daaf0..0000000000 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/MsckTableNode.java +++ /dev/null @@ -1,104 +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.tajo.plan.logical; - - -import com.google.common.base.Objects; -import com.google.gson.annotations.Expose; -import org.apache.tajo.algebra.MsckTableOpType; -import org.apache.tajo.plan.PlanString; - -public class MsckTableNode extends LogicalNode implements Cloneable { - - @Expose private String tableName; - @Expose private MsckTableOpType msckTableOpType; - - - public MsckTableNode(int pid) { - super(pid, NodeType.MSCK_TABLE); - } - - @Override - public int childNum() { - return 0; - } - - @Override - public LogicalNode getChild(int idx) { - return null; - } - - public String getTableName() { - return tableName; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - } - - public MsckTableOpType getMsckTableOpType() { - return msckTableOpType; - } - - public void setMsckTableOpType(MsckTableOpType msckTableOpType) { - this.msckTableOpType = msckTableOpType; - } - - @Override - public PlanString getPlanString() { - return new PlanString(this); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof MsckTableNode) { - MsckTableNode other = (MsckTableNode) obj; - return super.equals(other); - } else { - return false; - } - } - - public int hashCode() { - return Objects.hashCode(tableName, msckTableOpType); - } - - @Override - public Object clone() throws CloneNotSupportedException { - MsckTableNode msck = (MsckTableNode) super.clone(); - msck.tableName = tableName; - msck.msckTableOpType = msckTableOpType; - return msck; - } - - @Override - public String toString() { - return "Msck (table=" + tableName + ", opType = " + msckTableOpType.name().toString() + ")"; - } - - @Override - public void preOrder(LogicalNodeVisitor visitor) { - visitor.visit(this); - } - - @Override - public void postOrder(LogicalNodeVisitor visitor) { - visitor.visit(this); - } -} diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java index 7876faf452..75ae3b7271 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java @@ -22,7 +22,6 @@ package org.apache.tajo.plan.logical; - /** * This indicates a logical node type. */ @@ -56,7 +55,6 @@ public enum NodeType { DROP_TABLE(DropTableNode.class), ALTER_TABLESPACE (AlterTablespaceNode.class), ALTER_TABLE (AlterTableNode.class), - MSCK_TABLE (MsckTableNode.class), TRUNCATE_TABLE (TruncateTableNode.class); private final Class baseClass; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java index 6fcc187a1b..c1d9f9a11b 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java @@ -23,7 +23,6 @@ import org.apache.hadoop.fs.Path; import org.apache.tajo.OverridableConf; import org.apache.tajo.algebra.JoinType; -import org.apache.tajo.algebra.MsckTableOpType; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.Schema; @@ -152,9 +151,6 @@ public int compare(PlanProto.LogicalNode o1, PlanProto.LogicalNode o2) { case TRUNCATE_TABLE: current = convertTruncateTable(protoNode); break; - case MSCK_TABLE: - current = convertMsckTable(protoNode); - break; default: throw new RuntimeException("Unknown NodeType: " + protoNode.getType().name()); @@ -613,23 +609,6 @@ private static TruncateTableNode convertTruncateTable(PlanProto.LogicalNode prot return truncateTable; } - private static MsckTableNode convertMsckTable(PlanProto.LogicalNode protoNode) { - MsckTableNode msckTableNode = new MsckTableNode(protoNode.getNodeId()); - - PlanProto.MsckTableNode protoNodeMsckNode = protoNode.getMsckTableNode(); - msckTableNode.setTableName(protoNodeMsckNode.getTableName()); - - switch (protoNodeMsckNode.getSetType()) { - case REPAIR_TABLE: - msckTableNode.setMsckTableOpType(MsckTableOpType.REPAIR_TABLE); - break; - default: - throw new UnimplementedException("Unknown SET type in MSCK TABLE: " + protoNodeMsckNode.getSetType().name()); - } - - return msckTableNode; - } - private static AggregationFunctionCallEval [] convertAggFuncCallEvals(OverridableConf context, EvalContext evalContext, List evalTrees) { AggregationFunctionCallEval [] aggFuncs = new AggregationFunctionCallEval[evalTrees.size()]; diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java index ecf4f89f2e..6737756c65 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java @@ -593,28 +593,6 @@ public LogicalNode visitTruncateTable(SerializeContext context, LogicalPlan plan return node; } - @Override - public LogicalNode visitMsckTable(SerializeContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, - MsckTableNode node, Stack stack) throws PlanningException { - PlanProto.MsckTableNode.Builder msckTableBuilder = PlanProto.MsckTableNode.newBuilder(); - msckTableBuilder.setTableName(node.getTableName()); - - switch (node.getMsckTableOpType()) { - case REPAIR_TABLE: - msckTableBuilder.setSetType(PlanProto.MsckTableNode.Type.REPAIR_TABLE); - break; - - default: - throw new UnimplementedException("Unknown SET type in MSCK TABLE: " + node.getMsckTableOpType().name()); - } - - PlanProto.LogicalNode.Builder nodeBuilder = createNodeBuilder(context, node); - nodeBuilder.setMsckTableNode(msckTableBuilder); - context.treeBuilder.addNodes(nodeBuilder); - - return node; - } - public LogicalNode visitInsert(SerializeContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, InsertNode node, Stack stack) throws PlanningException { super.visitInsert(context, plan, block, node, stack); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java index fb49b84cb5..19e6ad1076 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java @@ -70,8 +70,7 @@ public static boolean checkIfDDLPlan(LogicalNode node) { baseNode.getType() == NodeType.DROP_TABLE || baseNode.getType() == NodeType.ALTER_TABLESPACE || baseNode.getType() == NodeType.ALTER_TABLE || - baseNode.getType() == NodeType.TRUNCATE_TABLE || - baseNode.getType() == NodeType.MSCK_TABLE; + baseNode.getType() == NodeType.TRUNCATE_TABLE; } /** diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java index 29bb36756e..ecf9050ab2 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java @@ -137,9 +137,6 @@ public RESULT visit(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock bl case TRUNCATE_TABLE: current = visitTruncateTable(context, plan, block, (TruncateTableNode) node, stack); break; - case MSCK_TABLE: - current = visitMsckTable(context, plan, block, (MsckTableNode) node, stack); - break; default: throw new PlanningException("Unknown logical node type: " + node.getType()); } @@ -381,10 +378,4 @@ public RESULT visitTruncateTable(CONTEXT context, LogicalPlan plan, LogicalPlan. TruncateTableNode node, Stack stack) throws PlanningException { return null; } - - @Override - public RESULT visitMsckTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, - MsckTableNode node, Stack stack) throws PlanningException { - return null; - } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java index 1da1e26327..5be2eec6fa 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java @@ -104,7 +104,4 @@ RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock RESULT visitTruncateTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, TruncateTableNode node, Stack stack) throws PlanningException; - - RESULT visitMsckTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, MsckTableNode node, - Stack stack) throws PlanningException; } From 6766f9fb59fa5902d1d4165fbbd1b8a9391001c0 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 14 Jul 2015 16:25:03 +0900 Subject: [PATCH 04/26] Remove unnecessary test cases --- .../tajo/engine/query/TestMsckTable.java | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java deleted file mode 100644 index cbaf43e063..0000000000 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestMsckTable.java +++ /dev/null @@ -1,64 +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.tajo.engine.query; - -import org.apache.tajo.QueryTestCaseBase; -import org.apache.tajo.TajoConstants; -import org.apache.tajo.catalog.CatalogUtil; -import org.junit.Test; - -import java.sql.ResultSet; - -import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class TestMsckTable extends QueryTestCaseBase { - - public TestMsckTable() { - super(TajoConstants.DEFAULT_DATABASE_NAME); - } - - @Test - public final void testMsckRepairTable1() throws Exception { - ResultSet res = null; - String tableName = CatalogUtil.normalizeIdentifier("testMsckRepairTable1"); - - res = executeString( - "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) "); - res.close(); - - assertTrue(catalog.existsTable(DEFAULT_DATABASE_NAME, tableName)); - assertEquals(2, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getSchema().size()); - assertEquals(3, catalog.getTableDesc(DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size()); - - res = testBase.execute( - "insert overwrite into " + tableName + " select l_orderkey, l_partkey, " + - "l_quantity from lineitem"); - res.close(); - - // TODO: drop all partitions to test msck. - - res = testBase.execute("MSCK REPAIR TABLE " + tableName); - res.close(); - - - } -} - From 3ca17401672ca1fc4978d65a83d72cf8d38c8576 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 14 Jul 2015 16:36:57 +0900 Subject: [PATCH 05/26] Add a unit test case. --- .../tajo/engine/query/TestAlterTable.java | 34 +++++++++++++++++++ .../queries/default/msck_repair_table.sql | 1 - .../plan/serder/LogicalNodeDeserializer.java | 3 ++ .../plan/serder/LogicalNodeSerializer.java | 4 +++ tajo-plan/src/main/proto/Plan.proto | 13 +------ 5 files changed, 42 insertions(+), 13 deletions(-) delete mode 100644 tajo-core/src/test/resources/queries/default/msck_repair_table.sql diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java index 44fa1f3594..a840fc2789 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java @@ -20,14 +20,24 @@ import org.apache.tajo.IntegrationTest; import org.apache.tajo.QueryTestCaseBase; +import org.apache.tajo.TajoConstants; +import org.apache.tajo.catalog.CatalogUtil; import org.junit.Test; import org.junit.experimental.categories.Category; import java.sql.ResultSet; import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @Category(IntegrationTest.class) public class TestAlterTable extends QueryTestCaseBase { + + public TestAlterTable() { + super(TajoConstants.DEFAULT_DATABASE_NAME); + } + @Test public final void testAlterTableName() throws Exception { List createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC"); @@ -63,4 +73,28 @@ public final void testAlterTableSetProperty() throws Exception { assertResultSet(after_res, "after_set_property_delimiter.result"); cleanupQuery(after_res); } + + @Test + public final void testAlterTableRepairPartition1() throws Exception { + ResultSet res = null; + String tableName = CatalogUtil.normalizeIdentifier("testMsckRepairTable1"); + + res = executeString( + "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) "); + res.close(); + + assertTrue(catalog.existsTable(TajoConstants.DEFAULT_DATABASE_NAME, tableName)); + assertEquals(2, catalog.getTableDesc(TajoConstants.DEFAULT_DATABASE_NAME, tableName).getSchema().size()); + assertEquals(3, catalog.getTableDesc(TajoConstants.DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size()); + + res = testBase.execute( + "insert overwrite into " + tableName + " select l_orderkey, l_partkey, " + + "l_quantity from lineitem"); + res.close(); + + res = testBase.execute("ALTER TABLE " + tableName + " REPAIR PARTITION"); + res.close(); + + // TODO: Check partition directories and catalog informs. + } } diff --git a/tajo-core/src/test/resources/queries/default/msck_repair_table.sql b/tajo-core/src/test/resources/queries/default/msck_repair_table.sql deleted file mode 100644 index 6c94870988..0000000000 --- a/tajo-core/src/test/resources/queries/default/msck_repair_table.sql +++ /dev/null @@ -1 +0,0 @@ -MSCK REPAIR TABLE table1 \ No newline at end of file diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java index c1d9f9a11b..d8104e6520 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeDeserializer.java @@ -593,6 +593,9 @@ private static AlterTableNode convertAlterTable(PlanProto.LogicalNode protoNode) case SET_PROPERTY: alterTable.setProperties(new KeyValueSet(alterTableProto.getProperties())); break; + case REPAIR_PARTITION: + alterTable.setTableName(alterTableProto.getTableName()); + break; default: throw new UnimplementedException("Unknown SET type in ALTER TABLE: " + alterTableProto.getSetType().name()); } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java index 6737756c65..5722323253 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/serder/LogicalNodeSerializer.java @@ -569,6 +569,10 @@ public LogicalNode visitAlterTable(SerializeContext context, LogicalPlan plan, L alterTableBuilder.setSetType(PlanProto.AlterTableNode.Type.SET_PROPERTY); alterTableBuilder.setProperties(node.getProperties().getProto()); break; + case REPAIR_PARTITION: + alterTableBuilder.setSetType(PlanProto.AlterTableNode.Type.REPAIR_PARTITION); + alterTableBuilder.setTableName(node.getTableName()); + break; default: throw new UnimplementedException("Unknown SET type in ALTER TABLE: " + node.getAlterTableOpType().name()); } diff --git a/tajo-plan/src/main/proto/Plan.proto b/tajo-plan/src/main/proto/Plan.proto index 149b3a01c9..715439d844 100644 --- a/tajo-plan/src/main/proto/Plan.proto +++ b/tajo-plan/src/main/proto/Plan.proto @@ -56,7 +56,6 @@ enum NodeType { ALTER_TABLESPACE = 25; ALTER_TABLE = 26; TRUNCATE_TABLE = 27; - MSCK_TABLE = 28; } message LogicalNodeTree { @@ -97,7 +96,6 @@ message LogicalNode { optional AlterTablespaceNode alterTablespace = 28; optional AlterTableNode alterTable = 29; optional TruncateTableNode truncateTableNode = 30; - optional MsckTableNode msckTableNode = 31; } message ScanNode { @@ -282,6 +280,7 @@ message AlterTableNode { RENAME_COLUMN = 1; ADD_COLUMN = 2; SET_PROPERTY = 3; + REPAIR_PARTITION = 4; } message RenameTable { @@ -305,16 +304,6 @@ message AlterTableNode { optional KeyValueSetProto properties = 6; } -message MsckTableNode { - enum Type { - REPAIR_TABLE = 0; - } - - required string tableName = 1; - required Type setType = 2; -} - - enum EvalType { NOT = 0; AND = 1; From 9b91a9f4392ca91a83d421a7bf7331d2cda37302 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 4 Aug 2015 13:50:11 +0900 Subject: [PATCH 06/26] Apply CatalogStore::addPartitions to DDLExecutor and fix some bugs. --- .../apache/tajo/master/exec/DDLExecutor.java | 55 ++++++++--- .../tajo/engine/query/TestAlterTable.java | 94 ++++++++++++++----- .../alter_table_drop_partition1.sql | 2 +- .../alter_table_drop_partition2.sql | 2 +- .../create_partitioned_table2.sql | 2 + .../main/sphinx/sql_language/alter_table.rst | 2 +- 6 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 tajo-core/src/test/resources/queries/TestAlterTable/create_partitioned_table2.sql diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 7a4e649472..62d01abff4 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -29,9 +29,11 @@ import org.apache.tajo.annotation.Nullable; import org.apache.tajo.catalog.*; import org.apache.tajo.catalog.exception.*; +import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.AlterTablespaceProto; import org.apache.tajo.catalog.proto.CatalogProtos.PartitionKeyProto; +import org.apache.tajo.catalog.proto.CatalogProtos.PartitionDescProto; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.engine.query.QueryContext; import org.apache.tajo.exception.TajoInternalError; @@ -43,6 +45,8 @@ import org.apache.tajo.storage.StorageUtil; import org.apache.tajo.storage.TablespaceManager; import org.apache.tajo.util.Pair; +import org.apache.tajo.util.StringUtils; +import org.apache.tajo.util.TUtil; import java.io.IOException; import java.util.ArrayList; @@ -524,15 +528,10 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer catalog.alterTable(CatalogUtil.addOrDropPartition(qualifiedName, alterTable.getPartitionColumns(), alterTable.getPartitionValues(), alterTable.getLocation(), AlterTableType.DROP_PARTITION)); - // When dropping partition on an managed table, the data will be delete from file system. - if (!desc.isExternal()) { + // When dropping partition on a table, the data in the table will NOT be deleted from the file system. + // But if PURGE is specified, the partition data will be deleted. + if (alterTable.isPurge()) { deletePartitionPath(partitionDescProto); - } else { - // When dropping partition on an external table, the data in the table will NOT be deleted from the file - // system. But if PURGE is specified, the partition data will be deleted. - if (alterTable.isPurge()) { - deletePartitionPath(partitionDescProto); - } } } @@ -603,18 +602,44 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext filteredPaths = PartitionedTableRewriter.toPathArray(fs.listStatus(filteredPaths, filters[i])); } - int partitionCount = 0; + List partitions = TUtil.newList(); for(Path filteredPath : filteredPaths) { - String partitionPath = filteredPath.toString(); - int startIndex = partitionPath.indexOf(simpleTableName); - String partitionName = partitionPath.substring(startIndex + simpleTableName.length() + 1, partitionPath.length()); - // TODO: check partition --> add partition - partitionCount++; + partitions.add(getPartitionDesc(simpleTableName, filteredPath)); } + catalog.addPartitions(databaseName, simpleTableName, partitions, true); - LOG.info("Added partition directories: " + partitionCount); + LOG.info("Added partition directories: " + partitions.size()); } + private PartitionDescProto getPartitionDesc(String tableName, Path path) throws IOException { + String partitionPath = path.toString(); + + String partitionName = StringUtils.unescapePathName(partitionPath); + int startIndex = partitionPath.indexOf(tableName); + partitionName = partitionName.substring(startIndex + tableName.length() + 1, partitionPath.length()); + + CatalogProtos.PartitionDescProto.Builder builder = CatalogProtos.PartitionDescProto.newBuilder(); + builder.setPartitionName(partitionName); + + String[] partitionKeyPairs = partitionName.split("/"); + + for(int i = 0; i < partitionKeyPairs.length; i++) { + String partitionKeyPair = partitionKeyPairs[i]; + String[] split = partitionKeyPair.split("="); + + PartitionKeyProto.Builder keyBuilder = PartitionKeyProto.newBuilder(); + keyBuilder.setColumnName(split[0]); + keyBuilder.setPartitionValue(split[1]); + + builder.addPartitionKeys(keyBuilder.build()); + } + + builder.setPath(partitionPath); + + return builder.build(); + } + + private void deletePartitionPath(CatalogProtos.PartitionDescProto partitionDescProto) throws IOException { Path partitionPath = new Path(partitionDescProto.getPath()); FileSystem fs = partitionPath.getFileSystem(context.getConf()); diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java index ea2a42ae30..a838e4119f 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java @@ -25,7 +25,6 @@ import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.TableDesc; import org.apache.tajo.catalog.proto.CatalogProtos; -import org.apache.tajo.TajoConstants; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -37,10 +36,6 @@ @Category(IntegrationTest.class) public class TestAlterTable extends QueryTestCaseBase { - public TestAlterTable() { - super(TajoConstants.DEFAULT_DATABASE_NAME); - } - @Test public final void testAlterTableName() throws Exception { List createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC"); @@ -81,7 +76,8 @@ public final void testAlterTableSetProperty() throws Exception { public final void testAlterTableAddPartition() throws Exception { executeDDL("create_partitioned_table.sql", null); - String tableName = CatalogUtil.buildFQName("TestAlterTable", "partitioned_table"); + String simpleTableName = "partitioned_table"; + String tableName = CatalogUtil.buildFQName(getCurrentDatabase(), simpleTableName); assertTrue(catalog.existsTable(tableName)); TableDesc retrieved = catalog.getTableDesc(tableName); @@ -94,7 +90,8 @@ public final void testAlterTableAddPartition() throws Exception { executeDDL("alter_table_add_partition1.sql", null); executeDDL("alter_table_add_partition2.sql", null); - List partitions = catalog.getPartitions("TestAlterTable", "partitioned_table"); + List partitions = + catalog.getPartitions(getCurrentDatabase(), simpleTableName); assertNotNull(partitions); assertEquals(partitions.size(), 1); assertEquals(partitions.get(0).getPartitionName(), "col3=1/col4=2"); @@ -112,33 +109,88 @@ public final void testAlterTableAddPartition() throws Exception { executeDDL("alter_table_drop_partition1.sql", null); executeDDL("alter_table_drop_partition2.sql", null); - partitions = catalog.getPartitions("TestAlterTable", "partitioned_table"); + partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); assertNotNull(partitions); assertEquals(partitions.size(), 0); assertFalse(fs.exists(partitionPath)); + + assertTrue(catalog.dropTable(tableName)); } @Test - public final void testAlterTableRepairPartition1() throws Exception { - ResultSet res = null; - String tableName = CatalogUtil.normalizeIdentifier("testMsckRepairTable1"); + public final void testAlterTableRepairPartition() throws Exception { + executeDDL("create_partitioned_table2.sql", null); + + String simpleTableName = "partitioned_table2"; + String tableName = CatalogUtil.buildFQName(getCurrentDatabase(), simpleTableName); + assertTrue(catalog.existsTable(tableName)); + + TableDesc tableDesc = catalog.getTableDesc(tableName); + assertEquals(tableDesc.getName(), tableName); + assertEquals(tableDesc.getPartitionMethod().getPartitionType(), CatalogProtos.PartitionType.COLUMN); + assertEquals(tableDesc.getPartitionMethod().getExpressionSchema().getAllColumns().size(), 2); + assertEquals(tableDesc.getPartitionMethod().getExpressionSchema().getColumn(0).getSimpleName(), "col1"); + assertEquals(tableDesc.getPartitionMethod().getExpressionSchema().getColumn(1).getSimpleName(), "col2"); - res = executeString( - "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) "); + ResultSet res = executeString( + "insert overwrite into " + simpleTableName + " select l_quantity, l_returnflag, l_orderkey, l_partkey " + + " from default.lineitem"); res.close(); - assertTrue(catalog.existsTable(TajoConstants.DEFAULT_DATABASE_NAME, tableName)); - assertEquals(2, catalog.getTableDesc(TajoConstants.DEFAULT_DATABASE_NAME, tableName).getSchema().size()); - assertEquals(3, catalog.getTableDesc(TajoConstants.DEFAULT_DATABASE_NAME, tableName).getLogicalSchema().size()); + res = executeString("select * from " + simpleTableName + " order by col1, col2, col3, col4"); + String result = resultSetToString(res); + String expectedResult = "col3,col4,col1,col2\n" + + "-------------------------------\n" + + "17.0,N,1,1\n" + + "36.0,N,1,1\n" + + "38.0,N,2,2\n" + + "45.0,R,3,2\n" + + "49.0,R,3,3\n"; - res = testBase.execute( - "insert overwrite into " + tableName + " select l_orderkey, l_partkey, " + - "l_quantity from lineitem"); res.close(); + assertEquals(expectedResult, result); - res = testBase.execute("ALTER TABLE " + tableName + " REPAIR PARTITION"); + List partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); + assertNotNull(partitions); + assertEquals(partitions.size(), 4); + + Path tablePath = new Path(tableDesc.getUri()); + FileSystem fs = tablePath.getFileSystem(conf); + assertTrue(fs.exists(new Path(tableDesc.getUri()))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=1/col2=1"))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=2/col2=2"))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=2"))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=3"))); + + res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 1 , col2 = 1)"); res.close(); - // TODO: Check partition directories and catalog informs. + res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 2 , col2 = 2)"); + res.close(); + + res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 2)"); + res.close(); + + res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 3)"); + res.close(); + + partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); + assertNotNull(partitions); + assertEquals(partitions.size(), 0); + + assertTrue(fs.exists(new Path(tableDesc.getUri()))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=1/col2=1"))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=2/col2=2"))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=2"))); + assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=3"))); + + res = executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION"); + res.close(); + + partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); + assertNotNull(partitions); + assertEquals(partitions.size(), 4); + + assertTrue(catalog.dropTable(tableName)); } } diff --git a/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql b/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql index b5d672fc52..cc4d6dd683 100644 --- a/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql +++ b/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition1.sql @@ -1 +1 @@ -ALTER TABLE partitioned_table DROP PARTITION (col3 = 1 , col4 = 2) \ No newline at end of file +ALTER TABLE partitioned_table DROP PARTITION (col3 = 1 , col4 = 2) PURGE \ No newline at end of file diff --git a/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql b/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql index 0d4c93298b..452164b7c1 100644 --- a/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql +++ b/tajo-core/src/test/resources/queries/TestAlterTable/alter_table_drop_partition2.sql @@ -1 +1 @@ -ALTER TABLE partitioned_table DROP IF EXISTS PARTITION (col3 = 1 , col4 = 2) \ No newline at end of file +ALTER TABLE partitioned_table DROP IF EXISTS PARTITION (col3 = 1 , col4 = 2) PURGE \ No newline at end of file diff --git a/tajo-core/src/test/resources/queries/TestAlterTable/create_partitioned_table2.sql b/tajo-core/src/test/resources/queries/TestAlterTable/create_partitioned_table2.sql new file mode 100644 index 0000000000..0fc809481e --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestAlterTable/create_partitioned_table2.sql @@ -0,0 +1,2 @@ +create table partitioned_table2 (col3 float8, col4 text) USING text WITH ('text.delimiter'='|') +PARTITION by column(col1 int4, col2 int4) \ No newline at end of file diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index ffc34d10f9..d4e6e7ec38 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -96,4 +96,4 @@ You can use ``ALTER TABLE ADD PARTITION`` to add partitions to a table. The loca ALTER TABLE table1 DROP PARTITION (col1 = '2015' , col2 = '01', col3 = '11' ) ALTER TABLE table1 DROP PARTITION (col1 = 'TAJO' ) PURGE -You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This removes the data for a managed table and this doesn't remove the data for an external table. But if ``PURGE`` is specified for an external table, the partition data will be removed. The metadata is completely lost in all cases. An error is thrown if the partition for the table doesn't exists. You can use ``IF EXISTS`` to skip the error. +You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This doesn't remove the data for a table. But if ``PURGE`` is specified, the partition data will be removed. The metadata is completely lost in all cases. An error is thrown if the partition for the table doesn't exists. You can use ``IF EXISTS`` to skip the error. From 5fcfc953abfd78dab880e59e41cb678e9d856111 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 4 Aug 2015 14:56:25 +0900 Subject: [PATCH 07/26] Fix some bugs --- .../main/java/org/apache/tajo/master/exec/DDLExecutor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index dd7d298b59..dcd1b1f417 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -404,7 +404,8 @@ public void truncateTable(final QueryContext queryContext, final TruncateTableNo public void alterTable(TajoMaster.MasterContext context, final QueryContext queryContext, final AlterTableNode alterTable) throws IOException, UndefinedTableException, DuplicateTableException, DuplicateColumnException, - DuplicatePartitionException, UndefinedPartitionException, UndefinedPartitionKeyException, AmbiguousPartitionDirectoryExistException { + DuplicatePartitionException, UndefinedPartitionException, UndefinedPartitionKeyException, + AmbiguousPartitionDirectoryExistException, UndefinedPartitionMethodException { final CatalogService catalog = context.getCatalog(); final String tableName = alterTable.getTableName(); @@ -569,7 +570,8 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer * @throws IOException */ public void repairPartition(TajoMaster.MasterContext context, final QueryContext queryContext, - final AlterTableNode alterTable) throws IOException { + final AlterTableNode alterTable) throws IOException, UndefinedTableException, + UndefinedPartitionMethodException { final CatalogService catalog = context.getCatalog(); final String tableName = alterTable.getTableName(); @@ -584,7 +586,6 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext databaseName = queryContext.getCurrentDatabase(); simpleTableName = tableName; } - final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName); if (!catalog.existsTable(databaseName, simpleTableName)) { throw new UndefinedTableException(alterTable.getTableName()); From dff20f24c99b2b7a6ab5092539dd930cc940b2ec Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 25 Aug 2015 11:36:18 +0900 Subject: [PATCH 08/26] Trigger for travis ci build --- .../src/main/java/org/apache/tajo/master/exec/DDLExecutor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 975e72cdba..decbda050a 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -548,7 +548,6 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer deletePartitionPath(partitionDescProto); } } - break; case REPAIR_PARTITION: repairPartition(context, queryContext, alterTable); From 2c63fe90ae094643b8aed09a287f38221f861f6e Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Fri, 4 Sep 2015 12:08:34 +0900 Subject: [PATCH 09/26] Check existing partition from CatalogStore --- .../tajo/catalog/store/HiveCatalogStore.java | 33 ++++++++++++++++++- .../tajo/engine/query/TestAlterTable.java | 24 ++++++++++++++ .../apache/tajo/master/exec/DDLExecutor.java | 29 +++++++++++++--- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java index e2229baca3..74cfdbd58f 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java @@ -847,7 +847,38 @@ public boolean existPartitionMethod(String databaseName, String tableName) throw @Override public List getPartitions(String databaseName, String tableName) { - throw new UnsupportedOperationException(); + HiveCatalogStoreClientPool.HiveCatalogStoreClient client = null; + List partitions = null; + + try { + client = clientPool.getClient(); + partitions = TUtil.newList(); + + List hivePartitions = client.getHiveClient().listPartitionsByFilter(databaseName, tableName + , "", (short) -1); + + for (Partition hivePartition : hivePartitions) { + CatalogProtos.PartitionDescProto.Builder builder = CatalogProtos.PartitionDescProto.newBuilder(); + builder.setPath(hivePartition.getSd().getLocation()); + + int startIndex = hivePartition.getSd().getLocation().indexOf(tableName) + tableName.length(); + String partitionName = hivePartition.getSd().getLocation().substring(startIndex + 1); + builder.setPartitionName(partitionName); + + partitions.add(builder.build()); + } + + } catch (NoSuchObjectException e) { + return null; + } catch (Exception e) { + throw new TajoInternalError(e); + } finally { + if (client != null) { + client.release(); + } + } + return partitions; + } diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java index 8ee9ce041c..8f8c6d056b 100644 --- a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java +++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java @@ -162,6 +162,7 @@ public final void testAlterTableRepairPartition() throws Exception { assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=2"))); assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=3"))); + // Remove all partitions res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 1 , col2 = 1)"); res.close(); @@ -191,6 +192,29 @@ public final void testAlterTableRepairPartition() throws Exception { assertNotNull(partitions); assertEquals(partitions.size(), 4); + + // Remove just one of existing partitions + res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 3)"); + res.close(); + + res = executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION"); + res.close(); + + partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); + assertNotNull(partitions); + assertEquals(partitions.size(), 4); + + + // Remove a partition directory from filesystem + fs.delete(new Path(tablePath.toUri() + "/col1=3/col2=3"), true); + res = executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION"); + res.close(); + + partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); + assertNotNull(partitions); + assertEquals(partitions.size(), 4); + + catalog.dropTable(tableName); } } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index eaeec6b341..d8cf298323 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -52,6 +52,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Set; import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME; @@ -615,13 +616,33 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext filteredPaths = PartitionedTableRewriter.toPathArray(fs.listStatus(filteredPaths, filters[i])); } - List partitions = TUtil.newList(); + // Find missing partitions from filesystem + List existingPartitions = catalog.getPartitions(databaseName, simpleTableName); + Path existingPartitionPath = null; + for(PartitionDescProto existingPartition : existingPartitions) { + existingPartitionPath = new Path(existingPartition.getPath()); + if (!fs.exists(existingPartitionPath)) { + LOG.info("Partitions missing from Filesystem:" + existingPartition.getPartitionName()); + } + } + + // Find missing partitions from CatalogStore + List targetPartitions = TUtil.newList(); for(Path filteredPath : filteredPaths) { - partitions.add(getPartitionDesc(simpleTableName, filteredPath)); + PartitionDescProto targetPartition = getPartitionDesc(simpleTableName, filteredPath); + + if (!existingPartitions.contains(targetPartition)) { + LOG.info("Partitions not in CatalogStore:" + targetPartition.getPartitionName()); + targetPartitions.add(targetPartition); + } } - catalog.addPartitions(databaseName, simpleTableName, partitions, true); - LOG.info("Added partition directories: " + partitions.size()); + catalog.addPartitions(databaseName, simpleTableName, targetPartitions, true); + + for(PartitionDescProto targetPartition: targetPartitions) { + LOG.info("Repair: Added partition to CatalogStore " + tableName + ":" + targetPartition.getPartitionName()); + } + LOG.info("Total added partitions to CatalogStore: " + targetPartitions.size()); } private PartitionDescProto getPartitionDesc(String tableName, Path path) throws IOException { From 98094bcbd612533dace0c1167e283ae658099451 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Fri, 4 Sep 2015 14:01:08 +0900 Subject: [PATCH 10/26] Fix bug for HiveCatalogStore --- .../java/org/apache/tajo/catalog/store/HiveCatalogStore.java | 2 +- .../main/java/org/apache/tajo/master/exec/DDLExecutor.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java index 74cfdbd58f..8a07a013ee 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java @@ -1062,7 +1062,7 @@ public void addPartitions(String databaseName, String tableName, List existingPartitions = catalog.getPartitions(databaseName, simpleTableName); + List existingPartitionNames = TUtil.newList(); Path existingPartitionPath = null; for(PartitionDescProto existingPartition : existingPartitions) { existingPartitionPath = new Path(existingPartition.getPath()); + existingPartitionNames.add(existingPartition.getPartitionName()); if (!fs.exists(existingPartitionPath)) { LOG.info("Partitions missing from Filesystem:" + existingPartition.getPartitionName()); } @@ -630,8 +632,7 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext List targetPartitions = TUtil.newList(); for(Path filteredPath : filteredPaths) { PartitionDescProto targetPartition = getPartitionDesc(simpleTableName, filteredPath); - - if (!existingPartitions.contains(targetPartition)) { + if (!existingPartitionNames.contains(targetPartition.getPartitionName())) { LOG.info("Partitions not in CatalogStore:" + targetPartition.getPartitionName()); targetPartitions.add(targetPartition); } From dcc5fd27123ad782789f4bee3d5be258200325b1 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Fri, 4 Sep 2015 17:50:18 +0900 Subject: [PATCH 11/26] Add description for repair partition --- .../main/sphinx/sql_language/alter_table.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index d4e6e7ec38..d77f67cb71 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -97,3 +97,21 @@ You can use ``ALTER TABLE ADD PARTITION`` to add partitions to a table. The loca ALTER TABLE table1 DROP PARTITION (col1 = 'TAJO' ) PURGE You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This doesn't remove the data for a table. But if ``PURGE`` is specified, the partition data will be removed. The metadata is completely lost in all cases. An error is thrown if the partition for the table doesn't exists. You can use ``IF EXISTS`` to skip the error. + +======================== +Repair partition +======================== + +Tajo stores a list of partitions for each table in its catalogstore. If partitions are manually added to the distributed file system, the metastore is not aware of these partitions. Running the ``ALTER TABLE REPAIR PARTITION`` statement ensures that the tables are properly populated. + +*Synopsis* + +.. code-block:: sql + + ALTER TABLE REPAIR PARTITION + +*Examples* + +.. code-block:: sql + + ALTER TABLE student REPAIR PARTITION; From 6bddc54c0980d3bb1c596c5b282987a5e059e9d7 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 8 Sep 2015 15:28:12 +0900 Subject: [PATCH 12/26] Trigger for travis CI build --- .../src/main/java/org/apache/tajo/master/exec/DDLExecutor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index f4d26e4f5f..0d80073e62 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -620,6 +620,7 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext List existingPartitions = catalog.getPartitions(databaseName, simpleTableName); List existingPartitionNames = TUtil.newList(); Path existingPartitionPath = null; + for(PartitionDescProto existingPartition : existingPartitions) { existingPartitionPath = new Path(existingPartition.getPath()); existingPartitionNames.add(existingPartition.getPartitionName()); From 7628cc97eb4a452ab376fe9497d019e326d73edf Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Fri, 11 Sep 2015 13:47:24 +0900 Subject: [PATCH 13/26] Recover SQLAnalyzer --- .../apache/tajo/parser/sql/SQLAnalyzer.java | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java index 515961c5b6..793cb1c6f9 100644 --- a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java +++ b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java @@ -18,6 +18,9 @@ package org.apache.tajo.parser.sql; +import com.facebook.presto.hive.shaded.com.google.common.base.Function; +import com.facebook.presto.hive.shaded.com.google.common.collect.Collections2; +import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import org.antlr.v4.runtime.ANTLRInputStream; @@ -387,7 +390,8 @@ public Aggregation visitGroupby_clause(Groupby_clauseContext ctx) { } else if (checkIfExist(functionType.ROW_NUMBER())) { functionBody = new GeneralSetFunctionExpr("row_number", false, new Expr[] {}); } else if (checkIfExist(functionType.FIRST_VALUE())) { - functionBody = new GeneralSetFunctionExpr("first_value", false, new Expr[]{ visitColumn_reference(functionType.column_reference())}); + functionBody = new GeneralSetFunctionExpr("first_value", false, + new Expr[]{ visitColumn_reference(functionType.column_reference())}); } else if (checkIfExist(functionType.LAST_VALUE())) { functionBody = new GeneralSetFunctionExpr("last_value", false, new Expr[]{visitColumn_reference(functionType.column_reference())}); } else if (checkIfExist(functionType.LAG())) { @@ -437,7 +441,7 @@ public Window visitWindow_clause(@NotNull Window_clauseContext ctx) { new Window.WindowDefinition[ctx.window_definition_list().window_definition().size()]; for (int i = 0; i < definitions.length; i++) { Window_definitionContext windowDefinitionContext = ctx.window_definition_list().window_definition(i); - String windowName = windowDefinitionContext.window_name().identifier().getText(); + String windowName = buildIdentifier(windowDefinitionContext.window_name().identifier()); WindowSpec windowSpec = buildWindowSpec(windowDefinitionContext.window_specification()); definitions[i] = new Window.WindowDefinition(windowName, windowSpec); } @@ -1051,7 +1055,7 @@ public ExistsPredicate visitExists_predicate(Exists_predicateContext ctx) { @Override public ColumnReferenceExpr visitColumn_reference(Column_referenceContext ctx) { - String columnReferenceName = ctx.getText(); + String columnReferenceName = buildIdentifierChain(ctx.identifier()); // find the last dot (.) position to separate a name into both a qualifier and name int lastDotIdx = columnReferenceName.lastIndexOf("."); @@ -1117,7 +1121,7 @@ public FunctionExpr visitRoutine_invocation(Routine_invocationContext ctx) { public NamedExpr visitDerived_column(Derived_columnContext ctx) { NamedExpr target = new NamedExpr(visitValue_expression(ctx.value_expression())); if (ctx.as_clause() != null) { - target.setAlias(ctx.as_clause().identifier().getText()); + target.setAlias(buildIdentifier(ctx.as_clause().identifier())); } return target; } @@ -1175,14 +1179,6 @@ public Expr visitNumeric_value_function(Numeric_value_functionContext ctx) { public Expr visitExtract_expression(Extract_expressionContext ctx) { Expr extractTarget = new LiteralValue(ctx.extract_field_string.getText(), LiteralType.String); Expr extractSource = visitDatetime_value_expression(ctx.extract_source().datetime_value_expression()); -// if (checkIfExist(ctx.extract_source().column_reference())) { -// extractSource = visitColumn_reference(ctx.extract_source().column_reference()); -// } else if (checkIfExist(ctx.extract_source().datetime_literal())) { -// extractSource = visitDatetime_literal(ctx.extract_source().datetime_literal()); -// } else { -// return null; -// } - String functionName = "date_part"; Expr[] params = new Expr[]{extractTarget, extractSource}; @@ -1225,7 +1221,7 @@ public Expr visitTrim_function(Trim_functionContext ctx) { @Override public Expr visitCreate_index_statement(Create_index_statementContext ctx) { String indexName = ctx.index_name.getText(); - String tableName = ctx.table_name().getText(); + String tableName = buildIdentifierChain(ctx.table_name().identifier()); Relation relation = new Relation(tableName); SortSpec[] sortSpecs = buildSortSpecs(ctx.sort_specifier_list()); NamedExpr[] targets = new NamedExpr[sortSpecs.length]; @@ -1242,7 +1238,7 @@ public Expr visitCreate_index_statement(Create_index_statementContext ctx) { createIndex.setUnique(true); } if (checkIfExist(ctx.method_specifier())) { - String methodName = ctx.method_specifier().identifier().getText(); + String methodName = buildIdentifier(ctx.method_specifier().identifier()); createIndex.setMethodSpec(new IndexMethodSpec(methodName)); } if (checkIfExist(ctx.param_clause())) { @@ -1263,26 +1259,26 @@ public Expr visitCreate_index_statement(Create_index_statementContext ctx) { @Override public Expr visitDrop_index_statement(Drop_index_statementContext ctx) { - String indexName = ctx.identifier().getText(); + String indexName = buildIdentifier(ctx.identifier()); return new DropIndex(indexName); } @Override public Expr visitDatabase_definition(@NotNull Database_definitionContext ctx) { - return new CreateDatabase(ctx.identifier().getText(), null, checkIfExist(ctx.if_not_exists())); + return new CreateDatabase(buildIdentifier(ctx.identifier()), null, checkIfExist(ctx.if_not_exists())); } @Override public Expr visitDrop_database_statement(@NotNull Drop_database_statementContext ctx) { - return new DropDatabase(ctx.identifier().getText(), checkIfExist(ctx.if_exists())); + return new DropDatabase(buildIdentifier(ctx.identifier()), checkIfExist(ctx.if_exists())); } @Override public Expr visitCreate_table_statement(Create_table_statementContext ctx) { - String tableName = ctx.table_name(0).getText(); + String tableName = buildIdentifierChain(ctx.table_name(0).identifier()); CreateTable createTable = new CreateTable(tableName, checkIfExist(ctx.if_not_exists())); if(checkIfExist(ctx.LIKE())) { - createTable.setLikeParentTable(ctx.like_table_name.getText()); + createTable.setLikeParentTable(buildIdentifierChain(ctx.like_table_name.identifier())); return createTable; } @@ -1345,7 +1341,7 @@ public Expr visitTruncate_table_statement(@NotNull Truncate_table_statementConte List tableNames = new ArrayList(); for (Table_nameContext eachTableNameContext: tableNameContexts) { - tableNames.add(eachTableNameContext.getChild(0).getText()); + tableNames.add(buildIdentifierChain(eachTableNameContext.identifier())); } return new TruncateTable(tableNames); @@ -1630,7 +1626,7 @@ public Expr visitInsert_statement(Insert_statementContext ctx) { } if (ctx.table_name() != null) { - insertExpr.setTableName(ctx.table_name().getText()); + insertExpr.setTableName(buildIdentifierChain(ctx.table_name().identifier())); if (ctx.column_reference_list() != null) { ColumnReferenceExpr [] targetColumns = @@ -1667,7 +1663,8 @@ public Expr visitInsert_statement(Insert_statementContext ctx) { @Override public Expr visitDrop_table_statement(Drop_table_statementContext ctx) { - return new DropTable(ctx.table_name().getText(), checkIfExist(ctx.if_exists()), checkIfExist(ctx.PURGE())); + return new DropTable(buildIdentifierChain(ctx.table_name().identifier()), + checkIfExist(ctx.if_exists()), checkIfExist(ctx.PURGE())); } @@ -1862,18 +1859,16 @@ public Expr visitAlter_table_statement(Alter_table_statementContext ctx) { final List tables = ctx.table_name(); - final AlterTable alterTable = new AlterTable(tables.get(0).getText()); + final AlterTable alterTable = new AlterTable(buildIdentifierChain(tables.get(0).identifier())); if (tables.size() == 2) { - alterTable.setNewTableName(tables.get(1).getText()); - } else if (tables.size() == 1) { - alterTable.setTableName(tables.get(0).getText()); + alterTable.setNewTableName(buildIdentifierChain(tables.get(1).identifier())); } if (checkIfExist(ctx.column_name()) && ctx.column_name().size() == 2) { final List columns = ctx.column_name(); - alterTable.setColumnName(columns.get(0).getText()); - alterTable.setNewColumnName(columns.get(1).getText()); + alterTable.setColumnName(buildIdentifier(columns.get(0).identifier())); + alterTable.setNewColumnName(buildIdentifier(columns.get(1).identifier())); } Field_elementContext field_elementContext = ctx.field_element(); @@ -1891,7 +1886,7 @@ public Expr visitAlter_table_statement(Alter_table_statementContext ctx) { Expr[] values = new Expr[size]; for (int i = 0; i < size; i++) { Partition_column_valueContext columnValue = columnValueList.get(i); - columns[i] = new ColumnReferenceExpr(columnValue.identifier().getText()); + columns[i] = new ColumnReferenceExpr(buildIdentifier(columnValue.identifier())); values[i] = visitRow_value_predicand(columnValue.row_value_predicand()); } alterTable.setColumns(columns); @@ -1933,7 +1928,6 @@ private AlterTableOpType determineAlterTableType(Alter_table_statementContext ct final int PARTITION_MASK = 00000020; final int SET_MASK = 00000002; final int PROPERTY_MASK = 00010000; - final int REPAIR_MASK = 00000003; int val = 00000000; @@ -1965,9 +1959,6 @@ private AlterTableOpType determineAlterTableType(Alter_table_statementContext ct case PROPERTY: val = val | PROPERTY_MASK; break; - case REPAIR: - val = val | REPAIR_MASK; - break; default: break; } @@ -1979,8 +1970,6 @@ private AlterTableOpType determineAlterTableType(Alter_table_statementContext ct private AlterTableOpType evaluateAlterTableOperationTye(final int value) { switch (value) { - case 19: - return AlterTableOpType.REPAIR_PARTITION; case 65: return AlterTableOpType.RENAME_TABLE; case 73: @@ -1997,4 +1986,27 @@ private AlterTableOpType evaluateAlterTableOperationTye(final int value) { return null; } } + + /** + * Return identifier, where text case sensitivity is kept depending on the kind of identifier and + * + * @param identifier IdentifierContext + * @return Identifier + */ + private static String buildIdentifier(IdentifierContext identifier) { + if (checkIfExist(identifier.nonreserved_keywords())) { + return identifier.getText().toLowerCase(); + } else { + return identifier.getText(); + } + } + + private static String buildIdentifierChain(final Collection identifierChains) { + return Joiner.on(".").join(Collections2.transform(identifierChains, new Function() { + @Override + public String apply(IdentifierContext identifierContext) { + return buildIdentifier(identifierContext); + } + })); + } } From 6fff553dd3bb50242e9094ee783aa8470d991275 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Fri, 11 Sep 2015 13:49:00 +0900 Subject: [PATCH 14/26] Add repair partition to SQLAnalyzer --- .../main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java index 793cb1c6f9..cc2a7db2fa 100644 --- a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java +++ b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java @@ -1928,6 +1928,7 @@ private AlterTableOpType determineAlterTableType(Alter_table_statementContext ct final int PARTITION_MASK = 00000020; final int SET_MASK = 00000002; final int PROPERTY_MASK = 00010000; + final int REPAIR_MASK = 00000003; int val = 00000000; @@ -1959,6 +1960,9 @@ private AlterTableOpType determineAlterTableType(Alter_table_statementContext ct case PROPERTY: val = val | PROPERTY_MASK; break; + case REPAIR: + val = val | REPAIR_MASK; + break; default: break; } @@ -1970,6 +1974,8 @@ private AlterTableOpType determineAlterTableType(Alter_table_statementContext ct private AlterTableOpType evaluateAlterTableOperationTye(final int value) { switch (value) { + case 19: + return AlterTableOpType.REPAIR_PARTITION; case 65: return AlterTableOpType.RENAME_TABLE; case 73: From 9074e7daf91aac4e41e75c1a8558d73ae19457ac Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 16 Sep 2015 15:27:26 +0900 Subject: [PATCH 15/26] Add abnormal directories for unit test --- .../tajo/engine/query/TestAlterTable.java | 68 ++++++++----------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java index 8f8c6d056b..1667a6e564 100644 --- a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java +++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java @@ -18,6 +18,7 @@ package org.apache.tajo.engine.query; +import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.tajo.IntegrationTest; @@ -55,7 +56,7 @@ public final void testAlterTableColumnName() throws Exception { public final void testAlterTableAddNewColumn() throws Exception { List createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "EFG"); executeDDL("alter_table_add_new_column_ddl.sql", null); - assertColumnExists(createdNames.get(0),"cool"); + assertColumnExists(createdNames.get(0), "cool"); } @Test @@ -150,9 +151,7 @@ public final void testAlterTableRepairPartition() throws Exception { res.close(); assertEquals(expectedResult, result); - List partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); - assertNotNull(partitions); - assertEquals(partitions.size(), 4); + verifyPartitionCount(getCurrentDatabase(), simpleTableName, 4); Path tablePath = new Path(tableDesc.getUri()); FileSystem fs = tablePath.getFileSystem(conf); @@ -163,21 +162,12 @@ public final void testAlterTableRepairPartition() throws Exception { assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=3"))); // Remove all partitions - res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 1 , col2 = 1)"); - res.close(); - - res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 2 , col2 = 2)"); - res.close(); + executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 1 , col2 = 1)").close(); + executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 2 , col2 = 2)").close(); + executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 2)").close(); + executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 3)").close(); - res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 2)"); - res.close(); - - res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 3)"); - res.close(); - - partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); - assertNotNull(partitions); - assertEquals(partitions.size(), 0); + verifyPartitionCount(getCurrentDatabase(), simpleTableName, 0); assertTrue(fs.exists(new Path(tableDesc.getUri()))); assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=1/col2=1"))); @@ -185,36 +175,34 @@ public final void testAlterTableRepairPartition() throws Exception { assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=2"))); assertTrue(fs.isDirectory(new Path(tablePath.toUri() + "/col1=3/col2=3"))); - res = executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION"); - res.close(); - - partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); - assertNotNull(partitions); - assertEquals(partitions.size(), 4); - + executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION").close(); + verifyPartitionCount(getCurrentDatabase(), simpleTableName, 4); // Remove just one of existing partitions - res = executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 3)"); - res.close(); - - res = executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION"); - res.close(); - - partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); - assertNotNull(partitions); - assertEquals(partitions.size(), 4); - + executeString("ALTER TABLE " + simpleTableName + " DROP PARTITION (col1 = 3 , col2 = 3)").close(); + executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION").close(); + verifyPartitionCount(getCurrentDatabase(), simpleTableName, 4); // Remove a partition directory from filesystem fs.delete(new Path(tablePath.toUri() + "/col1=3/col2=3"), true); - res = executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION"); - res.close(); + executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION").close(); + verifyPartitionCount(getCurrentDatabase(), simpleTableName, 4); - partitions = catalog.getPartitions(getCurrentDatabase(), simpleTableName); - assertNotNull(partitions); - assertEquals(partitions.size(), 4); + // Add abnormal directories + assertTrue(fs.mkdirs(new Path(tablePath.toUri() + "/col10=1/col20=1"))); + assertTrue(fs.mkdirs(new Path(tablePath.toUri() + "/col1="))); + assertTrue(fs.mkdirs(new Path(tablePath.toUri() + "/test"))); + assertEquals(6, fs.listStatus(new Path(tablePath.toUri())).length); + executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION").close(); + verifyPartitionCount(getCurrentDatabase(), simpleTableName, 4); catalog.dropTable(tableName); } + + private void verifyPartitionCount(String databaseName, String tableName, int expectedCount) { + List partitions = catalog.getPartitions(databaseName, tableName); + assertNotNull(partitions); + assertEquals(partitions.size(), expectedCount); + } } From c311c0c441a6e9935b667cc8d6a066c7f19dbc6c Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 16 Sep 2015 15:40:55 +0900 Subject: [PATCH 16/26] Add more decsription --- .../src/main/sphinx/sql_language/alter_table.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index d77f67cb71..5f1496caf1 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -102,7 +102,7 @@ You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This Repair partition ======================== -Tajo stores a list of partitions for each table in its catalogstore. If partitions are manually added to the distributed file system, the metastore is not aware of these partitions. Running the ``ALTER TABLE REPAIR PARTITION`` statement ensures that the tables are properly populated. +Tajo stores a list of partitions for each table in its catalog. If partitions are manually added to the distributed file system, the metastore is not aware of these partitions. Running the ``ALTER TABLE REPAIR PARTITION`` statement ensures that the tables are properly populated. *Synopsis* @@ -115,3 +115,12 @@ Tajo stores a list of partitions for each table in its catalogstore. If partitio .. code-block:: sql ALTER TABLE student REPAIR PARTITION; + +.. note:: + + If you recover partitions in the situation that partitions just exists on catalog and it doesn't exist on file system, Tajo would not make directories on the file system and would print messages to TajoMaster log as following: + + .. code-block:: sql + + Partitions missing from Filesystem: + From 426ee252dc9d4655df2aeede55c25357041506b9 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 16 Sep 2015 15:42:06 +0900 Subject: [PATCH 17/26] Update subtitle --- tajo-docs/src/main/sphinx/sql_language/alter_table.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index 5f1496caf1..13cf266ff7 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -99,7 +99,7 @@ You can use ``ALTER TABLE ADD PARTITION`` to add partitions to a table. The loca You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This doesn't remove the data for a table. But if ``PURGE`` is specified, the partition data will be removed. The metadata is completely lost in all cases. An error is thrown if the partition for the table doesn't exists. You can use ``IF EXISTS`` to skip the error. ======================== -Repair partition +REPAIR PARTITION ======================== Tajo stores a list of partitions for each table in its catalog. If partitions are manually added to the distributed file system, the metastore is not aware of these partitions. Running the ``ALTER TABLE REPAIR PARTITION`` statement ensures that the tables are properly populated. From 78a674b4c2728d7598072d974b722612aedb306d Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Thu, 17 Sep 2015 12:25:00 +0900 Subject: [PATCH 18/26] Trigger for the travis CI build --- .../test/java/org/apache/tajo/engine/query/TestAlterTable.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java index df518db48d..9a6074ab75 100644 --- a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java +++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java @@ -196,7 +196,6 @@ public final void testAlterTableRepairPartition() throws Exception { executeString("ALTER TABLE " + simpleTableName + " REPAIR PARTITION").close(); verifyPartitionCount(getCurrentDatabase(), simpleTableName, 4); - catalog.dropTable(tableName); } From b9514d86f9c8edc5ecc234010877fe98d3ec43cc Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Tue, 22 Sep 2015 17:57:38 +0900 Subject: [PATCH 19/26] Update wrong method name --- .../test/java/org/apache/tajo/engine/query/TestAlterTable.java | 2 +- .../src/main/java/org/apache/tajo/master/exec/DDLExecutor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java index 509e9f3bfc..d10c0f2479 100644 --- a/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java +++ b/tajo-core-tests/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java @@ -202,7 +202,7 @@ public final void testAlterTableRepairPartition() throws Exception { private void verifyPartitionCount(String databaseName, String tableName, int expectedCount) throws UndefinedDatabaseException, UndefinedTableException, UndefinedPartitionMethodException, UndefinedPartitionException { - List partitions = catalog.getAllPartitions(databaseName, tableName); + List partitions = catalog.getPartitions(databaseName, tableName); assertNotNull(partitions); assertEquals(partitions.size(), expectedCount); } diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index ab8087acfc..80c9ffac9a 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -608,7 +608,7 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext } // Find missing partitions from filesystem - List existingPartitions = catalog.getAllPartitions(databaseName, simpleTableName); + List existingPartitions = catalog.getPartitions(databaseName, simpleTableName); List existingPartitionNames = TUtil.newList(); Path existingPartitionPath = null; From 063e4ec85c396c15d28b2d8bf988e36df3da0b41 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 12:08:41 +0900 Subject: [PATCH 20/26] Remove unused import --- .../src/main/java/org/apache/tajo/master/exec/DDLExecutor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 5d9cbdad1d..bbf8a93cc7 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -52,7 +52,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.Set; import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME; From a9f2a4c8ed8f5b8a577b696741a998d7f806d806 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 12:20:45 +0900 Subject: [PATCH 21/26] Update log type --- .../src/main/java/org/apache/tajo/master/exec/DDLExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index bbf8a93cc7..09b0221e8f 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -615,7 +615,7 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext existingPartitionPath = new Path(existingPartition.getPath()); existingPartitionNames.add(existingPartition.getPartitionName()); if (!fs.exists(existingPartitionPath)) { - LOG.info("Partitions missing from Filesystem:" + existingPartition.getPartitionName()); + LOG.warn("Partitions missing from Filesystem:" + existingPartition.getPartitionName()); } } From d42dffa82753fe06e32ab5a298c50d751d8b8341 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 15:29:49 +0900 Subject: [PATCH 22/26] Update description and log type --- .../apache/tajo/master/exec/DDLExecutor.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index 09b0221e8f..d8129d3cd4 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -535,8 +535,7 @@ public void alterTable(TajoMaster.MasterContext context, final QueryContext quer catalog.alterTable(CatalogUtil.addOrDropPartition(qualifiedName, alterTable.getPartitionColumns(), alterTable.getPartitionValues(), alterTable.getLocation(), AlterTableType.DROP_PARTITION)); - // When dropping partition on a table, the data in the table will NOT be deleted from the file system. - // But if PURGE is specified, the partition data will be deleted. + // When dropping a partition on a table, its data will NOT be deleted if the 'PURGE' option is not specified. if (alterTable.isPurge()) { deletePartitionPath(partitionDescProto); } @@ -614,8 +613,8 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext for(PartitionDescProto existingPartition : existingPartitions) { existingPartitionPath = new Path(existingPartition.getPath()); existingPartitionNames.add(existingPartition.getPartitionName()); - if (!fs.exists(existingPartitionPath)) { - LOG.warn("Partitions missing from Filesystem:" + existingPartition.getPartitionName()); + if (!fs.exists(existingPartitionPath) && LOG.isDebugEnabled()) { + LOG.debug("Partitions missing from Filesystem:" + existingPartition.getPartitionName()); } } @@ -624,16 +623,21 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext for(Path filteredPath : filteredPaths) { PartitionDescProto targetPartition = getPartitionDesc(simpleTableName, filteredPath); if (!existingPartitionNames.contains(targetPartition.getPartitionName())) { - LOG.info("Partitions not in CatalogStore:" + targetPartition.getPartitionName()); + if (LOG.isDebugEnabled()) { + LOG.debug("Partitions not in CatalogStore:" + targetPartition.getPartitionName()); + } targetPartitions.add(targetPartition); } } catalog.addPartitions(databaseName, simpleTableName, targetPartitions, true); - for(PartitionDescProto targetPartition: targetPartitions) { - LOG.info("Repair: Added partition to CatalogStore " + tableName + ":" + targetPartition.getPartitionName()); + if (LOG.isDebugEnabled()) { + for(PartitionDescProto targetPartition: targetPartitions) { + LOG.debug("Repair: Added partition to CatalogStore " + tableName + ":" + targetPartition.getPartitionName()); + } } + LOG.info("Total added partitions to CatalogStore: " + targetPartitions.size()); } From f1901acfe4400afb4f2fa0cf2cb0d5a6dfdfdb91 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 15:34:48 +0900 Subject: [PATCH 23/26] Remove unnecessary codes --- .../main/java/org/apache/tajo/master/exec/DDLExecutor.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java index d8129d3cd4..a67a625d3e 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java @@ -589,10 +589,7 @@ public void repairPartition(TajoMaster.MasterContext context, final QueryContext FileSystem fs = tablePath.getFileSystem(context.getConf()); PartitionMethodDesc partitionDesc = tableDesc.getPartitionMethod(); - Schema partitionColumns = new Schema(); - for (Column column : partitionDesc.getExpressionSchema().getRootColumns()) { - partitionColumns.addColumn(column); - } + Schema partitionColumns = partitionDesc.getExpressionSchema(); // Get the array of path filter, accepting all partition paths. PathFilter[] filters = PartitionedTableRewriter.buildAllAcceptingPathFilters(partitionColumns); From 6e52166f4a2579671e9e5644f26fb326dc158b06 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 15:35:40 +0900 Subject: [PATCH 24/26] Fix a typo --- tajo-docs/src/main/sphinx/sql_language/alter_table.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index 13cf266ff7..20be2798cd 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -96,7 +96,7 @@ You can use ``ALTER TABLE ADD PARTITION`` to add partitions to a table. The loca ALTER TABLE table1 DROP PARTITION (col1 = '2015' , col2 = '01', col3 = '11' ) ALTER TABLE table1 DROP PARTITION (col1 = 'TAJO' ) PURGE -You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This doesn't remove the data for a table. But if ``PURGE`` is specified, the partition data will be removed. The metadata is completely lost in all cases. An error is thrown if the partition for the table doesn't exists. You can use ``IF EXISTS`` to skip the error. +You can use ``ALTER TABLE DROP PARTITION`` to drop a partition for a table. This doesn't remove the data for a table. But if ``PURGE`` is specified, the partition data will be removed. The metadata is completely lost in all cases. An error is thrown if the partition for the table doesn't exist. You can use ``IF EXISTS`` to skip the error. ======================== REPAIR PARTITION From 8c127735f4cdb9ba7ff86af32337bdc303299ac7 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 15:37:42 +0900 Subject: [PATCH 25/26] Remove unnecessary example --- tajo-docs/src/main/sphinx/sql_language/alter_table.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index 20be2798cd..8b917a9430 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -110,15 +110,9 @@ Tajo stores a list of partitions for each table in its catalog. If partitions ar ALTER TABLE REPAIR PARTITION -*Examples* - -.. code-block:: sql - - ALTER TABLE student REPAIR PARTITION; - .. note:: - If you recover partitions in the situation that partitions just exists on catalog and it doesn't exist on file system, Tajo would not make directories on the file system and would print messages to TajoMaster log as following: + If you recover partitions in the situation that partitions just exists on catalog and it doesn't exist on file system, Tajo would not make directories on the file system and would print messages to TajoMaster log with log4 debug level as following: .. code-block:: sql From 2ae8fd7e3ecaae0a4dd220634b1bf9fea21cbbe0 Mon Sep 17 00:00:00 2001 From: JaeHwa Jung Date: Wed, 23 Sep 2015 15:38:45 +0900 Subject: [PATCH 26/26] Update notice messages --- tajo-docs/src/main/sphinx/sql_language/alter_table.rst | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst index 8b917a9430..959ebcc5c6 100644 --- a/tajo-docs/src/main/sphinx/sql_language/alter_table.rst +++ b/tajo-docs/src/main/sphinx/sql_language/alter_table.rst @@ -112,9 +112,5 @@ Tajo stores a list of partitions for each table in its catalog. If partitions ar .. note:: - If you recover partitions in the situation that partitions just exists on catalog and it doesn't exist on file system, Tajo would not make directories on the file system and would print messages to TajoMaster log with log4 debug level as following: - - .. code-block:: sql - - Partitions missing from Filesystem: + Even though an information of a partition is stored in the catalog, Tajo does not recover it when its partition directory doesn't exist in the file system.