You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/03/31 17:20:16 UTC
[1/2] TAJO-480: Umbrella Jira for adding ALTER TABLE statement.
(Alvin Henrick via hyunsik)
Repository: tajo
Updated Branches:
refs/heads/master 40851e565 -> bd418a5c3
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
index 30d4c2e..35ad4c2 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
@@ -125,7 +125,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
Expr current = visitNon_join_query_primary(ctx.non_join_query_primary());
Expr left;
- for (int i = 1; i < ctx.getChildCount();) {
+ for (int i = 1; i < ctx.getChildCount(); ) {
int idx = i;
boolean distinct = true;
@@ -147,7 +147,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
left = current;
current = new SetOperation(OpType.Intersect, left, right, distinct);
- i+=idx;
+ i += idx;
}
}
@@ -215,6 +215,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
* : select_sublist (COMMA select_sublist)*
* ;
* </pre>
+ *
* @param ctx
* @return
*/
@@ -237,6 +238,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
* | asterisked_qualifier
* ;
* </pre>
+ *
* @param ctx
* @return
*/
@@ -251,7 +253,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
@Override
public RelationList visitFrom_clause(SQLParser.From_clauseContext ctx) {
- Expr [] relations = new Expr[ctx.table_reference_list().table_reference().size()];
+ Expr[] relations = new Expr[ctx.table_reference_list().table_reference().size()];
for (int i = 0; i < relations.length; i++) {
relations[i] = visitTable_reference(ctx.table_reference_list().table_reference(i));
}
@@ -308,7 +310,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
@Override
public Sort visitOrderby_clause(SQLParser.Orderby_clauseContext ctx) {
int size = ctx.sort_specifier_list().sort_specifier().size();
- Sort.SortSpec specs [] = new Sort.SortSpec[size];
+ Sort.SortSpec specs[] = new Sort.SortSpec[size];
for (int i = 0; i < size; i++) {
SQLParser.Sort_specifierContext specContext = ctx.sort_specifier_list().sort_specifier(i);
Expr column = visitRow_value_predicand(specContext.key);
@@ -381,7 +383,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
join_condition().search_condition());
join.setQual(searchCondition);
} else if (ctx.join_specification().named_columns_join() != null) {
- ColumnReferenceExpr [] columns = getColumnReferences(ctx.join_specification().
+ ColumnReferenceExpr[] columns = getColumnReferences(ctx.join_specification().
named_columns_join().column_reference_list());
join.setJoinColumns(columns);
}
@@ -392,7 +394,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return join;
}
- private Expr [] getRowValuePredicandsFromOrdinaryGroupingSetList(Ordinary_grouping_set_listContext ctx) {
+ private Expr[] getRowValuePredicandsFromOrdinaryGroupingSetList(Ordinary_grouping_set_listContext ctx) {
ArrayList<Expr> rowValuePredicands = new ArrayList<Expr>();
for (int i = 0; i < ctx.ordinary_grouping_set().size(); i++) {
Collections.addAll(rowValuePredicands, getRowValuePredicandsFromOrdinaryGroupingSet(ctx.ordinary_grouping_set(i)));
@@ -400,7 +402,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return rowValuePredicands.toArray(new Expr[rowValuePredicands.size()]);
}
- private Expr [] getRowValuePredicandsFromOrdinaryGroupingSet(Ordinary_grouping_setContext ctx) {
+ private Expr[] getRowValuePredicandsFromOrdinaryGroupingSet(Ordinary_grouping_setContext ctx) {
ArrayList<Expr> rowValuePredicands = new ArrayList<Expr>();
if (ctx.row_value_predicand() != null) {
rowValuePredicands.add(visitRow_value_predicand(ctx.row_value_predicand()));
@@ -411,16 +413,16 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return rowValuePredicands.toArray(new Expr[rowValuePredicands.size()]);
}
- private Expr [] getRowValuePredicands(Row_value_predicand_listContext ctx) {
- Expr [] rowValuePredicands = new Expr[ctx.row_value_predicand().size()];
+ private Expr[] getRowValuePredicands(Row_value_predicand_listContext ctx) {
+ Expr[] rowValuePredicands = new Expr[ctx.row_value_predicand().size()];
for (int i = 0; i < rowValuePredicands.length; i++) {
rowValuePredicands[i] = visitRow_value_predicand(ctx.row_value_predicand(i));
}
return rowValuePredicands;
}
- private ColumnReferenceExpr [] getColumnReferences(Column_reference_listContext ctx) {
- ColumnReferenceExpr [] columnRefs = new ColumnReferenceExpr[ctx.column_reference().size()];
+ private ColumnReferenceExpr[] getColumnReferences(Column_reference_listContext ctx) {
+ ColumnReferenceExpr[] columnRefs = new ColumnReferenceExpr[ctx.column_reference().size()];
for (int i = 0; i < columnRefs.length; i++) {
columnRefs[i] = visitColumn_reference(ctx.column_reference(i));
}
@@ -482,7 +484,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
}
}
- @Override public CaseWhenPredicate visitSearched_case(SQLParser.Searched_caseContext ctx) {
+ @Override
+ public CaseWhenPredicate visitSearched_case(SQLParser.Searched_caseContext ctx) {
CaseWhenPredicate caseWhen = new CaseWhenPredicate();
for (int i = 0; i < ctx.searched_when_clause().size(); i++) {
@@ -497,7 +500,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return caseWhen;
}
- @Override public Expr visitCommon_value_expression(SQLParser.Common_value_expressionContext ctx) {
+ @Override
+ public Expr visitCommon_value_expression(SQLParser.Common_value_expressionContext ctx) {
if (checkIfExist(ctx.NULL())) {
return new NullLiteral();
} else {
@@ -671,7 +675,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return current;
}
- @Override public Expr visitFactor(SQLParser.FactorContext ctx) {
+ @Override
+ public Expr visitFactor(SQLParser.FactorContext ctx) {
Expr current = visitNumeric_primary(ctx.numeric_primary());
if (checkIfExist(ctx.sign()) && checkIfExist(ctx.sign().MINUS())) {
current = new SignedExpr(true, current);
@@ -696,27 +701,44 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
public static OpType tokenToExprType(int tokenId) {
switch (tokenId) {
- case SQLParser.UNION: return OpType.Union;
- case SQLParser.EXCEPT: return OpType.Except;
- case SQLParser.INTERSECT: return OpType.Intersect;
-
- case SQLParser.AND: return OpType.And;
- case SQLParser.OR: return OpType.Or;
-
- case SQLParser.EQUAL: return OpType.Equals;
- case SQLParser.NOT_EQUAL: return OpType.NotEquals;
- case SQLParser.LTH: return OpType.LessThan;
- case SQLParser.LEQ: return OpType.LessThanOrEquals;
- case SQLParser.GTH: return OpType.GreaterThan;
- case SQLParser.GEQ: return OpType.GreaterThanOrEquals;
-
- case SQLParser.MULTIPLY: return OpType.Multiply;
- case SQLParser.DIVIDE: return OpType.Divide;
- case SQLParser.MODULAR: return OpType.Modular;
- case SQLParser.PLUS: return OpType.Plus;
- case SQLParser.MINUS: return OpType.Minus;
-
- default: throw new RuntimeException("Unknown Token Id: " + tokenId);
+ case SQLParser.UNION:
+ return OpType.Union;
+ case SQLParser.EXCEPT:
+ return OpType.Except;
+ case SQLParser.INTERSECT:
+ return OpType.Intersect;
+
+ case SQLParser.AND:
+ return OpType.And;
+ case SQLParser.OR:
+ return OpType.Or;
+
+ case SQLParser.EQUAL:
+ return OpType.Equals;
+ case SQLParser.NOT_EQUAL:
+ return OpType.NotEquals;
+ case SQLParser.LTH:
+ return OpType.LessThan;
+ case SQLParser.LEQ:
+ return OpType.LessThanOrEquals;
+ case SQLParser.GTH:
+ return OpType.GreaterThan;
+ case SQLParser.GEQ:
+ return OpType.GreaterThanOrEquals;
+
+ case SQLParser.MULTIPLY:
+ return OpType.Multiply;
+ case SQLParser.DIVIDE:
+ return OpType.Divide;
+ case SQLParser.MODULAR:
+ return OpType.Modular;
+ case SQLParser.PLUS:
+ return OpType.Plus;
+ case SQLParser.MINUS:
+ return OpType.Minus;
+
+ default:
+ throw new RuntimeException("Unknown Token Id: " + tokenId);
}
}
@@ -730,7 +752,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
public Expr visitIn_predicate_value(SQLParser.In_predicate_valueContext ctx) {
if (checkIfExist(ctx.in_value_list())) {
int size = ctx.in_value_list().row_value_expression().size();
- Expr [] exprs = new Expr[size];
+ Expr[] exprs = new Expr[size];
for (int i = 0; i < size; i++) {
exprs[i] = visitRow_value_expression(ctx.in_value_list().row_value_expression(i));
}
@@ -743,7 +765,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
@Override
public Expr visitArray(SQLParser.ArrayContext ctx) {
int size = ctx.numeric_value_expression().size();
- Expr [] exprs = new Expr[size];
+ Expr[] exprs = new Expr[size];
for (int i = 0; i < size; i++) {
exprs[i] = visit(ctx.numeric_value_expression(i));
}
@@ -825,7 +847,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
}
}
- @Override public FunctionExpr visitAggregate_function( SQLParser.Aggregate_functionContext ctx) {
+ @Override
+ public FunctionExpr visitAggregate_function(SQLParser.Aggregate_functionContext ctx) {
if (ctx.COUNT() != null && ctx.MULTIPLY() != null) {
return new CountRowsFunctionExpr();
} else {
@@ -833,7 +856,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
}
}
- @Override public FunctionExpr visitGeneral_set_function(SQLParser.General_set_functionContext ctx) {
+ @Override
+ public FunctionExpr visitGeneral_set_function(SQLParser.General_set_functionContext ctx) {
String signature = ctx.set_function_type().getText();
boolean distinct = checkIfExist(ctx.set_qualifier()) && checkIfExist(ctx.set_qualifier().DISTINCT());
Expr param = visitValue_expression(ctx.value_expression());
@@ -847,7 +871,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
FunctionExpr function = new FunctionExpr(signature);
if (ctx.sql_argument_list() != null) {
int numArgs = ctx.sql_argument_list().value_expression().size();
- Expr [] argument_list = new Expr[numArgs];
+ Expr[] argument_list = new Expr[numArgs];
for (int i = 0; i < numArgs; i++) {
argument_list[i] = visitValue_expression(ctx.sql_argument_list().
value_expression().get(i));
@@ -894,7 +918,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
right = visitCharacter_factor((Character_factorContext) ctx.getChild(i));
if (left.getType() == OpType.Literal && right.getType() == OpType.Literal) {
- current = new LiteralValue(((LiteralValue)left).getValue() + ((LiteralValue)right).getValue(),
+ current = new LiteralValue(((LiteralValue) left).getValue() + ((LiteralValue) right).getValue(),
LiteralType.String);
} else {
current = new BinaryOperator(OpType.Concatenate, left, right);
@@ -927,7 +951,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
}
String functionName = "date_part";
- Expr [] params = new Expr[] {extractTarget, extractSource};
+ Expr[] params = new Expr[]{extractTarget, extractSource};
return new FunctionExpr(functionName, params);
}
@@ -954,11 +978,11 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
trimCharacters = visitCharacter_value_expression(ctx.trim_operands().trim_character);
}
- Expr [] params;
+ Expr[] params;
if (trimCharacters != null) {
- params = new Expr[] {trimSource, trimCharacters};
+ params = new Expr[]{trimSource, trimCharacters};
} else {
- params = new Expr[] {trimSource};
+ params = new Expr[]{trimSource};
}
return new FunctionExpr(functionName, params);
@@ -982,7 +1006,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
if (checkIfExist(ctx.EXTERNAL())) {
createTable.setExternal();
- CreateTable.ColumnDefinition [] elements = getDefinitions(ctx.table_elements());
+ ColumnDefinition[] elements = getDefinitions(ctx.table_elements());
String fileType = ctx.file_type.getText();
String path = stripQuote(ctx.path.getText());
@@ -991,7 +1015,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
createTable.setLocation(path);
} else {
if (checkIfExist(ctx.table_elements())) {
- CreateTable.ColumnDefinition [] elements = getDefinitions(ctx.table_elements());
+ ColumnDefinition[] elements = getDefinitions(ctx.table_elements());
createTable.setTableElements(elements);
}
@@ -1019,13 +1043,13 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return createTable;
}
- private CreateTable.ColumnDefinition [] getDefinitions(SQLParser.Table_elementsContext ctx) {
+ private ColumnDefinition[] getDefinitions(SQLParser.Table_elementsContext ctx) {
int size = ctx.field_element().size();
- CreateTable.ColumnDefinition [] elements = new CreateTable.ColumnDefinition[size];
+ ColumnDefinition[] elements = new ColumnDefinition[size];
for (int i = 0; i < size; i++) {
String name = ctx.field_element(i).name.getText();
DataTypeExpr typeDef = visitData_type(ctx.field_element(i).field_type().data_type());
- elements[i] = new CreateTable.ColumnDefinition(name, typeDef);
+ elements[i] = new ColumnDefinition(name, typeDef);
}
return elements;
@@ -1074,7 +1098,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
for (List_value_partitionContext listValuePartition : partitions) {
int size = listValuePartition.in_value_list().row_value_expression().size();
- Expr [] exprs = new Expr[size];
+ Expr[] exprs = new Expr[size];
for (int i = 0; i < size; i++) {
exprs[i] = visitRow_value_expression(listValuePartition.in_value_list().row_value_expression(i));
}
@@ -1120,7 +1144,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
}
} else if (character_string_type.TEXT() != null) {
- typeDefinition = new DataTypeExpr(Type.TEXT.name());
+ typeDefinition = new DataTypeExpr(Type.TEXT.name());
}
} else if (predefined_type.national_character_string_type() != null) {
@@ -1187,7 +1211,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
typeDefinition = new DataTypeExpr(Type.FLOAT8.name());
}
}
- } else if (predefined_type.boolean_type() != null) {
+ } else if (predefined_type.boolean_type() != null) {
typeDefinition = new DataTypeExpr(Type.BOOLEAN.name());
} else if (predefined_type.datetime_type() != null) {
SQLParser.Datetime_typeContext dateTimeType = predefined_type.datetime_type();
@@ -1246,7 +1270,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
insertExpr.setTableName(ctx.table_name().getText());
if (ctx.column_name_list() != null) {
- String [] targetColumns = new String[ctx.column_name_list().identifier().size()];
+ String[] targetColumns = new String[ctx.column_name_list().identifier().size()];
for (int i = 0; i < targetColumns.length; i++) {
targetColumns[i] = ctx.column_name_list().identifier().get(i).getText();
}
@@ -1296,7 +1320,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getKey().equals(CatalogConstants.CSVFILE_DELIMITER)) {
params.put(entry.getKey(), escapeDelimiter(entry.getValue()));
- } else {
+ } else {
params.put(entry.getKey(), entry.getValue());
}
}
@@ -1317,13 +1341,15 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
return str.substring(1, str.length() - 1);
}
- @Override public Expr visitCast_specification(SQLParser.Cast_specificationContext ctx) {
+ @Override
+ public Expr visitCast_specification(SQLParser.Cast_specificationContext ctx) {
Expr operand = visitChildren(ctx.cast_operand());
DataTypeExpr castTarget = visitData_type(ctx.cast_target().data_type());
return new CastExpr(operand, castTarget);
}
- @Override public Expr visitUnsigned_value_specification(@NotNull SQLParser.Unsigned_value_specificationContext ctx) {
+ @Override
+ public Expr visitUnsigned_value_specification(@NotNull SQLParser.Unsigned_value_specificationContext ctx) {
return visitChildren(ctx);
}
@@ -1351,7 +1377,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
public Expr visitDatetime_literal(@NotNull SQLParser.Datetime_literalContext ctx) {
if (checkIfExist(ctx.time_literal())) {
return visitTime_literal(ctx.time_literal());
- } else if(checkIfExist(ctx.date_literal())) {
+ } else if (checkIfExist(ctx.date_literal())) {
return visitDate_literal(ctx.date_literal());
} else {
return visitTimestamp_literal(ctx.timestamp_literal());
@@ -1373,7 +1399,7 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
@Override
public Expr visitTimestamp_literal(SQLParser.Timestamp_literalContext ctx) {
String timestampStr = stripQuote(ctx.timestamp_string.getText());
- String [] parts = timestampStr.split(" ");
+ String[] parts = timestampStr.split(" ");
String datePart = parts[0];
String timePart = parts[1];
return new TimestampLiteral(parseDate(datePart), parseTime(timePart));
@@ -1381,18 +1407,18 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
private DateValue parseDate(String datePart) {
// e.g., 1980-04-01
- String [] parts = datePart.split("-");
+ String[] parts = datePart.split("-");
return new DateValue(parts[0], parts[1], parts[2]);
}
private TimeValue parseTime(String timePart) {
// e.g., 12:01:50.399
- String [] parts = timePart.split(":");
+ String[] parts = timePart.split(":");
TimeValue time;
boolean hasFractionOfSeconds = parts[2].indexOf('.') > 0;
if (hasFractionOfSeconds) {
- String [] secondsParts = parts[2].split("\\.");
+ String[] secondsParts = parts[2].split("\\.");
time = new TimeValue(parts[0], parts[1], secondsParts[0]);
if (secondsParts.length == 2) {
time.setSecondsFraction(secondsParts[1]);
@@ -1402,4 +1428,77 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
}
return time;
}
+
+ @Override
+ public Expr visitAlter_table_statement(SQLParser.Alter_table_statementContext ctx) {
+
+ final List<Table_nameContext> tables = ctx.table_name();
+
+ final AlterTable alterTable = new AlterTable(tables.get(0).getText());
+
+ if (tables.size() == 2) {
+ alterTable.setNewTableName(tables.get(1).getText());
+ }
+
+ if (checkIfExist(ctx.column_name()) && ctx.column_name().size() == 2) {
+ final List<Column_nameContext> columns = ctx.column_name();
+ alterTable.setColumnName(columns.get(0).getText());
+ alterTable.setNewColumnName(columns.get(1).getText());
+ }
+
+ Field_elementContext field_elementContext = ctx.field_element();
+ if (checkIfExist(field_elementContext)) {
+ final String name = field_elementContext.name.getText();
+ final DataTypeExpr typeDef = visitData_type(field_elementContext.field_type().data_type());
+ final ColumnDefinition columnDefinition = new ColumnDefinition(name, typeDef);
+ alterTable.setAddNewColumn(columnDefinition);
+ }
+
+ alterTable.setAlterTableOpType(determineAlterTableType(ctx));
+
+ return alterTable;
+ }
+
+ private AlterTableOpType determineAlterTableType(SQLParser.Alter_table_statementContext ctx) {
+
+ final int RENAME_MASK = 00000001;
+ final int COLUMN_MASK = 00000010;
+ final int TO_MASK = 00000100;
+ final int ADD_MASK = 00001000;
+
+ int val = 00000000;
+
+ for (int idx = 1; idx < ctx.getChildCount(); idx++) {
+
+ if (ctx.getChild(idx) instanceof TerminalNode) {
+ if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == RENAME) {
+ val = val | RENAME_MASK;
+ }
+ if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == COLUMN) {
+ val = val | COLUMN_MASK;
+ }
+ if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == TO) {
+ val = val | TO_MASK;
+ }
+ if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == ADD) {
+ val = val | ADD_MASK;
+ }
+ }
+ }
+ return evaluateAlterTableOperationTye(val);
+ }
+
+ private AlterTableOpType evaluateAlterTableOperationTye(final int value) {
+
+ switch (value) {
+ case 65:
+ return AlterTableOpType.RENAME_TABLE;
+ case 73:
+ return AlterTableOpType.RENAME_COLUMN;
+ case 520:
+ return AlterTableOpType.ADD_COLUMN;
+ default:
+ return null;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
index 84cdc08..0ea2c77 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/AlgebraVisitor.java
@@ -45,8 +45,9 @@ public interface AlgebraVisitor<CONTEXT, RESULT> {
RESULT visitDropDatabase(CONTEXT ctx, Stack<Expr> stack, DropDatabase expr) throws PlanningException;
RESULT visitCreateTable(CONTEXT ctx, Stack<Expr> stack, CreateTable expr) throws PlanningException;
RESULT visitDropTable(CONTEXT ctx, Stack<Expr> stack, DropTable expr) throws PlanningException;
+ RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException;
- // Insert or Update
+ // Insert or Update
RESULT visitInsert(CONTEXT ctx, Stack<Expr> stack, Insert expr) throws PlanningException;
// Logical operators
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
index 62cee57..6f217a7 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BaseAlgebraVisitor.java
@@ -109,6 +109,9 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
case DropTable:
current = visitDropTable(ctx, stack, (DropTable) expr);
break;
+ case AlterTable:
+ current = visitAlterTable(ctx, stack, (AlterTable) expr);
+ break;
case Insert:
current = visitInsert(ctx, stack, (Insert) expr);
@@ -434,6 +437,11 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE
return null;
}
+ @Override
+ public RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException {
+ return null;
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Insert or Update Section
///////////////////////////////////////////////////////////////////////////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
index 772e5fb..d569758 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BasicLogicalPlanVisitor.java
@@ -116,6 +116,9 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi
case DROP_TABLE:
current = visitDropTable(context, plan, block, (DropTableNode) node, stack);
break;
+ case ALTER_TABLE:
+ current = visitAlterTable(context, plan, block, (AlterTableNode) node, stack);
+ break;
default:
throw new PlanningException("Unknown logical node type: " + node.getType());
}
@@ -298,4 +301,9 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi
Stack<LogicalNode> stack) {
return null;
}
+ @Override
+ public RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, AlterTableNode node,
+ Stack<LogicalNode> stack) {
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
index 1ac416f..540d45b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
@@ -413,6 +413,13 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
return dropTable;
}
+ @Override
+ public LogicalNode visitAlterTable(PreprocessContext ctx, Stack<Expr> stack, AlterTable expr)
+ throws PlanningException {
+ AlterTableNode alterTableNode = ctx.plan.createNode(AlterTableNode.class);
+ return alterTableNode;
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Insert or Update Section
///////////////////////////////////////////////////////////////////////////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
index 76454b9..7f38026 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanVisitor.java
@@ -82,4 +82,7 @@ public interface LogicalPlanVisitor<CONTEXT, RESULT> {
RESULT visitDropTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, DropTableNode node,
Stack<LogicalNode> stack) throws PlanningException;
+
+ RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, AlterTableNode node,
+ Stack<LogicalNode> stack) throws PlanningException;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
index 15fe6c0..317c05b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
@@ -30,7 +30,6 @@ import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.tajo.algebra.*;
-import org.apache.tajo.algebra.CreateTable.ColumnDefinition;
import org.apache.tajo.catalog.*;
import org.apache.tajo.catalog.partition.PartitionMethodDesc;
import org.apache.tajo.catalog.proto.CatalogProtos;
@@ -1412,10 +1411,10 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
* @param elements to be transformed
* @return schema transformed from table definition elements
*/
- private Schema convertColumnsToSchema(CreateTable.ColumnDefinition[] elements) {
+ private Schema convertColumnsToSchema(ColumnDefinition[] elements) {
Schema schema = new Schema();
- for (CreateTable.ColumnDefinition columnDefinition: elements) {
+ for (ColumnDefinition columnDefinition: elements) {
schema.addColumn(convertColumn(columnDefinition));
}
@@ -1428,10 +1427,10 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
* @param elements to be transformed
* @return schema transformed from table definition elements
*/
- private Schema convertTableElementsSchema(CreateTable.ColumnDefinition[] elements) {
+ private Schema convertTableElementsSchema(ColumnDefinition[] elements) {
Schema schema = new Schema();
- for (CreateTable.ColumnDefinition columnDefinition: elements) {
+ for (ColumnDefinition columnDefinition: elements) {
schema.addColumn(convertColumn(columnDefinition));
}
@@ -1467,6 +1466,21 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
return dropTableNode;
}
+ @Override
+ public LogicalNode visitAlterTable(PlanContext context, Stack<Expr> stack, AlterTable alterTable) {
+ AlterTableNode alterTableNode = context.queryBlock.getNodeFromExpr(alterTable);
+ alterTableNode.setTableName(alterTable.getTableName());
+ alterTableNode.setNewTableName(alterTable.getNewTableName());
+ alterTableNode.setColumnName(alterTable.getColumnName());
+ alterTableNode.setNewColumnName(alterTable.getNewColumnName());
+
+ if (null != alterTable.getAddNewColumn()) {
+ alterTableNode.setAddNewColumn(convertColumn(alterTable.getAddNewColumn()));
+ }
+ alterTableNode.setAlterTableOpType(alterTable.getAlterTableOpType());
+ return alterTableNode;
+ }
+
/*===============================================================================================
Util SECTION
===============================================================================================*/
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
index fbd65a9..ccd9847 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
@@ -49,9 +49,9 @@ public class PlannerUtil {
return
type == NodeType.CREATE_DATABASE ||
- type == NodeType.DROP_DATABASE ||
- (type == NodeType.CREATE_TABLE && !((CreateTableNode)baseNode).hasSubQuery()) ||
- baseNode.getType() == NodeType.DROP_TABLE;
+ type == NodeType.DROP_DATABASE ||
+ (type == NodeType.CREATE_TABLE && !((CreateTableNode) baseNode).hasSubQuery()) ||
+ baseNode.getType() == NodeType.DROP_TABLE || baseNode.getType() == NodeType.ALTER_TABLE;
}
/**
@@ -60,9 +60,9 @@ public class PlannerUtil {
* @param from The LogicalNode to start visiting LogicalNodes.
* @return an array of all descendant RelationNode of LogicalNode.
*/
- public static String [] getRelationLineage(LogicalNode from) {
- LogicalNode [] scans = findAllNodes(from, NodeType.SCAN, NodeType.PARTITIONS_SCAN);
- String [] tableNames = new String[scans.length];
+ public static String[] getRelationLineage(LogicalNode from) {
+ LogicalNode[] scans = findAllNodes(from, NodeType.SCAN, NodeType.PARTITIONS_SCAN);
+ String[] tableNames = new String[scans.length];
ScanNode scan;
for (int i = 0; i < scans.length; i++) {
scan = (ScanNode) scans[i];
@@ -106,11 +106,11 @@ public class PlannerUtil {
return node;
}
}
-
+
/**
* Delete the logical node from a plan.
*
- * @param parent this node must be a parent node of one node to be removed.
+ * @param parent this node must be a parent node of one node to be removed.
* @param tobeRemoved this node must be a child node of the parent.
*/
public static LogicalNode deleteNode(LogicalNode parent, LogicalNode tobeRemoved) {
@@ -137,7 +137,7 @@ public class PlannerUtil {
}
} else {
throw new InvalidQueryException("Unexpected logical plan: " + parent);
- }
+ }
return child;
}
@@ -233,13 +233,13 @@ public class PlannerUtil {
@Override
public LogicalNode visitPartitionedTableScan(ReplacerContext context, LogicalPlan plan, LogicalPlan.
- QueryBlock block,PartitionedTableScanNode node, Stack<LogicalNode> stack)
+ QueryBlock block, PartitionedTableScanNode node, Stack<LogicalNode> stack)
throws PlanningException {
return node;
}
}
-
+
public static void replaceNode(LogicalNode plan, LogicalNode newNode, NodeType type) {
LogicalNode parent = findTopParentNode(plan, type);
Preconditions.checkArgument(parent instanceof UnaryNode);
@@ -254,7 +254,7 @@ public class PlannerUtil {
/**
* Find the top logical node matched to type from the given node
- *
+ *
* @param node start node
* @param type to find
* @return a found logical node
@@ -262,10 +262,10 @@ public class PlannerUtil {
public static <T extends LogicalNode> T findTopNode(LogicalNode node, NodeType type) {
Preconditions.checkNotNull(node);
Preconditions.checkNotNull(type);
-
+
LogicalNodeFinder finder = new LogicalNodeFinder(type);
node.preOrder(finder);
-
+
if (finder.getFoundNodes().size() == 0) {
return null;
}
@@ -299,7 +299,7 @@ public class PlannerUtil {
* @param type to find
* @return a found logical node
*/
- public static LogicalNode [] findAllNodes(LogicalNode node, NodeType...type) {
+ public static LogicalNode[] findAllNodes(LogicalNode node, NodeType... type) {
Preconditions.checkNotNull(node);
Preconditions.checkNotNull(type);
@@ -307,15 +307,15 @@ public class PlannerUtil {
node.postOrder(finder);
if (finder.getFoundNodes().size() == 0) {
- return new LogicalNode[] {};
+ return new LogicalNode[]{};
}
List<LogicalNode> founds = finder.getFoundNodes();
return founds.toArray(new LogicalNode[founds.size()]);
}
-
+
/**
* Find a parent node of a given-typed operator.
- *
+ *
* @param node start node
* @param type to find
* @return the parent node of a found logical node
@@ -323,10 +323,10 @@ public class PlannerUtil {
public static <T extends LogicalNode> T findTopParentNode(LogicalNode node, NodeType type) {
Preconditions.checkNotNull(node);
Preconditions.checkNotNull(type);
-
+
ParentNodeFinder finder = new ParentNodeFinder(type);
node.postOrder(finder);
-
+
if (finder.getFoundNodes().size() == 0) {
return null;
}
@@ -339,7 +339,7 @@ public class PlannerUtil {
private boolean topmost = false;
private boolean finished = false;
- public LogicalNodeFinder(NodeType...type) {
+ public LogicalNodeFinder(NodeType... type) {
this.tofind = type;
}
@@ -366,11 +366,11 @@ public class PlannerUtil {
return list;
}
- public LogicalNode [] getFoundNodeArray() {
+ public LogicalNode[] getFoundNodeArray() {
return list.toArray(new LogicalNode[list.size()]);
}
}
-
+
private static class ParentNodeFinder implements LogicalNodeVisitor {
private List<LogicalNode> list = new ArrayList<LogicalNode>();
private NodeType tofind;
@@ -386,7 +386,7 @@ public class PlannerUtil {
if (unary.getChild().getType() == tofind) {
list.add(node);
}
- } else if (node instanceof BinaryNode){
+ } else if (node instanceof BinaryNode) {
BinaryNode bin = (BinaryNode) node;
if (bin.getLeftChild().getType() == tofind ||
bin.getRightChild().getType() == tofind) {
@@ -403,10 +403,10 @@ public class PlannerUtil {
/**
* fill targets with FieldEvals from a given schema
*
- * @param schema to be transformed to targets
+ * @param schema to be transformed to targets
* @param targets to be filled
*/
- public static void schemaToTargets(Schema schema, Target [] targets) {
+ public static void schemaToTargets(Schema schema, Target[] targets) {
FieldEval eval;
for (int i = 0; i < schema.size(); i++) {
eval = new FieldEval(schema.getColumn(i));
@@ -440,7 +440,7 @@ public class PlannerUtil {
return schemaToSortSpecs(schema.toArray());
}
- public static SortSpec[] schemaToSortSpecs(Column [] columns) {
+ public static SortSpec[] schemaToSortSpecs(Column[] columns) {
SortSpec[] specs = new SortSpec[columns.length];
for (int i = 0; i < columns.length; i++) {
@@ -450,7 +450,7 @@ public class PlannerUtil {
return specs;
}
- public static SortSpec [] columnsToSortSpec(Collection<Column> columns) {
+ public static SortSpec[] columnsToSortSpec(Collection<Column> columns) {
SortSpec[] specs = new SortSpec[columns.size()];
int i = 0;
for (Column column : columns) {
@@ -472,7 +472,7 @@ public class PlannerUtil {
/**
* is it join qual or not?
*
- * @param qual The condition to be checked
+ * @param qual The condition to be checked
* @return true if two operands refers to columns and the operator is comparison,
*/
public static boolean isJoinQual(EvalNode qual) {
@@ -489,7 +489,7 @@ public class PlannerUtil {
}
public static SortSpec[][] getSortKeysFromJoinQual(EvalNode joinQual, Schema outer, Schema inner) {
- List<Column []> joinKeyPairs = getJoinKeyPairs(joinQual, outer, inner);
+ List<Column[]> joinKeyPairs = getJoinKeyPairs(joinQual, outer, inner);
SortSpec[] outerSortSpec = new SortSpec[joinKeyPairs.size()];
SortSpec[] innerSortSpec = new SortSpec[joinKeyPairs.size()];
@@ -498,12 +498,12 @@ public class PlannerUtil {
innerSortSpec[i] = new SortSpec(joinKeyPairs.get(i)[1]);
}
- return new SortSpec[][] {outerSortSpec, innerSortSpec};
+ return new SortSpec[][]{outerSortSpec, innerSortSpec};
}
public static TupleComparator[] getComparatorsFromJoinQual(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
SortSpec[][] sortSpecs = getSortKeysFromJoinQual(joinQual, leftSchema, rightSchema);
- TupleComparator [] comparators = new TupleComparator[2];
+ TupleComparator[] comparators = new TupleComparator[2];
comparators[0] = new TupleComparator(leftSchema, sortSpecs[0]);
comparators[1] = new TupleComparator(rightSchema, sortSpecs[1]);
return comparators;
@@ -512,27 +512,27 @@ public class PlannerUtil {
/**
* @return the first array contains left table's columns, and the second array contains right table's columns.
*/
- public static Column [][] joinJoinKeyForEachTable(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
- List<Column []> joinKeys = getJoinKeyPairs(joinQual, leftSchema, rightSchema);
- Column [] leftColumns = new Column[joinKeys.size()];
- Column [] rightColumns = new Column[joinKeys.size()];
+ public static Column[][] joinJoinKeyForEachTable(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
+ List<Column[]> joinKeys = getJoinKeyPairs(joinQual, leftSchema, rightSchema);
+ Column[] leftColumns = new Column[joinKeys.size()];
+ Column[] rightColumns = new Column[joinKeys.size()];
for (int i = 0; i < joinKeys.size(); i++) {
leftColumns[i] = joinKeys.get(i)[0];
rightColumns[i] = joinKeys.get(i)[1];
}
- return new Column[][] {leftColumns, rightColumns};
+ return new Column[][]{leftColumns, rightColumns};
}
- public static List<Column []> getJoinKeyPairs(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
+ public static List<Column[]> getJoinKeyPairs(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
JoinKeyPairFinder finder = new JoinKeyPairFinder(leftSchema, rightSchema);
joinQual.preOrder(finder);
return finder.getPairs();
}
public static class JoinKeyPairFinder implements EvalNodeVisitor {
- private final List<Column []> pairs = Lists.newArrayList();
- private Schema [] schemas = new Schema[2];
+ private final List<Column[]> pairs = Lists.newArrayList();
+ private Schema[] schemas = new Schema[2];
public JoinKeyPairFinder(Schema outer, Schema inner) {
schemas[0] = outer;
@@ -542,13 +542,13 @@ public class PlannerUtil {
@Override
public void visit(EvalNode node) {
if (EvalTreeUtil.isJoinQual(node)) {
- Column [] pair = new Column[2];
+ Column[] pair = new Column[2];
for (int i = 0; i <= 1; i++) { // access left, right sub expression
Column column = EvalTreeUtil.findAllColumnRefs(node.getExpr(i)).get(0);
for (int j = 0; j < schemas.length; j++) {
- // check whether the column is for either outer or inner
- // 0 is outer, and 1 is inner
+ // check whether the column is for either outer or inner
+ // 0 is outer, and 1 is inner
if (schemas[j].containsByQualifiedName(column.getQualifiedName())) {
pair[j] = column;
}
@@ -562,7 +562,7 @@ public class PlannerUtil {
}
}
- public List<Column []> getPairs() {
+ public List<Column[]> getPairs() {
return this.pairs;
}
}
@@ -573,7 +573,7 @@ public class PlannerUtil {
public static Schema targetToSchema(Target[] targets) {
Schema schema = new Schema();
- for(Target t : targets) {
+ for (Target t : targets) {
DataType type = t.getEvalTree().getValueType();
String name;
if (t.hasAlias()) {
@@ -595,9 +595,9 @@ public class PlannerUtil {
* @param sourceTargets The targets to be stripped
* @return The stripped targets
*/
- public static Target [] stripTarget(Target [] sourceTargets) {
- Target [] copy = new Target[sourceTargets.length];
- for(int i = 0; i < sourceTargets.length; i++) {
+ public static Target[] stripTarget(Target[] sourceTargets) {
+ Target[] copy = new Target[sourceTargets.length];
+ for (int i = 0; i < sourceTargets.length; i++) {
try {
copy[i] = (Target) sourceTargets[i].clone();
} catch (CloneNotSupportedException e) {
@@ -650,6 +650,7 @@ public class PlannerUtil {
boolean generalSetFunction;
boolean distinctSetFunction;
}
+
static class AggregationFunctionFinder extends SimpleAlgebraVisitor<AggFunctionFoundResult, Object> {
@Override
public Object visitCountRowsFunction(AggFunctionFoundResult ctx, Stack<Expr> stack, CountRowsFunctionExpr expr)
@@ -670,7 +671,7 @@ public class PlannerUtil {
public static Collection<String> toQualifiedFieldNames(Collection<String> fieldNames, String qualifier) {
List<String> names = TUtil.newList();
for (String n : fieldNames) {
- String [] parts = n.split("\\.");
+ String[] parts = n.split("\\.");
if (parts.length == 1) {
names.add(qualifier + "." + parts[0]);
} else {
@@ -680,8 +681,8 @@ public class PlannerUtil {
return names;
}
- public static SortSpec [] convertSortSpecs(Collection<CatalogProtos.SortSpecProto> sortSpecProtos) {
- SortSpec [] sortSpecs = new SortSpec[sortSpecProtos.size()];
+ public static SortSpec[] convertSortSpecs(Collection<CatalogProtos.SortSpecProto> sortSpecProtos) {
+ SortSpec[] sortSpecs = new SortSpec[sortSpecProtos.size()];
int i = 0;
for (CatalogProtos.SortSpecProto proto : sortSpecProtos) {
sortSpecs[i++] = new SortSpec(proto);
@@ -701,7 +702,7 @@ public class PlannerUtil {
StringBuilder explains = new StringBuilder();
try {
ExplainLogicalPlanVisitor.Context explainContext = explain.getBlockPlanStrings(null, node);
- while(!explainContext.explains.empty()) {
+ while (!explainContext.explains.empty()) {
explains.append(
ExplainLogicalPlanVisitor.printDepthString(explainContext.getMaxDepth(), explainContext.explains.pop()));
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
index dc7b7a2..bae6e4a 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
@@ -121,10 +121,15 @@ public abstract class SimpleAlgebraVisitor<CONTEXT, RESULT> extends BaseAlgebraV
return super.visitDropTable(ctx, stack, expr);
}
+ @Override
+ public RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException {
+ return super.visitAlterTable(ctx, stack, expr);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Insert or Update Section
///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ @Override
public RESULT visitInsert(CONTEXT ctx, Stack<Expr> stack, Insert expr) throws PlanningException {
return super.visitInsert(ctx, stack, expr);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java
new file mode 100644
index 0000000..76a47d0
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/AlterTableNode.java
@@ -0,0 +1,134 @@
+/**
+ * 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.planner.logical;
+
+
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.algebra.AlterTableOpType;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.engine.planner.PlanString;
+
+public class AlterTableNode extends LogicalNode {
+
+ @Expose
+ private String tableName;
+ @Expose
+ private String newTableName;
+ @Expose
+ private String columnName;
+ @Expose
+ private String newColumnName;
+ @Expose
+ private Column addNewColumn;
+ @Expose
+ private AlterTableOpType alterTableOpType;
+
+ public AlterTableNode(int pid) {
+ super(pid, NodeType.ALTER_TABLE);
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getNewTableName() {
+ return newTableName;
+ }
+
+ public void setNewTableName(String newTableName) {
+ this.newTableName = newTableName;
+ }
+
+ public String getColumnName() {
+ return columnName;
+ }
+
+ public void setColumnName(String columnName) {
+ this.columnName = columnName;
+ }
+
+ public String getNewColumnName() {
+ return newColumnName;
+ }
+
+ public void setNewColumnName(String newColumnName) {
+ this.newColumnName = newColumnName;
+ }
+
+ public Column getAddNewColumn() {
+ return addNewColumn;
+ }
+
+ public void setAddNewColumn(Column addNewColumn) {
+ this.addNewColumn = addNewColumn;
+ }
+
+ public AlterTableOpType getAlterTableOpType() {
+ return alterTableOpType;
+ }
+
+ public void setAlterTableOpType(AlterTableOpType alterTableOpType) {
+ this.alterTableOpType = alterTableOpType;
+ }
+
+ @Override
+ public PlanString getPlanString() {
+ return new PlanString(this);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof AlterTableNode) {
+ AlterTableNode other = (AlterTableNode) obj;
+ return super.equals(other);
+ } else {
+ return false;
+ }
+ }
+
+ /*@Override
+ public Object clone() throws CloneNotSupportedException {
+ AlterTableNode alterTableNode = (AlterTableNode) super.clone();
+ alterTableNode.tableName = tableName;
+ alterTableNode.newTableName = newTableName;
+ alterTableNode.columnName = columnName;
+ alterTableNode.newColumnName=newColumnName;
+ alterTableNode.addNewColumn =(Column) addNewColumn.clone();
+ return alterTableNode;
+ }*/
+
+ @Override
+ public String toString() {
+ return "AlterTable (table=" + tableName + ")";
+ }
+
+ @Override
+ public void preOrder(LogicalNodeVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void postOrder(LogicalNodeVisitor visitor) {
+ visitor.visit(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
index 2b453fb..375926e 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
@@ -21,6 +21,7 @@
*/
package org.apache.tajo.engine.planner.logical;
+
/**
* This indicates a logical node type.
*/
@@ -47,8 +48,8 @@ public enum NodeType {
CREATE_DATABASE(CreateDatabaseNode.class),
DROP_DATABASE(DropDatabaseNode.class),
CREATE_TABLE(CreateTableNode.class),
- DROP_TABLE(DropTableNode.class)
- ;
+ DROP_TABLE(DropTableNode.class),
+ ALTER_TABLE (AlterTableNode.class);
private final Class<? extends LogicalNode> baseClass;
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
index fe3caeb..b0c0614 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
@@ -235,7 +235,10 @@ public class GlobalEngine extends AbstractService {
DropTableNode dropTable = (DropTableNode) root;
dropTable(session, dropTable.getTableName(), dropTable.isIfExists(), dropTable.isPurge());
return true;
-
+ case ALTER_TABLE:
+ AlterTableNode alterTable = (AlterTableNode) root;
+ alterTable(session,alterTable);
+ return true;
default:
throw new InternalError("updateQuery cannot handle such query: \n" + root.toJson());
}
@@ -275,6 +278,82 @@ public class GlobalEngine extends AbstractService {
return plan;
}
+ /**
+ * Alter a given table
+ */
+ public void alterTable(final Session session, final AlterTableNode alterTable) throws IOException {
+
+ final CatalogService catalog = context.getCatalog();
+ final String tableName = alterTable.getTableName();
+
+ String databaseName;
+ String simpleTableName;
+ if (CatalogUtil.isFQTableName(tableName)) {
+ String[] split = CatalogUtil.splitFQTableName(tableName);
+ databaseName = split[0];
+ simpleTableName = split[1];
+ } else {
+ databaseName = session.getCurrentDatabase();
+ simpleTableName = tableName;
+ }
+ final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName);
+
+ if (!catalog.existsTable(databaseName, simpleTableName)) {
+ throw new NoSuchTableException(qualifiedName);
+ }
+
+ switch (alterTable.getAlterTableOpType()) {
+ case RENAME_TABLE:
+ if (!catalog.existsTable(databaseName, simpleTableName)) {
+ throw new NoSuchTableException(alterTable.getTableName());
+ }
+ if (catalog.existsTable(databaseName, alterTable.getNewTableName())) {
+ throw new AlreadyExistsTableException(alterTable.getNewTableName());
+ }
+
+ TableDesc desc = catalog.getTableDesc(databaseName, simpleTableName);
+
+ if (!desc.isExternal()) { // if the table is the managed table
+ Path oldPath = StorageUtil.concatPath(context.getConf().getVar(TajoConf.ConfVars.WAREHOUSE_DIR),
+ databaseName, simpleTableName);
+ Path newPath = StorageUtil.concatPath(context.getConf().getVar(TajoConf.ConfVars.WAREHOUSE_DIR),
+ databaseName, alterTable.getNewTableName());
+ FileSystem fs = oldPath.getFileSystem(context.getConf());
+
+ if (!fs.exists(oldPath)) {
+ throw new IOException("No such a table directory: " + oldPath);
+ }
+ if (fs.exists(newPath)) {
+ throw new IOException("Already table directory exists: " + newPath);
+ }
+
+ fs.rename(oldPath, newPath);
+ }
+ catalog.alterTable(CatalogUtil.renameTable(qualifiedName, alterTable.getNewTableName(),
+ AlterTableType.RENAME_TABLE));
+ break;
+ case RENAME_COLUMN:
+ if (existColumnName(qualifiedName, alterTable.getNewColumnName())) {
+ throw new ColumnNameAlreadyExistException(alterTable.getNewColumnName());
+ }
+ catalog.alterTable(CatalogUtil.renameColumn(qualifiedName, alterTable.getColumnName(), alterTable.getNewColumnName(), AlterTableType.RENAME_COLUMN));
+ break;
+ case ADD_COLUMN:
+ if (existColumnName(qualifiedName, alterTable.getAddNewColumn().getSimpleName())) {
+ throw new ColumnNameAlreadyExistException(alterTable.getAddNewColumn().getSimpleName());
+ }
+ catalog.alterTable(CatalogUtil.addNewColumn(qualifiedName, alterTable.getAddNewColumn(), AlterTableType.ADD_COLUMN));
+ break;
+ default:
+ //TODO
+ }
+ }
+
+ private boolean existColumnName(String tableName, String columnName) {
+ final TableDesc tableDesc = catalog.getTableDesc(tableName);
+ return tableDesc.getSchema().containsByName(columnName) ? true : false;
+ }
+
private TableDesc createTable(Session session, CreateTableNode createTable, boolean ifNotExists) throws IOException {
TableMeta meta;
@@ -287,7 +366,18 @@ public class GlobalEngine extends AbstractService {
if(createTable.isExternal()){
Preconditions.checkState(createTable.hasPath(), "ERROR: LOCATION must be given.");
} else {
- Path tablePath = new Path(sm.getWarehouseDir(), createTable.getTableName());
+ String databaseName;
+ String tableName;
+ if (CatalogUtil.isFQTableName(createTable.getTableName())) {
+ databaseName = CatalogUtil.extractQualifier(createTable.getTableName());
+ tableName = CatalogUtil.extractSimpleName(createTable.getTableName());
+ } else {
+ databaseName = session.getCurrentDatabase();
+ tableName = createTable.getTableName();
+ }
+
+ // create a table directory (i.e., ${WAREHOUSE_DIR}/${DATABASE_NAME}/${TABLE_NAME} )
+ Path tablePath = StorageUtil.concatPath(sm.getWarehouseDir(), databaseName, tableName);
createTable.setPath(tablePath);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
index 65a0d47..784fea5 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
@@ -23,10 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
-import org.apache.tajo.algebra.CreateTable;
-import org.apache.tajo.algebra.DropTable;
-import org.apache.tajo.algebra.Expr;
-import org.apache.tajo.algebra.OpType;
+import org.apache.tajo.algebra.*;
import org.apache.tajo.annotation.Nullable;
import org.apache.tajo.catalog.CatalogService;
import org.apache.tajo.catalog.CatalogUtil;
@@ -321,6 +318,15 @@ public class QueryTestCaseBase {
assertTrue(client.existTable(tableName));
}
+ public void assertColumnExists(String tableName,String columnName) throws ServiceException {
+ TableDesc tableDesc = fetchTableMetaData(tableName);
+ assertTrue(tableDesc.getSchema().containsByName(columnName));
+ }
+
+ private TableDesc fetchTableMetaData(String tableName) throws ServiceException {
+ return client.getTableDesc(tableName);
+ }
+
public void assertTableNotExists(String tableName) throws ServiceException {
assertTrue(!client.existTable(tableName));
}
@@ -403,7 +409,7 @@ public class QueryTestCaseBase {
}
private List<String> executeDDL(String ddlFileName, @Nullable String dataFileName, boolean isLocalTable,
- @Nullable String [] args) throws Exception {
+ @Nullable String[] args) throws Exception {
Path ddlFilePath = new Path(currentQueryPath, ddlFileName);
FileSystem fs = ddlFilePath.getFileSystem(conf);
@@ -431,7 +437,7 @@ public class QueryTestCaseBase {
TableDesc createdTable = client.getTableDesc(tableName);
String createdTableName = createdTable.getName();
- assertTrue("table '" + createdTableName + "' creation check", client.existTable(createdTableName));
+ assertTrue("table '" + createdTableName + "' creation check", client.existTable(createdTableName));
if (isLocalTable) {
createdTableGlobalSet.add(createdTableName);
createdTableNames.add(tableName);
@@ -447,6 +453,14 @@ public class QueryTestCaseBase {
if (isLocalTable) {
createdTableGlobalSet.remove(tableName);
}
+ } else if (expr.getType() == OpType.AlterTable) {
+ AlterTable alterTable = (AlterTable) expr;
+ String tableName = alterTable.getTableName();
+ assertTrue("table '" + tableName + "' existence check", client.existTable(tableName));
+ client.updateQuery(compiled);
+ if (isLocalTable) {
+ createdTableGlobalSet.remove(tableName);
+ }
} else {
assertTrue(ddlFilePath + " is not a Create or Drop Table statement", false);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
new file mode 100644
index 0000000..5779347
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestAlterTable.java
@@ -0,0 +1,53 @@
+/**
+ * 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.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.List;
+
+@Category(IntegrationTest.class)
+public class TestAlterTable extends QueryTestCaseBase {
+ @Test
+ public final void testAlterTableName() throws Exception {
+ List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC");
+ assertTableExists(createdNames.get(0));
+ executeDDL("alter_table_rename_table_ddl.sql", null);
+ assertTableExists("DEF");
+
+ }
+
+ @Test
+ public final void testAlterTableColumnName() throws Exception {
+ List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "XYZ");
+ executeDDL("alter_table_rename_column_ddl.sql", null);
+ assertColumnExists(createdNames.get(0),"renum");
+ }
+
+ @Test
+ public final void testAlterTableAddNewColumn() throws Exception {
+ List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "EFG");
+ executeDDL("alter_table_add_new_column_ddl.sql", null);
+ assertColumnExists(createdNames.get(0),"cool");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
index e6840f6..72e92d2 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCTASQuery.java
@@ -212,13 +212,15 @@ public class TestCTASQuery extends QueryTestCaseBase {
@Test
public final void testCtasWithManagedTable() throws Exception {
- ResultSet res = executeFile("CtasWithManagedTable.sql");
- res.close();
-
- assertFalse(client.existTable("MANAGED_TABLE1"));
- assertTrue(client.existTable("\"MANAGED_TABLE1\""));
- TableDesc desc = client.getTableDesc("\"MANAGED_TABLE1\"");
- assertNotNull(desc);
- assertEquals("MANAGED_TABLE1", desc.getPath().getName());
+ if (!testingCluster.isHCatalogStoreRunning()) {
+ ResultSet res = executeFile("CtasWithManagedTable.sql");
+ res.close();
+
+ assertFalse(client.existTable("MANAGED_TABLE1"));
+ assertTrue(client.existTable("\"MANAGED_TABLE1\""));
+ TableDesc desc = client.getTableDesc("\"MANAGED_TABLE1\"");
+ assertNotNull(desc);
+ assertEquals("MANAGED_TABLE1", desc.getPath().getName());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
index a5b57b2..a6bb467 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestCreateTable.java
@@ -18,14 +18,23 @@
package org.apache.tajo.engine.query;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
import org.apache.tajo.IntegrationTest;
import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.storage.StorageUtil;
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 TestCreateTable extends QueryTestCaseBase {
@@ -79,6 +88,56 @@ public class TestCreateTable extends QueryTestCaseBase {
assertDatabaseNotExists("D2");
}
+ private final void assertPathOfCreatedTable(final String databaseName,
+ final String originalTableName,
+ final String newTableName,
+ String createTableStmt) throws Exception {
+ // create one table
+ executeString("CREATE DATABASE " + CatalogUtil.denormalizeIdentifier(databaseName)).close();
+ getClient().existDatabase(CatalogUtil.denormalizeIdentifier(databaseName));
+ final String oldFQTableName = CatalogUtil.buildFQName(databaseName, originalTableName);
+
+ ResultSet res = executeString(createTableStmt);
+ res.close();
+ assertTableExists(CatalogUtil.denormalizeIdentifier(oldFQTableName));
+ TableDesc oldTableDesc = client.getTableDesc(CatalogUtil.denormalizeIdentifier(oldFQTableName));
+
+
+ // checking the existence of the table directory and validating the path
+ FileSystem fs = testingCluster.getMaster().getStorageManager().getFileSystem();
+ Path warehouseDir = TajoConf.getWarehouseDir(testingCluster.getConfiguration());
+ assertTrue(fs.exists(oldTableDesc.getPath()));
+ assertEquals(StorageUtil.concatPath(warehouseDir, databaseName, originalTableName), oldTableDesc.getPath());
+
+ // Rename
+ client.executeQuery("ALTER TABLE " + CatalogUtil.denormalizeIdentifier(oldFQTableName)
+ + " RENAME to " + CatalogUtil.denormalizeIdentifier(newTableName));
+
+ // checking the existence of the new table directory and validating the path
+ final String newFQTableName = CatalogUtil.buildFQName(databaseName, newTableName);
+ TableDesc newTableDesc = client.getTableDesc(CatalogUtil.denormalizeIdentifier(newFQTableName));
+ assertTrue(fs.exists(newTableDesc.getPath()));
+ assertEquals(StorageUtil.concatPath(warehouseDir, databaseName, newTableName), newTableDesc.getPath());
+ }
+
+ @Test
+ public final void testCreatedTableViaCTASAndVerifyPath() throws Exception {
+ assertPathOfCreatedTable("d4", "old_table", "new_mgmt_table",
+ "CREATE TABLE d4.old_table AS SELECT * FROM default.lineitem;");
+ }
+
+ @Test
+ public final void testCreatedTableJustCreatedAndVerifyPath() throws Exception {
+ assertPathOfCreatedTable("d5", "old_table", "new_mgmt_table", "CREATE TABLE d5.old_table (age integer);");
+ }
+
+ @Test
+ public final void testCreatedTableWithQuotedIdentifierAndVerifyPath() throws Exception {
+ if (!testingCluster.isHCatalogStoreRunning()) {
+ assertPathOfCreatedTable("D6", "OldTable", "NewMgmtTable", "CREATE TABLE \"D6\".\"OldTable\" (age integer);");
+ }
+ }
+
@Test
public final void testCreateTableIfNotExists() throws Exception {
executeString("CREATE DATABASE D3;").close();
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
new file mode 100644
index 0000000..e362eef
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestDropTable.java
@@ -0,0 +1,39 @@
+/**
+ * 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.IntegrationTest;
+import org.apache.tajo.QueryTestCaseBase;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.List;
+
+@Category(IntegrationTest.class)
+public class TestDropTable extends QueryTestCaseBase {
+
+ @Test
+ public final void testDropManagedTable() throws Exception {
+ List<String> createdNames = executeDDL("table1_ddl.sql", "table1.tbl", "ABC");
+ assertTableExists(createdNames.get(0));
+ executeDDL("drop_table_ddl.sql", null);
+ assertTableNotExists("ABC");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestAlterTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestDropTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
new file mode 100644
index 0000000..567aed8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_add_new_column_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE EFG ADD COLUMN cool text;
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
new file mode 100644
index 0000000..7c326ff
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_column_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE XYZ RENAME COLUMN num TO renum;
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
new file mode 100644
index 0000000..eeab457
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/alter_table_rename_table_ddl.sql
@@ -0,0 +1 @@
+ ALTER TABLE ABC RENAME TO DEF;
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql
new file mode 100644
index 0000000..8d7fba0
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestAlterTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE EXTERNAL TABLE ${0} (id int, str text, num int) using csv location ${table.path};
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
new file mode 100644
index 0000000..c770b43
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/drop_table_ddl.sql
@@ -0,0 +1 @@
+DROP TABLE ABC PURGE
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql
new file mode 100644
index 0000000..0d56ec8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestDropTable/table1_ddl.sql
@@ -0,0 +1 @@
+CREATE TABLE ${0} (id int, str text, num int);
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
----------------------------------------------------------------------
diff --git a/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst b/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
index 51156fa..e31caba 100644
--- a/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
+++ b/tajo-docs/src/main/sphinx/functions/datetime_func_and_operators.rst
@@ -2,4 +2,41 @@
DateTime Functions and Operators
********************************
-.. todo::
\ No newline at end of file
+.. function:: utc_usec_to (string text , long timestamp , int dayOfWeek)
+
+ * If the **first parameter** is 'day'.
+
+ Shifts and return a UNIX timestamp in microseconds to the beginning of the day it occurs in.
+ For example, if unix_timestamp occurs on May 19th at 08:58, this function returns a UNIX timestamp for May 19th at 00:00 (midnight).
+
+ * If the **first parameter** is 'hour'.
+
+ Shifts and return a UNIX timestamp in microseconds to the beginning of the hour it occurs in.
+ For example, if unix_timestamp occurs at 08:58, this function returns a UNIX timestamp for 08:00 on the same day.
+
+ * If the **first parameter** is 'month'.
+
+ Shifts and return a UNIX timestamp in microseconds to the beginning of the month it occurs in.
+ For example, if unix_timestamp occurs on March 19th, this function returns a UNIX timestamp for March 1st of the same year.
+
+ * If the **first parameter** is 'year'.
+
+ Returns a UNIX timestamp in microseconds that represents the year of the unix_timestamp argument.
+ For example, if unix_timestamp occurs in 2010, the function returns 1274259481071200, the microsecond representation of 2010-01-01 00:00.
+
+ * If the **first parameter** is 'week' and **third parameter** is 2 i.e (TUESDAY)
+
+ Returns a UNIX timestamp in microseconds that represents a day in the week of the
+ For example, if unix_timestamp occurs on Friday, 2008-04-11, and you set day_of_week to 2 (Tuesday), the function returns a UNIX timestamp for Tuesday, 2008-04-08.
+
+ :param string: could be 'day' 'hour' 'month' 'year' 'week'
+ :param long: unix timestamp in microseconds
+ :param int: day of the week from 0 (Sunday) to 6 (Saturday).Optional parameter required only if first parameter is 'week'
+ :rtype: long
+ :alias: utc_usec_to
+ :example:
+
+ .. code-block:: sql
+
+ SELECT utc_usec_to('day', 1274259481071200);
+ > 1274227200000000
\ No newline at end of file
[2/2] git commit: TAJO-480: Umbrella Jira for adding ALTER TABLE
statement. (Alvin Henrick via hyunsik)
Posted by hy...@apache.org.
TAJO-480: Umbrella Jira for adding ALTER TABLE statement. (Alvin Henrick via hyunsik)
Project: http://git-wip-us.apache.org/repos/asf/tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/bd418a5c
Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/bd418a5c
Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/bd418a5c
Branch: refs/heads/master
Commit: bd418a5c3edb8bb8df4be31866a5d3ec9b407f88
Parents: 40851e5
Author: Hyunsik Choi <hy...@apache.org>
Authored: Tue Apr 1 00:12:39 2014 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Tue Apr 1 00:12:39 2014 +0900
----------------------------------------------------------------------
CHANGES.txt | 5 +-
.../org/apache/tajo/algebra/AlterTable.java | 111 ++++++++
.../apache/tajo/algebra/AlterTableOpType.java | 22 ++
.../apache/tajo/algebra/ColumnDefinition.java | 59 ++++
.../org/apache/tajo/algebra/CreateTable.java | 41 ---
.../java/org/apache/tajo/algebra/OpType.java | 1 +
.../tajo/catalog/AbstractCatalogClient.java | 18 +-
.../org/apache/tajo/catalog/CatalogService.java | 7 +
.../src/main/proto/CatalogProtocol.proto | 2 +
.../org/apache/tajo/catalog/AlterTableDesc.java | 150 ++++++++++
.../org/apache/tajo/catalog/AlterTableType.java | 22 ++
.../org/apache/tajo/catalog/CatalogUtil.java | 25 ++
.../ColumnNameAlreadyExistException.java | 31 +++
.../src/main/proto/CatalogProtos.proto | 18 ++
.../tajo/catalog/store/HCatalogStore.java | 147 +++++++++-
.../org/apache/tajo/catalog/CatalogServer.java | 25 +-
.../tajo/catalog/store/AbstractDBStore.java | 277 ++++++++++++++++---
.../apache/tajo/catalog/store/CatalogStore.java | 3 +-
.../org/apache/tajo/catalog/store/MemStore.java | 74 ++++-
.../org/apache/tajo/catalog/TestCatalog.java | 49 ++++
.../org/apache/tajo/engine/parser/SQLLexer.g4 | 4 +
.../org/apache/tajo/engine/parser/SQLParser.g4 | 17 ++
.../tajo/engine/parser/HiveQLAnalyzer.java | 4 +-
.../apache/tajo/engine/parser/SQLAnalyzer.java | 223 ++++++++++-----
.../tajo/engine/planner/AlgebraVisitor.java | 3 +-
.../tajo/engine/planner/BaseAlgebraVisitor.java | 8 +
.../engine/planner/BasicLogicalPlanVisitor.java | 8 +
.../engine/planner/LogicalPlanPreprocessor.java | 7 +
.../tajo/engine/planner/LogicalPlanVisitor.java | 3 +
.../tajo/engine/planner/LogicalPlanner.java | 24 +-
.../apache/tajo/engine/planner/PlannerUtil.java | 105 +++----
.../engine/planner/SimpleAlgebraVisitor.java | 7 +-
.../engine/planner/logical/AlterTableNode.java | 134 +++++++++
.../tajo/engine/planner/logical/NodeType.java | 5 +-
.../org/apache/tajo/master/GlobalEngine.java | 94 ++++++-
.../java/org/apache/tajo/QueryTestCaseBase.java | 26 +-
.../tajo/engine/query/TestAlterTable.java | 53 ++++
.../apache/tajo/engine/query/TestCTASQuery.java | 18 +-
.../tajo/engine/query/TestCreateTable.java | 59 ++++
.../apache/tajo/engine/query/TestDropTable.java | 39 +++
.../resources/dataset/TestAlterTable/table1.tbl | 3 +
.../resources/dataset/TestDropTable/table1.tbl | 3 +
.../alter_table_add_new_column_ddl.sql | 1 +
.../alter_table_rename_column_ddl.sql | 1 +
.../alter_table_rename_table_ddl.sql | 1 +
.../queries/TestAlterTable/table1_ddl.sql | 1 +
.../queries/TestDropTable/drop_table_ddl.sql | 1 +
.../queries/TestDropTable/table1_ddl.sql | 1 +
.../functions/datetime_func_and_operators.rst | 39 ++-
49 files changed, 1743 insertions(+), 236 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 50fa593..d4b8452 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,7 +4,10 @@ Release 0.8.0 - unreleased
NEW FEATURES
- TAJO-378: Implement concat_ws function. (Seungun Choe via jaehwa)
+ TAJO-480: Umbrella Jira for adding ALTER TABLE statement.
+ (Alvin Henrick via hyunsik)
+
+ TAJO-378: Implement concat_ws function. (Seungun Choe via jaehwa)
TAJO-377: Implement concat function (Seungun Choe via jaehwa)
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
new file mode 100644
index 0000000..4bb0ed2
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTable.java
@@ -0,0 +1,111 @@
+/**
+ * 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 org.apache.tajo.util.TUtil;
+
+public class AlterTable extends Expr {
+
+ private String tableName;
+ private String newTableName;
+ private String columnName;
+ private String newColumnName;
+ private ColumnDefinition addNewColumn;
+ private AlterTableOpType alterTableOpType;
+
+ public AlterTable(final String tableName) {
+ super(OpType.AlterTable);
+ this.tableName = tableName;
+ }
+
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getNewTableName() {
+ return newTableName;
+ }
+
+ public void setNewTableName(String newTableName) {
+ this.newTableName = newTableName;
+ }
+
+ public String getColumnName() {
+ return columnName;
+ }
+
+ public void setColumnName(String columnName) {
+ this.columnName = columnName;
+ }
+
+ public String getNewColumnName() {
+ return newColumnName;
+ }
+
+ public void setNewColumnName(String newColumnName) {
+ this.newColumnName = newColumnName;
+ }
+
+ public ColumnDefinition getAddNewColumn() {
+ return addNewColumn;
+ }
+
+ public void setAddNewColumn(ColumnDefinition addNewColumn) {
+ this.addNewColumn = addNewColumn;
+ }
+
+ public AlterTableOpType getAlterTableOpType() {
+ return alterTableOpType;
+ }
+
+ public void setAlterTableOpType(AlterTableOpType alterTableOpType) {
+ this.alterTableOpType = alterTableOpType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(tableName,
+ null != newTableName ? Objects.hashCode(newTableName) : newTableName,
+ null != columnName ? Objects.hashCode(columnName) : columnName,
+ null != newColumnName ? Objects.hashCode(newColumnName) : newColumnName,
+ null != addNewColumn ? Objects.hashCode(addNewColumn) : addNewColumn,
+ null != alterTableOpType ? Objects.hashCode(alterTableOpType) : alterTableOpType);
+
+ }
+
+ @Override
+ boolean equalsTo(Expr expr) {
+ AlterTable another = (AlterTable) expr;
+ return tableName.equals(another.tableName) &&
+ TUtil.checkEquals(newTableName, another.newTableName) &&
+ TUtil.checkEquals(columnName, another.columnName) &&
+ TUtil.checkEquals(newColumnName, another.newColumnName) &&
+ TUtil.checkEquals(addNewColumn, another.addNewColumn) &&
+ TUtil.checkEquals(alterTableOpType, another.alterTableOpType);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.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
new file mode 100644
index 0000000..67b28a2
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/AlterTableOpType.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 AlterTableOpType {
+ RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
new file mode 100644
index 0000000..ce935dd
--- /dev/null
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/ColumnDefinition.java
@@ -0,0 +1,59 @@
+/**
+ * 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 class ColumnDefinition extends DataTypeExpr {
+ String col_name;
+
+ public ColumnDefinition(String columnName, String dataType) {
+ super(dataType);
+ this.col_name = columnName;
+ }
+
+ public ColumnDefinition(String columnName, DataTypeExpr dataType) {
+ super(dataType.getTypeName());
+ if (dataType.hasLengthOrPrecision()) {
+ setLengthOrPrecision(dataType.lengthOrPrecision);
+ if (dataType.hasScale()) {
+ setScale(dataType.scale);
+ }
+ }
+ this.col_name = columnName;
+ }
+
+ public String getColumnName() {
+ return this.col_name;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ return hash * 89 * col_name.hashCode();
+
+ }
+
+ @Override
+ public boolean equalsTo(Expr expr) {
+ if (expr instanceof ColumnDefinition) {
+ ColumnDefinition another = (ColumnDefinition) expr;
+ return col_name.equals(another.col_name) && super.equalsTo(another);
+ }
+
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
index eb11ed0..63ca364 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java
@@ -155,47 +155,6 @@ public class CreateTable extends Expr {
ifNotExists == another.ifNotExists;
}
- public static class ColumnDefinition extends DataTypeExpr {
- String col_name;
-
- public ColumnDefinition(String columnName, String dataType) {
- super(dataType);
- this.col_name = columnName;
- }
-
- public ColumnDefinition(String columnName, DataTypeExpr dataType) {
- super(dataType.getTypeName());
- if (dataType.hasLengthOrPrecision()) {
- setLengthOrPrecision(dataType.lengthOrPrecision);
- if (dataType.hasScale()) {
- setScale(dataType.scale);
- }
- }
- this.col_name = columnName;
- }
-
- public String getColumnName() {
- return this.col_name;
- }
-
- @Override
- public int hashCode() {
- int hash = super.hashCode();
- return hash * 89 * col_name.hashCode();
-
- }
-
- @Override
- public boolean equalsTo(Expr expr) {
- if (expr instanceof ColumnDefinition) {
- ColumnDefinition another = (ColumnDefinition) expr;
- return col_name.equals(another.col_name) && super.equalsTo(another);
- }
-
- return false;
- }
- }
-
public static enum PartitionType {
RANGE,
HASH,
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java
----------------------------------------------------------------------
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 c4a007a..a4fb617 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
@@ -46,6 +46,7 @@ public enum OpType {
DropDatabase(DropDatabase.class),
CreateTable(CreateTable.class),
DropTable(DropTable.class),
+ AlterTable(AlterTable.class),
// Insert or Update
Insert(Insert.class),
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
index 6fb385e..60cce9a 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
+++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java
@@ -360,7 +360,7 @@ public abstract class AbstractCatalogClient implements CatalogService {
return false;
}
}
-
+ @Override
public final boolean existsTable(final String tableName) {
String [] splitted = CatalogUtil.splitFQTableName(tableName);
return existsTable(splitted[0], splitted[1]);
@@ -595,4 +595,20 @@ public abstract class AbstractCatalogClient implements CatalogService {
return false;
}
}
+
+ @Override
+ public final boolean alterTable(final AlterTableDesc desc) {
+ try {
+ return new ServerCallable<Boolean>(this.pool, catalogServerAddr, CatalogProtocol.class, false) {
+ public Boolean call(NettyClientBase client) throws ServiceException {
+ CatalogProtocolService.BlockingInterface stub = getStub(client);
+ return stub.alterTable(null, desc.getProto()).getValue();
+ }
+ }.withRetries();
+ } catch (ServiceException e) {
+ LOG.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
index d69ed7e..f68f11a 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
+++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/CatalogService.java
@@ -157,4 +157,11 @@ public interface CatalogService {
boolean containFunction(String signature, DataType... paramTypes);
boolean containFunction(String signature, FunctionType funcType, DataType... paramTypes);
+
+ /**
+ * Add a table via table description
+ * @see AlterTableDesc
+ * @throws Throwable
+ */
+ boolean alterTable(AlterTableDesc desc);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
index 06b69c1..0f34f7c 100644
--- a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
+++ b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto
@@ -30,6 +30,8 @@ service CatalogProtocolService {
rpc dropTablespace(StringProto) returns (BoolProto);
rpc existTablespace(StringProto) returns (BoolProto);
rpc getAllTablespaceNames(NullProto) returns (StringListProto);
+ rpc alterTable(AlterTableDescProto) returns (BoolProto);
+
rpc createDatabase(CreateDatabaseRequest) returns (BoolProto);
rpc dropDatabase(StringProto) returns (BoolProto);
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java
new file mode 100644
index 0000000..d69330d
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableDesc.java
@@ -0,0 +1,150 @@
+/**
+ * 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;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.annotations.Expose;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tajo.catalog.json.CatalogGsonHelper;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.common.ProtoObject;
+import org.apache.tajo.json.GsonObject;
+
+
+public class AlterTableDesc implements ProtoObject<CatalogProtos.AlterTableDescProto>, GsonObject, Cloneable {
+ private final Log LOG = LogFactory.getLog(AlterTableDesc.class);
+
+ protected CatalogProtos.AlterTableDescProto.Builder builder = null;
+
+ @Expose
+ protected String tableName; // required
+ @Expose
+ protected String newTableName; // optional
+ @Expose
+ protected String columnName; //optional
+ @Expose
+ protected String newColumnName; //optional
+ @Expose
+ protected Column addColumn = null; //optiona
+ @Expose
+ protected AlterTableType alterTableType; //required
+
+ public AlterTableDesc() {
+ builder = CatalogProtos.AlterTableDescProto.newBuilder();
+ }
+
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getNewTableName() {
+ return newTableName;
+ }
+
+ public void setNewTableName(String newTableName) {
+ this.newTableName = newTableName;
+ }
+
+ public String getColumnName() {
+ return columnName;
+ }
+
+ public void setColumnName(String columnName) {
+ this.columnName = columnName;
+ }
+
+ public String getNewColumnName() {
+ return newColumnName;
+ }
+
+ public void setNewColumnName(String newColumnName) {
+ this.newColumnName = newColumnName;
+ }
+
+ public Column getAddColumn() {
+ return addColumn;
+ }
+
+ public void setAddColumn(Column addColumn) {
+ this.addColumn = addColumn;
+ }
+
+ public AlterTableType getAlterTableType() {
+ return alterTableType;
+ }
+
+ public void setAlterTableType(AlterTableType alterTableType) {
+ this.alterTableType = alterTableType;
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new GsonBuilder().setPrettyPrinting().
+ excludeFieldsWithoutExposeAnnotation().create();
+ return gson.toJson(this);
+ }
+
+ @Override
+ public String toJson() {
+ return CatalogGsonHelper.toJson(this, AlterTableDesc.class);
+ }
+
+ @Override
+ public CatalogProtos.AlterTableDescProto getProto() {
+ if (null == builder) {
+ builder = CatalogProtos.AlterTableDescProto.newBuilder();
+ }
+ if (null != this.tableName) {
+ builder.setTableName(this.tableName);
+ }
+ if (null != this.newTableName) {
+ builder.setNewTableName(this.newTableName);
+ }
+ if (null != this.columnName && null != this.newColumnName) {
+ final CatalogProtos.AlterColumnProto.Builder alterColumnBuilder = CatalogProtos.AlterColumnProto.newBuilder();
+ alterColumnBuilder.setOldColumnName(this.columnName);
+ alterColumnBuilder.setNewColumnName(this.newColumnName);
+ builder.setAlterColumnName(alterColumnBuilder.build());
+ }
+ if (null != this.addColumn) {
+ builder.setAddColumn(addColumn.getProto());
+ }
+
+ switch (alterTableType) {
+ case RENAME_TABLE:
+ builder.setAlterTableType(CatalogProtos.AlterTableType.RENAME_TABLE);
+ break;
+ case RENAME_COLUMN:
+ builder.setAlterTableType(CatalogProtos.AlterTableType.RENAME_COLUMN);
+ break;
+ case ADD_COLUMN:
+ builder.setAlterTableType(CatalogProtos.AlterTableType.ADD_COLUMN);
+ break;
+ default:
+ }
+ return builder.build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.java
new file mode 100644
index 0000000..0b7639c
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/AlterTableType.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.catalog;
+
+public enum AlterTableType {
+ RENAME_TABLE, RENAME_COLUMN, ADD_COLUMN
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
index 9078e60..22f54ca 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java
@@ -441,4 +441,29 @@ public class CatalogUtil {
RESERVED_KEYWORDS_SET.add(keyword);
}
}
+
+ public static AlterTableDesc renameColumn(String tableName, String oldColumName, String newColumName, AlterTableType alterTableType) {
+ final AlterTableDesc alterTableDesc = new AlterTableDesc();
+ alterTableDesc.setTableName(tableName);
+ alterTableDesc.setColumnName(oldColumName);
+ alterTableDesc.setNewColumnName(newColumName);
+ alterTableDesc.setAlterTableType(alterTableType);
+ return alterTableDesc;
+ }
+
+ public static AlterTableDesc renameTable(String tableName, String newTableName, AlterTableType alterTableType) {
+ final AlterTableDesc alterTableDesc = new AlterTableDesc();
+ alterTableDesc.setTableName(tableName);
+ alterTableDesc.setNewTableName(newTableName);
+ alterTableDesc.setAlterTableType(alterTableType);
+ return alterTableDesc;
+ }
+
+ public static AlterTableDesc addNewColumn(String tableName, Column column, AlterTableType alterTableType) {
+ final AlterTableDesc alterTableDesc = new AlterTableDesc();
+ alterTableDesc.setTableName(tableName);
+ alterTableDesc.setAddColumn(column);
+ alterTableDesc.setAlterTableType(alterTableType);
+ return alterTableDesc;
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java
new file mode 100644
index 0000000..1c026d7
--- /dev/null
+++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/ColumnNameAlreadyExistException.java
@@ -0,0 +1,31 @@
+/**
+ * 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 ColumnNameAlreadyExistException extends CatalogException {
+
+ private static final long serialVersionUID = -4863862140874083282L;
+
+ public ColumnNameAlreadyExistException() {
+ }
+
+ public ColumnNameAlreadyExistException(String columnName) {
+ super("Column already exists : " + columnName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
index 06ffcfd..d3abc70 100644
--- a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
+++ b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto
@@ -48,6 +48,12 @@ enum PartitionType {
COLUMN = 3;
}
+enum AlterTableType {
+ RENAME_TABLE = 0;
+ RENAME_COLUMN = 1;
+ ADD_COLUMN = 2;
+}
+
message ColumnProto {
required string name = 1;
required DataType dataType = 3;
@@ -263,3 +269,15 @@ message PartitionDescProto {
optional string path = 5;
}
+message AlterTableDescProto {
+ required string tableName = 1;
+ optional string newTableName = 2 ;
+ optional ColumnProto addColumn = 3;
+ optional AlterColumnProto alterColumnName = 4;
+ required AlterTableType alterTableType = 5;
+}
+
+message AlterColumnProto {
+ required string oldColumnName = 1;
+ required string newColumnName = 2;
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
index 6ef255f..a4bdb28 100644
--- a/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
+++ b/tajo-catalog/tajo-catalog-drivers/tajo-hcatalog/src/main/java/org/apache/tajo/catalog/store/HCatalogStore.java
@@ -36,9 +36,7 @@ import org.apache.hcatalog.data.schema.HCatSchema;
import org.apache.tajo.TajoConstants;
import org.apache.tajo.catalog.*;
import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.catalog.exception.AlreadyExistsDatabaseException;
-import org.apache.tajo.catalog.exception.CatalogException;
-import org.apache.tajo.catalog.exception.NoSuchDatabaseException;
+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.statistics.TableStats;
@@ -135,7 +133,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
isPartitionKey = false;
if (table.getPartitionKeys() != null) {
- for(FieldSchema partitionKey: table.getPartitionKeys()) {
+ for (FieldSchema partitionKey : table.getPartitionKeys()) {
if (partitionKey.getName().equals(eachField.getName())) {
isPartitionKey = true;
}
@@ -198,7 +196,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
// set data size
long totalSize = 0;
- if(properties.getProperty("totalSize") != null) {
+ if (properties.getProperty("totalSize") != null) {
totalSize = Long.parseLong(properties.getProperty("totalSize"));
} else {
try {
@@ -219,7 +217,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
StringBuilder sb = new StringBuilder();
if (table.getPartitionKeys().size() > 0) {
List<FieldSchema> partitionKeys = table.getPartitionKeys();
- for(int i = 0; i < partitionKeys.size(); i++) {
+ for (int i = 0; i < partitionKeys.size(); i++) {
FieldSchema fieldSchema = partitionKeys.get(i);
TajoDataTypes.Type dataType = HCatalogUtil.getTajoFieldType(fieldSchema.getType().toString());
String fieldName = databaseName + CatalogUtil.IDENTIFIER_DELIMITER + tableName +
@@ -377,7 +375,7 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
HCatalogStoreClientPool.HCatalogStoreClient client = null;
TableDesc tableDesc = new TableDesc(tableDescProto);
- String [] splitted = CatalogUtil.splitFQTableName(tableDesc.getName());
+ String[] splitted = CatalogUtil.splitFQTableName(tableDesc.getName());
String databaseName = splitted[0];
String tableName = splitted[1];
@@ -425,8 +423,8 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
// set partition keys
if (tableDesc.hasPartition() && tableDesc.getPartitionMethod().getPartitionType().equals(PartitionType.COLUMN)) {
List<FieldSchema> partitionKeys = new ArrayList<FieldSchema>();
- for(Column eachPartitionKey: tableDesc.getPartitionMethod().getExpressionSchema().getColumns()) {
- partitionKeys.add(new FieldSchema( eachPartitionKey.getSimpleName(),
+ for (Column eachPartitionKey : tableDesc.getPartitionMethod().getExpressionSchema().getColumns()) {
+ partitionKeys.add(new FieldSchema(eachPartitionKey.getSimpleName(),
HCatalogUtil.getHiveFieldType(eachPartitionKey.getDataType()), ""));
}
table.setPartitionKeys(partitionKeys);
@@ -500,6 +498,110 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
}
}
+
+ @Override
+ public void alterTable(final CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException {
+
+ HCatalogStoreClientPool.HCatalogStoreClient client = clientPool.getClient();
+
+ final String[] split = CatalogUtil.splitFQTableName(alterTableDescProto.getTableName());
+
+ if (split.length == 1) {
+ throw new IllegalArgumentException("alterTable() requires a qualified table name, but it is \""
+ + alterTableDescProto.getTableName() + "\".");
+ }
+
+ final String databaseName = split[0];
+ final String tableName = split[1];
+
+
+ switch (alterTableDescProto.getAlterTableType()) {
+ case RENAME_TABLE:
+ if (existTable(databaseName,alterTableDescProto.getNewTableName().toLowerCase())) {
+ throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName());
+ }
+ renameTable(databaseName, tableName, alterTableDescProto.getNewTableName().toLowerCase());
+ break;
+ case RENAME_COLUMN:
+ if (existColumn(databaseName,tableName, alterTableDescProto.getAlterColumnName().getNewColumnName())) {
+ throw new ColumnNameAlreadyExistException(alterTableDescProto.getAlterColumnName().getNewColumnName());
+ }
+ renameColumn(databaseName, tableName, alterTableDescProto.getAlterColumnName());
+ break;
+ case ADD_COLUMN:
+ if (existColumn(databaseName,tableName, alterTableDescProto.getAddColumn().getName())) {
+ throw new ColumnNameAlreadyExistException(alterTableDescProto.getAddColumn().getName());
+ }
+ addNewColumn(databaseName, tableName, alterTableDescProto.getAddColumn());
+ break;
+ default:
+ //TODO
+ }
+
+
+ }
+
+
+ private void renameTable(String databaseName, String tableName, String newTableName) {
+ HCatalogStoreClientPool.HCatalogStoreClient client = null;
+ try {
+ client = clientPool.getClient();
+ Table newTable = client.getHiveClient().getTable(databaseName, tableName);
+ newTable.setTableName(newTableName);
+ client.getHiveClient().alter_table(databaseName, tableName, newTable);
+
+ } catch (NoSuchObjectException nsoe) {
+ } catch (Exception e) {
+ throw new CatalogException(e);
+ } finally {
+ client.release();
+ }
+ }
+
+ private void renameColumn(String databaseName, String tableName, CatalogProtos.AlterColumnProto alterColumnProto) {
+ HCatalogStoreClientPool.HCatalogStoreClient client = null;
+ try {
+
+ client = clientPool.getClient();
+ Table table = client.getHiveClient().getTable(databaseName, tableName);
+ List<FieldSchema> columns = table.getSd().getCols();
+
+ for (final FieldSchema currentColumn : columns) {
+ if (currentColumn.getName().equalsIgnoreCase(alterColumnProto.getOldColumnName())) {
+ currentColumn.setName(alterColumnProto.getNewColumnName());
+ }
+ }
+ client.getHiveClient().alter_table(databaseName, tableName, table);
+
+ } catch (NoSuchObjectException nsoe) {
+ } catch (Exception e) {
+ throw new CatalogException(e);
+ } finally {
+ client.release();
+ }
+ }
+
+
+ private void addNewColumn(String databaseName, String tableName, CatalogProtos.ColumnProto columnProto) {
+ HCatalogStoreClientPool.HCatalogStoreClient client = null;
+ try {
+
+ client = clientPool.getClient();
+ Table table = client.getHiveClient().getTable(databaseName, tableName);
+ List<FieldSchema> columns = table.getSd().getCols();
+ columns.add(new FieldSchema(columnProto.getName(),
+ HCatalogUtil.getHiveFieldType(columnProto.getDataType()), ""));
+ client.getHiveClient().alter_table(databaseName, tableName, table);
+
+
+ } catch (NoSuchObjectException nsoe) {
+ } catch (Exception e) {
+ throw new CatalogException(e);
+ } finally {
+ client.release();
+ }
+ }
+
@Override
public void addPartitionMethod(CatalogProtos.PartitionMethodProto partitionMethodProto) throws CatalogException {
// TODO - not implemented yet
@@ -618,4 +720,31 @@ public class HCatalogStore extends CatalogConstants implements CatalogStore {
public final void close() {
clientPool.close();
}
+
+ private boolean existColumn(final String databaseName ,final String tableName , final String columnName) throws CatalogException {
+ boolean exist = false;
+ HCatalogStoreClientPool.HCatalogStoreClient client = null;
+
+ try {
+
+ client = clientPool.getClient();
+ Table table = client.getHiveClient().getTable(databaseName, tableName);
+ List<FieldSchema> columns = table.getSd().getCols();
+
+ for (final FieldSchema currentColumn : columns) {
+ if (currentColumn.getName().equalsIgnoreCase(columnName)) {
+ exist = true;
+ }
+ }
+ client.getHiveClient().alter_table(databaseName, tableName, table);
+
+ } catch (NoSuchObjectException nsoe) {
+ } catch (Exception e) {
+ throw new CatalogException(e);
+ } finally {
+ client.release();
+ }
+
+ return exist;
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
index a171fb4..b6f7f08 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
@@ -102,7 +102,7 @@ public class CatalogServer extends AbstractService {
this.builtingFuncs = sqlFuncs;
}
- @Override
+
public void serviceInit(Configuration conf) throws Exception {
Constructor<?> cons;
@@ -306,6 +306,26 @@ public class CatalogServer extends AbstractService {
}
@Override
+ public BoolProto alterTable(RpcController controller, AlterTableDescProto proto) throws ServiceException {
+ wlock.lock();
+ try {
+ String [] split = CatalogUtil.splitTableName(proto.getTableName());
+ if (!store.existTable(split[0], split[1])) {
+ throw new NoSuchTableException(proto.getTableName());
+ }
+ store.alterTable(proto);
+ } catch (Exception e) {
+ LOG.error(e.getMessage(), e);
+ return BOOL_FALSE;
+ } finally {
+ wlock.unlock();
+ LOG.info("Table " + proto.getTableName() + " is altered in the catalog ("
+ + bindAddressStr + ")");
+ }
+ return BOOL_TRUE;
+ }
+
+ @Override
public BoolProto dropDatabase(RpcController controller, StringProto request) throws ServiceException {
String databaseName = request.getValue();
@@ -593,7 +613,6 @@ public class CatalogServer extends AbstractService {
@Override
public BoolProto addPartitions(RpcController controller, PartitionsProto request) throws ServiceException {
-
return ProtoUtil.TRUE;
}
@@ -814,7 +833,7 @@ public class CatalogServer extends AbstractService {
return BOOL_TRUE;
}
- @Override
+ @Override
public BoolProto dropFunction(RpcController controller, UnregisterFunctionRequest request)
throws ServiceException {
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
index d10f545..b1efc7f 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/AbstractDBStore.java
@@ -29,10 +29,7 @@ import org.apache.tajo.annotation.Nullable;
import org.apache.tajo.catalog.CatalogConstants;
import org.apache.tajo.catalog.CatalogUtil;
import org.apache.tajo.catalog.FunctionDesc;
-import org.apache.tajo.catalog.exception.CatalogException;
-import org.apache.tajo.catalog.exception.NoSuchDatabaseException;
-import org.apache.tajo.catalog.exception.NoSuchTableException;
-import org.apache.tajo.catalog.exception.NoSuchTablespaceException;
+import org.apache.tajo.catalog.exception.*;
import org.apache.tajo.catalog.proto.CatalogProtos;
import org.apache.tajo.catalog.proto.CatalogProtos.*;
import org.apache.tajo.common.TajoDataTypes.Type;
@@ -73,7 +70,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
this.conf = conf;
- if(conf.get(CatalogConstants.DEPRECATED_CATALOG_URI) != null) {
+ if (conf.get(CatalogConstants.DEPRECATED_CATALOG_URI) != null) {
LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CATALOG_URI + " " +
"is deprecated. Use " + CatalogConstants.CATALOG_URI + " instead.");
this.catalogUri = conf.get(CatalogConstants.DEPRECATED_CATALOG_URI);
@@ -81,7 +78,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
this.catalogUri = conf.get(CatalogConstants.CATALOG_URI);
}
- if(conf.get(CatalogConstants.DEPRECATED_CONNECTION_ID) != null) {
+ if (conf.get(CatalogConstants.DEPRECATED_CONNECTION_ID) != null) {
LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CONNECTION_ID + " " +
"is deprecated. Use " + CatalogConstants.CONNECTION_ID + " instead.");
this.connectionId = conf.get(CatalogConstants.DEPRECATED_CONNECTION_ID);
@@ -89,7 +86,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
this.connectionId = conf.get(CatalogConstants.CONNECTION_ID);
}
- if(conf.get(CatalogConstants.DEPRECATED_CONNECTION_PASSWORD) != null) {
+ if (conf.get(CatalogConstants.DEPRECATED_CONNECTION_PASSWORD) != null) {
LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CONNECTION_PASSWORD + " " +
"is deprecated. Use " + CatalogConstants.CONNECTION_PASSWORD + " instead.");
this.connectionPassword = conf.get(CatalogConstants.DEPRECATED_CONNECTION_PASSWORD);
@@ -146,7 +143,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
}
}
- protected String getCatalogUri(){
+ protected String getCatalogUri() {
return catalogUri;
}
@@ -180,7 +177,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
boolean noVersion = !result.next();
- int schemaVersion = result.getInt(1);
+ int schemaVersion = result.getInt(1);
if (noVersion || schemaVersion != getDriverVersion()) {
LOG.error(String.format("Catalog version (%d) and current driver version (%d) are mismatch to each other",
schemaVersion, getDriverVersion()));
@@ -266,7 +263,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
try {
StringBuilder sql = new StringBuilder();
- sql.append("SELECT SPACE_NAME FROM " + TB_SPACES +" WHERE SPACE_NAME = ?");
+ sql.append("SELECT SPACE_NAME FROM " + TB_SPACES + " WHERE SPACE_NAME = ?");
if (LOG.isDebugEnabled()) {
LOG.debug(sql.toString());
}
@@ -302,7 +299,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
dropDatabase(databaseName);
}
- String sql = "DELETE FROM " + TB_SPACES + " WHERE " + COL_TABLESPACE_PK +"= ?";
+ String sql = "DELETE FROM " + TB_SPACES + " WHERE " + COL_TABLESPACE_PK + "= ?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, tableSpace.getSpaceId());
pstmt.executeUpdate();
@@ -326,7 +323,6 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
return getAllTablespaceNamesInternal(null);
}
-
private Collection<String> getAllTablespaceNamesInternal(@Nullable String whereCondition) throws CatalogException {
Connection conn = null;
PreparedStatement pstmt = null;
@@ -344,7 +340,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
conn = getConnection();
pstmt = conn.prepareStatement(sql);
resultSet = pstmt.executeQuery();
- while(resultSet.next()) {
+ while (resultSet.next()) {
tablespaceNames.add(resultSet.getString(1));
}
} catch (SQLException se) {
@@ -476,7 +472,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
conn = getConnection();
pstmt = conn.prepareStatement(sql);
resultSet = pstmt.executeQuery();
- while(resultSet.next()) {
+ while (resultSet.next()) {
databaseNames.add(resultSet.getString(1));
}
} catch (SQLException se) {
@@ -572,7 +568,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
conn = getConnection();
conn.setAutoCommit(false);
- String [] splitted = CatalogUtil.splitTableName(table.getTableName());
+ String[] splitted = CatalogUtil.splitTableName(table.getTableName());
if (splitted.length == 1) {
throw new IllegalArgumentException("createTable() requires a qualified table name, but it is \""
+ table.getTableName() + "\".");
@@ -636,7 +632,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
}
pstmt = conn.prepareStatement(colSql);
- for(int i = 0; i < table.getSchema().getFieldsCount(); i++) {
+ for (int i = 0; i < table.getSchema().getFieldsCount(); i++) {
ColumnProto col = table.getSchema().getFields(i);
pstmt.setInt(1, tableId);
pstmt.setString(2, CatalogUtil.extractSimpleName(col.getName()));
@@ -649,7 +645,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
pstmt.executeBatch();
pstmt.close();
- if(table.getMeta().hasParams()) {
+ if (table.getMeta().hasParams()) {
String propSQL = "INSERT INTO " + TB_OPTIONS + "(TID, KEY_, VALUE_) VALUES(?, ?, ?)";
if (LOG.isDebugEnabled()) {
@@ -684,7 +680,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
pstmt.close();
}
- if(table.hasPartition()) {
+ if (table.hasPartition()) {
String partSql =
"INSERT INTO PARTITION_METHODS (TID, PARTITION_TYPE, EXPRESSION, EXPRESSION_SCHEMA) VALUES(?, ?, ?, ?)";
@@ -716,6 +712,183 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
}
}
+ @Override
+ public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException {
+
+ String[] splitted = CatalogUtil.splitTableName(alterTableDescProto.getTableName());
+ if (splitted.length == 1) {
+ throw new IllegalArgumentException("alterTable() requires a qualified table name, but it is \""
+ + alterTableDescProto.getTableName() + "\".");
+ }
+ String databaseName = splitted[0];
+ String tableName = splitted[1];
+
+ try {
+
+ int databaseId = getDatabaseId(databaseName);
+ int tableId = getTableId(databaseId, databaseName, tableName);
+
+ switch (alterTableDescProto.getAlterTableType()) {
+ case RENAME_TABLE:
+ if (existTable(databaseName,alterTableDescProto.getNewTableName())) {
+ throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName());
+ }
+ renameTable(tableId, alterTableDescProto.getNewTableName());
+ break;
+ case RENAME_COLUMN:
+ if (existColumn(tableId, alterTableDescProto.getAlterColumnName().getNewColumnName())) {
+ throw new ColumnNameAlreadyExistException(alterTableDescProto.getAlterColumnName().getNewColumnName());
+ }
+ renameColumn(tableId, alterTableDescProto.getAlterColumnName());
+ break;
+ case ADD_COLUMN:
+ if (existColumn(tableId, alterTableDescProto.getAddColumn().getName())) {
+ throw new ColumnNameAlreadyExistException(alterTableDescProto.getAddColumn().getName());
+ }
+ addNewColumn(tableId, alterTableDescProto.getAddColumn());
+ break;
+ default:
+ }
+ } catch (SQLException sqlException) {
+ throw new CatalogException(sqlException);
+ }
+
+ }
+
+ private void renameTable(final int tableId, final String tableName) throws CatalogException {
+
+ final String updtaeRenameTableSql = "UPDATE " + TB_TABLES + " SET " + COL_TABLES_NAME + " = ? " + " WHERE TID = ?";
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(updtaeRenameTableSql);
+ }
+
+ Connection conn;
+ PreparedStatement pstmt = null;
+
+ try {
+
+ conn = getConnection();
+ pstmt = conn.prepareStatement(updtaeRenameTableSql);
+ pstmt.setString(1, tableName);
+ pstmt.setInt(2, tableId);
+ pstmt.executeUpdate();
+
+ } catch (SQLException sqlException) {
+ throw new CatalogException(sqlException);
+ } finally {
+ CatalogUtil.closeQuietly(pstmt);
+ }
+ }
+
+ private void renameColumn(final int tableId, final CatalogProtos.AlterColumnProto alterColumnProto) throws CatalogException {
+
+ final String selectColumnSql = "SELECT COLUMN_NAME, DATA_TYPE, TYPE_LENGTH, ORDINAL_POSITION from " + TB_COLUMNS +" WHERE " + COL_TABLES_PK + " = ?" + " AND COLUMN_NAME = ?" ;
+ final String deleteColumnNameSql = "DELETE FROM " + TB_COLUMNS + " WHERE TID = ? AND COLUMN_NAME = ?";
+ final String insertNewColumnSql = "INSERT INTO " + TB_COLUMNS + " (TID, COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, TYPE_LENGTH) VALUES(?, ?, ?, ?, ?) ";
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(selectColumnSql);
+ LOG.debug(deleteColumnNameSql);
+ LOG.debug(insertNewColumnSql);
+ }
+
+ Connection conn;
+ PreparedStatement pstmt = null;
+ ResultSet resultSet = null;
+
+ try {
+
+ conn = getConnection();
+ conn.setAutoCommit(false);
+
+ //SELECT COLUMN
+ pstmt = conn.prepareStatement(selectColumnSql);
+ pstmt.setInt(1, tableId);
+ pstmt.setString(2, alterColumnProto.getOldColumnName());
+ resultSet = pstmt.executeQuery();
+
+ CatalogProtos.ColumnProto columnProto = null;
+ int ordinalPostion = -1;
+
+ if (resultSet.next()) {
+ columnProto = resultToColumnProto(resultSet);
+ //NOTE ==> Setting new column Name
+ columnProto = columnProto.toBuilder().setName(alterColumnProto.getNewColumnName()).build();
+ ordinalPostion = resultSet.getInt("ORDINAL_POSITION");
+ }
+
+ resultSet.close();
+ pstmt.close();
+ resultSet = null;
+
+ //DELETE COLUMN
+ pstmt = conn.prepareStatement(deleteColumnNameSql);
+ pstmt.setInt(1, tableId);
+ pstmt.setString(2, alterColumnProto.getOldColumnName());
+ pstmt.executeUpdate();
+ pstmt.close();
+
+ //INSERT COLUMN
+ pstmt = conn.prepareStatement(insertNewColumnSql);
+ pstmt.setInt(1, tableId);
+ pstmt.setString(2, CatalogUtil.extractSimpleName(columnProto.getName()));
+ pstmt.setInt(3, ordinalPostion);
+ pstmt.setString(4, columnProto.getDataType().getType().name());
+ pstmt.setInt(5, (columnProto.getDataType().hasLength() ? columnProto.getDataType().getLength() : 0));
+ pstmt.executeUpdate();
+
+ conn.commit();
+
+
+ } catch (SQLException sqlException) {
+ throw new CatalogException(sqlException);
+ } finally {
+ CatalogUtil.closeQuietly(pstmt,resultSet);
+ }
+ }
+
+ private void addNewColumn(int tableId, CatalogProtos.ColumnProto columnProto) throws CatalogException {
+
+ final String insertNewColumnSql = "INSERT INTO " + TB_COLUMNS + " (TID, COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, TYPE_LENGTH) VALUES(?, ?, ?, ?, ?) ";
+ final String columnCountSql = "SELECT COLUMN_NAME, MAX(ORDINAL_POSITION) AS POSITION FROM " + TB_COLUMNS + " WHERE TID = ? GROUP BY COLUMN_NAME";
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(insertNewColumnSql);
+ LOG.debug(columnCountSql);
+ }
+
+ Connection conn;
+ PreparedStatement pstmt = null;
+ ResultSet resultSet = null;
+
+ try {
+ conn = getConnection();
+ pstmt = conn.prepareStatement(columnCountSql);
+ pstmt.setInt(1 , tableId);
+ resultSet = pstmt.executeQuery();
+
+ int position = resultSet.next() ? resultSet.getInt("POSITION") : 0;
+
+ resultSet.close();
+ pstmt.close();
+ resultSet = null;
+
+ pstmt = conn.prepareStatement(insertNewColumnSql);
+ pstmt.setInt(1, tableId);
+ pstmt.setString(2, CatalogUtil.extractSimpleName(columnProto.getName()));
+ pstmt.setInt(3, position + 1);
+ pstmt.setString(4, columnProto.getDataType().getType().name());
+ pstmt.setInt(5, (columnProto.getDataType().hasLength() ? columnProto.getDataType().getLength() : 0));
+ pstmt.executeUpdate();
+
+ } catch (SQLException sqlException) {
+ throw new CatalogException(sqlException);
+ } finally {
+ CatalogUtil.closeQuietly(pstmt,resultSet);
+ }
+ }
+
private int getDatabaseId(String databaseName) throws SQLException {
String sql = String.format("SELECT DB_ID from %s WHERE DB_NAME = ?", TB_DATABASES);
@@ -986,7 +1159,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
//////////////////////////////////////////
CatalogProtos.TableProto.Builder metaBuilder = CatalogProtos.TableProto.newBuilder();
metaBuilder.setStoreType(storeType);
- sql = "SELECT key_, value_ FROM " + TB_OPTIONS +" WHERE " + COL_TABLES_PK + " = ?";
+ sql = "SELECT key_, value_ FROM " + TB_OPTIONS + " WHERE " + COL_TABLES_PK + " = ?";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
@@ -1136,12 +1309,12 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
private static void addPartitionInternal(PreparedStatement pstmt, int tableId, PartitionDescProto partition) throws
SQLException {
- pstmt.setInt(1, tableId);
- pstmt.setString(2, partition.getPartitionName());
- pstmt.setInt(3, partition.getOrdinalPosition());
- pstmt.setString(4, partition.getPath());
- pstmt.addBatch();
- pstmt.clearParameters();
+ pstmt.setInt(1, tableId);
+ pstmt.setString(2, partition.getPartitionName());
+ pstmt.setInt(3, partition.getOrdinalPosition());
+ pstmt.setString(4, partition.getPath());
+ pstmt.addBatch();
+ pstmt.clearParameters();
}
@Override
@@ -1151,7 +1324,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
try {
String sql = "INSERT INTO " + TB_PARTITION_METHODS + " (TID, PARTITION_TYPE, EXPRESSION, EXPRESSION_SCHEMA) " +
- "VALUES (?,?,?,?)";
+ "VALUES (?,?,?,?)";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
@@ -1209,7 +1382,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
try {
String sql = "SELECT partition_type, expression, expression_schema FROM " + TB_PARTITION_METHODS +
- " WHERE " + COL_TABLES_NAME + " = ? ";
+ " WHERE " + COL_TABLES_NAME + " = ? ";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
@@ -1242,7 +1415,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
try {
String sql = "SELECT partition_type, expression, expression_schema FROM " + TB_PARTITION_METHODS +
- " WHERE " + COL_TABLES_NAME + "= ?";
+ " WHERE " + COL_TABLES_NAME + "= ?";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
@@ -1256,7 +1429,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
exist = res.next();
} catch (SQLException se) {
throw new CatalogException(se);
- } finally {
+ } finally {
CatalogUtil.closeQuietly(pstmt, res);
}
return exist;
@@ -1362,7 +1535,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
int tableId = getTableId(databaseId, databaseName, tableName);
String sql = "INSERT INTO " + TB_INDEXES +
- " (" + COL_DATABASES_PK + ", " + COL_TABLES_PK + ", INDEX_NAME, " +
+ " (" + COL_DATABASES_PK + ", " + COL_TABLES_PK + ", INDEX_NAME, " +
"COLUMN_NAME, DATA_TYPE, INDEX_TYPE, IS_UNIQUE, IS_CLUSTERED, IS_ASCENDING) VALUES (?,?,?,?,?,?,?,?,?)";
if (LOG.isDebugEnabled()) {
@@ -1422,7 +1595,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
try {
pstmt =
- conn.prepareStatement("SELECT " + COL_TABLES_NAME + " FROM " + TB_TABLES + " WHERE " + COL_TABLES_PK +"=?");
+ conn.prepareStatement("SELECT " + COL_TABLES_NAME + " FROM " + TB_TABLES + " WHERE " + COL_TABLES_PK + "=?");
pstmt.setInt(1, tableId);
res = pstmt.executeQuery();
if (!res.next()) {
@@ -1435,9 +1608,10 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
}
final static String GET_INDEXES_SQL =
- "SELECT " + COL_TABLES_PK + ", INDEX_NAME, COLUMN_NAME, DATA_TYPE, INDEX_TYPE, IS_UNIQUE, "+
+ "SELECT " + COL_TABLES_PK + ", INDEX_NAME, COLUMN_NAME, DATA_TYPE, INDEX_TYPE, IS_UNIQUE, " +
"IS_CLUSTERED, IS_ASCENDING FROM " + TB_INDEXES;
+
@Override
public IndexDescProto getIndexByName(String databaseName, final String indexName)
throws CatalogException {
@@ -1497,7 +1671,8 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
conn = getConnection();
pstmt = conn.prepareStatement(sql);
- pstmt.setInt(1, databaseId);;
+ pstmt.setInt(1, databaseId);
+ ;
pstmt.setString(2, columnName);
res = pstmt.executeQuery();
if (!res.next()) {
@@ -1625,7 +1800,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
}
private void resultToIndexDescProtoBuilder(IndexDescProto.Builder builder,
- final ResultSet res) throws SQLException {
+ final ResultSet res) throws SQLException {
builder.setIndexName(res.getString("index_name"));
builder.setColumn(indexResultToColumnProto(res));
builder.setIndexMethod(getIndexMethod(res.getString("index_type").trim()));
@@ -1653,7 +1828,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
Type type = getDataType(res.getString("data_type").trim());
int typeLength = res.getInt("type_length");
- if(typeLength > 0 ) {
+ if (typeLength > 0) {
builder.setDataType(CatalogUtil.newDataTypeWithLen(type, typeLength));
} else {
builder.setDataType(CatalogUtil.newSimpleDataType(type));
@@ -1696,7 +1871,7 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
return partBuilder.build();
}
- @Override
+
public void close() {
CatalogUtil.closeQuietly(conn);
LOG.info("Shutdown database (" + catalogUri + ")");
@@ -1722,4 +1897,34 @@ public abstract class AbstractDBStore extends CatalogConstants implements Catalo
// TODO - not implemented yet
return null;
}
+
+ private boolean existColumn(final int tableId, final String columnName) throws CatalogException {
+ Connection conn ;
+ PreparedStatement pstmt = null;
+ ResultSet res = null;
+ boolean exist = false;
+
+ try {
+
+ String sql = "SELECT COLUMN_NAME FROM " + TB_COLUMNS + " WHERE TID = ? AND COLUMN_NAME = ?";
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(sql.toString());
+ }
+
+ conn = getConnection();
+ pstmt = conn.prepareStatement(sql.toString());
+
+ pstmt.setInt(1, tableId);
+ pstmt.setString(2, columnName);
+ res = pstmt.executeQuery();
+ exist = res.next();
+ } catch (SQLException se) {
+ throw new CatalogException(se);
+ } finally {
+ CatalogUtil.closeQuietly(pstmt, res);
+ }
+
+ return exist;
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
index 3f8686d..e0c5a9d 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/CatalogStore.java
@@ -60,8 +60,9 @@ public interface CatalogStore extends Closeable {
List<String> getAllTableNames(String databaseName) throws CatalogException;
+ void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException;
- /************************ PARTITION METHOD **************************/
+ /************************ PARTITION METHOD **************************/
void addPartitionMethod(PartitionMethodProto partitionMethodProto) throws CatalogException;
PartitionMethodProto getPartitionMethod(String databaseName, String tableName)
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
index ef98ee2..ca29a6b 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/store/MemStore.java
@@ -23,6 +23,8 @@ package org.apache.tajo.catalog.store;
import com.google.common.collect.Maps;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.TajoConstants;
import org.apache.tajo.catalog.CatalogUtil;
import org.apache.tajo.catalog.FunctionDesc;
import org.apache.tajo.catalog.exception.*;
@@ -42,11 +44,11 @@ public class MemStore implements CatalogStore {
private final Map<String, CatalogProtos.FunctionDescProto> functions = Maps.newHashMap();
private final Map<String, Map<String, IndexDescProto>> indexes = Maps.newHashMap();
private final Map<String, Map<String, IndexDescProto>> indexesByColumn = Maps.newHashMap();
-
+
public MemStore(Configuration conf) {
}
- @Override
+
public void close() throws IOException {
databases.clear();
functions.clear();
@@ -157,6 +159,74 @@ public class MemStore implements CatalogStore {
}
/* (non-Javadoc)
+ * @see CatalogStore#alterTable(AlterTableDesc)
+ */
+ @Override
+ public void alterTable(CatalogProtos.AlterTableDescProto alterTableDescProto) throws CatalogException {
+
+ String[] split = CatalogUtil.splitTableName(alterTableDescProto.getTableName());
+ if (split.length == 1) {
+ throw new IllegalArgumentException("alterTable() requires a qualified table name, but it is \""
+ + alterTableDescProto.getTableName() + "\".");
+ }
+ String databaseName = split[0];
+ String tableName = split[1];
+
+ final Map<String, CatalogProtos.TableDescProto> database = checkAndGetDatabaseNS(databases, databaseName);
+
+ final CatalogProtos.TableDescProto tableDescProto = database.get(tableName);
+ CatalogProtos.TableDescProto newTableDescProto;
+ CatalogProtos.SchemaProto schemaProto;
+
+ switch (alterTableDescProto.getAlterTableType()) {
+ case RENAME_TABLE:
+ if (database.containsKey(alterTableDescProto.getNewTableName())) {
+ throw new AlreadyExistsTableException(alterTableDescProto.getNewTableName());
+ }
+ // Currently, we only use the default table space (i.e., WAREHOUSE directory).
+ String spaceUri = tablespaces.get(TajoConstants.DEFAULT_TABLESPACE_NAME);
+ // Create a new table directory.
+ String newPath = new Path(spaceUri, new Path(databaseName, alterTableDescProto.getNewTableName())).toString();
+ newTableDescProto = tableDescProto.toBuilder()
+ .setTableName(alterTableDescProto.getNewTableName())
+ .setPath(newPath).build();
+ database.remove(tableName);
+ database.put(alterTableDescProto.getNewTableName(), newTableDescProto);
+ break;
+ case RENAME_COLUMN:
+ schemaProto = tableDescProto.getSchema();
+ final int index = getIndexOfColumnToBeRenamed(schemaProto.getFieldsList(),
+ alterTableDescProto.getAlterColumnName().getOldColumnName());
+ final CatalogProtos.ColumnProto columnProto = schemaProto.getFields(index);
+ final CatalogProtos.ColumnProto newcolumnProto =
+ columnProto.toBuilder().setName(alterTableDescProto.getAlterColumnName().getNewColumnName()).build();
+ newTableDescProto = tableDescProto.toBuilder().setSchema(schemaProto.toBuilder().
+ setFields(index, newcolumnProto).build()).build();
+ database.put(tableName, newTableDescProto);
+ break;
+ case ADD_COLUMN:
+ schemaProto = tableDescProto.getSchema();
+ CatalogProtos.SchemaProto newSchemaProto =
+ schemaProto.toBuilder().addFields(alterTableDescProto.getAddColumn()).build();
+ newTableDescProto = tableDescProto.toBuilder().setSchema(newSchemaProto).build();
+ database.put(tableName, newTableDescProto);
+ break;
+ default:
+ //TODO
+ }
+ }
+
+ private int getIndexOfColumnToBeRenamed(List<CatalogProtos.ColumnProto> fieldList, String columnName) {
+ int fieldCount = fieldList.size();
+ for (int index = 0; index < fieldCount; index++) {
+ CatalogProtos.ColumnProto columnProto = fieldList.get(index);
+ if (null != columnProto && columnProto.getName().equalsIgnoreCase(columnName)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+ /* (non-Javadoc)
* @see CatalogStore#getTable(java.lang.String)
*/
@Override
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
index 36c6b6b..22ab552 100644
--- a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
+++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java
@@ -667,4 +667,53 @@ public class TestCatalog {
catalog.dropTable(tableName);
assertFalse(catalog.existsTable(tableName));
}
+
+ @Test
+ public void testAlterTableName () throws Exception {
+
+ //CREATE_TABLE
+ TableDesc tableRenameTestDesc = createMockupTable("default", "mycooltable") ;
+ catalog.createTable(tableRenameTestDesc);
+
+ //RENAME_TABLE
+ catalog.alterTable(createMockAlterTableName());
+ assertTrue(catalog.existsTable("default", "mynewcooltable"));
+
+ //RENAME_COLUMN
+ catalog.alterTable(createMockAlterTableRenameColumn());
+ TableDesc columnRenameDesc = catalog.getTableDesc("default","mynewcooltable");
+ assertTrue(columnRenameDesc.getSchema().containsByName("ren"+FieldName1));
+
+ //ADD_COLUMN
+ catalog.alterTable(createMockAlterTableAddColumn());
+ TableDesc addColumnDesc = catalog.getTableDesc("default","mynewcooltable");
+ assertTrue(addColumnDesc.getSchema().containsByName("mynewcol"));
+
+ }
+
+ private AlterTableDesc createMockAlterTableName(){
+ AlterTableDesc alterTableDesc = new AlterTableDesc();
+ alterTableDesc.setTableName("default.mycooltable");
+ alterTableDesc.setNewTableName("mynewcooltable");
+ alterTableDesc.setAlterTableType(AlterTableType.RENAME_TABLE);
+ return alterTableDesc;
+ }
+
+ private AlterTableDesc createMockAlterTableRenameColumn(){
+ AlterTableDesc alterTableDesc = new AlterTableDesc();
+ alterTableDesc.setTableName("default.mynewcooltable");
+ alterTableDesc.setColumnName(FieldName1);
+ alterTableDesc.setNewColumnName("ren" + FieldName1);
+ alterTableDesc.setAlterTableType(AlterTableType.RENAME_COLUMN);
+ return alterTableDesc;
+ }
+
+ private AlterTableDesc createMockAlterTableAddColumn(){
+ AlterTableDesc alterTableDesc = new AlterTableDesc();
+ alterTableDesc.setTableName("default.mynewcooltable");
+ alterTableDesc.setAddColumn(new Column("mynewcol", Type.TEXT));
+ alterTableDesc.setAlterTableType(AlterTableType.ADD_COLUMN);
+ return alterTableDesc;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
index 6eccd12..3b8f9cf 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4
@@ -121,6 +121,7 @@ ANY : A N Y;
ASYMMETRIC : A S Y M M E T R I C;
ASC : A S C;
+
BOTH : B O T H;
CASE : C A S E;
@@ -189,6 +190,8 @@ WITH : W I T H;
===============================================================================
*/
AVG : A V G;
+ADD: A D D;
+ALTER : A L T E R;
BETWEEN : B E T W E E N;
BY : B Y;
@@ -263,6 +266,7 @@ RANGE : R A N G E;
REGEXP : R E G E X P;
RLIKE : R L I K E;
ROLLUP : R O L L U P;
+RENAME : R E N A M E;
SECOND : S E C O N D;
SET : S E T;
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
index c0edf09..825969a 100644
--- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
+++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4
@@ -58,6 +58,7 @@ schema_statement
| drop_database_statement
| create_table_statement
| drop_table_statement
+ | alter_table_statement
;
index_statement
@@ -1059,6 +1060,10 @@ table_name
: identifier (DOT identifier ( DOT identifier)? )?
;
+column_name
+ : identifier
+ ;
+
query_specification
: SELECT set_qualifier? select_list table_expression?
;
@@ -1366,3 +1371,15 @@ insert_statement
: INSERT (OVERWRITE)? INTO table_name (LEFT_PAREN column_name_list RIGHT_PAREN)? query_expression
| INSERT (OVERWRITE)? INTO LOCATION path=Character_String_Literal (USING file_type=identifier (param_clause)?)? query_expression
;
+
+/*
+===============================================================================
+ <alter table>
+===============================================================================
+*/
+
+alter_table_statement
+ : ALTER TABLE table_name RENAME TO table_name
+ | ALTER TABLE table_name RENAME COLUMN column_name TO column_name
+ | ALTER TABLE table_name ADD COLUMN field_element
+ ;
http://git-wip-us.apache.org/repos/asf/tajo/blob/bd418a5c/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
index afd0ce9..c734583 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/HiveQLAnalyzer.java
@@ -1450,7 +1450,7 @@ public class HiveQLAnalyzer extends HiveQLParserBaseVisitor<Expr> {
if (ctx.columnNameTypeList() != null) {
List<HiveQLParser.ColumnNameTypeContext> list = ctx.columnNameTypeList().columnNameType();
- CreateTable.ColumnDefinition[] columns = new CreateTable.ColumnDefinition[list.size()];
+ ColumnDefinition[] columns = new ColumnDefinition[list.size()];
for (int i = 0; i < list.size(); i++) {
HiveQLParser.ColumnNameTypeContext eachColumn = list.get(i);
@@ -1459,7 +1459,7 @@ public class HiveQLAnalyzer extends HiveQLParserBaseVisitor<Expr> {
if (eachColumn.colType().type().primitiveType() != null) {
HiveQLParser.PrimitiveTypeContext primitiveType = eachColumn.colType().type().primitiveType();
type = getDataTypeExpr(primitiveType).getTypeName();
- columns[i] = new CreateTable.ColumnDefinition(eachColumn.colName.Identifier().getText(), type);
+ columns[i] = new ColumnDefinition(eachColumn.colName.Identifier().getText(), type);
}
}
}