Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/tajo into hbase_storage

Conflicts:
	tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java
diff --git a/CHANGES b/CHANGES
index c4c7435..f0efc1e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -92,8 +92,11 @@
 
   BUG FIXES
 
-    TAJO-1194: 'INSERT OVERWRITE .. SELECT' does not remove existing data when result is empty.
-    (jaehwa)
+    TAJO-1231: Implicit table properties in session are not stored in 
+    table property. (hyunsik)
+
+    TAJO-1194: 'INSERT OVERWRITE .. SELECT' does not remove existing data 
+    when result is empty. (jaehwa)
 
     TAJO-1191: Change DateDatum timezone to UTC. (Jaewoong Jung via hyunsik)
 
diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
index 616799f..21dd7d5 100644
--- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
+++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
@@ -680,7 +680,7 @@
   }
 
   @Test
-  public void testSetCvsNull() throws Exception {
+  public void testNullCharSession() throws Exception {
     String sql =
         "select\n" +
             "  c_custkey,\n" +
@@ -692,17 +692,44 @@
             "  c_custkey,\n" +
             "  orders.o_orderkey;\n";
 
-    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+    Map<String, String> variables = new HashMap<String, String>();
+    variables.put(SessionVars.NULL_CHAR.keyname(), "\\\\T");
+    client.updateSessionVariables(variables);
+    TajoResultSet resultDesc = (TajoResultSet)client.executeQueryAndGetResult(sql);
+    resultDesc.close();
+    assertNullCharSessionVar(resultDesc.getTableDesc());
+  }
+
+  @Test
+  public void testNullCharSessionInCTAS() throws Exception {
+    String sql =
+        "create table nullcharsession as select\n" +
+            "  c_custkey,\n" +
+            "  orders.o_orderkey,\n" +
+            "  orders.o_orderstatus \n" +
+            "from\n" +
+            "  orders full outer join customer on c_custkey = o_orderkey\n" +
+            "order by\n" +
+            "  c_custkey,\n" +
+            "  orders.o_orderkey;\n";
 
     Map<String, String> variables = new HashMap<String, String>();
     variables.put(SessionVars.NULL_CHAR.keyname(), "\\\\T");
     client.updateSessionVariables(variables);
-
     TajoResultSet res = (TajoResultSet)client.executeQueryAndGetResult(sql);
+    res.close();
 
-    assertEquals(res.getTableDesc().getMeta().getOption(StorageConstants.TEXT_NULL), "\\\\T");
+    TableDesc resultDesc = client.getTableDesc("nullcharsession");
+    assertNullCharSessionVar(resultDesc);
+  }
 
-    Path path = new Path(res.getTableDesc().getPath());
+
+  public void assertNullCharSessionVar(TableDesc resultDesc) throws Exception {
+    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
+
+    assertEquals(resultDesc.getMeta().getOption(StorageConstants.TEXT_NULL), "\\\\T");
+
+    Path path = new Path(resultDesc.getPath());
     FileSystem fs = path.getFileSystem(tajoConf);
 
     FileStatus[] files = fs.listStatus(path);
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java
index e40eced..c054fd1 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestIntervalType.java
@@ -26,92 +26,92 @@
 import static org.junit.Assert.fail;
 
 public class TestIntervalType extends ExprTestBase {
-//  @Test
-//  public void testIntervalPostgresqlCase() throws IOException {
-//
-//    // http://www.postgresql.org/docs/8.2/static/functions-datetime.html
-//    testSimpleEval("select date '2001-09-28' + 7", new String[]{"2001-10-05"});
-//    testSimpleEval("select date '2001-09-28' + interval '1 hour'",
-//        new String[]{"2001-09-28 01:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select date '2001-09-28' + time '03:00'",
-//        new String[]{"2001-09-28 03:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select time '03:00' + date '2001-09-28'",
-//        new String[]{"2001-09-28 03:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select interval '1 day' + interval '1 hour'", new String[]{"1 day 01:00:00"});
-//
-//    testSimpleEval("select timestamp '2001-09-28 01:00' + interval '23 hours'",
-//        new String[]{"2001-09-29 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select time '01:00' + interval '3 hours'", new String[]{"04:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select date '2001-10-01' - date '2001-09-28'", new String[]{"3"});
-//    testSimpleEval("select date '2001-10-01' - 7", new String[]{"2001-09-24"});
-//    testSimpleEval("select date '2001-09-28' - interval '1 hour'",
-//        new String[]{"2001-09-27 23:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select time '05:00' - time '03:00'", new String[]{"02:00:00"});
-//    testSimpleEval("select time '05:00' - interval '2 hours'", new String[]{"03:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select timestamp '2001-09-28 23:00' - interval '23 hours'",
-//        new String[]{"2001-09-28 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select interval '1 day' - interval '1 hour'", new String[]{"23:00:00"});
-//
-//    testSimpleEval("select timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'", new String[]{"1 day 15:00:00"});
-//    testSimpleEval("select 900 * interval '1 second'", new String[]{"00:15:00"});
-//    testSimpleEval("select 21 * interval '1 day'", new String[]{"21 days"});
-//    testSimpleEval("select 3.5 * interval '1 hour'", new String[]{"03:30:00"});
-//    testSimpleEval("select interval '1 hour' / 1.5", new String[]{"00:40:00"});
-//  }
-//
-//  @Test
-//  public void testCaseByCase() throws Exception {
-//    testSimpleEval("select date '2001-08-28' + interval '10 day 1 hour'",
-//        new String[]{"2001-09-07 01:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select interval '10 day 01:00:00' + date '2001-08-28'",
-//        new String[]{"2001-09-07 01:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select time '10:20:30' + interval '1 day 01:00:00'",
-//        new String[]{"11:20:30" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select interval '1 day 01:00:00' + time '10:20:30'",
-//        new String[]{"11:20:30" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select time '10:20:30' - interval '1 day 01:00:00'",
-//        new String[]{"09:20:30" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select (interval '1 month 20 day' + interval '50 day')", new String[]{"1 month 70 days"});
-//    testSimpleEval("select date '2013-01-01' + interval '1 month 70 day'",
-//        new String[]{"2013-04-12 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select date '2013-01-01' + (interval '1 month 20 day' + interval '50 day')",
-//        new String[]{"2013-04-12 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select interval '1 month 70 day' + date '2013-01-01'",
-//        new String[]{"2013-04-12 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select date '2013-01-01' - interval '1 month 70 day'",
-//        new String[]{"2012-09-22 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select timestamp '2001-09-28 23:00' - interval '1 month 2 day 10:20:30'",
-//        new String[]{"2001-08-26 12:39:30" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select timestamp '2001-09-28 23:00' + interval '1 month 2 day 10:20:30'",
-//        new String[]{"2001-10-31 09:20:30" + getUserTimeZoneDisplay()});
-//    testSimpleEval("select interval '1 month 2 day 10:20:30' + timestamp '2001-09-28 23:00'",
-//        new String[]{"2001-10-31 09:20:30" + getUserTimeZoneDisplay()});
-//
-//
-//    testSimpleEval("select interval '5 month' / 3", new String[]{"1 month 20 days"});
-//
-//    // Notice: Different from postgresql result(13 days 01:02:36.4992) because of double type precision.
-//    testSimpleEval("select interval '1 month' / 2.3", new String[]{"13 days 01:02:36.522"});
-//
-//    testSimpleEval("select interval '1 month' * 2.3", new String[]{"2 months 9 days"});
-//    testSimpleEval("select interval '3 year 5 month 1 hour' / 1.5", new String[]{"2 years 3 months 10 days 00:40:00"});
-//
-//    testSimpleEval("select date '2001-09-28' - time '03:00'",
-//        new String[]{"2001-09-27 21:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select date '2014-03-20' + interval '1 day'",
-//        new String[]{"2014-03-21 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("select date '2014-03-20' - interval '1 day'",
-//        new String[]{"2014-03-19 00:00:00" + getUserTimeZoneDisplay()});
-//  }
+  @Test
+  public void testIntervalPostgresqlCase() throws IOException {
+
+    // http://www.postgresql.org/docs/8.2/static/functions-datetime.html
+    testSimpleEval("select date '2001-09-28' + 7", new String[]{"2001-10-05"});
+    testSimpleEval("select date '2001-09-28' + interval '1 hour'",
+        new String[]{"2001-09-28 01:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select date '2001-09-28' + time '03:00'",
+        new String[]{"2001-09-28 03:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select time '03:00' + date '2001-09-28'",
+        new String[]{"2001-09-28 03:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select interval '1 day' + interval '1 hour'", new String[]{"1 day 01:00:00"});
+
+    testSimpleEval("select timestamp '2001-09-28 01:00' + interval '23 hours'",
+        new String[]{"2001-09-29 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select time '01:00' + interval '3 hours'", new String[]{"04:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select date '2001-10-01' - date '2001-09-28'", new String[]{"3"});
+    testSimpleEval("select date '2001-10-01' - 7", new String[]{"2001-09-24"});
+    testSimpleEval("select date '2001-09-28' - interval '1 hour'",
+        new String[]{"2001-09-27 23:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select time '05:00' - time '03:00'", new String[]{"02:00:00"});
+    testSimpleEval("select time '05:00' - interval '2 hours'", new String[]{"03:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select timestamp '2001-09-28 23:00' - interval '23 hours'",
+        new String[]{"2001-09-28 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select interval '1 day' - interval '1 hour'", new String[]{"23:00:00"});
+
+    testSimpleEval("select timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'", new String[]{"1 day 15:00:00"});
+    testSimpleEval("select 900 * interval '1 second'", new String[]{"00:15:00"});
+    testSimpleEval("select 21 * interval '1 day'", new String[]{"21 days"});
+    testSimpleEval("select 3.5 * interval '1 hour'", new String[]{"03:30:00"});
+    testSimpleEval("select interval '1 hour' / 1.5", new String[]{"00:40:00"});
+  }
+
+  @Test
+  public void testCaseByCase() throws Exception {
+    testSimpleEval("select date '2001-08-28' + interval '10 day 1 hour'",
+        new String[]{"2001-09-07 01:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select interval '10 day 01:00:00' + date '2001-08-28'",
+        new String[]{"2001-09-07 01:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select time '10:20:30' + interval '1 day 01:00:00'",
+        new String[]{"11:20:30" + getUserTimeZoneDisplay()});
+    testSimpleEval("select interval '1 day 01:00:00' + time '10:20:30'",
+        new String[]{"11:20:30" + getUserTimeZoneDisplay()});
+    testSimpleEval("select time '10:20:30' - interval '1 day 01:00:00'",
+        new String[]{"09:20:30" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select (interval '1 month 20 day' + interval '50 day')", new String[]{"1 month 70 days"});
+    testSimpleEval("select date '2013-01-01' + interval '1 month 70 day'",
+        new String[]{"2013-04-12 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select date '2013-01-01' + (interval '1 month 20 day' + interval '50 day')",
+        new String[]{"2013-04-12 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select interval '1 month 70 day' + date '2013-01-01'",
+        new String[]{"2013-04-12 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("select date '2013-01-01' - interval '1 month 70 day'",
+        new String[]{"2012-09-22 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select timestamp '2001-09-28 23:00' - interval '1 month 2 day 10:20:30'",
+        new String[]{"2001-08-26 12:39:30" + getUserTimeZoneDisplay()});
+    testSimpleEval("select timestamp '2001-09-28 23:00' + interval '1 month 2 day 10:20:30'",
+        new String[]{"2001-10-31 09:20:30" + getUserTimeZoneDisplay()});
+    testSimpleEval("select interval '1 month 2 day 10:20:30' + timestamp '2001-09-28 23:00'",
+        new String[]{"2001-10-31 09:20:30" + getUserTimeZoneDisplay()});
+
+
+    testSimpleEval("select interval '5 month' / 3", new String[]{"1 month 20 days"});
+
+    // Notice: Different from postgresql result(13 days 01:02:36.4992) because of double type precision.
+    testSimpleEval("select interval '1 month' / 2.3", new String[]{"13 days 01:02:36.522"});
+
+    testSimpleEval("select interval '1 month' * 2.3", new String[]{"2 months 9 days"});
+    testSimpleEval("select interval '3 year 5 month 1 hour' / 1.5", new String[]{"2 years 3 months 10 days 00:40:00"});
+
+    testSimpleEval("select date '2001-09-28' - time '03:00'",
+        new String[]{"2001-09-27 21:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select date '2014-03-20' + interval '1 day'",
+        new String[]{"2014-03-21 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("select date '2014-03-20' - interval '1 day'",
+        new String[]{"2014-03-19 00:00:00" + getUserTimeZoneDisplay()});
+  }
 
   @Test
   public void testWrongFormatLiteral() throws Exception {
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java
index c48b4d8..7cca13d 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestDateTimeFunctions.java
@@ -314,98 +314,98 @@
      testSimpleEval("select utc_usec_to('week' ,1207929480000000, 2);", new String[]{1207612800000000L+""});
   }
 
-//  @Test
-//  public void testToDate() throws IOException {
-//    testSimpleEval("select to_date('2014-01-04', 'YYYY-MM-DD')", new String[]{"2014-01-04"});
-//    testSimpleEval("select to_date('2014-01-04', 'YYYY-MM-DD') + interval '1 day'",
-//        new String[]{"2014-01-05 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT to_date('201404', 'yyyymm');", new String[]{"2014-04-01"});
-//  }
+  @Test
+  public void testToDate() throws IOException {
+    testSimpleEval("select to_date('2014-01-04', 'YYYY-MM-DD')", new String[]{"2014-01-04"});
+    testSimpleEval("select to_date('2014-01-04', 'YYYY-MM-DD') + interval '1 day'",
+        new String[]{"2014-01-05 00:00:00" + getUserTimeZoneDisplay()});
 
-//  @Test
-//  public void testAddMonths() throws Exception {
-//    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT2);",
-//        new String[]{"2014-02-17 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT4);",
-//        new String[]{"2014-02-17 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT8);",
-//        new String[]{"2014-02-17 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT2);",
-//        new String[]{"2014-02-17 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT4);",
-//        new String[]{"2014-02-17 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT8);",
-//        new String[]{"2014-02-17 12:10:20" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT2);",
-//        new String[]{"2013-11-05 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT4);",
-//        new String[]{"2013-11-05 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT8);",
-//        new String[]{"2013-11-05 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT2);",
-//        new String[]{"2013-11-05 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT4);",
-//        new String[]{"2013-11-05 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT8);",
-//        new String[]{"2013-11-05 12:10:20" + getUserTimeZoneDisplay()});
-//  }
+    testSimpleEval("SELECT to_date('201404', 'yyyymm');", new String[]{"2014-04-01"});
+  }
 
-//  @Test
-//  public void testAddDays() throws IOException {
-//    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT2);",
-//        new String[]{"2014-01-04 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT4);",
-//        new String[]{"2014-01-04 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT8);",
-//        new String[]{"2014-01-04 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT2);",
-//        new String[]{"2014-01-04 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT4);",
-//        new String[]{"2014-01-04 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT8);",
-//        new String[]{"2014-01-04 12:10:20" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT2);",
-//        new String[]{"2013-11-28 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT4);",
-//        new String[]{"2013-11-28 00:00:00" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT8);",
-//        new String[]{"2013-11-28 00:00:00" + getUserTimeZoneDisplay()});
-//
-//    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT2);",
-//        new String[]{"2013-11-28 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT4);",
-//        new String[]{"2013-11-28 12:10:20" + getUserTimeZoneDisplay()});
-//    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT8);",
-//        new String[]{"2013-11-28 12:10:20" + getUserTimeZoneDisplay()});
-//  }
-//
-//  @Test
-//  public void testDateTimeNow() throws IOException {
-//    TimeZone originTimeZone = TajoConf.setCurrentTimeZone(TimeZone.getTimeZone("GMT-6"));
-//    TimeZone systemOriginTimeZone = TimeZone.getDefault();
-//    TimeZone.setDefault(TimeZone.getTimeZone("GMT-6"));
-//    try {
-//      Date expectedDate = new Date(System.currentTimeMillis());
-//
-//      testSimpleEval("select to_char(now(), 'yyyy-MM-dd');",
-//          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
-//      testSimpleEval("select cast(extract(year from now()) as INT4);",
-//          new String[]{dateFormat(expectedDate, "yyyy")});
-//      testSimpleEval("select current_date();",
-//          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
-//      testSimpleEval("select cast(extract(hour from current_time()) as INT4);",
-//          new String[]{String.valueOf(Integer.parseInt(dateFormat(expectedDate, "HH")))});
-//    } finally {
-//      TajoConf.setCurrentTimeZone(originTimeZone);
-//      TimeZone.setDefault(systemOriginTimeZone);
-//    }
-//  }
+  @Test
+  public void testAddMonths() throws Exception {
+    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT2);",
+        new String[]{"2014-02-17 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT4);",
+        new String[]{"2014-02-17 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(date '2013-12-17', 2::INT8);",
+        new String[]{"2014-02-17 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT2);",
+        new String[]{"2014-02-17 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT4);",
+        new String[]{"2014-02-17 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(timestamp '2013-12-17 12:10:20', 2::INT8);",
+        new String[]{"2014-02-17 12:10:20" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT2);",
+        new String[]{"2013-11-05 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT4);",
+        new String[]{"2013-11-05 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(date '2014-02-05', -3::INT8);",
+        new String[]{"2013-11-05 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT2);",
+        new String[]{"2013-11-05 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT4);",
+        new String[]{"2013-11-05 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_months(timestamp '2014-02-05 12:10:20', -3::INT8);",
+        new String[]{"2013-11-05 12:10:20" + getUserTimeZoneDisplay()});
+  }
+
+  @Test
+  public void testAddDays() throws IOException {
+    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT2);",
+        new String[]{"2014-01-04 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT4);",
+        new String[]{"2014-01-04 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(date '2013-12-30', 5::INT8);",
+        new String[]{"2014-01-04 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT2);",
+        new String[]{"2014-01-04 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT4);",
+        new String[]{"2014-01-04 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-30 12:10:20', 5::INT8);",
+        new String[]{"2014-01-04 12:10:20" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT2);",
+        new String[]{"2013-11-28 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT4);",
+        new String[]{"2013-11-28 00:00:00" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(date '2013-12-05', -7::INT8);",
+        new String[]{"2013-11-28 00:00:00" + getUserTimeZoneDisplay()});
+
+    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT2);",
+        new String[]{"2013-11-28 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT4);",
+        new String[]{"2013-11-28 12:10:20" + getUserTimeZoneDisplay()});
+    testSimpleEval("SELECT add_days(timestamp '2013-12-05 12:10:20', -7::INT8);",
+        new String[]{"2013-11-28 12:10:20" + getUserTimeZoneDisplay()});
+  }
+
+  @Test
+  public void testDateTimeNow() throws IOException {
+    TimeZone originTimeZone = TajoConf.setCurrentTimeZone(TimeZone.getTimeZone("GMT-6"));
+    TimeZone systemOriginTimeZone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("GMT-6"));
+    try {
+      Date expectedDate = new Date(System.currentTimeMillis());
+
+      testSimpleEval("select to_char(now(), 'yyyy-MM-dd');",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+      testSimpleEval("select cast(extract(year from now()) as INT4);",
+          new String[]{dateFormat(expectedDate, "yyyy")});
+      testSimpleEval("select current_date();",
+          new String[]{dateFormat(expectedDate, "yyyy-MM-dd")});
+      testSimpleEval("select cast(extract(hour from current_time()) as INT4);",
+          new String[]{String.valueOf(Integer.parseInt(dateFormat(expectedDate, "HH")))});
+    } finally {
+      TajoConf.setCurrentTimeZone(originTimeZone);
+      TimeZone.setDefault(systemOriginTimeZone);
+    }
+  }
 
   @Test
   public void testTimeValueKeyword() throws IOException {
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
index 3b1b4e3..69c0e4b 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
@@ -1706,13 +1706,25 @@
       createTableNode.setStorageType(CatalogProtos.StoreType.CSV);
     }
 
-    // Set default storage properties to be created.
-    KeyValueSet keyValueSet = CatalogUtil.newPhysicalProperties(createTableNode.getStorageType());
+
+
+    // Set default storage properties to table
+    KeyValueSet properties = CatalogUtil.newPhysicalProperties(createTableNode.getStorageType());
+
+    // Priority to apply table properties
+    // 1. Explicit table properties specified in WITH clause
+    // 2. Session variables
+
+    // Set session variables to properties
+    PlannerUtil.applySessionToTableProperties(context.queryContext, createTableNode.getStorageType(), properties);
+    // Set table properties specified in WITH clause
     if (expr.hasParams()) {
-      keyValueSet.putAll(expr.getParams());
+      properties.putAll(expr.getParams());
     }
 
-    createTableNode.setOptions(keyValueSet);
+    createTableNode.setOptions(properties);
+
+
 
     if (expr.hasPartition()) {
       if (expr.getPartitionMethod().getPartitionType().equals(PartitionType.COLUMN)) {
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java
index b5d2db3..4e61de4 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java
@@ -21,6 +21,8 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import org.apache.tajo.OverridableConf;
+import org.apache.tajo.SessionVars;
 import org.apache.tajo.algebra.*;
 import org.apache.tajo.annotation.Nullable;
 import org.apache.tajo.catalog.*;
@@ -33,11 +35,16 @@
 import org.apache.tajo.plan.visitor.BasicLogicalPlanVisitor;
 import org.apache.tajo.plan.visitor.ExplainLogicalPlanVisitor;
 import org.apache.tajo.plan.visitor.SimpleAlgebraVisitor;
+import org.apache.tajo.storage.StorageConstants;
+import org.apache.tajo.util.KeyValueSet;
 import org.apache.tajo.util.TUtil;
 
 import java.io.IOException;
 import java.util.*;
 
+import static org.apache.tajo.catalog.proto.CatalogProtos.StoreType.CSV;
+import static org.apache.tajo.catalog.proto.CatalogProtos.StoreType.TEXTFILE;
+
 public class PlannerUtil {
 
   public static boolean checkIfDDLPlan(LogicalNode node) {
@@ -776,6 +783,16 @@
     return explains.toString();
   }
 
+  public static void applySessionToTableProperties(OverridableConf sessionVars,
+                                                   CatalogProtos.StoreType storeType,
+                                                   KeyValueSet tableProperties) {
+    if (storeType == CSV || storeType == TEXTFILE) {
+      if (sessionVars.containsKey(SessionVars.NULL_CHAR)) {
+        tableProperties.set(StorageConstants.TEXT_NULL, sessionVars.get(SessionVars.NULL_CHAR));
+      }
+    }
+  }
+
   public static boolean isFileStorageType(String storageType) {
     if (storageType.equalsIgnoreCase("hbase")) {
       return false;