tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From blrun...@apache.org
Subject [1/3] tajo git commit: TAJO-1493: Make partition pruning based on catalog informations.
Date Thu, 24 Sep 2015 08:57:05 GMT
Repository: tajo
Updated Branches:
  refs/heads/master 5af330d22 -> b5aacb917


http://git-wip-us.apache.org/repos/asf/tajo/blob/b5aacb91/tajo-plan/src/main/java/org/apache/tajo/plan/util/EvalNodeToExprConverter.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/util/EvalNodeToExprConverter.java
b/tajo-plan/src/main/java/org/apache/tajo/plan/util/EvalNodeToExprConverter.java
new file mode 100644
index 0000000..c656671
--- /dev/null
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/util/EvalNodeToExprConverter.java
@@ -0,0 +1,297 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.plan.util;
+
+import org.apache.tajo.algebra.*;
+import org.apache.tajo.datum.DateDatum;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.TimeDatum;
+import org.apache.tajo.datum.TimestampDatum;
+import org.apache.tajo.plan.expr.*;
+
+import java.util.Stack;
+
+/**
+ * This converts EvalNode tree to Expr tree.
+ *
+ */
+public class EvalNodeToExprConverter extends SimpleEvalNodeVisitor<Object> {
+  private Stack<Expr> exprs = new Stack<Expr>();
+
+  private String tableName;
+
+  public EvalNodeToExprConverter(String tableName) {
+    this.tableName = tableName;
+  }
+
+  public Expr getResult() {
+    return exprs.pop();
+  }
+
+  @Override
+  protected EvalNode visitBinaryEval(Object o, Stack<EvalNode> stack, BinaryEval binaryEval)
{
+    stack.push(binaryEval);
+    visit(o, binaryEval.getLeftExpr(), stack);
+    Expr left = exprs.pop();
+
+    visit(o, binaryEval.getRightExpr(), stack);
+    Expr right = exprs.pop();
+
+    Expr expr = null;
+    switch (binaryEval.getType()) {
+      // Arithmetic expression
+      case PLUS:
+        expr = new BinaryOperator(OpType.Plus, left, right);
+        break;
+      case MINUS:
+        expr = new BinaryOperator(OpType.Minus, left, right);
+        break;
+      case MULTIPLY:
+        expr = new BinaryOperator(OpType.Multiply, left, right);
+        break;
+      case DIVIDE:
+        expr = new BinaryOperator(OpType.Divide, left, right);
+        break;
+      case MODULAR:
+        expr = new BinaryOperator(OpType.Modular, left, right);
+        break;
+
+      // Logical Predicates
+      case AND:
+        expr = new BinaryOperator(OpType.And, left, right);
+        break;
+      case OR:
+        expr = new BinaryOperator(OpType.Or, left, right);
+        break;
+      case NOT:
+        expr = new BinaryOperator(OpType.Not, left, right);
+        break;
+
+      // Comparison Predicates
+      case EQUAL:
+        expr = new BinaryOperator(OpType.Equals, left, right);
+        break;
+      case NOT_EQUAL:
+        expr = new BinaryOperator(OpType.NotEquals, left, right);
+        break;
+      case LTH:
+        expr = new BinaryOperator(OpType.LessThan, left, right);
+        break;
+      case LEQ:
+        expr = new BinaryOperator(OpType.LessThanOrEquals, left, right);
+        break;
+      case GTH:
+        expr = new BinaryOperator(OpType.GreaterThan, left, right);
+        break;
+      case GEQ:
+        expr = new BinaryOperator(OpType.GreaterThanOrEquals, left, right);
+        break;
+
+      // SQL standard predicates
+      case IS_NULL:
+        expr = new BinaryOperator(OpType.IsNullPredicate, left, right);
+        break;
+      case CASE:
+        expr = new BinaryOperator(OpType.CaseWhen, left, right);
+        break;
+      case IN:
+        InEval inEval = (InEval) binaryEval;
+        expr = new InPredicate(left, right, inEval.isNot());
+        break;
+
+      // String operators and Pattern match predicates
+      case LIKE:
+        LikePredicateEval likePredicateEval = (LikePredicateEval) binaryEval;
+        expr = new PatternMatchPredicate(OpType.LikePredicate, likePredicateEval.isNot(),
left, right);
+        break;
+      case SIMILAR_TO:
+        SimilarToPredicateEval similarToPredicateEval = (SimilarToPredicateEval) binaryEval;
+        expr = new PatternMatchPredicate(OpType.SimilarToPredicate, similarToPredicateEval.isNot(),
left, right);
+        break;
+      case REGEX:
+        RegexPredicateEval regexPredicateEval = (RegexPredicateEval) binaryEval;
+        expr = new PatternMatchPredicate(OpType.Regexp, regexPredicateEval.isNot(), left,
right);
+        break;
+      case CONCATENATE:
+      default:
+        throw new RuntimeException("Unsupported type: " + binaryEval.getType().name());
+    }
+
+    if (expr != null) {
+      exprs.push(expr);
+    }
+
+    stack.pop();
+    return null;
+  }
+
+  @Override
+  protected EvalNode visitConst(Object o, ConstEval evalNode, Stack<EvalNode> stack)
{
+    Expr value = null;
+    DateValue dateValue;
+    TimeValue timeValue;
+
+    switch (evalNode.getValueType().getType()) {
+      case NULL_TYPE:
+        value = new NullLiteral();
+        break;
+      case BOOLEAN:
+        value = new LiteralValue(evalNode.getValue().asChars(), LiteralValue.LiteralType.Boolean);
+        break;
+      case INT1:
+      case INT2:
+      case INT4:
+        value = new LiteralValue(evalNode.getValue().asChars(), LiteralValue.LiteralType.Unsigned_Integer);
+        break;
+      case INT8:
+        value = new LiteralValue(evalNode.getValue().asChars(), LiteralValue.LiteralType.Unsigned_Large_Integer);
+        break;
+      case FLOAT4:
+      case FLOAT8:
+        value = new LiteralValue(evalNode.getValue().asChars(), LiteralValue.LiteralType.Unsigned_Float);
+        break;
+      case TEXT:
+        value = new LiteralValue(evalNode.getValue().asChars(), LiteralValue.LiteralType.String);
+        break;
+      case DATE:
+        DateDatum dateDatum = (DateDatum) evalNode.getValue();
+
+        dateValue = new DateValue(""+dateDatum.getYear(),
+          ""+dateDatum.getMonthOfYear(), ""+dateDatum.getDayOfMonth());
+        value = new DateLiteral(dateValue);
+
+        break;
+      case TIMESTAMP:
+        TimestampDatum timestampDatum = (TimestampDatum) evalNode.getValue();
+
+        dateValue = new DateValue(""+timestampDatum.getYear(),
+          ""+timestampDatum.getMonthOfYear(), ""+timestampDatum.getDayOfMonth());
+
+        timeValue = new TimeValue(""+timestampDatum.getHourOfDay()
+        , ""+timestampDatum.getMinuteOfHour(), ""+timestampDatum.getSecondOfMinute());
+
+        value = new TimestampLiteral(dateValue, timeValue);
+        break;
+      case TIME:
+        TimeDatum timeDatum = (TimeDatum) evalNode.getValue();
+        timeValue = new TimeValue(""+timeDatum.getHourOfDay()
+          , ""+timeDatum.getMinuteOfHour(), ""+timeDatum.getSecondOfMinute());
+
+        value = new TimeLiteral(timeValue);
+        break;
+      default:
+        throw new RuntimeException("Unsupported type: " + evalNode.getValueType().getType().name());
+    }
+    exprs.push(value);
+
+    return super.visitConst(o, evalNode, stack);
+  }
+
+  @Override
+  protected EvalNode visitRowConstant(Object o, RowConstantEval evalNode, Stack<EvalNode>
stack) {
+    Expr[] values = new Expr[evalNode.getValues().length];
+    for (int i = 0; i < evalNode.getValues().length; i++) {
+      Datum datum = evalNode.getValues()[i];
+      LiteralValue value;
+      switch (datum.type()) {
+        case BOOLEAN:
+          value = new LiteralValue(datum.asChars(), LiteralValue.LiteralType.Boolean);
+          break;
+        case TEXT:
+          value = new LiteralValue(datum.asChars(), LiteralValue.LiteralType.String);
+          break;
+        case INT1:
+        case INT2:
+        case INT4:
+          value = new LiteralValue(datum.asChars(), LiteralValue.LiteralType.Unsigned_Integer);
+          break;
+        case INT8:
+          value = new LiteralValue(datum.asChars(), LiteralValue.LiteralType.Unsigned_Large_Integer);
+          break;
+        case FLOAT4:
+        case FLOAT8:
+          value = new LiteralValue(datum.asChars(), LiteralValue.LiteralType.Unsigned_Float);
+          break;
+        default:
+          throw new RuntimeException("Unsupported type: " + datum.type().name());
+      }
+      values[i] = value;
+    }
+    ValueListExpr expr = new ValueListExpr(values);
+    exprs.push(expr);
+
+    return super.visitRowConstant(o, evalNode, stack);
+  }
+
+  @Override
+  protected EvalNode visitField(Object o, FieldEval evalNode, Stack<EvalNode> stack)
 {
+    ColumnReferenceExpr expr = new ColumnReferenceExpr(tableName, evalNode.getColumnName());
+    exprs.push(expr);
+    return super.visitField(o, evalNode, stack);
+  }
+
+  @Override
+  protected EvalNode visitBetween(Object o, BetweenPredicateEval evalNode, Stack<EvalNode>
stack) {
+    stack.push(evalNode);
+
+    visit(o, evalNode.getPredicand(), stack);
+    Expr predicand = exprs.pop();
+
+    visit(o, evalNode.getBegin(), stack);
+    Expr begin = exprs.pop();
+
+    visit(o, evalNode.getEnd(), stack);
+    Expr end = exprs.pop();
+
+    Expr expr = new BetweenPredicate(evalNode.isNot(), evalNode.isSymmetric(), predicand,
begin, end);
+    exprs.push(expr);
+
+    stack.pop();
+
+    return null;
+  }
+
+  @Override
+  protected EvalNode visitCaseWhen(Object o, CaseWhenEval evalNode, Stack<EvalNode>
stack) {
+    stack.push(evalNode);
+
+    CaseWhenPredicate caseWhenPredicate = new CaseWhenPredicate();
+
+    for (CaseWhenEval.IfThenEval ifThenEval : evalNode.getIfThenEvals()) {
+      visit(o, ifThenEval.getCondition(), stack);
+      Expr condition = exprs.pop();
+      visit(o, ifThenEval.getResult(), stack);
+      Expr result = exprs.pop();
+
+      caseWhenPredicate.addWhen(condition, result);
+    }
+
+    if (evalNode.hasElse()) {
+      visit(o, evalNode.getElse(), stack);
+      Expr elseResult = exprs.pop();
+      caseWhenPredicate.setElseResult(elseResult);
+    }
+
+    exprs.push(caseWhenPredicate);
+
+    stack.pop();
+
+    return null;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/b5aacb91/tajo-plan/src/main/java/org/apache/tajo/plan/util/PartitionFilterAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PartitionFilterAlgebraVisitor.java
b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PartitionFilterAlgebraVisitor.java
new file mode 100644
index 0000000..72fd939
--- /dev/null
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PartitionFilterAlgebraVisitor.java
@@ -0,0 +1,573 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tajo.plan.util;
+
+import org.apache.tajo.algebra.*;
+import org.apache.tajo.catalog.CatalogConstants;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.common.TajoDataTypes.*;
+import org.apache.tajo.datum.TimeDatum;
+import org.apache.tajo.exception.TajoException;
+import org.apache.tajo.exception.UnsupportedException;
+import org.apache.tajo.plan.ExprAnnotator;
+import org.apache.tajo.plan.visitor.SimpleAlgebraVisitor;
+import org.apache.tajo.util.Pair;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.util.datetime.DateTimeUtil;
+import org.apache.tajo.util.datetime.TimeMeta;
+
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Stack;
+import java.util.TimeZone;
+
+/**
+ *  This build SQL statements for getting partitions informs on CatalogStore with algebra
expressions.
+ *  This visitor assumes that all columns of algebra expressions are reserved for one table.
+ *
+ */
+public class PartitionFilterAlgebraVisitor extends SimpleAlgebraVisitor<Object, Expr>
{
+  private String tableAlias;
+  private Column column;
+  private boolean isHiveCatalog = false;
+
+  private Stack<String> queries = new Stack();
+  private List<Pair<Type, Object>> parameters = TUtil.newList();
+
+  public String getTableAlias() {
+    return tableAlias;
+  }
+
+  public void setTableAlias(String tableAlias) {
+    this.tableAlias = tableAlias;
+  }
+
+  public Column getColumn() {
+    return column;
+  }
+
+  public void setColumn(Column column) {
+    this.column = column;
+  }
+
+  public boolean isHiveCatalog() {
+    return isHiveCatalog;
+  }
+
+  public void setIsHiveCatalog(boolean isHiveCatalog) {
+    this.isHiveCatalog = isHiveCatalog;
+  }
+
+  public List<Pair<Type, Object>> getParameters() {
+    return parameters;
+  }
+
+  public void setParameters(List<Pair<Type, Object>> parameters) {
+    this.parameters = parameters;
+  }
+
+  public void clearParameters() {
+    this.parameters.clear();
+  }
+
+  public String getResult() {
+    return queries.pop();
+  }
+
+  @Override
+  public Expr visit(Object ctx, Stack<Expr> stack, Expr expr) throws TajoException
{
+    if (expr.getType() == OpType.LikePredicate) {
+      return visitLikePredicate(ctx, stack, (PatternMatchPredicate) expr);
+    } else if (expr.getType() == OpType.SimilarToPredicate) {
+      return visitSimilarToPredicate(ctx, stack, (PatternMatchPredicate) expr);
+    } else if (expr.getType() == OpType.Regexp) {
+      return visitRegexpPredicate(ctx, stack, (PatternMatchPredicate) expr);
+    }
+    return super.visit(ctx, stack, expr);
+  }
+
+  @Override
+  public Expr visitDateLiteral(Object ctx, Stack<Expr> stack, DateLiteral expr) throws
TajoException {
+    StringBuilder sb = new StringBuilder();
+
+    if (!isHiveCatalog) {
+      sb.append("?").append(" )");
+      parameters.add(new Pair(Type.DATE, Date.valueOf(expr.toString())));
+    } else {
+      sb.append("\"").append(expr.toString()).append("\"");
+    }
+    queries.push(sb.toString());
+    return expr;
+  }
+
+  @Override
+  public Expr visitTimestampLiteral(Object ctx, Stack<Expr> stack, TimestampLiteral
expr) throws TajoException {
+    StringBuilder sb = new StringBuilder();
+
+    if (!isHiveCatalog) {
+      DateValue dateValue = expr.getDate();
+      TimeValue timeValue = expr.getTime();
+
+      int [] dates = ExprAnnotator.dateToIntArray(dateValue.getYears(),
+        dateValue.getMonths(),
+        dateValue.getDays());
+      int [] times = ExprAnnotator.timeToIntArray(timeValue.getHours(),
+        timeValue.getMinutes(),
+        timeValue.getSeconds(),
+        timeValue.getSecondsFraction());
+
+      long julianTimestamp;
+      if (timeValue.hasSecondsFraction()) {
+        julianTimestamp = DateTimeUtil.toJulianTimestamp(dates[0], dates[1], dates[2], times[0],
times[1], times[2],
+          times[3] * 1000);
+      } else {
+        julianTimestamp = DateTimeUtil.toJulianTimestamp(dates[0], dates[1], dates[2], times[0],
times[1], times[2], 0);
+      }
+
+      TimeMeta tm = new TimeMeta();
+      DateTimeUtil.toJulianTimeMeta(julianTimestamp, tm);
+
+      TimeZone tz = TimeZone.getDefault();
+      DateTimeUtil.toUTCTimezone(tm, tz);
+
+      sb.append("?").append(" )");
+      Timestamp timestamp = new Timestamp(DateTimeUtil.julianTimeToJavaTime(DateTimeUtil.toJulianTimestamp(tm)));
+      parameters.add(new Pair(Type.TIMESTAMP, timestamp));
+    } else {
+      sb.append("\"").append(expr.toString()).append("\"");
+    }
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitTimeLiteral(Object ctx, Stack<Expr> stack, TimeLiteral expr) throws
TajoException {
+    StringBuilder sb = new StringBuilder();
+
+    if (!isHiveCatalog) {
+      TimeValue timeValue = expr.getTime();
+
+      int [] times = ExprAnnotator.timeToIntArray(timeValue.getHours(),
+        timeValue.getMinutes(),
+        timeValue.getSeconds(),
+        timeValue.getSecondsFraction());
+
+      long time;
+      if (timeValue.hasSecondsFraction()) {
+        time = DateTimeUtil.toTime(times[0], times[1], times[2], times[3] * 1000);
+      } else {
+        time = DateTimeUtil.toTime(times[0], times[1], times[2], 0);
+      }
+      TimeDatum timeDatum = new TimeDatum(time);
+      TimeMeta tm = timeDatum.asTimeMeta();
+
+      TimeZone tz = TimeZone.getDefault();
+      DateTimeUtil.toUTCTimezone(tm, tz);
+
+      sb.append("?").append(" )");
+      parameters.add(new Pair(Type.TIME, new Time(DateTimeUtil.toJavaTime(tm.hours, tm.minutes,
tm.secs, tm.fsecs))));
+    } else {
+      sb.append("\"").append(expr.toString()).append("\"");
+    }
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitLiteral(Object ctx, Stack<Expr> stack, LiteralValue expr) throws
TajoException {
+    StringBuilder sb = new StringBuilder();
+
+    if (!isHiveCatalog) {
+      sb.append("?").append(" )");
+      switch (expr.getValueType()) {
+        case Boolean:
+          parameters.add(new Pair(Type.BOOLEAN, Boolean.valueOf(expr.getValue())));
+          break;
+        case Unsigned_Float:
+          parameters.add(new Pair(Type.FLOAT8, Double.valueOf(expr.getValue())));
+          break;
+        case String:
+          parameters.add(new Pair(Type.TEXT, expr.getValue()));
+          break;
+        default:
+          parameters.add(new Pair(Type.INT8, Long.valueOf(expr.getValue())));
+          break;
+      }
+    } else {
+      switch (expr.getValueType()) {
+        case String:
+          sb.append("\"").append(expr.getValue()).append("\"");
+          break;
+        default:
+          sb.append(expr.getValue());
+          break;
+      }
+    }
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitValueListExpr(Object ctx, Stack<Expr> stack, ValueListExpr expr)
throws TajoException {
+    StringBuilder sb = new StringBuilder();
+
+    if (!isHiveCatalog) {
+      sb.append("(");
+      for(int i = 0; i < expr.getValues().length; i++) {
+        if (i > 0) {
+          sb.append(", ");
+        }
+        sb.append("?");
+        stack.push(expr.getValues()[i]);
+        visit(ctx, stack, expr.getValues()[i]);
+        stack.pop();
+      }
+      sb.append(")");
+      sb.append(" )");
+      queries.push(sb.toString());
+    } else {
+      throw new UnsupportedException("IN Operator");
+    }
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitColumnReference(Object ctx, Stack<Expr> stack, ColumnReferenceExpr
expr) throws TajoException {
+    StringBuilder sb = new StringBuilder();
+
+    if (!isHiveCatalog) {
+      sb.append("( ").append(tableAlias).append(".").append(CatalogConstants.COL_COLUMN_NAME)
+        .append(" = '").append(expr.getName()).append("'")
+        .append(" AND ").append(tableAlias).append(".").append(CatalogConstants.COL_PARTITION_VALUE);
+    } else {
+      sb.append(expr.getName());
+    }
+    queries.push(sb.toString());
+    return expr;
+  }
+
+
+  @Override
+  public Expr visitUnaryOperator(Object ctx, Stack<Expr> stack, UnaryOperator expr)
throws TajoException {
+    stack.push(expr);
+    Expr child = visit(ctx, stack, expr.getChild());
+    stack.pop();
+
+    if (child.getType() == OpType.Literal) {
+      return new NullLiteral();
+    }
+
+    String childSql = queries.pop();
+
+    StringBuilder sb = new StringBuilder();
+    if (expr.getType() == OpType.IsNullPredicate) {
+      IsNullPredicate isNullPredicate = (IsNullPredicate) expr;
+      sb.append(childSql);
+      sb.append(" IS ");
+      if (isNullPredicate.isNot()) {
+        sb.append("NOT NULL");
+      } else {
+        sb.append("NULL");
+      }
+    }
+
+    if (!isHiveCatalog) {
+      sb.append(" )");
+    }
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitBetween(Object ctx, Stack<Expr> stack, BetweenPredicate expr) throws
TajoException {
+    stack.push(expr);
+
+    visit(ctx, stack, expr.predicand());
+    String predicandSql = queries.pop();
+
+    visit(ctx, stack, expr.begin());
+    String beginSql= queries.pop();
+    if (!isHiveCatalog && beginSql.endsWith(")")) {
+      beginSql = beginSql.substring(0, beginSql.length()-1);
+    }
+
+    visit(ctx, stack, expr.end());
+    String endSql = queries.pop();
+    if (!isHiveCatalog && endSql.endsWith(")")) {
+      endSql = beginSql.substring(0, endSql.length()-1);
+    }
+
+    StringBuilder sb = new StringBuilder();
+    sb.append(predicandSql);
+    sb.append(" BETWEEN ");
+    sb.append(beginSql);
+    sb.append(" AND ");
+    sb.append(endSql);
+
+    if (!isHiveCatalog) {
+      sb.append(")");
+    }
+
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitCaseWhen(Object ctx, Stack<Expr> stack, CaseWhenPredicate expr)
throws TajoException {
+    stack.push(expr);
+
+    StringBuilder sb = new StringBuilder();
+    sb.append("CASE ");
+
+    String condition, result;
+
+    for (CaseWhenPredicate.WhenExpr when : expr.getWhens()) {
+      visit(ctx, stack, when.getCondition());
+      condition = queries.pop();
+      visit(ctx, stack, when.getResult());
+      result = queries.pop();
+
+      String whenSql = condition + " " + result;
+      if (!isHiveCatalog && whenSql.endsWith(")")) {
+        whenSql = whenSql.substring(0, whenSql.length()-1);
+      }
+
+      sb.append(whenSql).append(" ");
+    }
+
+    if (expr.hasElseResult()) {
+      visit(ctx, stack, expr.getElseResult());
+      String elseSql = queries.pop();
+      if (!isHiveCatalog && elseSql.endsWith(")")) {
+        elseSql = elseSql.substring(0, elseSql.length()-1);
+      }
+
+      sb.append("ELSE ").append(elseSql).append(" END");
+    }
+
+    if (!isHiveCatalog) {
+      sb.append(")");
+    }
+
+    queries.push(sb.toString());
+
+    stack.pop();
+    return expr;
+  }
+
+  @Override
+  public Expr visitBinaryOperator(Object ctx, Stack<Expr> stack, BinaryOperator expr)
throws TajoException {
+    stack.push(expr);
+    Expr lhs = visit(ctx, stack, expr.getLeft());
+    String leftSql = queries.pop();
+    Expr rhs = visit(ctx, stack, expr.getRight());
+    String rightSql = queries.pop();
+    stack.pop();
+
+    if (!expr.getLeft().equals(lhs)) {
+      expr.setLeft(lhs);
+    }
+    if (!expr.getRight().equals(rhs)) {
+      expr.setRight(rhs);
+    }
+
+    if (lhs.getType() == OpType.Literal && rhs.getType() == OpType.Literal) {
+      return new NullLiteral();
+    }
+
+    StringBuilder sb = new StringBuilder();
+    sb.append(leftSql);
+    sb.append(" ").append(getOperator(expr.getType())).append(" ");
+    sb.append(rightSql);
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  private String getOperator(OpType type) {
+    String operator;
+    switch (type) {
+      case Not:
+        operator = "!";
+        break;
+      case And:
+        operator = "AND";
+        break;
+      case Or:
+        operator = "OR";
+        break;
+      case Equals:
+        operator = "=";
+        break;
+      case IsNullPredicate:
+        operator = "IS NULL";
+        break;
+      case NotEquals:
+        operator = "<>";
+        break;
+      case LessThan:
+        operator = "<";
+        break;
+      case LessThanOrEquals:
+        operator = "<=";
+        break;
+      case GreaterThan:
+        operator = ">";
+        break;
+      case GreaterThanOrEquals:
+        operator = ">=";
+        break;
+      case Plus:
+        operator = "+";
+        break;
+      case Minus:
+        operator = "-";
+        break;
+      case Modular:
+        operator = "%";
+        break;
+      case Multiply:
+        operator = "*";
+        break;
+      case Divide:
+        operator = "/";
+        break;
+      case LikePredicate:
+        operator = "LIKE";
+        break;
+      case SimilarToPredicate:
+        operator = "([.])";
+        break;
+      case InPredicate:
+        operator = "IN";
+        break;
+      case Asterisk:
+        operator = "*";
+        break;
+      //TODO: need to check more types.
+      default:
+        operator = type.name();
+        break;
+    }
+
+    return operator;
+  }
+
+  @Override
+  public Expr visitLikePredicate(Object ctx, Stack<Expr> stack, PatternMatchPredicate
expr) throws TajoException {
+    stack.push(expr);
+
+    visit(ctx, stack, expr.getPredicand());
+    String predicand = queries.pop();
+    visit(ctx, stack, expr.getPattern());
+    String pattern = queries.pop();
+    stack.pop();
+
+    if(isHiveCatalog) {
+      if (pattern.startsWith("%") || pattern.endsWith("%")) {
+        throw new UnsupportedException("LIKE Operator with '%'");
+      }
+    }
+    StringBuilder sb = new StringBuilder();
+    sb.append(predicand);
+
+    if (expr.isNot()) {
+      sb.append(" NOT ");
+    }
+
+    if (expr.isCaseInsensitive()) {
+      sb.append(" ILIKE ");
+    } else {
+      sb.append(" LIKE ");
+    }
+
+
+    sb.append(pattern);
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitSimilarToPredicate(Object ctx, Stack<Expr> stack, PatternMatchPredicate
expr) throws TajoException {
+    if (isHiveCatalog) {
+      throw new UnsupportedException("SIMILAR TO Operator");
+    }
+
+    stack.push(expr);
+
+    visit(ctx, stack, expr.getPredicand());
+    String predicand = queries.pop();
+    visit(ctx, stack, expr.getPattern());
+    String pattern = queries.pop();
+    stack.pop();
+
+    StringBuilder sb = new StringBuilder();
+    sb.append(predicand);
+
+    if (expr.isNot()) {
+      sb.append(" NOT ");
+    }
+
+    sb.append(" SIMILAR TO ");
+
+    sb.append(pattern);
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+  @Override
+  public Expr visitRegexpPredicate(Object ctx, Stack<Expr> stack, PatternMatchPredicate
expr) throws TajoException {
+    if (isHiveCatalog) {
+      throw new UnsupportedException("REGEXP Operator");
+    }
+
+    stack.push(expr);
+
+    visit(ctx, stack, expr.getPredicand());
+    String predicand = queries.pop();
+    visit(ctx, stack, expr.getPattern());
+    String pattern = queries.pop();
+    stack.pop();
+
+    StringBuilder sb = new StringBuilder();
+    sb.append(predicand);
+
+    if (expr.isNot()) {
+      sb.append(" NOT ");
+    }
+    sb.append(" REGEXP ");
+
+    sb.append(pattern);
+    queries.push(sb.toString());
+
+    return expr;
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/b5aacb91/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/FileTablespace.java
----------------------------------------------------------------------
diff --git a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/FileTablespace.java
b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/FileTablespace.java
index 6ba2029..1af94aa 100644
--- a/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/FileTablespace.java
+++ b/tajo-storage/tajo-storage-hdfs/src/main/java/org/apache/tajo/storage/FileTablespace.java
@@ -343,9 +343,9 @@ public class FileTablespace extends Tablespace {
 
       FileStatus[] matches = fs.globStatus(p, inputFilter);
       if (matches == null) {
-        errors.add(new IOException("Input path does not exist: " + p));
+        LOG.warn("Input path does not exist: " + p);
       } else if (matches.length == 0) {
-        errors.add(new IOException("Input Pattern " + p + " matches 0 files"));
+        LOG.warn("Input Pattern " + p + " matches 0 files");
       } else {
         for (FileStatus globStat : matches) {
           if (globStat.isDirectory()) {


Mime
View raw message