Test to stress the StorageManager blob interface.
diff --git a/.gitmodules b/.gitmodules
index cf380b5..7671b11 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,6 +7,3 @@
 [submodule "third_party/googletest"]
 	path = third_party/googletest
 	url = https://github.com/google/googletest
-[submodule "storage/bitweaving"]
-	path = storage/bitweaving
-	url = https://github.com/UWQuickstep/bitweaving.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 642925f..c9578b0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 #   Copyright 2011-2015 Quickstep Technologies LLC.
-#   Copyright 2015 Pivotal Software, Inc.
+#   Copyright 2015-2016 Pivotal Software, Inc.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -137,6 +137,8 @@
   )
 endif()
 
+option(ENABLE_DISTRIBUTED "Use the distributed version of Quickstep" OFF)
+
 # Turn on the QUICKSTEP_DEBUG flag in the source if this is a debug build.
 if (CMAKE_MAJOR_VERSION GREATER 2)
   cmake_policy(SET CMP0043 NEW)
diff --git a/cli/QuickstepCli.cpp b/cli/QuickstepCli.cpp
index b0b98a3..8dee1f7 100644
--- a/cli/QuickstepCli.cpp
+++ b/cli/QuickstepCli.cpp
@@ -169,7 +169,7 @@
            real_num_workers,
            (static_cast<double>(quickstep::FLAGS_buffer_pool_slots) * quickstep::kSlotSizeBytes)/quickstep::kAGigaByte);
   } else {
-    LOG(FATAL) << "Quickstep needs at least one worker thread";
+    LOG(FATAL) << "Quickstep needs at least one worker thread to run";
   }
 
 #ifdef QUICKSTEP_HAVE_FILE_MANAGER_HDFS
@@ -262,14 +262,19 @@
       DefaultsConfigurator::GetNumNUMANodesCoveredByWorkers(worker_cpu_affinities);
 
   if (quickstep::FLAGS_preload_buffer_pool) {
+    std::chrono::time_point<std::chrono::steady_clock> preload_start, preload_end;
+    preload_start = std::chrono::steady_clock::now();
+    printf("Preloading the buffer pool ... ");
+    fflush(stdout);
     quickstep::PreloaderThread preloader(*query_processor->getDefaultDatabase(),
                                          query_processor->getStorageManager(),
                                          worker_cpu_affinities.front());
-    printf("Preloading buffer pool... ");
-    fflush(stdout);
+
     preloader.start();
     preloader.join();
-    printf("DONE\n");
+    preload_end = std::chrono::steady_clock::now();
+    printf("in %g seconds\n",
+           std::chrono::duration<double>(preload_end - preload_start).count());
   }
 
   Foreman foreman(&bus,
diff --git a/parser/CMakeLists.txt b/parser/CMakeLists.txt
index d35f3be..9738c2c 100644
--- a/parser/CMakeLists.txt
+++ b/parser/CMakeLists.txt
@@ -199,7 +199,8 @@
                       quickstep_types_TypedValue
                       quickstep_types_VarCharType
                       quickstep_types_YearMonthIntervalType
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_SqlError)
 target_link_libraries(quickstep_parser_ParseOrderBy
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseTreeNode
diff --git a/parser/ParseLiteralValue.cpp b/parser/ParseLiteralValue.cpp
index 1462244..f839bed 100644
--- a/parser/ParseLiteralValue.cpp
+++ b/parser/ParseLiteralValue.cpp
@@ -37,6 +37,7 @@
 #include "types/Type.hpp"
 #include "types/VarCharType.hpp"
 #include "types/YearMonthIntervalType.hpp"
+#include "utility/SqlError.hpp"
 
 #include "glog/logging.h"
 
diff --git a/parser/ParseSubqueryExpression.cpp b/parser/ParseSubqueryExpression.cpp
index 1673a74..556b19d 100644
--- a/parser/ParseSubqueryExpression.cpp
+++ b/parser/ParseSubqueryExpression.cpp
@@ -1,6 +1,8 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
  *   Copyright 2015 Pivotal Software, Inc.
+ *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
+ *     University of Wisconsin—Madison.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -27,7 +29,8 @@
 class ParseTreeNode;
 
 std::string ParseSubqueryExpression::generateName() const {
-  LOG(FATAL) << "ParseSubqueryExpression::generateName() is not implemented yet";
+  // TODO(jianqiao): generate a more informative name for ParseSubqueryExpression.
+  return getName();
 }
 
 void ParseSubqueryExpression::getFieldStringItems(
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index 3043322..a399723 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -191,6 +191,7 @@
   "create"           return TOKEN_CREATE;
   "date"             return TOKEN_DATE;
   "datetime"         return TOKEN_DATETIME;
+  "day"              return TOKEN_DAY;
   "decimal"          return TOKEN_DECIMAL;
   "default"          return TOKEN_DEFAULT;
   "delete"           return TOKEN_DELETE;
@@ -214,6 +215,7 @@
   "group"            return TOKEN_GROUP;
   "hash"             return TOKEN_HASH;
   "having"           return TOKEN_HAVING;
+  "hour"             return TOKEN_HOUR;
   "in"               return TOKEN_IN;
   "index"            return TOKEN_INDEX;
   "inner"            return TOKEN_INNER;
@@ -230,6 +232,8 @@
   "like"             return TOKEN_LIKE;
   "limit"            return TOKEN_LIMIT;
   "long"             return TOKEN_LONG;
+  "minute"           return TOKEN_MINUTE;
+  "month"            return TOKEN_MONTH;
   "not"              return TOKEN_NOT;
   "null"             return TOKEN_NULL;
   "nulls"            return TOKEN_NULLS;
@@ -249,6 +253,7 @@
   "regexp"           return TOKEN_REGEXP;
   "right"            return TOKEN_RIGHT;
   "row_delimiter"    return TOKEN_ROW_DELIMITER;
+  "second"           return TOKEN_SECOND;
   "select"           return TOKEN_SELECT;
   "set"              return TOKEN_SET;
   "sma"              return TOKEN_SMA;
@@ -267,6 +272,7 @@
   "when"             return TOKEN_WHEN;
   "where"            return TOKEN_WHERE;
   "with"             return TOKEN_WITH;
+  "year"             return TOKEN_YEAR;
   "yearmonth"        return TOKEN_YEARMONTH;
 
   "="                return TOKEN_EQ;
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index bb19d8b..1202d66 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -197,7 +197,7 @@
   quickstep::ParseOrderBy *opt_order_by_clause_;
   bool *order_direction_;
   quickstep::ParseLimit *opt_limit_clause_;
-  
+
   quickstep::ParseSample *opt_sample_clause_;
 
   quickstep::PtrList<quickstep::ParseOrderByItem> *order_commalist_;
@@ -256,6 +256,7 @@
 %token TOKEN_CREATE;
 %token TOKEN_DATE;
 %token TOKEN_DATETIME;
+%token TOKEN_DAY;
 %token TOKEN_DECIMAL;
 %token TOKEN_DEFAULT;
 %token TOKEN_DELETE;
@@ -278,6 +279,7 @@
 %token TOKEN_GROUP;
 %token TOKEN_HASH;
 %token TOKEN_HAVING;
+%token TOKEN_HOUR;
 %token TOKEN_IN;
 %token TOKEN_INDEX;
 %token TOKEN_INNER;
@@ -291,6 +293,8 @@
 %token TOKEN_LEFT;
 %token TOKEN_LIMIT;
 %token TOKEN_LONG;
+%token TOKEN_MINUTE;
+%token TOKEN_MONTH;
 %token TOKEN_NOT;
 %token TOKEN_NULL;
 %token TOKEN_NULLS;
@@ -310,6 +314,7 @@
 %token TOKEN_REGEXP;
 %token TOKEN_RIGHT;
 %token TOKEN_ROW_DELIMITER;
+%token TOKEN_SECOND;
 %token TOKEN_SELECT;
 %token TOKEN_SET;
 %token TOKEN_SMA;
@@ -328,12 +333,14 @@
 %token TOKEN_WHEN;
 %token TOKEN_WHERE;
 %token TOKEN_WITH;
+%token TOKEN_YEAR;
 %token TOKEN_YEARMONTH;
 %token TOKEN_EOF;
 %token TOKEN_LEX_ERROR;
 
 %type <string_value_>
   any_name
+  datetime_unit
   index_type
   partition_type
 
@@ -1503,6 +1510,9 @@
   }
   | '(' add_expression ')' {
     $$ = $2;
+  }
+  | subquery_expression {
+    $$ = $1;
   };
 
 function_call:
@@ -1522,7 +1532,7 @@
   };
 
 extract_function:
-  TOKEN_EXTRACT '(' any_name TOKEN_FROM add_expression ')' {
+  TOKEN_EXTRACT '(' datetime_unit TOKEN_FROM add_expression ')' {
     $$ = new quickstep::ParseExtractFunction(@1.first_line, @1.first_column, $3, $5);
   };
 
@@ -1627,6 +1637,19 @@
       YYERROR;
     }
   }
+  | TOKEN_INTERVAL TOKEN_STRING_SINGLE_QUOTED datetime_unit {
+    quickstep::StringParseLiteralValue *parse_value;
+    const std::string &datetime_type_value = $3->value();
+    if (quickstep::StringParseLiteralValue::ParseAmbiguousInterval(
+        &($2->append((" " + datetime_type_value).c_str(), datetime_type_value.length() + 1)),
+        &parse_value)) {
+      $$ = parse_value;
+    } else {
+      $$ = nullptr;
+      quickstep_yyerror(&@3, yyscanner, nullptr, "Failed to parse literal as specified type");
+      YYERROR;
+    }
+  }
   | data_type TOKEN_STRING_SINGLE_QUOTED {
     quickstep::StringParseLiteralValue *parse_value
         = new quickstep::StringParseLiteralValue($2, &($1->getType()));
@@ -1639,6 +1662,26 @@
     } else {
       $$ = parse_value;
     }
+  }
+
+datetime_unit:
+  TOKEN_YEAR {
+     $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("YEAR"));
+  }
+  | TOKEN_MONTH {
+     $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("MONTH"));
+  }
+  | TOKEN_DAY {
+     $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("DAY"));
+  }
+  | TOKEN_HOUR {
+     $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("HOUR"));
+  }
+  | TOKEN_MINUTE {
+     $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("MINUTE"));
+  }
+  | TOKEN_SECOND {
+     $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("SECOND"));
   };
 
 literal_value_commalist:
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index 553a7d9..d836988 100644
--- a/parser/preprocessed/SqlLexer_gen.cpp
+++ b/parser/preprocessed/SqlLexer_gen.cpp
@@ -381,8 +381,8 @@
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 144
-#define YY_END_OF_BUFFER 145
+#define YY_NUM_RULES 150
+#define YY_END_OF_BUFFER 151
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -390,66 +390,68 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[527] =
+static yyconst flex_int16_t yy_accept[545] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  145,    2,    2,  143,  143,  142,  141,  143,
-      120,  116,  119,  116,  116,  139,  112,  109,  113,  138,
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  117,    4,    5,    5,    3,  135,  135,
-      132,  136,  136,  130,  137,  137,  134,    1,  142,  110,
-      140,  139,  139,  139,    0,  114,  111,  115,  138,  138,
-      138,  138,   10,  138,  138,  138,   22,  138,  138,  138,
-      138,  138,  138,  138,  138,  138,  138,  118,  138,  138,
+        0,    0,  151,    2,    2,  149,  149,  148,  147,  149,
+      126,  122,  125,  122,  122,  145,  118,  115,  119,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  123,    4,    5,    5,    3,  141,
+      141,  138,  142,  142,  136,  143,  143,  140,    1,  148,
+      116,  146,  145,  145,  145,    0,  120,  117,  121,  144,
+      144,  144,  144,   10,  144,  144,  144,   22,  144,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  124,  144,
 
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-       55,   63,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,   75,   76,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  138,  138,  138,    4,    5,    3,  135,
-      131,  136,  129,  129,  121,  123,  124,  125,  126,  127,
-      128,  129,  137,  133,  140,  139,    0,  139,    6,    7,
-      138,    9,   11,  138,  138,   15,  138,  138,  138,  138,
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  138,   42,  138,  138,  138,  138,  138,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,   57,   65,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  144,   79,   80,  144,  144,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+        4,    5,    3,  141,  137,  142,  135,  135,  127,  129,
+      130,  131,  132,  133,  134,  135,  143,  139,  146,  145,
+        0,  145,    6,    7,  144,    9,   11,  144,  144,   15,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+       32,  144,  144,  144,  144,  144,  144,  144,  144,   43,
 
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-       59,  138,   65,  138,  138,  138,  138,  138,   71,  138,
-       74,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  138,   91,   92,  138,  138,  138,  138,
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  121,
-      123,  122,  138,  138,  138,  138,  138,  138,  138,   20,
-       23,  138,  138,  138,   28,  138,  138,   30,  138,  138,
-      138,  138,   36,  138,  138,   40,   41,  138,  138,  138,
-      138,  138,  138,  138,   50,   51,  138,   53,  138,  138,
-      138,  138,  138,   62,   64,   66,   67,   68,  138,   70,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  144,  144,   61,  144,   67,  144,
+      144,  144,  144,  144,  144,  144,   75,  144,   78,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,   96,   97,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,  127,  129,
+      128,  144,  144,  144,  144,  144,  144,  144,   20,   23,
+      144,  144,  144,   28,  144,  144,   30,  144,  144,  144,
+      144,   37,  144,  144,   41,   42,  144,  144,  144,  144,
+      144,  144,  144,   51,   52,  144,   54,  144,   56,  144,
 
-       72,  138,  138,  138,  138,  138,   83,  138,   85,  138,
-      138,  138,  138,  138,  138,  138,   95,   96,   98,  138,
-      138,  138,  138,  138,  138,  105,  138,  107,  138,  121,
-      122,    8,  138,  138,  138,  138,  138,  138,  138,   25,
-      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
-      138,  138,  138,  138,  138,   46,   47,   48,  138,   52,
-      138,   56,   57,  138,  138,  138,   69,   73,   77,   78,
-      138,  138,  138,   84,  138,  138,   88,  138,  138,  138,
-       94,  138,  138,  138,  138,  102,  138,  138,  106,  138,
-      138,  138,   14,  138,  138,  138,  138,  138,   26,  138,
+      144,  144,  144,   64,   66,   68,   69,   70,  144,   72,
+      144,  144,   76,  144,  144,  144,  144,  144,   87,  144,
+       89,  144,  144,  144,  144,  144,  144,  144,  144,  100,
+      101,  103,  144,  144,  144,  144,  144,  144,  110,  144,
+      112,  113,  127,  128,    8,  144,  144,  144,  144,  144,
+      144,  144,   25,  144,  144,  144,  144,  144,  144,  144,
+      144,  144,  144,  144,  144,  144,  144,  144,   47,   48,
+       49,  144,   53,  144,   58,   59,  144,  144,  144,   71,
+      144,   74,   77,   81,   82,  144,  144,  144,   88,  144,
+      144,   92,  144,  144,  144,  144,   99,  144,  144,  144,
 
-       29,  138,  138,  138,  138,   34,  138,  138,  138,   39,
-      138,   44,  138,  138,   54,   58,  138,  138,  138,  138,
-      138,  138,   87,  138,   90,  138,  138,  138,  100,  101,
-      103,  138,  138,  138,   13,  138,  138,  138,  138,  138,
-      138,   21,  138,   32,   33,  138,  138,  138,  138,   45,
-       49,   60,  138,  138,   81,   82,  138,  138,  138,  138,
-      138,  104,  138,  138,  138,  138,  138,  138,  138,  138,
-       31,  138,  138,   38,  138,   61,  138,  138,  138,   93,
-      138,  138,  138,   12,  138,  138,  138,  138,   24,  138,
-       35,  138,  138,   79,  138,  138,   97,  138,  108,   16,
+      144,  107,  144,  144,  111,  144,  144,  144,   14,  144,
+      144,  144,  144,  144,   26,  144,   29,  144,  144,  144,
+      144,   35,  144,  144,  144,   40,  144,   45,  144,  144,
+       55,   60,  144,  144,   73,  144,  144,  144,  144,   91,
+      144,   94,   95,  144,  144,  144,  105,  106,  108,  144,
+      144,  144,   13,  144,  144,  144,  144,  144,  144,   21,
+      144,   33,   34,  144,  144,  144,  144,   46,   50,   62,
+      144,  144,   85,   86,  144,  144,  144,  144,  144,  109,
+      144,  144,  144,  144,  144,  144,  144,  144,   31,  144,
+      144,   39,  144,   63,  144,  144,  144,   98,  144,  144,
 
-      138,  138,  138,   27,   37,  138,   80,   86,  138,  138,
-      138,   18,   19,  138,  138,   99,  138,  138,  138,  138,
-      138,   89,  138,   43,   17,    0
+      144,   12,  144,  144,  144,  144,   24,  144,   36,  144,
+      144,   83,  144,  144,  102,  144,  114,   16,  144,  144,
+      144,   27,   38,  144,   84,   90,  144,  144,  144,   18,
+       19,  144,  144,  104,  144,  144,  144,  144,  144,   93,
+      144,   44,   17,    0
     } ;
 
 static yyconst YY_CHAR yy_ec[256] =
@@ -496,282 +498,288 @@
         8
     } ;
 
-static yyconst flex_uint16_t yy_base[542] =
+static yyconst flex_uint16_t yy_base[560] =
     {   0,
         0,    1,   46,    0,  117,  163,    2,    3,  128,  132,
-        6,   10,  260, 1177, 1177,    0, 1177,   13, 1177,  241,
-     1177, 1177, 1177,  239,    6,  130,    4, 1177,  202,  124,
-      161,  170,  178,  207,  260,   92,  110,  161,   97,  108,
-      219,    0,  153,  221,  176,  108,  232,  171,  276,  272,
-      129,  221,  177, 1177,  184,    4,   19,    0,    0,    0,
-      146,    0,    0,  340,    0,    0,  145,    0,   22, 1177,
-        0,  249,  284,  334,   18, 1177, 1177, 1177,    0,  232,
-      262,  234,  270,  267,  285,  278,    0,  276,  307,  331,
-      291,  307,  299,  347,  313,  312,  325, 1177,  325,  345,
+        6,   10,  257, 1212, 1212,    0, 1212,   13, 1212,  233,
+     1212, 1212, 1212,  208,    6,  130,    4, 1212,  195,  124,
+      161,  170,  178,  207,  260,   92,  167,  161,   96,  107,
+      219,  214,  212,  224,  236,   92,  279,  171,  278,  281,
+      128,  227,    0,  125, 1212,  184,    4,   19,    0,    0,
+        0,  146,    0,    0,  343,    0,    0,  145,    0,   22,
+     1212,    0,  297,  316,  338,   18, 1212, 1212, 1212,    0,
+      170,  227,  173,  178,  224,  299,  270,    0,  270,  335,
+      330,  286,  320,  327,  376,  308,  316,  326, 1212,  335,
 
-      348,  343,  343,  338,  342,  347,  352,  358,  362,  378,
-      394,    0,  381,  366,  382,  396,  392,  390,  387,  397,
-      404,    0,  407,  392,  397,  398,  408,  409,  407,  447,
-      415,  400,  437,  434,  453,  451,  445,  438,  444,  452,
-      458,  454,  453,  461,  447,  467,  148,   29,    0,    0,
-     1177,    0, 1177, 1177,   22,   24, 1177, 1177, 1177, 1177,
-     1177,    0,    0, 1177,    0,  474,   26,   28,    0,    0,
-      467,    0,  468,  451,  466,  453,  478,  475,  480,  496,
-      485,  488,  486,  511,  493,  509,  506,  515,  512,  515,
-      499,  518,  507,  519,    0,  524,  507,  511,  511,  512,
+      351,  355,  371,  348,  346,  353,  359,  370,  382,  383,
+      380,  379,  399,    0,  392,  379,  386,  401,  399,  401,
+      402,  407,  402,  413,  420,    0,  431,  417,  420,  422,
+      434,  437,  435,  451,  446,  433,  456,  459,  459,  457,
+      450,  444,  454,  462,  469,  465,  465,  474,  460,  483,
+      148,   29,    0,    0, 1212,    0, 1212, 1212,   22,   24,
+     1212, 1212, 1212, 1212, 1212,    0,    0, 1212,    0,  515,
+       26,   28,    0,    0,  488,    0,  490,  473,  489,  478,
+      501,  502,  496,  512,  496,  499,  494,  520,  503,  521,
+        0,  519,  528,  526,  529,  514,  535,  522,  534,    0,
 
-      531,  528,  521,  525,  517,  531,  542,  551,  552,  559,
-      560,  555,    0,  550,  551,  567,  564,  567,    0,  564,
-        0,  572,  573,  559,  578,  569,  563,  577,  575,  583,
-      584,  582,   98,  586,    0,  580,  583,  582,  592,  604,
-      602,  598,  621,  609,  606,  625,  615,  622,  613,   30,
-      125,    0,  614,  620,  630,  622,  632,  628,  627,    0,
-      640,  631,  632,  626,    0,  627,  630,  629,  637,  632,
-      634,  642,  662,  663,  661,    0,    0,  664,  661,  684,
-      681,  667,  668,  680,    0,    0,  674,    0,  677,  668,
-      675,  676,  688,    0,    0,    0,    0,    0,  677,    0,
+      539,  522,  524,  532,  534,  553,  551,  546,  550,  544,
+      564,  564,  556,  570,  571,  572,  574,  564,    0,  561,
+      564,  581,  578,  583,  571,  573,    0,  583,    0,  591,
+      592,  578,  596,  587,  589,  604,  600,  609,  612,  612,
+       98,  608,  625,    0,  619,  620,  619,  629,  630,  624,
+      620,  638,  628,  623,  642,  633,  640,  632,   30,  125,
+        0,  635,  640,  650,  642,  652,  647,  654,    0,  668,
+      659,  659,  655,    0,  658,  663,  668,  676,  669,  671,
+      679,  688,  685,  683,    0,    0,  681,  680,  701,  698,
+      685,  686,  699,    0,    0,  693,    0,  697,    0,  688,
 
-      679,  681,  682,  694,  699,  704,    0,  702,    0,  690,
-      687,  692,  709,  722,  718,  726,    0,  719,    0,  734,
-      722,  724,  738,  741,  739,    0,  743,    0,  736,  136,
-     1177,    0,  746,  746,  732,  752,  739,  750,  754,    0,
-      747,  744,  758,  759,  756,  765,  757,  765,  762,  769,
-      774,  784,  791,  778,  798,    0,    0,    0,  795,    0,
-      796,    0,    0,  784,  800,  784,    0,    0,    0,    0,
-      787,  794,  791,    0,  805,  795,    0,  808,  794,  806,
-        0,  796,  800,  815,  816,    0,  803,  822,    0,  809,
-      818,  814,    0,  807,  823,  845,  838,  834,    0,  854,
+      695,  696,  709,    0,    0,    0,    0,    0,  695,    0,
+      705,  720,  711,  715,  718,  730,  741,  746,    0,  743,
+        0,  731,  726,  731,  748,  739,  752,  746,  755,    0,
+      742,    0,  758,  743,  746,  760,  764,  762,    0,  766,
+        0,  759,  136, 1212,    0,  769,  769,  763,  784,  772,
+      780,  791,    0,  783,  786,  800,  801,  798,  807,  797,
+      805,  802,  799,  802,  813,  814,  802,  819,    0,    0,
+        0,  817,    0,  818,    0,    0,  807,  823,  807,    0,
+      825,    0,    0,    0,    0,  811,  818,  823,    0,  838,
+      828,    0,  841,  845,  832,  846,    0,  842,  844,  859,
 
-        0,  854,  847,  849,  842,    0,  843,  860,  862,    0,
-       93,    0,  846,  853,    0,    0,  850,  868,  862,  852,
-      848,  860,    0,  865,    0,  864,  878,  879,    0,    0,
-        0,  863,  868,  871,    0,  877,  872,  886,  892,  900,
-      903,    0,  908,    0,    0,  912,  909,  899,  901,    0,
-        0,    0,  909,  907,    0,    0,  920,  915,  905,  913,
-      914,    0,  909,  923,  917,  916,  919,  916,  919,  924,
-        0,  921,  926,    0,  923,    0,  930,  940,  944,    0,
-      946,  947,  962,    0,  964,  970,  964,  972,    0,  958,
-        0,  972,  962,  962,  963,  974,    0,  972,    0,    0,
+      860,    0,  847,  866,    0,  853,  860,  857,    0,  852,
+      858,  876,  870,  860,    0,  881,    0,  878,  872,  874,
+      867,    0,  868,  885,  887,    0,   93,    0,  879,  887,
+        0,    0,  884,  903,    0,  898,  890,  888,  906,    0,
+      909,    0,    0,  908,  922,  923,    0,    0,    0,  907,
+      912,  913,    0,  920,  917,  921,  923,  932,  929,    0,
+      935,    0,    0,  936,  934,  924,  926,    0,    0,    0,
+      934,  932,    0,    0,  945,  948,  939,  947,  949,    0,
+      945,  961,  957,  962,  963,  960,  963,  968,    0,  965,
+      970,    0,  965,    0,  973,  985,  979,    0,  977,  979,
 
-      967,  982,  970,    0,    0,  980,    0,    0,  970,  988,
-      974,    0,    0,  981,  991,    0,  988,  991,  983,  997,
-      984,    0,  996,    0,    0, 1177, 1061, 1071, 1081, 1091,
-     1101, 1105, 1108, 1114, 1122, 1132, 1142, 1152, 1162, 1167,
-     1169
+      988,    0,  991,  994,  989,  997,    0,  983,    0,  997,
+      987,  987,  996, 1008,    0, 1006,    0,    0, 1002, 1018,
+     1008,    0,    0, 1020,    0,    0, 1016, 1032, 1018,    0,
+        0, 1025, 1035,    0, 1032, 1035, 1025, 1040, 1029,    0,
+     1031,    0,    0, 1212, 1096, 1106, 1116, 1126, 1136, 1140,
+     1143, 1149, 1157, 1167, 1177, 1187, 1197, 1202, 1204
     } ;
 
-static yyconst flex_int16_t yy_def[542] =
+static yyconst flex_int16_t yy_def[560] =
     {   0,
-      527,  527,  526,    3,  528,  528,  529,  529,  530,  530,
-      531,  531,  526,  526,  526,  532,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  526,  526,  526,  526,  534,  535,  535,
-      526,  536,  536,  537,  538,  538,  526,  532,  526,  526,
-      539,  526,  526,  526,  526,  526,  526,  526,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  526,  533,  533,
+      545,  545,  544,    3,  546,  546,  547,  547,  548,  548,
+      549,  549,  544,  544,  544,  550,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  544,  544,  544,  544,  552,  553,
+      553,  544,  554,  554,  555,  556,  556,  544,  550,  544,
+      544,  557,  544,  544,  544,  544,  544,  544,  544,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  544,  551,
 
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  526,  526,  534,  535,
-      526,  536,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  540,  538,  526,  539,  526,  526,  526,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      544,  544,  552,  553,  544,  554,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  558,  556,  544,  557,  544,
+      544,  544,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
 
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  526,
-      526,  541,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  544,  544,
+      559,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
 
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  526,
-      526,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  544,  544,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
 
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
 
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
-      533,  533,  533,  533,  533,    0,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,  551,  551,  551,  551,  551,  551,  551,
+      551,  551,  551,    0,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544
     } ;
 
-static yyconst flex_uint16_t yy_nxt[1249] =
+static yyconst flex_uint16_t yy_nxt[1284] =
     {   0,
-      526,  526,   15,   15,   60,   60,  148,  148,   66,   61,
-       61,   67,   66,  526,   69,   67,   69,   72,   72,   76,
-       77,  148,  148,   69,  526,   69,  167,  167,  526,  168,
-      168,  148,  148,  250,  251,  251,  251,  168,  168,  168,
-      168,  330,  251,  526,   16,   16,   17,   18,   19,   18,
+      544,  544,   15,   15,   61,   61,  152,  152,   67,   62,
+       62,   68,   67,  544,   70,   68,   70,   73,   73,   77,
+       78,  152,  152,   70,  544,   70,  171,  171,  544,  172,
+      172,  152,  152,  259,  260,  260,  260,  172,  172,  172,
+      172,  343,  260,  544,   16,   16,   17,   18,   19,   18,
        20,   21,   22,   23,   22,   24,   25,   26,   26,   17,
        27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
        37,   38,   39,   40,   41,   42,   43,   44,   45,   46,
-       47,   48,   49,   50,   51,   52,   42,   53,   42,   54,
+       47,   48,   49,   50,   51,   52,   53,   54,   53,   55,
        17,   17,   30,   31,   32,   33,   34,   35,   36,   37,
 
        38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
-       48,   49,   50,   51,   52,   42,   53,   17,   55,   56,
-       57,   17,   17,   17,   17,   17,  109,  110,  113,  114,
-       63,   17,   17,   17,   63,   61,  251,  251,  449,   61,
-       73,   74,   74,  313,   80,  128,  143,  251,  251,  147,
-      164,   75,   81,  151,   82,  109,  110,  113,  114,   83,
-       17,   17,   17,   17,   55,   56,   57,   17,   17,   17,
-       17,   17,   64,   80,  128,  143,   64,   17,   17,   17,
-       75,   81,   84,   82,  119,  147,   85,   88,   83,   86,
-      120,  111,  133,  125,   89,   93,  112,  126,  146,   94,
+       48,   49,   50,   51,   52,   53,   54,   17,   56,   57,
+       58,   17,   17,   17,   17,   17,  110,  115,  116,  132,
+       64,   17,   17,   17,   64,   62,  260,  260,  467,   62,
+       74,   75,   75,  325,   81,  147,  150,  260,  260,  151,
+      168,   76,   82,  155,   83,  110,  115,  116,  132,   84,
+       17,   17,   17,   17,   56,   57,   58,   17,   17,   17,
+       17,   17,   65,   81,  147,  150,   65,   17,   17,   17,
+       76,   82,   85,   83,  111,  151,   86,   89,   84,   87,
+      173,  113,  137,  176,   90,   94,  114,  177,  112,   95,
 
-      134,   90,   87,   95,   91,   92,   17,   17,   17,   96,
-      127,   84,   97,  119,   98,   85,   88,   78,   86,  120,
-      111,  133,  125,   89,   93,  112,  126,  146,   94,  134,
-       90,   87,   95,   91,   92,   99,  115,  100,   96,  127,
-      116,   97,  101,  121,  117,  144,  145,  102,   71,  129,
-      118,  122,  169,  130,  172,  123,   70,  131,  124,  526,
-       72,   72,  526,  132,   99,  115,  100,  526,  526,  116,
-       75,  101,  121,  117,  144,  145,  102,  103,  129,  118,
-      122,  169,  130,  172,  123,  104,  131,  124,  105,  173,
-      170,  106,  132,  135,  107,  166,  166,  108,  171,   75,
+      138,   91,   88,   96,   92,   93,   17,   17,   17,   97,
+       79,   85,   98,  111,   99,   86,   89,   72,   87,  173,
+      113,  137,  176,   90,   94,  114,  177,  112,   95,  138,
+       91,   88,   96,   92,   93,  100,  117,  101,   97,  121,
+      118,   98,  102,  123,  119,  122,  125,  103,   71,  124,
+      120,  148,  149,  129,  126,  174,  544,  130,  127,  544,
+      178,  128,  544,  175,  100,  117,  101,  544,  121,  118,
+      131,  102,  123,  119,  122,  125,  103,  104,  124,  120,
+      148,  149,  129,  126,  174,  105,  130,  127,  106,  178,
+      128,  107,  175,  544,  108,  139,  133,  109,  544,  131,
 
-      136,  137,  140,  174,  141,   75,  103,  142,  175,  177,
-      138,  178,  184,  139,  104,  526,  526,  105,  173,  170,
-      106,  176,  135,  107,  179,  185,  108,  171,  180,  136,
-      137,  140,  174,  141,   75,  186,  142,  175,  177,  138,
-      178,  184,  139,  154,   73,   74,   74,  526,  191,  192,
-      176,  155,  156,  179,  185,   75,  193,  180,  157,  181,
-      194,  182,  158,  183,  186,  195,  187,  196,  197,  188,
-      159,  199,  200,  201,  160,  189,  161,  191,  192,  198,
-      162,  202,  190,  203,   75,  193,  204,  157,  181,  194,
-      182,  158,  183,  205,  195,  187,  196,  197,  188,  159,
+      134,  181,  140,  141,  135,  182,  104,  188,   73,   73,
+      136,  144,  142,  145,  105,  143,  146,  106,   76,  544,
+      107,  544,  179,  108,  139,  133,  109,  170,  170,  134,
+      181,  140,  141,  135,  182,  180,  188,   76,  189,  136,
+      144,  142,  145,  196,  143,  146,  158,   76,   74,   75,
+       75,  179,  183,  197,  159,  160,  184,  198,  185,   76,
+      186,  161,  187,  190,  180,  162,   76,  189,  191,  544,
+      199,  200,  196,  163,  201,  544,  204,  164,  544,  165,
+      205,  183,  197,  166,  206,  184,  198,  185,   76,  186,
+      161,  187,  190,  207,  162,  192,  202,  191,  193,  199,
 
-      199,  200,  201,  160,  189,  161,  212,  213,  198,  162,
-      202,  190,  203,  206,  208,  204,  207,  214,  215,  216,
-      218,  217,  205,  219,  209,  220,  221,  222,  223,  210,
-      211,  224,  225,  226,  227,  212,  213,  228,  232,  233,
-      526,  526,  206,  208,  526,  207,  214,  215,  216,  218,
-      217,  236,  219,  209,  220,  221,  222,  223,  210,  211,
-      224,  225,  226,  227,  229,  234,  228,  232,  233,  230,
-      231,  237,  238,  235,  239,  240,  241,  242,  243,  244,
-      236,  245,  247,  248,  249,  166,  166,  246,  253,  254,
-      255,  256,  257,  229,  234,   75,  260,  258,  230,  231,
+      200,  208,  163,  201,  194,  204,  164,  203,  165,  205,
+      209,  195,  166,  206,  210,  211,  213,  218,  212,  214,
+      219,  220,  207,  221,  192,  202,  222,  193,  223,  215,
+      208,  224,  225,  194,  216,  217,  203,  226,  227,  209,
+      195,  228,  229,  210,  211,  213,  218,  212,  214,  219,
+      220,  230,  221,  231,  232,  222,  233,  223,  215,  234,
+      224,  225,  235,  216,  217,  236,  226,  227,  237,  240,
+      228,  229,  241,  238,  239,  242,  245,  246,  247,  248,
+      230,  249,  231,  232,  243,  233,  250,  251,  234,  252,
+      253,  235,  244,  254,  236,  256,  257,  237,  240,  255,
 
-      237,  238,  235,  239,  240,  241,  242,  243,  244,  259,
-      245,  247,  248,  249,  261,  262,  246,  253,  254,  255,
-      256,  257,  263,  264,   75,  260,  258,  265,  266,  267,
-      268,  269,  270,  271,  273,  274,  275,  272,  259,  276,
-      277,  278,  279,  261,  262,  280,  281,  282,  283,  284,
-      285,  263,  264,  286,  287,  288,  265,  266,  267,  268,
-      269,  270,  271,  273,  274,  275,  272,  289,  276,  277,
-      278,  279,  290,  291,  280,  281,  282,  283,  284,  285,
-      292,  293,  286,  287,  288,  295,  296,  297,  298,  299,
-      300,  294,  301,  302,  303,  304,  289,  305,  306,  307,
+      258,  241,  238,  239,  242,  245,  246,  247,  248,  262,
+      249,  263,  264,  243,  265,  250,  251,  266,  252,  253,
+      267,  244,  254,  269,  256,  257,  170,  170,  255,  258,
+      270,  271,  268,  272,  273,  274,   76,  275,  262,  276,
+      263,  264,  277,  265,  278,  279,  266,  280,  282,  267,
+      283,  281,  269,  284,  285,  286,  287,  288,  289,  270,
+      271,  268,  272,  273,  274,   76,  275,  290,  276,  291,
+      292,  277,  293,  278,  279,  294,  280,  282,  295,  283,
+      281,  296,  284,  285,  286,  287,  288,  289,  297,  298,
+      299,  300,  301,  302,  305,  303,  290,  306,  291,  292,
 
-      308,  290,  291,  309,  310,  311,  312,  314,  315,  292,
-      293,  316,  317,  318,  295,  296,  297,  298,  299,  300,
-      294,  301,  302,  303,  304,  319,  305,  306,  307,  308,
-      320,  321,  309,  310,  311,  312,  314,  315,  322,  323,
-      316,  317,  318,  324,  325,  326,  328,  329,  332,  327,
-      333,  334,  335,  336,  319,  337,  338,  339,  340,  320,
-      321,  341,  342,  343,  344,  345,  346,  322,  323,  347,
-      348,  349,  324,  325,  326,  328,  329,  332,  327,  333,
-      334,  335,  336,  350,  337,  338,  339,  340,  351,  352,
-      341,  342,  343,  344,  345,  346,  353,  354,  347,  348,
+      307,  293,  308,  309,  294,  304,  310,  295,  311,  312,
+      296,  313,  314,  315,  316,  317,  318,  297,  298,  299,
+      300,  301,  302,  305,  303,  319,  306,  320,  321,  307,
+      322,  308,  309,  323,  304,  310,  324,  311,  312,  326,
+      313,  314,  315,  316,  317,  318,  327,  328,  329,  330,
+      331,  332,  333,  334,  319,  335,  320,  321,  336,  322,
+      337,  338,  323,  339,  341,  324,  342,  340,  326,  345,
+      346,  347,  348,  349,  350,  327,  328,  329,  330,  331,
+      332,  333,  334,  351,  335,  352,  353,  336,  354,  337,
+      338,  355,  339,  341,  356,  342,  340,  357,  345,  346,
 
-      349,  355,  356,  357,  358,  359,  360,  361,  362,  363,
-      364,  365,  350,  367,  368,  369,  370,  351,  352,  371,
-      372,  373,  366,  374,  375,  353,  354,  376,  377,  378,
-      355,  356,  357,  358,  359,  360,  361,  362,  363,  364,
-      365,  379,  367,  368,  369,  370,  380,  381,  371,  372,
-      373,  366,  374,  375,  382,  383,  376,  377,  378,  384,
-      385,  386,  387,  388,  389,  390,  391,  392,  393,  394,
-      379,  395,  397,  398,  396,  380,  381,  399,  400,  401,
-      402,  403,  404,  382,  383,  405,  406,  407,  384,  385,
-      386,  387,  388,  389,  390,  391,  392,  393,  394,  408,
+      347,  348,  349,  350,  358,  359,  360,  361,  362,  363,
+      364,  365,  351,  366,  352,  353,  367,  354,  368,  369,
+      355,  370,  371,  356,  372,  373,  357,  374,  375,  376,
+      377,  380,  378,  358,  359,  360,  361,  362,  363,  364,
+      365,  381,  366,  379,  382,  367,  383,  368,  369,  384,
+      370,  371,  385,  372,  373,  386,  374,  375,  376,  377,
+      380,  378,  387,  388,  389,  390,  391,  392,  393,  394,
+      381,  395,  379,  382,  396,  383,  397,  398,  384,  399,
+      400,  385,  401,  402,  386,  403,  404,  405,  406,  407,
+      408,  387,  388,  389,  390,  391,  392,  393,  394,  409,
 
-      395,  397,  398,  396,  409,  410,  399,  400,  401,  402,
-      403,  404,  411,  412,  405,  406,  407,  413,  414,  415,
-      416,  417,  418,  419,  420,  421,  422,  423,  408,  424,
-      425,  426,  427,  409,  410,  428,  429,  430,  431,  432,
-      433,  411,  412,  434,  435,  436,  413,  414,  415,  416,
-      417,  418,  419,  420,  421,  422,  423,  437,  424,  425,
-      426,  427,  438,  439,  428,  429,  430,  431,  432,  433,
-      440,  441,  434,  435,  436,  442,  443,  444,  445,  446,
-      447,  448,  450,  451,  452,  453,  437,  454,  455,  456,
-      457,  438,  439,  458,  459,  460,  461,  462,  463,  440,
+      395,  410,  413,  396,  411,  397,  398,  412,  399,  400,
+      414,  401,  402,  415,  403,  404,  405,  406,  407,  408,
+      416,  417,  418,  419,  420,  421,  422,  423,  409,  424,
+      410,  413,  425,  411,  426,  427,  412,  428,  429,  414,
+      430,  431,  415,  432,  433,  434,  435,  436,  437,  416,
+      417,  418,  419,  420,  421,  422,  423,  438,  424,  439,
+      440,  425,  441,  426,  427,  442,  428,  429,  443,  430,
+      431,  444,  432,  433,  434,  435,  436,  437,  445,  446,
+      447,  448,  449,  450,  451,  452,  438,  453,  439,  440,
+      454,  441,  455,  456,  442,  457,  458,  443,  459,  460,
 
-      441,  464,  465,  466,  442,  443,  444,  445,  446,  447,
-      448,  450,  451,  452,  453,  467,  454,  455,  456,  457,
-      468,  469,  458,  459,  460,  461,  462,  463,  470,  471,
-      464,  465,  466,  472,  473,  474,  475,  476,  477,  478,
-      479,  480,  481,  482,  467,  483,  484,  485,  486,  468,
-      469,  487,  488,  489,  490,  491,  492,  470,  471,  493,
-      494,  495,  472,  473,  474,  475,  476,  477,  478,  479,
-      480,  481,  482,  496,  483,  484,  485,  486,  497,  498,
-      487,  488,  489,  490,  491,  492,  499,  500,  493,  494,
-      495,  501,  502,  503,  504,  505,  506,  507,  508,  509,
+      444,  461,  462,  463,  464,  465,  466,  445,  446,  447,
+      448,  449,  450,  451,  452,  468,  453,  469,  470,  454,
+      471,  455,  456,  472,  457,  458,  473,  459,  460,  474,
+      461,  462,  463,  464,  465,  466,  475,  476,  477,  478,
+      479,  480,  481,  482,  468,  483,  469,  470,  484,  471,
+      485,  486,  472,  487,  488,  473,  489,  490,  474,  491,
+      492,  493,  494,  495,  496,  475,  476,  477,  478,  479,
+      480,  481,  482,  497,  483,  498,  499,  484,  500,  485,
+      486,  501,  487,  488,  502,  489,  490,  503,  491,  492,
+      493,  494,  495,  496,  504,  505,  506,  507,  508,  509,
 
-      510,  511,  496,  512,  513,  514,  515,  497,  498,  516,
-      517,  518,  519,  520,  521,  499,  500,  522,  523,  524,
-      501,  502,  503,  504,  505,  506,  507,  508,  509,  510,
-      511,  525,  512,  513,  514,  515,  526,  526,  516,  517,
-      518,  519,  520,  521,  526,  526,  522,  523,  524,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      525,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-       14,   58,   58,   58,   58,   58,   58,   58,   58,   58,
-       58,   59,   59,   59,   59,   59,   59,   59,   59,   59,
-       59,   62,   62,   62,   62,   62,   62,   62,   62,   62,
+      510,  511,  497,  512,  498,  499,  513,  500,  514,  515,
+      501,  516,  517,  502,  518,  519,  503,  520,  521,  522,
+      523,  524,  525,  504,  505,  506,  507,  508,  509,  510,
+      511,  526,  512,  527,  528,  513,  529,  514,  515,  530,
+      516,  517,  531,  518,  519,  532,  520,  521,  522,  523,
+      524,  525,  533,  534,  535,  536,  537,  538,  539,  540,
+      526,  541,  527,  528,  542,  529,  543,  544,  530,  544,
+      544,  531,  544,  544,  532,  544,  544,  544,  544,  544,
+      544,  533,  534,  535,  536,  537,  538,  539,  540,  544,
+      541,  544,  544,  542,  544,  543,   14,   14,   14,   14,
 
-       62,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   68,   68,   79,   79,   79,  526,   79,  149,  149,
-      149,  149,  150,  150,  150,  526,  150,  150,  150,  150,
-      150,  150,  152,  152,  152,  526,  152,  152,  152,  152,
-      526,  152,  153,  153,  153,  153,  153,  153,  153,  153,
-      153,  153,  163,  163,  526,  163,  163,  163,  163,  163,
-      163,  163,  165,  526,  165,  165,  165,  165,  165,  165,
-      165,  165,  252,  252,  331,  331,   13,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+       14,   14,   14,   14,   14,   14,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   60,   60,   60,   60,
+       60,   60,   60,   60,   60,   60,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   66,   66,   66,   66,
+       66,   66,   66,   66,   66,   66,   69,   69,   80,   80,
+       80,  544,   80,  153,  153,  153,  153,  154,  154,  154,
+      544,  154,  154,  154,  154,  154,  154,  156,  156,  156,
+      544,  156,  156,  156,  156,  544,  156,  157,  157,  157,
+      157,  157,  157,  157,  157,  157,  157,  167,  167,  544,
+      167,  167,  167,  167,  167,  167,  167,  169,  544,  169,
 
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526
+      169,  169,  169,  169,  169,  169,  169,  261,  261,  344,
+      344,   13,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544
     } ;
 
-static yyconst flex_int16_t yy_chk[1249] =
+static yyconst flex_int16_t yy_chk[1284] =
     {   0,
-        0,    0,    1,    2,    7,    8,   56,   56,   11,    7,
+        0,    0,    1,    2,    7,    8,   57,   57,   11,    7,
         8,   11,   12,    0,   18,   12,   18,   25,   25,   27,
-       27,   57,   57,   69,    0,   69,   75,   75,    0,   75,
-       75,  148,  148,  155,  155,  156,  156,  167,  167,  168,
-      168,  250,  250,    0,    1,    2,    3,    3,    3,    3,
+       27,   58,   58,   70,    0,   70,   76,   76,    0,   76,
+       76,  152,  152,  159,  159,  160,  160,  171,  171,  172,
+      172,  259,  259,    0,    1,    2,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
@@ -780,134 +788,138 @@
 
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,   36,   37,   39,   40,
-        9,    5,    5,    5,   10,    9,  251,  251,  411,   10,
-       26,   26,   26,  233,   30,   46,   51,  330,  330,  147,
-       67,   26,   30,   61,   30,   36,   37,   39,   40,   30,
+        5,    5,    5,    5,    5,    5,   36,   39,   40,   46,
+        9,    5,    5,    5,   10,    9,  260,  260,  427,   10,
+       26,   26,   26,  241,   30,   51,   54,  343,  343,  151,
+       68,   26,   30,   62,   30,   36,   39,   40,   46,   30,
         5,    5,    5,    6,    6,    6,    6,    6,    6,    6,
-        6,    6,    9,   30,   46,   51,   10,    6,    6,    6,
-       26,   30,   31,   30,   43,   55,   31,   32,   30,   31,
-       43,   38,   48,   45,   32,   33,   38,   45,   53,   33,
+        6,    6,    9,   30,   51,   54,   10,    6,    6,    6,
+       26,   30,   31,   30,   37,   56,   31,   32,   30,   31,
+       81,   38,   48,   83,   32,   33,   38,   84,   37,   33,
 
        48,   32,   31,   33,   32,   32,    6,    6,    6,   33,
-       45,   31,   33,   43,   34,   31,   32,   29,   31,   43,
-       38,   48,   45,   32,   33,   38,   45,   53,   33,   48,
-       32,   31,   33,   32,   32,   34,   41,   34,   33,   45,
-       41,   33,   34,   44,   41,   52,   52,   34,   24,   47,
-       41,   44,   80,   47,   82,   44,   20,   47,   44,   13,
-       72,   72,    0,   47,   34,   41,   34,    0,    0,   41,
-       72,   34,   44,   41,   52,   52,   34,   35,   47,   41,
-       44,   80,   47,   82,   44,   35,   47,   44,   35,   83,
-       81,   35,   47,   49,   35,   73,   73,   35,   81,   72,
+       29,   31,   33,   37,   34,   31,   32,   24,   31,   81,
+       38,   48,   83,   32,   33,   38,   84,   37,   33,   48,
+       32,   31,   33,   32,   32,   34,   41,   34,   33,   42,
+       41,   33,   34,   43,   41,   42,   44,   34,   20,   43,
+       41,   52,   52,   45,   44,   82,   13,   45,   44,    0,
+       85,   44,    0,   82,   34,   41,   34,    0,   42,   41,
+       45,   34,   43,   41,   42,   44,   34,   35,   43,   41,
+       52,   52,   45,   44,   82,   35,   45,   44,   35,   85,
+       44,   35,   82,    0,   35,   49,   47,   35,    0,   45,
 
-       49,   49,   50,   84,   50,   73,   35,   50,   85,   86,
-       49,   88,   91,   49,   35,    0,    0,   35,   83,   81,
-       35,   85,   49,   35,   89,   92,   35,   81,   89,   49,
-       49,   50,   84,   50,   73,   93,   50,   85,   86,   49,
-       88,   91,   49,   64,   74,   74,   74,    0,   95,   96,
-       85,   64,   64,   89,   92,   74,   97,   89,   64,   90,
-       99,   90,   64,   90,   93,  100,   94,  101,  102,   94,
-       64,  103,  104,  105,   64,   94,   64,   95,   96,  102,
-       64,  106,   94,  107,   74,   97,  108,   64,   90,   99,
-       90,   64,   90,  109,  100,   94,  101,  102,   94,   64,
+       47,   87,   49,   49,   47,   89,   35,   92,   73,   73,
+       47,   50,   49,   50,   35,   49,   50,   35,   73,    0,
+       35,    0,   86,   35,   49,   47,   35,   74,   74,   47,
+       87,   49,   49,   47,   89,   86,   92,   74,   93,   47,
+       50,   49,   50,   96,   49,   50,   65,   73,   75,   75,
+       75,   86,   90,   97,   65,   65,   90,   98,   91,   75,
+       91,   65,   91,   94,   86,   65,   74,   93,   94,    0,
+      100,  101,   96,   65,  102,    0,  104,   65,    0,   65,
+      105,   90,   97,   65,  106,   90,   98,   91,   75,   91,
+       65,   91,   94,  107,   65,   95,  103,   94,   95,  100,
 
-      103,  104,  105,   64,   94,   64,  113,  114,  102,   64,
-      106,   94,  107,  110,  111,  108,  110,  115,  116,  117,
-      118,  117,  109,  119,  111,  120,  121,  123,  124,  111,
-      111,  125,  126,  127,  128,  113,  114,  129,  131,  132,
-        0,    0,  110,  111,    0,  110,  115,  116,  117,  118,
-      117,  134,  119,  111,  120,  121,  123,  124,  111,  111,
-      125,  126,  127,  128,  130,  133,  129,  131,  132,  130,
-      130,  135,  136,  133,  137,  138,  139,  140,  141,  142,
-      134,  143,  144,  145,  146,  166,  166,  143,  171,  173,
-      174,  175,  176,  130,  133,  166,  178,  177,  130,  130,
+      101,  108,   65,  102,   95,  104,   65,  103,   65,  105,
+      109,   95,   65,  106,  110,  111,  112,  115,  111,  113,
+      116,  117,  107,  118,   95,  103,  119,   95,  119,  113,
+      108,  120,  121,   95,  113,  113,  103,  122,  123,  109,
+       95,  124,  125,  110,  111,  112,  115,  111,  113,  116,
+      117,  127,  118,  128,  129,  119,  130,  119,  113,  131,
+      120,  121,  132,  113,  113,  133,  122,  123,  134,  135,
+      124,  125,  136,  134,  134,  137,  138,  139,  140,  141,
+      127,  142,  128,  129,  137,  130,  143,  144,  131,  145,
+      146,  132,  137,  147,  133,  148,  149,  134,  135,  147,
 
-      135,  136,  133,  137,  138,  139,  140,  141,  142,  177,
-      143,  144,  145,  146,  179,  180,  143,  171,  173,  174,
-      175,  176,  181,  182,  166,  178,  177,  183,  184,  185,
-      186,  187,  188,  189,  190,  191,  192,  189,  177,  193,
-      194,  196,  197,  179,  180,  198,  199,  200,  201,  202,
-      203,  181,  182,  204,  205,  206,  183,  184,  185,  186,
-      187,  188,  189,  190,  191,  192,  189,  207,  193,  194,
-      196,  197,  208,  209,  198,  199,  200,  201,  202,  203,
-      210,  211,  204,  205,  206,  212,  214,  215,  216,  217,
-      218,  211,  220,  222,  223,  224,  207,  225,  226,  227,
+      150,  136,  134,  134,  137,  138,  139,  140,  141,  175,
+      142,  177,  178,  137,  179,  143,  144,  180,  145,  146,
+      181,  137,  147,  182,  148,  149,  170,  170,  147,  150,
+      183,  184,  181,  185,  186,  187,  170,  188,  175,  189,
+      177,  178,  190,  179,  192,  193,  180,  194,  195,  181,
+      196,  194,  182,  197,  198,  199,  201,  202,  203,  183,
+      184,  181,  185,  186,  187,  170,  188,  204,  189,  205,
+      206,  190,  207,  192,  193,  208,  194,  195,  209,  196,
+      194,  210,  197,  198,  199,  201,  202,  203,  211,  212,
+      213,  214,  215,  216,  218,  217,  204,  220,  205,  206,
 
-      228,  208,  209,  229,  230,  231,  232,  234,  236,  210,
-      211,  237,  238,  239,  212,  214,  215,  216,  217,  218,
-      211,  220,  222,  223,  224,  240,  225,  226,  227,  228,
-      241,  242,  229,  230,  231,  232,  234,  236,  243,  244,
-      237,  238,  239,  245,  246,  247,  248,  249,  253,  247,
-      254,  255,  256,  257,  240,  258,  259,  261,  262,  241,
-      242,  263,  264,  266,  267,  268,  269,  243,  244,  270,
-      271,  272,  245,  246,  247,  248,  249,  253,  247,  254,
-      255,  256,  257,  273,  258,  259,  261,  262,  274,  275,
-      263,  264,  266,  267,  268,  269,  278,  279,  270,  271,
+      221,  207,  222,  223,  208,  217,  224,  209,  225,  226,
+      210,  228,  230,  231,  232,  233,  234,  211,  212,  213,
+      214,  215,  216,  218,  217,  235,  220,  236,  237,  221,
+      238,  222,  223,  239,  217,  224,  240,  225,  226,  242,
+      228,  230,  231,  232,  233,  234,  243,  245,  246,  247,
+      248,  249,  250,  251,  235,  252,  236,  237,  253,  238,
+      254,  255,  239,  256,  257,  240,  258,  256,  242,  262,
+      263,  264,  265,  266,  267,  243,  245,  246,  247,  248,
+      249,  250,  251,  268,  252,  270,  271,  253,  272,  254,
+      255,  273,  256,  257,  275,  258,  256,  276,  262,  263,
 
-      272,  280,  281,  282,  283,  284,  287,  289,  290,  291,
-      292,  293,  273,  299,  301,  302,  303,  274,  275,  304,
-      305,  306,  293,  308,  310,  278,  279,  311,  312,  313,
-      280,  281,  282,  283,  284,  287,  289,  290,  291,  292,
-      293,  314,  299,  301,  302,  303,  315,  316,  304,  305,
-      306,  293,  308,  310,  318,  320,  311,  312,  313,  321,
-      322,  323,  324,  325,  327,  329,  333,  334,  335,  336,
-      314,  337,  338,  339,  337,  315,  316,  341,  342,  343,
-      344,  345,  346,  318,  320,  347,  348,  349,  321,  322,
-      323,  324,  325,  327,  329,  333,  334,  335,  336,  350,
+      264,  265,  266,  267,  277,  278,  279,  280,  281,  282,
+      283,  284,  268,  287,  270,  271,  288,  272,  289,  290,
+      273,  291,  292,  275,  293,  296,  276,  298,  300,  301,
+      302,  309,  303,  277,  278,  279,  280,  281,  282,  283,
+      284,  311,  287,  303,  312,  288,  313,  289,  290,  314,
+      291,  292,  315,  293,  296,  316,  298,  300,  301,  302,
+      309,  303,  317,  318,  320,  322,  323,  324,  325,  326,
+      311,  327,  303,  312,  328,  313,  329,  331,  314,  333,
+      334,  315,  335,  336,  316,  337,  338,  340,  342,  346,
+      347,  317,  318,  320,  322,  323,  324,  325,  326,  348,
 
-      337,  338,  339,  337,  351,  352,  341,  342,  343,  344,
-      345,  346,  353,  354,  347,  348,  349,  355,  359,  361,
-      364,  365,  366,  371,  372,  373,  375,  376,  350,  378,
-      379,  380,  382,  351,  352,  383,  384,  385,  387,  388,
-      390,  353,  354,  391,  392,  394,  355,  359,  361,  364,
-      365,  366,  371,  372,  373,  375,  376,  395,  378,  379,
-      380,  382,  396,  397,  383,  384,  385,  387,  388,  390,
-      398,  400,  391,  392,  394,  402,  403,  404,  405,  407,
-      408,  409,  413,  414,  417,  418,  395,  419,  420,  421,
-      422,  396,  397,  424,  426,  427,  428,  432,  433,  398,
+      327,  349,  351,  328,  350,  329,  331,  350,  333,  334,
+      352,  335,  336,  354,  337,  338,  340,  342,  346,  347,
+      355,  356,  357,  358,  359,  360,  361,  362,  348,  363,
+      349,  351,  364,  350,  365,  366,  350,  367,  368,  352,
+      372,  374,  354,  377,  378,  379,  381,  386,  387,  355,
+      356,  357,  358,  359,  360,  361,  362,  388,  363,  390,
+      391,  364,  393,  365,  366,  394,  367,  368,  395,  372,
+      374,  396,  377,  378,  379,  381,  386,  387,  398,  399,
+      400,  401,  403,  404,  406,  407,  388,  408,  390,  391,
+      410,  393,  411,  412,  394,  413,  414,  395,  416,  418,
 
-      400,  434,  436,  437,  402,  403,  404,  405,  407,  408,
-      409,  413,  414,  417,  418,  438,  419,  420,  421,  422,
-      439,  440,  424,  426,  427,  428,  432,  433,  441,  443,
-      434,  436,  437,  446,  447,  448,  449,  453,  454,  457,
-      458,  459,  460,  461,  438,  463,  464,  465,  466,  439,
-      440,  467,  468,  469,  470,  472,  473,  441,  443,  475,
-      477,  478,  446,  447,  448,  449,  453,  454,  457,  458,
-      459,  460,  461,  479,  463,  464,  465,  466,  481,  482,
-      467,  468,  469,  470,  472,  473,  483,  485,  475,  477,
-      478,  486,  487,  488,  490,  492,  493,  494,  495,  496,
+      396,  419,  420,  421,  423,  424,  425,  398,  399,  400,
+      401,  403,  404,  406,  407,  429,  408,  430,  433,  410,
+      434,  411,  412,  436,  413,  414,  437,  416,  418,  438,
+      419,  420,  421,  423,  424,  425,  439,  441,  444,  445,
+      446,  450,  451,  452,  429,  454,  430,  433,  455,  434,
+      456,  457,  436,  458,  459,  437,  461,  464,  438,  465,
+      466,  467,  471,  472,  475,  439,  441,  444,  445,  446,
+      450,  451,  452,  476,  454,  477,  478,  455,  479,  456,
+      457,  481,  458,  459,  482,  461,  464,  483,  465,  466,
+      467,  471,  472,  475,  484,  485,  486,  487,  488,  490,
 
-      498,  501,  479,  502,  503,  506,  509,  481,  482,  510,
-      511,  514,  515,  517,  518,  483,  485,  519,  520,  521,
-      486,  487,  488,  490,  492,  493,  494,  495,  496,  498,
-      501,  523,  502,  503,  506,  509,    0,    0,  510,  511,
-      514,  515,  517,  518,    0,    0,  519,  520,  521,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-      523,  527,  527,  527,  527,  527,  527,  527,  527,  527,
-      527,  528,  528,  528,  528,  528,  528,  528,  528,  528,
-      528,  529,  529,  529,  529,  529,  529,  529,  529,  529,
-      529,  530,  530,  530,  530,  530,  530,  530,  530,  530,
+      491,  493,  476,  495,  477,  478,  496,  479,  497,  499,
+      481,  500,  501,  482,  503,  504,  483,  505,  506,  508,
+      510,  511,  512,  484,  485,  486,  487,  488,  490,  491,
+      493,  513,  495,  514,  516,  496,  519,  497,  499,  520,
+      500,  501,  521,  503,  504,  524,  505,  506,  508,  510,
+      511,  512,  527,  528,  529,  532,  533,  535,  536,  537,
+      513,  538,  514,  516,  539,  519,  541,    0,  520,    0,
+        0,  521,    0,    0,  524,    0,    0,    0,    0,    0,
+        0,  527,  528,  529,  532,  533,  535,  536,  537,    0,
+      538,    0,    0,  539,    0,  541,  545,  545,  545,  545,
 
-      530,  531,  531,  531,  531,  531,  531,  531,  531,  531,
-      531,  532,  532,  533,  533,  533,    0,  533,  534,  534,
-      534,  534,  535,  535,  535,    0,  535,  535,  535,  535,
-      535,  535,  536,  536,  536,    0,  536,  536,  536,  536,
-        0,  536,  537,  537,  537,  537,  537,  537,  537,  537,
-      537,  537,  538,  538,    0,  538,  538,  538,  538,  538,
-      538,  538,  539,    0,  539,  539,  539,  539,  539,  539,
-      539,  539,  540,  540,  541,  541,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+      545,  545,  545,  545,  545,  545,  546,  546,  546,  546,
+      546,  546,  546,  546,  546,  546,  547,  547,  547,  547,
+      547,  547,  547,  547,  547,  547,  548,  548,  548,  548,
+      548,  548,  548,  548,  548,  548,  549,  549,  549,  549,
+      549,  549,  549,  549,  549,  549,  550,  550,  551,  551,
+      551,    0,  551,  552,  552,  552,  552,  553,  553,  553,
+        0,  553,  553,  553,  553,  553,  553,  554,  554,  554,
+        0,  554,  554,  554,  554,    0,  554,  555,  555,  555,
+      555,  555,  555,  555,  555,  555,  555,  556,  556,    0,
+      556,  556,  556,  556,  556,  556,  556,  557,    0,  557,
 
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
-      526,  526,  526,  526,  526,  526,  526,  526
+      557,  557,  557,  557,  557,  557,  557,  558,  558,  559,
+      559,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  544,  544,  544,
+      544,  544,  544
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[145] =
+static yyconst flex_int32_t yy_rule_can_match_eol[151] =
     {   0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -915,8 +927,8 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 
-    0, 1, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
+    0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1033,7 +1045,7 @@
 
 
 
-#line 1037 "SqlLexer_gen.cpp"
+#line 1049 "SqlLexer_gen.cpp"
 
 #define INITIAL 0
 #define CONDITION_SQL 1
@@ -1324,7 +1336,7 @@
 #line 128 "../SqlLexer.lpp"
 
 
-#line 1328 "SqlLexer_gen.cpp"
+#line 1340 "SqlLexer_gen.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1351,13 +1363,13 @@
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 527 )
+				if ( yy_current_state >= 545 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 526 );
+		while ( yy_current_state != 544 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1576,27 +1588,27 @@
 case 32:
 YY_RULE_SETUP
 #line 194 "../SqlLexer.lpp"
-return TOKEN_DECIMAL;
+return TOKEN_DAY;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
 #line 195 "../SqlLexer.lpp"
-return TOKEN_DEFAULT;
+return TOKEN_DECIMAL;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
 #line 196 "../SqlLexer.lpp"
-return TOKEN_DELETE;
+return TOKEN_DEFAULT;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
 #line 197 "../SqlLexer.lpp"
-return TOKEN_DELIMITER;
+return TOKEN_DELETE;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
 #line 198 "../SqlLexer.lpp"
-return TOKEN_DESC;
+return TOKEN_DELIMITER;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
@@ -1606,426 +1618,456 @@
 case 38:
 YY_RULE_SETUP
 #line 200 "../SqlLexer.lpp"
-return TOKEN_DISTINCT;
+return TOKEN_DESC;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
 #line 201 "../SqlLexer.lpp"
-return TOKEN_DOUBLE;
+return TOKEN_DISTINCT;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 202 "../SqlLexer.lpp"
-return TOKEN_DROP;
+return TOKEN_DOUBLE;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 203 "../SqlLexer.lpp"
-return TOKEN_ELSE;
+return TOKEN_DROP;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 204 "../SqlLexer.lpp"
-return TOKEN_END;
+return TOKEN_ELSE;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 205 "../SqlLexer.lpp"
-return TOKEN_ESCAPE_STRINGS;
+return TOKEN_END;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 206 "../SqlLexer.lpp"
-return TOKEN_EXISTS;
+return TOKEN_ESCAPE_STRINGS;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 207 "../SqlLexer.lpp"
-return TOKEN_EXTRACT;
+return TOKEN_EXISTS;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 208 "../SqlLexer.lpp"
-return TOKEN_FALSE;
+return TOKEN_EXTRACT;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 209 "../SqlLexer.lpp"
-return TOKEN_FIRST;
+return TOKEN_FALSE;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 210 "../SqlLexer.lpp"
-return TOKEN_FLOAT;
+return TOKEN_FIRST;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 211 "../SqlLexer.lpp"
-return TOKEN_FOREIGN;
+return TOKEN_FLOAT;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 212 "../SqlLexer.lpp"
-return TOKEN_FROM;
+return TOKEN_FOREIGN;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 213 "../SqlLexer.lpp"
-return TOKEN_FULL;
+return TOKEN_FROM;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 214 "../SqlLexer.lpp"
-return TOKEN_GROUP;
+return TOKEN_FULL;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 215 "../SqlLexer.lpp"
-return TOKEN_HASH;
+return TOKEN_GROUP;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 216 "../SqlLexer.lpp"
-return TOKEN_HAVING;
+return TOKEN_HASH;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 217 "../SqlLexer.lpp"
-return TOKEN_IN;
+return TOKEN_HAVING;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 218 "../SqlLexer.lpp"
-return TOKEN_INDEX;
+return TOKEN_HOUR;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 219 "../SqlLexer.lpp"
-return TOKEN_INNER;
+return TOKEN_IN;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 220 "../SqlLexer.lpp"
-return TOKEN_INSERT;
+return TOKEN_INDEX;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 221 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+return TOKEN_INNER;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 222 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+return TOKEN_INSERT;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 223 "../SqlLexer.lpp"
-return TOKEN_INTERVAL;
+return TOKEN_INTEGER;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 224 "../SqlLexer.lpp"
-return TOKEN_INTO;
+return TOKEN_INTEGER;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
 #line 225 "../SqlLexer.lpp"
-return TOKEN_IS;
+return TOKEN_INTERVAL;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
 #line 226 "../SqlLexer.lpp"
-return TOKEN_JOIN;
+return TOKEN_INTO;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 227 "../SqlLexer.lpp"
-return TOKEN_KEY;
+return TOKEN_IS;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 228 "../SqlLexer.lpp"
-return TOKEN_LAST;
+return TOKEN_JOIN;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 229 "../SqlLexer.lpp"
-return TOKEN_LEFT;
+return TOKEN_KEY;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 230 "../SqlLexer.lpp"
-return TOKEN_LIKE;
+return TOKEN_LAST;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 231 "../SqlLexer.lpp"
-return TOKEN_LIMIT;
+return TOKEN_LEFT;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 232 "../SqlLexer.lpp"
-return TOKEN_LONG;
+return TOKEN_LIKE;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 233 "../SqlLexer.lpp"
-return TOKEN_NOT;
+return TOKEN_LIMIT;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
 #line 234 "../SqlLexer.lpp"
-return TOKEN_NULL;
+return TOKEN_LONG;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 235 "../SqlLexer.lpp"
-return TOKEN_NULLS;
+return TOKEN_MINUTE;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 236 "../SqlLexer.lpp"
-return TOKEN_OFF;
+return TOKEN_MONTH;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 237 "../SqlLexer.lpp"
-return TOKEN_ON;
+return TOKEN_NOT;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 238 "../SqlLexer.lpp"
-return TOKEN_OR;
+return TOKEN_NULL;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 239 "../SqlLexer.lpp"
-return TOKEN_ORDER;
+return TOKEN_NULLS;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
 #line 240 "../SqlLexer.lpp"
-return TOKEN_OUTER;
+return TOKEN_OFF;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
 #line 241 "../SqlLexer.lpp"
-return TOKEN_PARTITION;
+return TOKEN_ON;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
 #line 242 "../SqlLexer.lpp"
-return TOKEN_PARTITIONS;
+return TOKEN_OR;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
 #line 243 "../SqlLexer.lpp"
-return TOKEN_PERCENT;
+return TOKEN_ORDER;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 244 "../SqlLexer.lpp"
-return TOKEN_PRIMARY;
+return TOKEN_OUTER;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
 #line 245 "../SqlLexer.lpp"
-return TOKEN_QUIT;
+return TOKEN_PARTITION;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
 #line 246 "../SqlLexer.lpp"
-return TOKEN_RANGE;
+return TOKEN_PARTITIONS;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
 #line 247 "../SqlLexer.lpp"
-return TOKEN_REAL;
+return TOKEN_PERCENT;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
 #line 248 "../SqlLexer.lpp"
-return TOKEN_REFERENCES;
+return TOKEN_PRIMARY;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
 #line 249 "../SqlLexer.lpp"
-return TOKEN_REGEXP;
+return TOKEN_QUIT;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
 #line 250 "../SqlLexer.lpp"
-return TOKEN_RIGHT;
+return TOKEN_RANGE;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
 #line 251 "../SqlLexer.lpp"
-return TOKEN_ROW_DELIMITER;
+return TOKEN_REAL;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
 #line 252 "../SqlLexer.lpp"
-return TOKEN_SELECT;
+return TOKEN_REFERENCES;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
 #line 253 "../SqlLexer.lpp"
-return TOKEN_SET;
+return TOKEN_REGEXP;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
 #line 254 "../SqlLexer.lpp"
-return TOKEN_SMA;
+return TOKEN_RIGHT;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
 #line 255 "../SqlLexer.lpp"
-return TOKEN_SMALLINT;
+return TOKEN_ROW_DELIMITER;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
 #line 256 "../SqlLexer.lpp"
-return TOKEN_TABLE;
+return TOKEN_SECOND;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
 #line 257 "../SqlLexer.lpp"
-return TOKEN_THEN;
+return TOKEN_SELECT;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
 #line 258 "../SqlLexer.lpp"
-return TOKEN_TIME;
+return TOKEN_SET;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
 #line 259 "../SqlLexer.lpp"
-return TOKEN_TIMESTAMP;
+return TOKEN_SMA;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
 #line 260 "../SqlLexer.lpp"
-return TOKEN_TRUE;
+return TOKEN_SMALLINT;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
 #line 261 "../SqlLexer.lpp"
-return TOKEN_TUPLESAMPLE;
+return TOKEN_TABLE;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
 #line 262 "../SqlLexer.lpp"
-return TOKEN_UNIQUE;
+return TOKEN_THEN;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
 #line 263 "../SqlLexer.lpp"
-return TOKEN_UPDATE;
+return TOKEN_TIME;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
 #line 264 "../SqlLexer.lpp"
-return TOKEN_USING;
+return TOKEN_TIMESTAMP;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
 #line 265 "../SqlLexer.lpp"
-return TOKEN_VALUES;
+return TOKEN_TRUE;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
 #line 266 "../SqlLexer.lpp"
-return TOKEN_VARCHAR;
+return TOKEN_TUPLESAMPLE;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
 #line 267 "../SqlLexer.lpp"
-return TOKEN_WHEN;
+return TOKEN_UNIQUE;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
 #line 268 "../SqlLexer.lpp"
-return TOKEN_WHERE;
+return TOKEN_UPDATE;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
 #line 269 "../SqlLexer.lpp"
-return TOKEN_WITH;
+return TOKEN_USING;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
 #line 270 "../SqlLexer.lpp"
-return TOKEN_YEARMONTH;
+return TOKEN_VALUES;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 272 "../SqlLexer.lpp"
-return TOKEN_EQ;
+#line 271 "../SqlLexer.lpp"
+return TOKEN_VARCHAR;
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 273 "../SqlLexer.lpp"
-return TOKEN_NEQ;
+#line 272 "../SqlLexer.lpp"
+return TOKEN_WHEN;
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 274 "../SqlLexer.lpp"
-return TOKEN_NEQ;
+#line 273 "../SqlLexer.lpp"
+return TOKEN_WHERE;
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 275 "../SqlLexer.lpp"
-return TOKEN_LT;
+#line 274 "../SqlLexer.lpp"
+return TOKEN_WITH;
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 276 "../SqlLexer.lpp"
-return TOKEN_GT;
+#line 275 "../SqlLexer.lpp"
+return TOKEN_YEAR;
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 277 "../SqlLexer.lpp"
-return TOKEN_LEQ;
+#line 276 "../SqlLexer.lpp"
+return TOKEN_YEARMONTH;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
 #line 278 "../SqlLexer.lpp"
-return TOKEN_GEQ;
+return TOKEN_EQ;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 280 "../SqlLexer.lpp"
-return yytext[0];
+#line 279 "../SqlLexer.lpp"
+return TOKEN_NEQ;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
+#line 280 "../SqlLexer.lpp"
+return TOKEN_NEQ;
+	YY_BREAK
+case 118:
+YY_RULE_SETUP
 #line 281 "../SqlLexer.lpp"
+return TOKEN_LT;
+	YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 282 "../SqlLexer.lpp"
+return TOKEN_GT;
+	YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 283 "../SqlLexer.lpp"
+return TOKEN_LEQ;
+	YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 284 "../SqlLexer.lpp"
+return TOKEN_GEQ;
+	YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 286 "../SqlLexer.lpp"
+return yytext[0];
+	YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 287 "../SqlLexer.lpp"
 return yytext[0];
 	YY_BREAK
 /**
     * Quoted strings. Prefacing a string with an 'e' or 'E' causes escape
     * sequences to be processed (as in PostgreSQL).
     **/
-case 118:
+case 124:
 YY_RULE_SETUP
-#line 287 "../SqlLexer.lpp"
+#line 293 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED_ESCAPED);
   }
 	YY_BREAK
-case 119:
+case 125:
 YY_RULE_SETUP
-#line 292 "../SqlLexer.lpp"
+#line 298 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED);
   }
 	YY_BREAK
-case 120:
+case 126:
 YY_RULE_SETUP
-#line 297 "../SqlLexer.lpp"
+#line 303 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_DOUBLE_QUOTED);
@@ -2037,7 +2079,7 @@
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED):
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED_ESCAPED):
 case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
-#line 306 "../SqlLexer.lpp"
+#line 312 "../SqlLexer.lpp"
 {
     delete yylval->string_value_;
     BEGIN(INITIAL);
@@ -2048,9 +2090,9 @@
 
 /* Process escape sequences. */
 
-case 121:
+case 127:
 YY_RULE_SETUP
-#line 316 "../SqlLexer.lpp"
+#line 322 "../SqlLexer.lpp"
 {
     /* Octal code */
     unsigned int code;
@@ -2064,9 +2106,9 @@
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 122:
+case 128:
 YY_RULE_SETUP
-#line 328 "../SqlLexer.lpp"
+#line 334 "../SqlLexer.lpp"
 {
     /* Hexadecimal code */
     unsigned int code;
@@ -2074,9 +2116,9 @@
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 123:
+case 129:
 YY_RULE_SETUP
-#line 334 "../SqlLexer.lpp"
+#line 340 "../SqlLexer.lpp"
 {
     /* A numeric escape sequence that isn't correctly specified. */
     delete yylval->string_value_;
@@ -2085,58 +2127,58 @@
     return TOKEN_LEX_ERROR;
   }
 	YY_BREAK
-case 124:
+case 130:
 YY_RULE_SETUP
-#line 341 "../SqlLexer.lpp"
+#line 347 "../SqlLexer.lpp"
 {
     /* Backspace */
     yylval->string_value_->push_back('\b');
   }
 	YY_BREAK
-case 125:
+case 131:
 YY_RULE_SETUP
-#line 345 "../SqlLexer.lpp"
+#line 351 "../SqlLexer.lpp"
 {
     /* Form-feed */
     yylval->string_value_->push_back('\f');
   }
 	YY_BREAK
-case 126:
+case 132:
 YY_RULE_SETUP
-#line 349 "../SqlLexer.lpp"
+#line 355 "../SqlLexer.lpp"
 {
     /* Newline */
     yylval->string_value_->push_back('\n');
   }
 	YY_BREAK
-case 127:
+case 133:
 YY_RULE_SETUP
-#line 353 "../SqlLexer.lpp"
+#line 359 "../SqlLexer.lpp"
 {
     /* Carriage-return */
     yylval->string_value_->push_back('\r');
   }
 	YY_BREAK
-case 128:
+case 134:
 YY_RULE_SETUP
-#line 357 "../SqlLexer.lpp"
+#line 363 "../SqlLexer.lpp"
 {
     /* Horizontal Tab */
     yylval->string_value_->push_back('\t');
   }
 	YY_BREAK
-case 129:
-/* rule 129 can match eol */
+case 135:
+/* rule 135 can match eol */
 YY_RULE_SETUP
-#line 361 "../SqlLexer.lpp"
+#line 367 "../SqlLexer.lpp"
 {
     /* Any other character (including actual newline or carriage return) */
     yylval->string_value_->push_back(yytext[1]);
   }
 	YY_BREAK
-case 130:
+case 136:
 YY_RULE_SETUP
-#line 365 "../SqlLexer.lpp"
+#line 371 "../SqlLexer.lpp"
 {
     /* This should only be encountered right before an EOF. */
     delete yylval->string_value_;
@@ -2147,17 +2189,17 @@
 	YY_BREAK
 
 
-case 131:
+case 137:
 YY_RULE_SETUP
-#line 375 "../SqlLexer.lpp"
+#line 381 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('\'');
   }
 	YY_BREAK
-case 132:
+case 138:
 YY_RULE_SETUP
-#line 379 "../SqlLexer.lpp"
+#line 385 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2166,17 +2208,17 @@
 	YY_BREAK
 
 
-case 133:
+case 139:
 YY_RULE_SETUP
-#line 387 "../SqlLexer.lpp"
+#line 393 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('"');
   }
 	YY_BREAK
-case 134:
+case 140:
 YY_RULE_SETUP
-#line 391 "../SqlLexer.lpp"
+#line 397 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2184,94 +2226,94 @@
   }
 	YY_BREAK
 
-case 135:
-/* rule 135 can match eol */
+case 141:
+/* rule 141 can match eol */
 YY_RULE_SETUP
-#line 398 "../SqlLexer.lpp"
+#line 404 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 136:
-/* rule 136 can match eol */
+case 142:
+/* rule 142 can match eol */
 YY_RULE_SETUP
-#line 403 "../SqlLexer.lpp"
+#line 409 "../SqlLexer.lpp"
 {
   /* Scan up to a quote or escape sequence. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 137:
-/* rule 137 can match eol */
+case 143:
+/* rule 143 can match eol */
 YY_RULE_SETUP
-#line 408 "../SqlLexer.lpp"
+#line 414 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
 
-case 138:
+case 144:
 YY_RULE_SETUP
-#line 414 "../SqlLexer.lpp"
+#line 420 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(
         yylloc->first_line, yylloc->first_column, std::string(yytext, yyleng));
     return TOKEN_NAME;
   }
 	YY_BREAK
-case 139:
+case 145:
 YY_RULE_SETUP
-#line 420 "../SqlLexer.lpp"
+#line 426 "../SqlLexer.lpp"
 {
     yylval->numeric_literal_value_ = new quickstep::NumericParseLiteralValue(
         yylloc->first_line, yylloc->first_column, yytext);
     return TOKEN_UNSIGNED_NUMVAL;
   }
 	YY_BREAK
-case 140:
+case 146:
 YY_RULE_SETUP
-#line 426 "../SqlLexer.lpp"
+#line 432 "../SqlLexer.lpp"
 /* comment */
 	YY_BREAK
-case 141:
-/* rule 141 can match eol */
+case 147:
+/* rule 147 can match eol */
 YY_RULE_SETUP
-#line 428 "../SqlLexer.lpp"
+#line 434 "../SqlLexer.lpp"
 { yycolumn = 0; }
 	YY_BREAK
-case 142:
+case 148:
 YY_RULE_SETUP
-#line 430 "../SqlLexer.lpp"
+#line 436 "../SqlLexer.lpp"
 ; /* ignore white space */
 	YY_BREAK
 /* CONDITION_SQL */
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(CONDITION_COMMAND):
 case YY_STATE_EOF(CONDITION_SQL):
-#line 434 "../SqlLexer.lpp"
+#line 440 "../SqlLexer.lpp"
 {
   /* All conditions except for mutli-state string extracting conditions. */
   BEGIN(INITIAL);
   return TOKEN_EOF;
 }
 	YY_BREAK
-case 143:
+case 149:
 YY_RULE_SETUP
-#line 440 "../SqlLexer.lpp"
+#line 446 "../SqlLexer.lpp"
 {
   BEGIN(INITIAL);
   quickstep_yyerror(NULL, yyscanner, NULL, "illegal character");
   return TOKEN_LEX_ERROR;
 }
 	YY_BREAK
-case 144:
+case 150:
 YY_RULE_SETUP
-#line 446 "../SqlLexer.lpp"
+#line 452 "../SqlLexer.lpp"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2275 "SqlLexer_gen.cpp"
+#line 2317 "SqlLexer_gen.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2565,7 +2607,7 @@
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 527 )
+			if ( yy_current_state >= 545 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2594,11 +2636,11 @@
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 527 )
+		if ( yy_current_state >= 545 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 526);
+	yy_is_jam = (yy_current_state == 544);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -3432,7 +3474,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 446 "../SqlLexer.lpp"
+#line 452 "../SqlLexer.lpp"
 
 
 
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index b30d697..d629f04 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -360,7 +360,7 @@
 #undef YY_DECL
 #endif
 
-#line 446 "../SqlLexer.lpp"
+#line 452 "../SqlLexer.lpp"
 
 
 #line 367 "SqlLexer_gen.hpp"
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index d625dc7..f2cb8ca 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -227,78 +227,84 @@
     TOKEN_CREATE = 297,
     TOKEN_DATE = 298,
     TOKEN_DATETIME = 299,
-    TOKEN_DECIMAL = 300,
-    TOKEN_DEFAULT = 301,
-    TOKEN_DELETE = 302,
-    TOKEN_DELIMITER = 303,
-    TOKEN_DESC = 304,
-    TOKEN_DISTINCT = 305,
-    TOKEN_DOUBLE = 306,
-    TOKEN_DROP = 307,
-    TOKEN_ELSE = 308,
-    TOKEN_END = 309,
-    TOKEN_ESCAPE_STRINGS = 310,
-    TOKEN_EXISTS = 311,
-    TOKEN_EXTRACT = 312,
-    TOKEN_FALSE = 313,
-    TOKEN_FIRST = 314,
-    TOKEN_FLOAT = 315,
-    TOKEN_FOREIGN = 316,
-    TOKEN_FROM = 317,
-    TOKEN_FULL = 318,
-    TOKEN_GROUP = 319,
-    TOKEN_HASH = 320,
-    TOKEN_HAVING = 321,
-    TOKEN_IN = 322,
-    TOKEN_INDEX = 323,
-    TOKEN_INNER = 324,
-    TOKEN_INSERT = 325,
-    TOKEN_INTEGER = 326,
-    TOKEN_INTERVAL = 327,
-    TOKEN_INTO = 328,
-    TOKEN_JOIN = 329,
-    TOKEN_KEY = 330,
-    TOKEN_LAST = 331,
-    TOKEN_LEFT = 332,
-    TOKEN_LIMIT = 333,
-    TOKEN_LONG = 334,
-    TOKEN_NULL = 335,
-    TOKEN_NULLS = 336,
-    TOKEN_OFF = 337,
-    TOKEN_ON = 338,
-    TOKEN_ORDER = 339,
-    TOKEN_OUTER = 340,
-    TOKEN_PARTITION = 341,
-    TOKEN_PARTITIONS = 342,
-    TOKEN_PERCENT = 343,
-    TOKEN_PRIMARY = 344,
-    TOKEN_QUIT = 345,
-    TOKEN_RANGE = 346,
-    TOKEN_REAL = 347,
-    TOKEN_REFERENCES = 348,
-    TOKEN_RIGHT = 349,
-    TOKEN_ROW_DELIMITER = 350,
-    TOKEN_SELECT = 351,
-    TOKEN_SET = 352,
-    TOKEN_SMA = 353,
-    TOKEN_SMALLINT = 354,
-    TOKEN_TABLE = 355,
-    TOKEN_THEN = 356,
-    TOKEN_TIME = 357,
-    TOKEN_TIMESTAMP = 358,
-    TOKEN_TRUE = 359,
-    TOKEN_TUPLESAMPLE = 360,
-    TOKEN_UNIQUE = 361,
-    TOKEN_UPDATE = 362,
-    TOKEN_USING = 363,
-    TOKEN_VALUES = 364,
-    TOKEN_VARCHAR = 365,
-    TOKEN_WHEN = 366,
-    TOKEN_WHERE = 367,
-    TOKEN_WITH = 368,
-    TOKEN_YEARMONTH = 369,
-    TOKEN_EOF = 370,
-    TOKEN_LEX_ERROR = 371
+    TOKEN_DAY = 300,
+    TOKEN_DECIMAL = 301,
+    TOKEN_DEFAULT = 302,
+    TOKEN_DELETE = 303,
+    TOKEN_DELIMITER = 304,
+    TOKEN_DESC = 305,
+    TOKEN_DISTINCT = 306,
+    TOKEN_DOUBLE = 307,
+    TOKEN_DROP = 308,
+    TOKEN_ELSE = 309,
+    TOKEN_END = 310,
+    TOKEN_ESCAPE_STRINGS = 311,
+    TOKEN_EXISTS = 312,
+    TOKEN_EXTRACT = 313,
+    TOKEN_FALSE = 314,
+    TOKEN_FIRST = 315,
+    TOKEN_FLOAT = 316,
+    TOKEN_FOREIGN = 317,
+    TOKEN_FROM = 318,
+    TOKEN_FULL = 319,
+    TOKEN_GROUP = 320,
+    TOKEN_HASH = 321,
+    TOKEN_HAVING = 322,
+    TOKEN_HOUR = 323,
+    TOKEN_IN = 324,
+    TOKEN_INDEX = 325,
+    TOKEN_INNER = 326,
+    TOKEN_INSERT = 327,
+    TOKEN_INTEGER = 328,
+    TOKEN_INTERVAL = 329,
+    TOKEN_INTO = 330,
+    TOKEN_JOIN = 331,
+    TOKEN_KEY = 332,
+    TOKEN_LAST = 333,
+    TOKEN_LEFT = 334,
+    TOKEN_LIMIT = 335,
+    TOKEN_LONG = 336,
+    TOKEN_MINUTE = 337,
+    TOKEN_MONTH = 338,
+    TOKEN_NULL = 339,
+    TOKEN_NULLS = 340,
+    TOKEN_OFF = 341,
+    TOKEN_ON = 342,
+    TOKEN_ORDER = 343,
+    TOKEN_OUTER = 344,
+    TOKEN_PARTITION = 345,
+    TOKEN_PARTITIONS = 346,
+    TOKEN_PERCENT = 347,
+    TOKEN_PRIMARY = 348,
+    TOKEN_QUIT = 349,
+    TOKEN_RANGE = 350,
+    TOKEN_REAL = 351,
+    TOKEN_REFERENCES = 352,
+    TOKEN_RIGHT = 353,
+    TOKEN_ROW_DELIMITER = 354,
+    TOKEN_SECOND = 355,
+    TOKEN_SELECT = 356,
+    TOKEN_SET = 357,
+    TOKEN_SMA = 358,
+    TOKEN_SMALLINT = 359,
+    TOKEN_TABLE = 360,
+    TOKEN_THEN = 361,
+    TOKEN_TIME = 362,
+    TOKEN_TIMESTAMP = 363,
+    TOKEN_TRUE = 364,
+    TOKEN_TUPLESAMPLE = 365,
+    TOKEN_UNIQUE = 366,
+    TOKEN_UPDATE = 367,
+    TOKEN_USING = 368,
+    TOKEN_VALUES = 369,
+    TOKEN_VARCHAR = 370,
+    TOKEN_WHEN = 371,
+    TOKEN_WHERE = 372,
+    TOKEN_WITH = 373,
+    TOKEN_YEAR = 374,
+    TOKEN_YEARMONTH = 375,
+    TOKEN_EOF = 376,
+    TOKEN_LEX_ERROR = 377
   };
 #endif
 
@@ -390,7 +396,7 @@
   quickstep::ParseOrderBy *opt_order_by_clause_;
   bool *order_direction_;
   quickstep::ParseLimit *opt_limit_clause_;
-  
+
   quickstep::ParseSample *opt_sample_clause_;
 
   quickstep::PtrList<quickstep::ParseOrderByItem> *order_commalist_;
@@ -399,7 +405,7 @@
   quickstep::PtrVector<quickstep::ParseSubqueryTableReference> *with_list_;
   quickstep::ParseSubqueryTableReference *with_list_element_;
 
-#line 403 "SqlParser_gen.cpp" /* yacc.c:355  */
+#line 409 "SqlParser_gen.cpp" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -434,7 +440,7 @@
 #include "SqlLexer_gen.hpp"
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature);
 
-#line 438 "SqlParser_gen.cpp" /* yacc.c:358  */
+#line 444 "SqlParser_gen.cpp" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -678,21 +684,21 @@
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  47
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   975
+#define YYLAST   1191
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  128
+#define YYNTOKENS  134
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  94
+#define YYNNTS  95
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  254
+#define YYNRULES  262
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  470
+#define YYNSTATES  478
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   371
+#define YYMAXUTOK   377
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -702,11 +708,11 @@
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     123,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     129,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,   127,     2,     2,
-     124,   125,    23,    21,   126,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   122,
+       2,     2,     2,     2,     2,     2,     2,   133,     2,     2,
+     130,   131,    23,    21,   132,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   128,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -738,39 +744,40 @@
       90,    91,    92,    93,    94,    95,    96,    97,    98,    99,
      100,   101,   102,   103,   104,   105,   106,   107,   108,   109,
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
-     120,   121
+     120,   121,   122,   123,   124,   125,   126,   127
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   575,   575,   579,   583,   587,   591,   594,   601,   604,
-     607,   610,   613,   616,   619,   622,   625,   628,   634,   640,
-     647,   653,   660,   669,   674,   683,   688,   693,   697,   703,
-     708,   711,   714,   719,   722,   725,   728,   731,   734,   737,
-     740,   743,   746,   758,   761,   764,   782,   802,   805,   808,
-     813,   818,   824,   830,   839,   843,   849,   852,   857,   862,
-     867,   874,   881,   885,   891,   894,   899,   902,   907,   910,
-     915,   918,   937,   941,   947,   951,   957,   960,   963,   968,
-     971,   978,   983,   994,   999,  1003,  1007,  1013,  1016,  1022,
-    1030,  1033,  1036,  1042,  1047,  1050,  1055,  1059,  1063,  1067,
-    1073,  1078,  1083,  1087,  1093,  1099,  1102,  1107,  1112,  1116,
-    1122,  1128,  1134,  1137,  1141,  1147,  1150,  1155,  1159,  1165,
-    1168,  1171,  1176,  1181,  1186,  1189,  1192,  1197,  1200,  1203,
-    1206,  1209,  1212,  1215,  1218,  1223,  1226,  1231,  1235,  1239,
-    1242,  1246,  1249,  1254,  1257,  1262,  1265,  1270,  1274,  1280,
-    1283,  1288,  1291,  1296,  1299,  1304,  1307,  1326,  1330,  1336,
-    1343,  1346,  1349,  1354,  1357,  1360,  1366,  1369,  1374,  1379,
-    1388,  1393,  1402,  1407,  1410,  1415,  1418,  1423,  1429,  1435,
-    1438,  1441,  1444,  1447,  1450,  1456,  1465,  1468,  1473,  1476,
-    1481,  1484,  1489,  1492,  1495,  1498,  1501,  1504,  1509,  1513,
-    1517,  1520,  1525,  1530,  1533,  1538,  1542,  1548,  1553,  1557,
-    1563,  1568,  1571,  1576,  1580,  1586,  1589,  1592,  1595,  1607,
-    1611,  1630,  1645,  1649,  1655,  1658,  1663,  1667,  1674,  1677,
-    1680,  1683,  1686,  1689,  1692,  1695,  1698,  1701,  1706,  1717,
-    1720,  1725,  1728,  1731,  1737,  1741,  1747,  1750,  1758,  1761,
-    1764,  1767,  1773,  1778,  1783
+       0,   582,   582,   586,   590,   594,   598,   601,   608,   611,
+     614,   617,   620,   623,   626,   629,   632,   635,   641,   647,
+     654,   660,   667,   676,   681,   690,   695,   700,   704,   710,
+     715,   718,   721,   726,   729,   732,   735,   738,   741,   744,
+     747,   750,   753,   765,   768,   771,   789,   809,   812,   815,
+     820,   825,   831,   837,   846,   850,   856,   859,   864,   869,
+     874,   881,   888,   892,   898,   901,   906,   909,   914,   917,
+     922,   925,   944,   948,   954,   958,   964,   967,   970,   975,
+     978,   985,   990,  1001,  1006,  1010,  1014,  1020,  1023,  1029,
+    1037,  1040,  1043,  1049,  1054,  1057,  1062,  1066,  1070,  1074,
+    1080,  1085,  1090,  1094,  1100,  1106,  1109,  1114,  1119,  1123,
+    1129,  1135,  1141,  1144,  1148,  1154,  1157,  1162,  1166,  1172,
+    1175,  1178,  1183,  1188,  1193,  1196,  1199,  1204,  1207,  1210,
+    1213,  1216,  1219,  1222,  1225,  1230,  1233,  1238,  1242,  1246,
+    1249,  1253,  1256,  1261,  1264,  1269,  1272,  1277,  1281,  1287,
+    1290,  1295,  1298,  1303,  1306,  1311,  1314,  1333,  1337,  1343,
+    1350,  1353,  1356,  1361,  1364,  1367,  1373,  1376,  1381,  1386,
+    1395,  1400,  1409,  1414,  1417,  1422,  1425,  1430,  1436,  1442,
+    1445,  1448,  1451,  1454,  1457,  1463,  1472,  1475,  1480,  1483,
+    1488,  1491,  1496,  1499,  1502,  1505,  1508,  1511,  1514,  1519,
+    1523,  1527,  1530,  1535,  1540,  1543,  1548,  1552,  1558,  1563,
+    1567,  1573,  1578,  1581,  1586,  1590,  1596,  1599,  1602,  1605,
+    1617,  1621,  1640,  1653,  1668,  1671,  1674,  1677,  1680,  1683,
+    1688,  1692,  1698,  1701,  1706,  1710,  1717,  1720,  1723,  1726,
+    1729,  1732,  1735,  1738,  1741,  1744,  1749,  1760,  1763,  1768,
+    1771,  1774,  1780,  1784,  1790,  1793,  1801,  1804,  1807,  1810,
+    1816,  1821,  1826
 };
 #endif
 
@@ -790,26 +797,27 @@
   "TOKEN_BLOCKSAMPLE", "TOKEN_BLOOM_FILTER", "TOKEN_CSB_TREE", "TOKEN_BY",
   "TOKEN_CASE", "TOKEN_CHARACTER", "TOKEN_CHECK", "TOKEN_COLUMN",
   "TOKEN_CONSTRAINT", "TOKEN_COPY", "TOKEN_CREATE", "TOKEN_DATE",
-  "TOKEN_DATETIME", "TOKEN_DECIMAL", "TOKEN_DEFAULT", "TOKEN_DELETE",
-  "TOKEN_DELIMITER", "TOKEN_DESC", "TOKEN_DISTINCT", "TOKEN_DOUBLE",
-  "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END", "TOKEN_ESCAPE_STRINGS",
-  "TOKEN_EXISTS", "TOKEN_EXTRACT", "TOKEN_FALSE", "TOKEN_FIRST",
-  "TOKEN_FLOAT", "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL",
-  "TOKEN_GROUP", "TOKEN_HASH", "TOKEN_HAVING", "TOKEN_IN", "TOKEN_INDEX",
-  "TOKEN_INNER", "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL",
-  "TOKEN_INTO", "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT",
-  "TOKEN_LIMIT", "TOKEN_LONG", "TOKEN_NULL", "TOKEN_NULLS", "TOKEN_OFF",
+  "TOKEN_DATETIME", "TOKEN_DAY", "TOKEN_DECIMAL", "TOKEN_DEFAULT",
+  "TOKEN_DELETE", "TOKEN_DELIMITER", "TOKEN_DESC", "TOKEN_DISTINCT",
+  "TOKEN_DOUBLE", "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END",
+  "TOKEN_ESCAPE_STRINGS", "TOKEN_EXISTS", "TOKEN_EXTRACT", "TOKEN_FALSE",
+  "TOKEN_FIRST", "TOKEN_FLOAT", "TOKEN_FOREIGN", "TOKEN_FROM",
+  "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH", "TOKEN_HAVING", "TOKEN_HOUR",
+  "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER", "TOKEN_INSERT",
+  "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO", "TOKEN_JOIN",
+  "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT", "TOKEN_LIMIT", "TOKEN_LONG",
+  "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS", "TOKEN_OFF",
   "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_PARTITION",
   "TOKEN_PARTITIONS", "TOKEN_PERCENT", "TOKEN_PRIMARY", "TOKEN_QUIT",
   "TOKEN_RANGE", "TOKEN_REAL", "TOKEN_REFERENCES", "TOKEN_RIGHT",
-  "TOKEN_ROW_DELIMITER", "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMA",
-  "TOKEN_SMALLINT", "TOKEN_TABLE", "TOKEN_THEN", "TOKEN_TIME",
+  "TOKEN_ROW_DELIMITER", "TOKEN_SECOND", "TOKEN_SELECT", "TOKEN_SET",
+  "TOKEN_SMA", "TOKEN_SMALLINT", "TOKEN_TABLE", "TOKEN_THEN", "TOKEN_TIME",
   "TOKEN_TIMESTAMP", "TOKEN_TRUE", "TOKEN_TUPLESAMPLE", "TOKEN_UNIQUE",
   "TOKEN_UPDATE", "TOKEN_USING", "TOKEN_VALUES", "TOKEN_VARCHAR",
-  "TOKEN_WHEN", "TOKEN_WHERE", "TOKEN_WITH", "TOKEN_YEARMONTH",
-  "TOKEN_EOF", "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('", "')'", "','",
-  "'%'", "$accept", "start", "sql_statement", "quit_statement",
-  "alter_table_statement", "create_table_statement",
+  "TOKEN_WHEN", "TOKEN_WHERE", "TOKEN_WITH", "TOKEN_YEAR",
+  "TOKEN_YEARMONTH", "TOKEN_EOF", "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('",
+  "')'", "','", "'%'", "$accept", "start", "sql_statement",
+  "quit_statement", "alter_table_statement", "create_table_statement",
   "create_index_statement", "drop_table_statement", "column_def",
   "column_def_commalist", "data_type", "column_constraint_def",
   "column_constraint_def_list", "opt_column_constraint_def_list",
@@ -835,10 +843,11 @@
   "extract_function", "case_expression", "simple_when_clause_list",
   "simple_when_clause", "searched_when_clause_list",
   "searched_when_clause", "opt_else_clause", "expression_list",
-  "literal_value", "literal_value_commalist", "attribute_ref",
-  "attribute_ref_list", "comparison_operation", "unary_operation",
-  "add_operation", "multiply_operation", "name_commalist", "any_name",
-  "boolean_value", "command", "command_argument_list", YY_NULLPTR
+  "literal_value", "datetime_unit", "literal_value_commalist",
+  "attribute_ref", "attribute_ref_list", "comparison_operation",
+  "unary_operation", "add_operation", "multiply_operation",
+  "name_commalist", "any_name", "boolean_value", "command",
+  "command_argument_list", YY_NULLPTR
 };
 #endif
 
@@ -859,7 +868,8 @@
      340,   341,   342,   343,   344,   345,   346,   347,   348,   349,
      350,   351,   352,   353,   354,   355,   356,   357,   358,   359,
      360,   361,   362,   363,   364,   365,   366,   367,   368,   369,
-     370,   371,    59,    10,    40,    41,    44,    37
+     370,   371,   372,   373,   374,   375,   376,   377,    59,    10,
+      40,    41,    44,    37
 };
 # endif
 
@@ -877,137 +887,139 @@
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-      63,  -223,  -223,   -56,   229,   -15,     4,   -51,    14,  -223,
-      36,   229,   229,  -223,    96,   124,  -223,  -223,  -223,  -223,
-    -223,  -223,  -223,  -223,  -223,  -223,    97,  -223,    48,   101,
-     229,  -223,  -223,   133,   229,   229,   229,   229,   229,  -223,
-    -223,   493,    23,    79,  -223,   199,    60,  -223,  -223,  -223,
-     179,  -223,  -223,  -223,  -223,    27,   260,   181,   165,   158,
-    -223,   123,  -223,  -223,   289,   293,  -223,  -223,  -223,   526,
-     178,  -223,   232,  -223,  -223,   180,  -223,  -223,   306,  -223,
-    -223,  -223,  -223,  -223,  -223,   188,   242,   735,   320,   273,
-     248,  -223,   221,    22,  -223,  -223,  -223,  -223,  -223,  -223,
-    -223,   768,    -5,   229,   229,   223,   229,   229,   115,   194,
-     237,   229,   229,   405,  -223,  -223,   234,   229,  -223,  -223,
-    -223,   405,    51,   -22,  -223,   377,  -223,   229,  -223,   378,
-    -223,     7,  -223,    21,   158,   735,  -223,  -223,   229,   735,
-    -223,  -223,  -223,  -223,   735,   293,  -223,   229,   272,   -64,
-    -223,   375,  -223,   287,  -223,   138,  -223,   287,   229,    58,
-     229,   229,   265,  -223,   266,  -223,   148,   851,   614,   223,
-     405,   384,   385,  -223,  -223,   349,   379,   856,   155,    16,
-     735,    -2,  -223,   735,  -223,   336,   276,   331,   277,  -223,
-      15,   195,   111,  -223,   278,   195,    52,   334,  -223,  -223,
-      22,  -223,  -223,   280,   735,  -223,   261,   161,   229,  -223,
-     735,   281,  -223,   229,  -223,  -223,   283,   328,   333,   290,
-    -223,  -223,  -223,   117,   229,   303,    58,   229,  -223,   151,
-    -223,  -223,     5,    64,   405,   405,    25,  -223,  -223,  -223,
-    -223,  -223,  -223,  -223,  -223,   735,   298,   735,    13,  -223,
-     166,   309,   735,    38,  -223,   358,   261,  -223,  -223,   735,
-    -223,   129,   229,  -223,  -223,   335,  -223,   338,   339,   345,
-      21,  -223,   423,   424,   195,   393,   364,  -223,   173,  -223,
-     735,  -223,   261,  -223,  -223,   405,   312,   316,   229,   436,
-      24,   182,  -223,   190,   415,   157,  -223,   317,   326,  -223,
-     360,   324,   856,  -223,   369,   229,  -223,  -223,   151,  -223,
-    -223,   385,  -223,  -223,  -223,   735,   327,   246,   647,  -223,
-     261,   365,  -223,  -223,   856,   340,   261,   735,  -223,    26,
-    -223,  -223,  -223,  -223,  -223,    21,   111,   366,   367,  -223,
-     735,   405,   368,  -223,   261,    12,   229,   229,   192,  -223,
-    -223,  -223,  -223,  -223,  -223,  -223,   153,  -223,   229,  -223,
-    -223,  -223,  -223,   341,    58,   422,   371,  -223,   405,  -223,
-    -223,   344,  -223,   250,   647,  -223,   735,   198,  -223,  -223,
-     856,   261,  -223,   381,  -223,  -223,   337,   384,   431,   389,
-    -223,   204,   207,  -223,   468,    24,  -223,   229,  -223,  -223,
-     350,   435,  -223,    30,   229,   735,   210,   261,  -223,   213,
-     405,   735,   469,  -223,   380,  -223,  -223,  -223,   225,  -223,
-    -223,  -223,  -223,    11,   229,   118,  -223,   352,   261,  -223,
-    -223,   384,   353,  -223,   186,  -223,   229,  -223,   229,  -223,
-    -223,   229,  -223,   227,  -223,  -223,   356,  -223,   735,  -223,
-    -223,   397,   361,  -223,   247,  -223,   229,  -223,   -13,  -223,
-     229,  -223,   252,  -223,  -223,   257,   392,  -223,   479,  -223
+     921,  -223,  -223,   -82,   231,   -14,    56,    22,    74,  -223,
+      70,   231,   231,  -223,   135,   120,  -223,  -223,  -223,  -223,
+    -223,  -223,  -223,  -223,  -223,  -223,   -35,  -223,   -73,   177,
+     231,  -223,  -223,   121,   231,   231,   231,   231,   231,  -223,
+    -223,   576,    85,    63,  -223,   173,    77,  -223,  -223,  -223,
+     140,  -223,  -223,  -223,  -223,    18,   218,   144,    97,   119,
+    -223,     4,  -223,  -223,   240,   245,  -223,  -223,  -223,   642,
+     134,  -223,   187,  -223,  -223,   146,  -223,  -223,   265,  -223,
+    -223,  -223,  -223,  -223,  -223,   164,   203,   708,   290,   230,
+     176,  -223,  -223,   256,    20,  -223,  -223,  -223,  -223,  -223,
+    -223,  -223,   840,   -11,   231,   231,   182,   231,   231,   167,
+     206,   204,   231,   231,   483,  -223,  -223,   205,   231,  -223,
+    -223,  -223,   483,    47,   -10,  -223,   329,  -223,   129,   129,
+     330,  -223,   207,    26,  -223,    32,   119,   906,  -223,  -223,
+     231,   906,  -223,  -223,  -223,  -223,   906,   245,  -223,   231,
+     324,   -70,  -223,   331,  -223,   234,  -223,   125,  -223,   234,
+     231,    49,   231,   231,   211,  -223,   213,  -223,   137,   991,
+     774,   182,   390,   336,   339,  -223,  -223,  1117,   335,  1001,
+     142,    10,   906,    -9,  -223,   906,  -223,   296,   228,  -223,
+    -223,  -223,  -223,  -223,  -223,   292,  -223,   232,  -223,  -223,
+      21,   163,   122,  -223,   229,   163,   -13,   294,  -223,  -223,
+      20,  -223,  -223,   236,   906,  -223,   259,   152,   231,  -223,
+     906,  -223,   231,  -223,  -223,   238,   287,   288,   241,  -223,
+    -223,  -223,    61,   231,   258,    49,   231,  -223,   156,  -223,
+    -223,    -6,    69,   483,   483,    55,  -223,  -223,  -223,  -223,
+    -223,  -223,  -223,  -223,   906,   244,   906,     5,  -223,   154,
+     260,   906,    37,  -223,   317,   259,  -223,  -223,   906,  -223,
+     102,   231,  -223,  -223,   284,  -223,   291,   297,   301,    32,
+    -223,   377,   379,   163,   348,   320,  -223,   157,  -223,   906,
+    -223,   259,  -223,   483,   263,   268,   231,   394,   151,   159,
+    -223,   168,   378,    25,  -223,   272,   283,  -223,   318,   279,
+    1001,  -223,   332,   231,  -223,  -223,   156,  -223,  -223,   339,
+    -223,  -223,  -223,   906,   285,   161,   708,  -223,   259,   327,
+    -223,  -223,  1001,   289,   259,   906,  -223,    33,  -223,  -223,
+    -223,  -223,  -223,    32,   122,   321,   323,  -223,   906,   483,
+     328,  -223,   259,    13,   231,   231,   170,  -223,  -223,  -223,
+    -223,  -223,  -223,  -223,    76,  -223,   231,  -223,  -223,  -223,
+    -223,   299,    49,   381,   340,  -223,   483,  -223,  -223,   300,
+    -223,   200,   708,  -223,   906,   172,  -223,  -223,  1001,   259,
+    -223,   342,  -223,  -223,   311,   336,   382,   361,  -223,   175,
+     179,  -223,   443,   151,  -223,   231,  -223,  -223,   333,   410,
+    -223,    29,   231,   906,   183,   259,  -223,   185,   483,   906,
+     444,  -223,   355,  -223,  -223,  -223,   188,  -223,  -223,  -223,
+    -223,    16,   231,    -5,  -223,   334,   259,  -223,  -223,   336,
+     326,  -223,   155,  -223,   231,  -223,   231,  -223,  -223,   231,
+    -223,   190,  -223,  -223,   337,  -223,   906,  -223,  -223,   369,
+     341,  -223,   192,  -223,   231,  -223,   110,  -223,   231,  -223,
+     194,  -223,  -223,   201,   365,  -223,   455,  -223
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
      Performed when YYTABLE does not specify something else to do.  Zero
      means the default is an error.  */
-static const yytype_uint8 yydefact[] =
+static const yytype_uint16 yydefact[] =
 {
-       0,     6,   254,     0,     0,     0,     0,     0,     0,    18,
+       0,     6,   262,     0,     0,     0,     0,     0,     0,    18,
      112,     0,     0,     7,     0,     0,    15,     8,    10,    11,
-      13,    14,     9,    17,    12,    16,     0,   105,     0,   252,
-       0,   246,   247,     0,     0,     0,     0,     0,     0,   113,
+      13,    14,     9,    17,    12,    16,     0,   105,     0,   260,
+       0,   254,   255,     0,     0,     0,     0,     0,     0,   113,
      114,     0,     0,   107,   108,     0,   145,     1,     3,     2,
-       0,   106,     5,     4,   253,     0,     0,     0,     0,   166,
-      25,     0,   219,   216,     0,   238,   115,    40,    29,     0,
+       0,   106,     5,     4,   261,     0,     0,     0,     0,   166,
+      25,     0,   220,   217,     0,   246,   115,    40,    29,     0,
        0,    30,    31,    34,    36,     0,    37,    39,     0,    41,
-     215,    35,    38,    32,    33,     0,     0,     0,     0,     0,
-     116,   117,   121,   187,   189,   191,   194,   195,   196,   193,
-     192,     0,   224,     0,     0,     0,     0,     0,     0,     0,
-      94,     0,     0,     0,   101,   167,     0,     0,    91,   217,
-     218,     0,     0,   211,   208,     0,    43,     0,   220,     0,
-      44,     0,   221,     0,   166,     0,   239,   240,     0,     0,
-     120,   242,   243,   241,     0,     0,   190,     0,     0,   166,
-     103,     0,   109,     0,   110,     0,   244,     0,     0,     0,
-       0,     0,     0,    93,    66,    27,     0,     0,     0,     0,
-       0,   168,   170,   172,   174,     0,   192,     0,     0,     0,
-       0,   211,   205,     0,   209,     0,     0,     0,     0,   197,
+     216,    35,    38,    32,    33,     0,     0,     0,     0,     0,
+     116,   117,   198,   121,   187,   189,   191,   194,   195,   196,
+     193,   192,     0,   232,     0,     0,     0,     0,     0,     0,
+       0,    94,     0,     0,     0,   101,   167,     0,     0,    91,
+     218,   219,     0,     0,   212,   209,     0,    43,     0,   221,
+       0,    44,     0,     0,   223,     0,   166,     0,   247,   248,
+       0,     0,   120,   250,   251,   249,     0,     0,   190,     0,
+       0,   166,   103,     0,   109,     0,   110,     0,   252,     0,
+       0,     0,     0,     0,     0,    93,    66,    27,     0,     0,
+       0,     0,     0,   168,   170,   172,   174,     0,   192,     0,
+       0,     0,     0,   212,   206,     0,   210,     0,     0,   226,
+     227,   228,   225,   229,   224,     0,   222,     0,   123,   197,
        0,     0,   147,   136,   122,   141,   124,   149,   118,   119,
-     186,   188,   225,     0,     0,   198,   213,     0,     0,   100,
-       0,     0,   146,     0,    92,    19,     0,     0,     0,     0,
-      20,    21,    22,     0,     0,     0,    64,     0,    42,    56,
-     173,   181,     0,     0,     0,     0,     0,   228,   230,   231,
-     232,   233,   229,   234,   236,     0,     0,     0,     0,   222,
-       0,     0,     0,     0,   206,     0,   212,   204,    45,     0,
-      46,   127,     0,   137,   143,   133,   128,   129,   131,     0,
-       0,   140,     0,     0,   139,     0,   151,   199,     0,   200,
-       0,   102,   104,   123,   245,     0,     0,     0,     0,     0,
-       0,     0,   226,     0,   224,     0,    63,    65,    68,    28,
-       0,     0,     0,    47,     0,     0,    49,    55,    57,    26,
-     180,   169,   171,   235,   237,     0,     0,     0,     0,   182,
-     179,     0,   178,    90,     0,     0,   210,     0,   203,     0,
-     142,   144,   134,   130,   132,     0,   148,     0,     0,   138,
-       0,     0,   153,   201,   214,     0,     0,     0,     0,    96,
-     250,   251,   249,   248,    97,    95,     0,    67,     0,    83,
-      84,    85,    86,    87,     0,     0,    70,    48,     0,    51,
-      50,     0,    54,     0,     0,   184,     0,     0,   177,   223,
-       0,   207,   202,     0,   125,   126,   150,   152,     0,   155,
-      61,     0,     0,    58,     0,     0,   227,     0,    24,    62,
-       0,     0,    23,     0,     0,     0,     0,   175,   183,     0,
-       0,     0,     0,   111,     0,    59,    98,    99,     0,    74,
-      76,    77,    78,     0,     0,     0,    52,     0,   176,   185,
-      89,   135,   154,   157,   160,   156,     0,    88,     0,    82,
-      80,     0,    79,     0,    72,    73,     0,    53,     0,   161,
-     162,   163,     0,    75,     0,    69,     0,   158,     0,   159,
-       0,    81,     0,   164,   165,     0,     0,    60,     0,    71
+     186,   188,   233,     0,     0,   199,   214,     0,     0,   100,
+       0,   146,     0,    92,    19,     0,     0,     0,     0,    20,
+      21,    22,     0,     0,     0,    64,     0,    42,    56,   173,
+     181,     0,     0,     0,     0,     0,   236,   238,   239,   240,
+     241,   237,   242,   244,     0,     0,     0,     0,   230,     0,
+       0,     0,     0,   207,     0,   213,   205,    45,     0,    46,
+     127,     0,   137,   143,   133,   128,   129,   131,     0,     0,
+     140,     0,     0,   139,     0,   151,   200,     0,   201,     0,
+     102,   104,   253,     0,     0,     0,     0,     0,     0,     0,
+     234,     0,   232,     0,    63,    65,    68,    28,     0,     0,
+       0,    47,     0,     0,    49,    55,    57,    26,   180,   169,
+     171,   243,   245,     0,     0,     0,     0,   182,   179,     0,
+     178,    90,     0,     0,   211,     0,   204,     0,   142,   144,
+     134,   130,   132,     0,   148,     0,     0,   138,     0,     0,
+     153,   202,   215,     0,     0,     0,     0,    96,   258,   259,
+     257,   256,    97,    95,     0,    67,     0,    83,    84,    85,
+      86,    87,     0,     0,    70,    48,     0,    51,    50,     0,
+      54,     0,     0,   184,     0,     0,   177,   231,     0,   208,
+     203,     0,   125,   126,   150,   152,     0,   155,    61,     0,
+       0,    58,     0,     0,   235,     0,    24,    62,     0,     0,
+      23,     0,     0,     0,     0,   175,   183,     0,     0,     0,
+       0,   111,     0,    59,    98,    99,     0,    74,    76,    77,
+      78,     0,     0,     0,    52,     0,   176,   185,    89,   135,
+     154,   157,   160,   156,     0,    88,     0,    82,    80,     0,
+      79,     0,    72,    73,     0,    53,     0,   161,   162,   163,
+       0,    75,     0,    69,     0,   158,     0,   159,     0,    81,
+       0,   164,   165,     0,     0,    60,     0,    71
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -223,  -223,  -223,  -223,  -223,  -223,  -223,  -223,  -121,  -223,
-     321,   183,  -223,  -223,  -222,  -223,  -223,  -223,  -223,  -223,
-    -223,    68,    49,  -223,  -223,  -223,  -223,  -223,  -223,  -223,
-    -223,  -223,  -223,  -223,  -223,   285,  -223,  -223,  -223,   390,
-       9,  -223,  -223,  -223,   370,  -223,  -100,  -223,  -223,  -149,
-     160,  -143,    -9,  -223,  -223,  -223,  -223,  -223,  -223,    53,
-    -223,  -223,   107,  -223,  -120,   262,   268,   342,   -30,   372,
-     362,   403,  -123,  -223,  -223,  -223,   347,  -223,   394,   355,
-    -192,  -161,   127,  -107,  -223,  -223,  -223,  -223,  -223,  -115,
-      -4,   113,  -223,  -223
+    -223,  -223,  -223,  -223,  -223,  -223,  -223,  -223,  -131,  -223,
+     303,   150,  -223,  -223,  -222,  -223,  -223,  -223,  -223,  -223,
+    -223,    38,    27,  -223,  -223,  -223,  -223,  -223,  -223,  -223,
+    -223,  -223,  -223,  -223,  -223,   257,  -223,  -223,  -223,   372,
+      14,  -223,  -223,  -223,   343,  -223,   -94,  -223,  -223,  -181,
+     131,  -170,    -8,  -223,  -223,  -223,  -223,  -223,  -223,    28,
+    -223,  -223,   -58,  -223,  -121,   235,   237,   312,   -30,   344,
+     346,   384,  -130,  -223,  -223,  -223,   314,  -223,   359,   315,
+    -208,  -169,   366,   106,  -105,  -223,  -223,  -223,  -223,  -223,
+    -115,    -4,    98,  -223,  -223
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   165,   166,
-      88,   307,   308,   309,   220,   297,   298,   225,   366,   402,
-     446,   418,   419,   420,   421,   422,   363,   398,    21,    22,
-     163,   291,    23,    24,   149,   150,    25,    26,    43,    44,
-     211,    41,    89,    90,    91,   134,   191,   274,   269,   192,
-     193,   263,   264,   194,   276,   342,   389,   413,   432,   433,
-     451,   459,   114,   115,   171,   172,   173,   174,   175,    93,
-      94,    95,    96,    97,    98,   181,   182,   123,   124,   185,
-     207,    99,   250,   100,   293,   247,   101,   139,   144,   155,
-     102,   354,    28,    29
+      -1,    14,    15,    16,    17,    18,    19,    20,   167,   168,
+      88,   315,   316,   317,   229,   305,   306,   234,   374,   410,
+     454,   426,   427,   428,   429,   430,   371,   406,    21,    22,
+     165,   299,    23,    24,   151,   152,    25,    26,    43,    44,
+     132,    41,    89,    90,    91,   136,    92,   283,   278,   202,
+     203,   272,   273,   204,   285,   350,   397,   421,   440,   441,
+     459,   467,   115,   116,   173,   174,   175,   176,   177,    94,
+      95,    96,    97,    98,    99,   183,   184,   124,   125,   187,
+     217,   100,   195,   259,   101,   301,   256,   102,   141,   146,
+     157,   103,   362,    28,    29
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1015,290 +1027,336 @@
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      33,   179,   178,    45,   296,   154,   176,    42,    46,    27,
-     195,    92,   278,   234,   176,    31,   249,    32,   439,    31,
-     234,    32,   147,   321,   234,    31,    55,    32,   136,   137,
-      57,    58,    59,    60,    61,    51,   183,   215,   234,   122,
-     440,   261,   313,   314,   315,   141,   142,   136,   137,    30,
-     232,   463,   271,   113,    37,   108,   183,   131,    34,   136,
-     137,   176,   208,   176,     1,    39,     2,   195,   464,   231,
-     118,    36,   136,   137,   236,   237,   238,   239,   240,   241,
-     242,   243,   244,   245,   109,   136,   137,   350,   140,   272,
-      35,    40,    38,     3,   121,    45,    47,   316,   322,   151,
-      46,   216,   156,   157,    54,    92,   299,   164,   167,     4,
-       5,   351,   352,   156,   180,     6,    10,   292,   206,   148,
-       7,   336,   252,   187,   217,   103,   377,   176,   176,   196,
-     310,   339,   189,   353,   199,   441,   246,   390,     8,   190,
-     233,   369,   399,   202,   327,   190,   319,   195,   386,   143,
-     253,   382,   218,   256,   167,   426,   221,   222,     9,   158,
-     159,   300,   273,   379,    10,   345,   214,   180,    52,   219,
-     289,    53,    50,   348,   206,    11,   148,   290,   176,   265,
-     282,    12,   406,    13,   106,   266,   196,    46,   444,   189,
-    -127,    46,   359,   267,   301,   360,   361,   265,    10,    31,
-      56,    32,   302,   266,   151,   104,   394,   136,   137,   284,
-     268,   267,   195,   395,   445,   317,   375,   320,   449,   249,
-     294,   387,   326,   167,    10,    31,   262,    32,   268,   329,
-     105,   391,   392,    31,   176,    32,   303,   116,   160,   161,
-     450,   197,   136,   137,    48,   304,    49,   117,   403,   305,
-     344,   396,   138,   331,   330,   376,   209,   107,    46,   405,
-     362,   176,   306,   212,   213,   110,   196,   136,   137,   111,
-      46,   136,   137,   226,   227,   113,    31,    62,    32,    63,
-     251,   213,   136,   137,   156,   373,   279,   280,   206,   112,
-     431,   323,   324,    64,    65,   203,   119,   381,   343,   280,
-     120,   371,   125,   176,   127,    67,    68,   355,   356,   126,
-     206,   128,   129,    69,    70,   357,   358,   393,   213,   130,
-      71,    72,    73,   408,   280,   132,   454,   204,    74,   414,
-     213,   196,   415,   213,    75,   429,   280,    76,   430,   324,
-     133,   462,   156,   156,   206,   465,   407,   153,    77,    78,
-     437,   438,   455,   438,   294,   162,    79,    80,   177,   236,
-     237,   238,   239,   240,   241,   242,   243,   244,   245,    81,
-     136,   137,   461,   213,   135,   428,    82,   466,   213,    83,
-      84,   434,   467,   213,   186,   188,   210,    85,    10,   223,
-     224,    86,   234,   423,   235,   257,    87,   205,   259,   248,
-     427,   258,   260,   275,   270,   277,   283,   285,   286,    31,
-      62,    32,    63,   287,   288,   168,   295,   328,   434,   442,
-     423,   246,   318,   325,   335,   332,    64,    65,   333,   334,
-     337,   338,   452,   340,   423,   341,   346,   156,    67,    68,
-     347,   349,   147,   364,   365,   367,    69,    70,   368,   370,
-     378,   374,   156,    71,    72,    73,   156,   388,   400,   384,
-     385,    74,   401,   280,   380,   397,   169,    75,   404,   410,
-      76,   411,   412,   416,   424,   425,   435,   447,   436,   448,
-     456,    77,    78,   458,   468,   460,   469,   453,   229,    79,
-      80,   372,   443,   281,   152,   383,   311,    31,    62,    32,
-      63,   457,    81,   312,   146,   198,   201,   409,   417,    82,
-     230,   200,    83,    84,    64,    65,    66,   184,     0,     0,
-      85,     0,     0,     0,    86,     0,    67,    68,   254,   170,
-      31,    62,    32,    63,    69,    70,   255,     0,     0,     0,
-       0,    71,    72,    73,     0,     0,     0,    64,    65,    74,
-       0,     0,     0,     0,     0,    75,     0,     0,    76,    67,
-      68,     0,     0,     0,     0,     0,     0,    69,    70,    77,
-      78,     0,     0,     0,    71,    72,    73,    79,    80,     0,
-       0,     0,    74,     0,     0,     0,     0,     0,    75,     0,
-      81,    76,     0,     0,     0,     0,     0,    82,     0,     0,
-      83,    84,    77,    78,     0,     0,     0,     0,    85,     0,
-      79,    80,    86,     0,     0,     0,     0,    87,    31,    62,
-      32,    63,     0,    81,     0,     0,     0,     0,     0,     0,
-      82,     0,     0,    83,    84,    64,    65,     0,     0,     0,
-       0,    85,   121,     0,     0,    86,     0,    67,    68,     0,
-      87,    31,    62,    32,    63,    69,    70,     0,     0,     0,
-       0,     0,    71,    72,    73,     0,     0,     0,    64,    65,
-      74,     0,     0,     0,     0,   169,    75,     0,     0,    76,
-      67,    68,     0,     0,     0,     0,     0,     0,    69,    70,
-      77,    78,     0,     0,     0,    71,    72,    73,    79,    80,
+      33,   181,   243,   180,    45,   205,   287,    42,    46,   178,
+     258,    93,   156,   304,    27,   329,   149,   178,   243,   270,
+      31,   243,    32,   447,   281,    31,    55,    32,    30,   224,
+      57,    58,    59,    60,    61,   280,    31,   243,    32,   123,
+      51,   201,    50,   143,   144,   448,   109,   138,   139,   185,
+     185,   241,   114,    52,   138,   139,    53,   133,   138,   139,
+     367,    34,   218,   368,   369,   178,   452,   178,   138,   139,
+     205,    10,   321,   322,   323,   119,   110,   240,   207,   245,
+     246,   247,   248,   249,   250,   251,   252,   253,   254,   142,
+     138,   139,   225,   219,   330,   453,    35,    45,   344,    39,
+     153,    46,   282,   158,   159,   307,   201,    93,   166,   169,
+      10,   122,   182,   347,   158,   297,   226,   150,   385,   150,
+     216,   261,   298,   117,    36,   318,    40,    10,   300,   324,
+     402,   206,    37,   370,   118,    47,   209,   403,   178,   178,
+     394,   377,   242,   255,   398,   212,   449,   227,   335,   205,
+     407,   200,   262,   145,    38,   265,   169,   199,   230,   231,
+     434,   327,   200,   387,   390,   228,   308,    31,   182,    32,
+     384,   274,   353,   223,   414,   471,   138,   139,   275,   189,
+      54,   356,   138,   139,   216,   201,   276,   457,   178,    56,
+     291,   274,   104,   472,   271,   105,   206,    46,   275,   309,
+     199,    46,   190,  -127,   106,   277,   276,   107,   310,   413,
+     458,   160,   161,   205,   153,   358,   191,   192,   292,   258,
+     108,   138,   139,   111,   325,   277,   328,   113,   395,   302,
+     383,   334,   169,   338,   193,    31,   112,    32,   337,   399,
+     400,   114,   359,   360,   178,   311,    48,   120,    49,   201,
+     162,   163,   121,   194,   312,   411,   221,   222,   313,   352,
+      31,   404,    32,   339,   126,   361,   127,    46,   235,   236,
+     129,   178,   314,   260,   222,   206,   128,   138,   139,    46,
+     138,   139,   131,   288,   289,   331,   332,   140,   351,   289,
+     363,   364,   158,   381,   130,   134,   216,   439,   135,   365,
+     366,   401,   222,   416,   289,   389,   422,   222,   137,   379,
+     423,   222,   155,   178,   437,   289,   438,   332,   216,   445,
+     446,   463,   446,   469,   222,   474,   222,   164,    31,    62,
+      32,    63,   475,   222,   462,   179,   188,   197,   198,   206,
+      10,   232,   220,   233,   243,    64,    65,   213,   244,   470,
+     158,   158,   216,   473,   415,   257,   266,    67,    68,   267,
+     268,   279,   302,   269,   284,    69,    70,   286,   293,   294,
+     295,   296,    71,    72,   326,    73,   303,   336,   340,   333,
+     214,    74,   343,   436,   345,   341,   346,    75,   348,   442,
+      76,   342,   349,   354,    31,    62,    32,    63,   355,   357,
+     170,   431,    77,    78,   372,   149,   373,   375,   435,   376,
+      79,    64,    65,    80,   378,   382,   386,   408,   392,   388,
+     393,   396,   419,    67,    68,    81,   442,   450,   431,   405,
+     412,    69,    70,    82,   418,   409,    83,    84,    71,    72,
+     460,    73,   431,   289,    85,   158,   420,    74,   424,    86,
+     433,   443,   171,    75,    87,   215,    76,   444,   456,   466,
+     158,   476,   477,   432,   158,   455,   380,   464,    77,    78,
+     451,   468,   238,   461,   391,   290,    79,   154,   319,    80,
+     208,   320,   239,   186,   465,   210,   148,    31,    62,    32,
+      63,    81,   211,   170,   417,   196,    10,   263,   264,    82,
+       0,   425,    83,    84,    64,    65,     0,     0,     0,     0,
+      85,     0,     0,     0,     0,    86,    67,    68,     0,     0,
+     172,     0,     0,     0,    69,    70,     0,     0,     0,     0,
+       0,    71,    72,     0,    73,     0,     0,     0,     0,     0,
+      74,     0,     0,     0,     0,   171,    75,     0,     0,    76,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    77,    78,     0,     0,     0,     0,     0,     0,    79,
+       0,     0,    80,     0,     0,     0,     0,     0,     0,     0,
+      31,    62,    32,    63,    81,     0,     0,     0,     0,     0,
+       0,     0,    82,     0,     0,    83,    84,    64,    65,    66,
+       0,     0,     0,    85,     0,     0,     0,     0,    86,    67,
+      68,     0,     0,   172,     0,     0,     0,    69,    70,     0,
+       0,     0,     0,     0,    71,    72,     0,    73,     0,     0,
        0,     0,     0,    74,     0,     0,     0,     0,     0,    75,
-       0,    81,    76,     0,     0,     0,     0,     0,    82,     0,
-       0,    83,    84,    77,    78,     0,     0,     0,     0,    85,
-       0,    79,    80,    86,     0,     0,     0,     0,   170,    31,
-      62,    32,    63,     0,    81,     0,     0,     0,    10,     0,
-       0,    82,     0,     0,    83,    84,    64,    65,     0,     0,
-       0,     0,    85,     0,     0,     0,    86,     0,    67,    68,
-       0,    87,    31,    62,    32,    63,    69,    70,     0,     0,
-       0,     0,     0,    71,    72,    73,     0,     0,     0,    64,
-     145,    74,     0,     0,     0,     0,     0,    75,     0,     0,
-      76,    67,    68,     0,     0,     0,     0,     0,     0,    69,
-      70,    77,    78,     0,     0,     0,    71,    72,    73,    79,
-      80,     0,     0,     0,    74,     0,     0,     0,     0,     0,
-      75,     0,    81,    76,     0,     0,     0,     0,     0,    82,
-       0,     0,    83,    84,    77,    78,     0,     0,     0,     0,
-      85,     0,    79,    80,    86,     0,     0,     0,     0,    87,
-       0,    62,     0,    63,     0,    81,     0,     0,     0,     0,
-       0,     0,    82,     0,     0,    83,    84,    64,   145,     0,
-       0,     0,     0,    85,    67,    68,     0,    86,     0,    67,
-      68,     0,    87,    70,     0,     0,     0,     0,    70,    71,
-      72,    73,     0,     0,    71,    72,    73,    74,     0,     0,
-       0,     0,    74,     0,     0,     0,    76,     0,     0,     0,
-       0,    76,     0,     0,     0,     0,     0,    77,   228,     0,
-       0,     0,    77,    78,     0,    79,     0,     0,     0,     0,
-      79,    80,     0,     0,     0,     0,     0,     0,    81,     0,
-       0,     0,     0,    81,     0,    82,     0,     0,    83,    84,
-      82,     0,     0,    83,    84,     0,    85,     0,     0,     0,
-      86,    85,     0,     0,     0,    86
+       0,     0,    76,     0,     0,     0,    31,    62,    32,    63,
+       0,     0,     0,     0,    77,    78,     0,     0,     0,     0,
+       0,     0,    79,    64,    65,    80,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    67,    68,    81,     0,     0,
+       0,     0,     0,    69,    70,    82,     0,     0,    83,    84,
+      71,    72,     0,    73,     0,     0,    85,     0,     0,    74,
+       0,    86,     0,     0,     0,    75,    87,     0,    76,     0,
+       0,     0,    31,    62,    32,    63,     0,     0,     0,     0,
+      77,    78,     0,     0,     0,     0,     0,     0,    79,    64,
+      65,    80,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    67,    68,    81,     0,     0,     0,     0,     0,    69,
+      70,    82,     0,     0,    83,    84,    71,    72,     0,    73,
+       0,     0,    85,   122,     0,    74,     0,    86,     0,     0,
+       0,    75,    87,     0,    76,     0,     0,     0,    31,    62,
+      32,    63,     0,     0,     0,     0,    77,    78,     0,     0,
+       0,     0,     0,     0,    79,    64,    65,    80,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    67,    68,    81,
+       0,     0,     0,     0,    10,    69,    70,    82,     0,     0,
+      83,    84,    71,    72,     0,    73,     0,     0,    85,     0,
+       0,    74,     0,    86,     0,     0,   171,    75,    87,     0,
+      76,     0,     0,     0,    31,    62,    32,    63,     0,     0,
+       0,     0,    77,    78,     0,     0,     0,     0,     0,     0,
+      79,    64,   147,    80,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    67,    68,    81,     0,     0,     0,     0,
+       0,    69,    70,    82,     0,     0,    83,    84,    71,    72,
+       0,    73,     0,     0,    85,     0,     0,    74,     0,    86,
+       0,     0,     0,    75,   172,     0,    76,     0,     0,     0,
+      31,    62,    32,    63,     0,     0,     0,     0,    77,    78,
+       0,     0,     1,     0,     2,     0,    79,    64,    65,    80,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    67,
+      68,    81,     0,     0,     0,     0,     0,    69,    70,    82,
+       0,     3,    83,    84,    71,    72,     0,    73,     0,     0,
+      85,     0,     0,    74,     0,    86,     0,     4,     5,    75,
+      87,     0,    76,     0,     6,     0,     0,     0,     0,     7,
+       0,     0,     0,     0,    77,    78,     0,     0,     0,     0,
+       0,     0,    79,     0,     0,    80,     0,     0,     8,     0,
+       0,     0,     0,     0,     0,     0,    62,    81,    63,     0,
+       0,     0,     0,     0,     0,    82,     0,     0,    83,    84,
+       9,     0,    64,   147,    67,    68,    85,    10,     0,     0,
+       0,    86,     0,    70,    67,    68,    87,     0,    11,    71,
+      72,     0,    73,    70,    12,     0,     0,    13,    74,    71,
+      72,     0,    73,     0,     0,     0,     0,    76,    74,     0,
+       0,     0,     0,     0,     0,     0,     0,    76,     0,    77,
+     237,     0,     0,     0,     0,     0,     0,    79,     0,    77,
+      78,     0,     0,     0,     0,     0,     0,    79,     0,     0,
+      80,     0,    81,     0,     0,     0,     0,     0,     0,     0,
+      82,     0,    81,    83,    84,     0,     0,     0,     0,     0,
+      82,    85,     0,    83,    84,     0,    86,     0,     0,     0,
+       0,    85,     0,     0,     0,     0,    86,   245,   246,   247,
+     248,   249,   250,   251,   252,   253,   254,     0,   138,   139,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   255
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,   121,   117,    12,   226,   105,   113,    11,    12,     0,
-     133,    41,   204,     8,   121,     4,   177,     6,     7,     4,
-       8,     6,    27,    10,     8,     4,    30,     6,    21,    22,
-      34,    35,    36,    37,    38,    26,    58,   158,     8,    69,
-      29,   190,    17,    18,    19,    23,    24,    21,    22,   105,
-     170,    64,   195,   117,   105,    28,    58,    87,    73,    21,
-      22,   168,   126,   170,     1,    29,     3,   190,    81,   169,
-      61,    67,    21,    22,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    57,    21,    22,    63,    92,    37,
-     105,    55,    78,    30,   116,   104,     0,    72,    85,   103,
-     104,    43,   106,   107,     3,   135,   227,   111,   112,    46,
-      47,    87,    88,   117,   116,    52,   101,   224,   148,   124,
-      57,   270,   106,   127,    66,   102,   318,   234,   235,   133,
-     125,   274,   125,   109,   138,   124,    72,   125,    75,   124,
-     170,   302,   364,   147,   106,   124,   246,   270,   340,   127,
-     180,   125,    94,   183,   158,   125,   160,   161,    95,    44,
-      45,    10,   110,   324,   101,   285,   157,   116,   120,   111,
-      53,   123,    75,   288,   204,   112,   124,    60,   285,    68,
-     210,   118,   374,   120,   124,    74,   190,   191,    70,   125,
-      79,   195,    35,    82,    43,    38,    39,    68,   101,     4,
-      67,     6,    51,    74,   208,   126,    53,    21,    22,   213,
-      99,    82,   335,    60,    96,   245,   316,   247,    32,   380,
-     224,   341,   252,   227,   101,     4,    31,     6,    99,   259,
-      31,   346,   347,     4,   341,     6,    85,   114,    44,    45,
-      54,   134,    21,    22,   120,    94,   122,   124,   368,    98,
-     280,   358,    31,   262,   125,     9,   149,    78,   262,     9,
-     103,   368,   111,   125,   126,     5,   270,    21,    22,    88,
-     274,    21,    22,   125,   126,   117,     4,     5,     6,     7,
-     125,   126,    21,    22,   288,   315,   125,   126,   318,   124,
-     410,   125,   126,    21,    22,    23,     7,   327,   125,   126,
-       7,   305,   124,   410,   124,    33,    34,   125,   126,    77,
-     340,     5,   124,    41,    42,   125,   126,   125,   126,    77,
-      48,    49,    50,   125,   126,     5,   441,    55,    56,   125,
-     126,   335,   125,   126,    62,   125,   126,    65,   125,   126,
-      67,   456,   346,   347,   374,   460,   376,   124,    76,    77,
-     125,   126,   125,   126,   358,   118,    84,    85,   124,    10,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    97,
-      21,    22,   125,   126,   126,   405,   104,   125,   126,   107,
-     108,   411,   125,   126,     7,     7,    11,   115,   101,   124,
-     124,   119,     8,   397,     9,    59,   124,   125,    67,    20,
-     404,   125,   125,    69,   126,   125,   125,   124,    80,     4,
-       5,     6,     7,    80,   124,    10,   113,    59,   448,   423,
-     424,    72,   124,   114,    79,    90,    21,    22,    90,    90,
-       7,     7,   436,    40,   438,    71,   124,   441,    33,    34,
-     124,     5,    27,   126,   118,    85,    41,    42,   124,    80,
-      85,   124,   456,    48,    49,    50,   460,    89,    36,    93,
-      93,    56,    91,   126,   124,   124,    61,    62,   124,    88,
-      65,    40,    83,     5,   124,    40,     7,   125,    98,   126,
-     124,    76,    77,    86,    92,   124,     7,   438,   167,    84,
-      85,   308,   424,   208,   104,   335,   234,     4,     5,     6,
-       7,   448,    97,   235,   101,   135,   144,   380,   395,   104,
-     168,   139,   107,   108,    21,    22,    23,   123,    -1,    -1,
-     115,    -1,    -1,    -1,   119,    -1,    33,    34,   181,   124,
-       4,     5,     6,     7,    41,    42,   181,    -1,    -1,    -1,
-      -1,    48,    49,    50,    -1,    -1,    -1,    21,    22,    56,
-      -1,    -1,    -1,    -1,    -1,    62,    -1,    -1,    65,    33,
-      34,    -1,    -1,    -1,    -1,    -1,    -1,    41,    42,    76,
-      77,    -1,    -1,    -1,    48,    49,    50,    84,    85,    -1,
-      -1,    -1,    56,    -1,    -1,    -1,    -1,    -1,    62,    -1,
-      97,    65,    -1,    -1,    -1,    -1,    -1,   104,    -1,    -1,
-     107,   108,    76,    77,    -1,    -1,    -1,    -1,   115,    -1,
-      84,    85,   119,    -1,    -1,    -1,    -1,   124,     4,     5,
-       6,     7,    -1,    97,    -1,    -1,    -1,    -1,    -1,    -1,
-     104,    -1,    -1,   107,   108,    21,    22,    -1,    -1,    -1,
-      -1,   115,   116,    -1,    -1,   119,    -1,    33,    34,    -1,
-     124,     4,     5,     6,     7,    41,    42,    -1,    -1,    -1,
-      -1,    -1,    48,    49,    50,    -1,    -1,    -1,    21,    22,
-      56,    -1,    -1,    -1,    -1,    61,    62,    -1,    -1,    65,
-      33,    34,    -1,    -1,    -1,    -1,    -1,    -1,    41,    42,
-      76,    77,    -1,    -1,    -1,    48,    49,    50,    84,    85,
-      -1,    -1,    -1,    56,    -1,    -1,    -1,    -1,    -1,    62,
-      -1,    97,    65,    -1,    -1,    -1,    -1,    -1,   104,    -1,
-      -1,   107,   108,    76,    77,    -1,    -1,    -1,    -1,   115,
-      -1,    84,    85,   119,    -1,    -1,    -1,    -1,   124,     4,
-       5,     6,     7,    -1,    97,    -1,    -1,    -1,   101,    -1,
-      -1,   104,    -1,    -1,   107,   108,    21,    22,    -1,    -1,
-      -1,    -1,   115,    -1,    -1,    -1,   119,    -1,    33,    34,
-      -1,   124,     4,     5,     6,     7,    41,    42,    -1,    -1,
-      -1,    -1,    -1,    48,    49,    50,    -1,    -1,    -1,    21,
-      22,    56,    -1,    -1,    -1,    -1,    -1,    62,    -1,    -1,
-      65,    33,    34,    -1,    -1,    -1,    -1,    -1,    -1,    41,
-      42,    76,    77,    -1,    -1,    -1,    48,    49,    50,    84,
-      85,    -1,    -1,    -1,    56,    -1,    -1,    -1,    -1,    -1,
-      62,    -1,    97,    65,    -1,    -1,    -1,    -1,    -1,   104,
-      -1,    -1,   107,   108,    76,    77,    -1,    -1,    -1,    -1,
-     115,    -1,    84,    85,   119,    -1,    -1,    -1,    -1,   124,
-      -1,     5,    -1,     7,    -1,    97,    -1,    -1,    -1,    -1,
-      -1,    -1,   104,    -1,    -1,   107,   108,    21,    22,    -1,
-      -1,    -1,    -1,   115,    33,    34,    -1,   119,    -1,    33,
-      34,    -1,   124,    42,    -1,    -1,    -1,    -1,    42,    48,
-      49,    50,    -1,    -1,    48,    49,    50,    56,    -1,    -1,
-      -1,    -1,    56,    -1,    -1,    -1,    65,    -1,    -1,    -1,
-      -1,    65,    -1,    -1,    -1,    -1,    -1,    76,    77,    -1,
-      -1,    -1,    76,    77,    -1,    84,    -1,    -1,    -1,    -1,
-      84,    85,    -1,    -1,    -1,    -1,    -1,    -1,    97,    -1,
-      -1,    -1,    -1,    97,    -1,   104,    -1,    -1,   107,   108,
-     104,    -1,    -1,   107,   108,    -1,   115,    -1,    -1,    -1,
-     119,   115,    -1,    -1,    -1,   119
+       4,   122,     8,   118,    12,   135,   214,    11,    12,   114,
+     179,    41,   106,   235,     0,    10,    27,   122,     8,   200,
+       4,     8,     6,     7,    37,     4,    30,     6,   110,   160,
+      34,    35,    36,    37,    38,   205,     4,     8,     6,    69,
+      26,   135,    77,    23,    24,    29,    28,    21,    22,    59,
+      59,   172,   122,   126,    21,    22,   129,    87,    21,    22,
+      35,    75,   132,    38,    39,   170,    71,   172,    21,    22,
+     200,   106,    17,    18,    19,    61,    58,   171,   136,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    93,
+      21,    22,    43,   151,    89,   100,   110,   105,   279,    29,
+     104,   105,   115,   107,   108,   236,   200,   137,   112,   113,
+     106,   121,   121,   283,   118,    54,    67,   130,   326,   130,
+     150,   111,    61,   119,    68,   131,    56,   106,   233,    74,
+      54,   135,   110,   108,   130,     0,   140,    61,   243,   244,
+     348,   310,   172,    74,   131,   149,   130,    98,   111,   279,
+     372,   130,   182,   133,    80,   185,   160,   131,   162,   163,
+     131,   255,   130,   332,   131,   116,    10,     4,   121,     6,
+       9,    69,   293,   159,   382,    65,    21,    22,    76,    50,
+       3,   296,    21,    22,   214,   279,    84,    32,   293,    68,
+     220,    69,   107,    83,    31,   132,   200,   201,    76,    43,
+     131,   205,    73,    81,    31,   103,    84,   130,    52,     9,
+      55,    44,    45,   343,   218,    64,    87,    88,   222,   388,
+      80,    21,    22,     5,   254,   103,   256,   130,   349,   233,
+     324,   261,   236,   131,   105,     4,    92,     6,   268,   354,
+     355,   122,    91,    92,   349,    89,   126,     7,   128,   343,
+      44,    45,     7,   124,    98,   376,   131,   132,   102,   289,
+       4,   366,     6,   271,   130,   114,    79,   271,   131,   132,
+       5,   376,   116,   131,   132,   279,   130,    21,    22,   283,
+      21,    22,    79,   131,   132,   131,   132,    31,   131,   132,
+     131,   132,   296,   323,   130,     5,   326,   418,    68,   131,
+     132,   131,   132,   131,   132,   335,   131,   132,   132,   313,
+     131,   132,   130,   418,   131,   132,   131,   132,   348,   131,
+     132,   131,   132,   131,   132,   131,   132,   123,     4,     5,
+       6,     7,   131,   132,   449,   130,     7,     7,   131,   343,
+     106,   130,    11,   130,     8,    21,    22,    23,     9,   464,
+     354,   355,   382,   468,   384,    20,    60,    33,    34,   131,
+      68,   132,   366,   131,    70,    41,    42,   131,   130,    82,
+      82,   130,    48,    49,   130,    51,   118,    60,    94,   119,
+      56,    57,    81,   413,     7,    94,     7,    63,    40,   419,
+      66,    94,    72,   130,     4,     5,     6,     7,   130,     5,
+      10,   405,    78,    79,   132,    27,   123,    89,   412,   130,
+      86,    21,    22,    89,    82,   130,    89,    36,    97,   130,
+      97,    93,    40,    33,    34,   101,   456,   431,   432,   130,
+     130,    41,    42,   109,    92,    95,   112,   113,    48,    49,
+     444,    51,   446,   132,   120,   449,    85,    57,     5,   125,
+      40,     7,    62,    63,   130,   131,    66,   102,   132,    90,
+     464,    96,     7,   130,   468,   131,   316,   130,    78,    79,
+     432,   130,   169,   446,   343,   218,    86,   105,   243,    89,
+     137,   244,   170,   124,   456,   141,   102,     4,     5,     6,
+       7,   101,   146,    10,   388,   129,   106,   183,   183,   109,
+      -1,   403,   112,   113,    21,    22,    -1,    -1,    -1,    -1,
+     120,    -1,    -1,    -1,    -1,   125,    33,    34,    -1,    -1,
+     130,    -1,    -1,    -1,    41,    42,    -1,    -1,    -1,    -1,
+      -1,    48,    49,    -1,    51,    -1,    -1,    -1,    -1,    -1,
+      57,    -1,    -1,    -1,    -1,    62,    63,    -1,    -1,    66,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    78,    79,    -1,    -1,    -1,    -1,    -1,    -1,    86,
+      -1,    -1,    89,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+       4,     5,     6,     7,   101,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   109,    -1,    -1,   112,   113,    21,    22,    23,
+      -1,    -1,    -1,   120,    -1,    -1,    -1,    -1,   125,    33,
+      34,    -1,    -1,   130,    -1,    -1,    -1,    41,    42,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    -1,    51,    -1,    -1,
+      -1,    -1,    -1,    57,    -1,    -1,    -1,    -1,    -1,    63,
+      -1,    -1,    66,    -1,    -1,    -1,     4,     5,     6,     7,
+      -1,    -1,    -1,    -1,    78,    79,    -1,    -1,    -1,    -1,
+      -1,    -1,    86,    21,    22,    89,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    33,    34,   101,    -1,    -1,
+      -1,    -1,    -1,    41,    42,   109,    -1,    -1,   112,   113,
+      48,    49,    -1,    51,    -1,    -1,   120,    -1,    -1,    57,
+      -1,   125,    -1,    -1,    -1,    63,   130,    -1,    66,    -1,
+      -1,    -1,     4,     5,     6,     7,    -1,    -1,    -1,    -1,
+      78,    79,    -1,    -1,    -1,    -1,    -1,    -1,    86,    21,
+      22,    89,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    33,    34,   101,    -1,    -1,    -1,    -1,    -1,    41,
+      42,   109,    -1,    -1,   112,   113,    48,    49,    -1,    51,
+      -1,    -1,   120,   121,    -1,    57,    -1,   125,    -1,    -1,
+      -1,    63,   130,    -1,    66,    -1,    -1,    -1,     4,     5,
+       6,     7,    -1,    -1,    -1,    -1,    78,    79,    -1,    -1,
+      -1,    -1,    -1,    -1,    86,    21,    22,    89,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,   101,
+      -1,    -1,    -1,    -1,   106,    41,    42,   109,    -1,    -1,
+     112,   113,    48,    49,    -1,    51,    -1,    -1,   120,    -1,
+      -1,    57,    -1,   125,    -1,    -1,    62,    63,   130,    -1,
+      66,    -1,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
+      -1,    -1,    78,    79,    -1,    -1,    -1,    -1,    -1,    -1,
+      86,    21,    22,    89,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    33,    34,   101,    -1,    -1,    -1,    -1,
+      -1,    41,    42,   109,    -1,    -1,   112,   113,    48,    49,
+      -1,    51,    -1,    -1,   120,    -1,    -1,    57,    -1,   125,
+      -1,    -1,    -1,    63,   130,    -1,    66,    -1,    -1,    -1,
+       4,     5,     6,     7,    -1,    -1,    -1,    -1,    78,    79,
+      -1,    -1,     1,    -1,     3,    -1,    86,    21,    22,    89,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    33,
+      34,   101,    -1,    -1,    -1,    -1,    -1,    41,    42,   109,
+      -1,    30,   112,   113,    48,    49,    -1,    51,    -1,    -1,
+     120,    -1,    -1,    57,    -1,   125,    -1,    46,    47,    63,
+     130,    -1,    66,    -1,    53,    -1,    -1,    -1,    -1,    58,
+      -1,    -1,    -1,    -1,    78,    79,    -1,    -1,    -1,    -1,
+      -1,    -1,    86,    -1,    -1,    89,    -1,    -1,    77,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,     5,   101,     7,    -1,
+      -1,    -1,    -1,    -1,    -1,   109,    -1,    -1,   112,   113,
+      99,    -1,    21,    22,    33,    34,   120,   106,    -1,    -1,
+      -1,   125,    -1,    42,    33,    34,   130,    -1,   117,    48,
+      49,    -1,    51,    42,   123,    -1,    -1,   126,    57,    48,
+      49,    -1,    51,    -1,    -1,    -1,    -1,    66,    57,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    66,    -1,    78,
+      79,    -1,    -1,    -1,    -1,    -1,    -1,    86,    -1,    78,
+      79,    -1,    -1,    -1,    -1,    -1,    -1,    86,    -1,    -1,
+      89,    -1,   101,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     109,    -1,   101,   112,   113,    -1,    -1,    -1,    -1,    -1,
+     109,   120,    -1,   112,   113,    -1,   125,    -1,    -1,    -1,
+      -1,   120,    -1,    -1,    -1,    -1,   125,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    -1,    21,    22,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    74
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     1,     3,    30,    46,    47,    52,    57,    75,    95,
-     101,   112,   118,   120,   129,   130,   131,   132,   133,   134,
-     135,   156,   157,   160,   161,   164,   165,   168,   220,   221,
-     105,     4,     6,   218,    73,   105,    67,   105,    78,    29,
-      55,   169,   218,   166,   167,   180,   218,     0,   120,   122,
-      75,   168,   120,   123,     3,   218,    67,   218,   218,   218,
-     218,   218,     5,     7,    21,    22,    23,    33,    34,    41,
-      42,    48,    49,    50,    56,    62,    65,    76,    77,    84,
-      85,    97,   104,   107,   108,   115,   119,   124,   138,   170,
-     171,   172,   196,   197,   198,   199,   200,   201,   202,   209,
-     211,   214,   218,   102,   126,    31,   124,    78,    28,    57,
-       5,    88,   124,   117,   190,   191,   114,   124,   168,     7,
-       7,   116,   196,   205,   206,   124,    77,   124,     5,   124,
-      77,   196,     5,    67,   173,   126,    21,    22,    31,   215,
-     218,    23,    24,   127,   216,    22,   199,    27,   124,   162,
-     163,   218,   167,   124,   174,   217,   218,   218,    44,    45,
-      44,    45,   118,   158,   218,   136,   137,   218,    10,    61,
-     124,   192,   193,   194,   195,   196,   211,   124,   217,   192,
-     116,   203,   204,    58,   206,   207,     7,   218,     7,   125,
-     124,   174,   177,   178,   181,   200,   218,   190,   172,   218,
-     197,   198,   218,    23,    55,   125,   196,   208,   126,   190,
-      11,   168,   125,   126,   168,   136,    43,    66,    94,   111,
-     142,   218,   218,   124,   124,   145,   125,   126,    77,   138,
-     195,   174,   192,   196,     8,     9,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    72,   213,    20,   209,
-     210,   125,   106,   196,   204,   207,   196,    59,   125,    67,
-     125,   177,    31,   179,   180,    68,    74,    82,    99,   176,
-     126,   179,    37,   110,   175,    69,   182,   125,   208,   125,
-     126,   163,   196,   125,   218,   124,    80,    80,   124,    53,
-      60,   159,   211,   212,   218,   113,   142,   143,   144,   136,
-      10,    43,    51,    85,    94,    98,   111,   139,   140,   141,
-     125,   193,   194,    17,    18,    19,    72,   196,   124,   174,
-     196,    10,    85,   125,   126,   114,   196,   106,    59,   196,
-     125,   180,    90,    90,    90,    79,   177,     7,     7,   179,
-      40,    71,   183,   125,   196,   192,   124,   124,   217,     5,
-      63,    87,    88,   109,   219,   125,   126,   125,   126,    35,
-      38,    39,   103,   154,   126,   118,   146,    85,   124,   209,
-      80,   218,   139,   196,   124,   174,     9,   208,    85,   209,
-     124,   196,   125,   178,    93,    93,   208,   192,    89,   184,
-     125,   217,   217,   125,    53,    60,   211,   124,   155,   142,
-      36,    91,   147,   192,   124,     9,   208,   196,   125,   210,
-      88,    40,    83,   185,   125,   125,     5,   219,   149,   150,
-     151,   152,   153,   218,   124,    40,   125,   218,   196,   125,
-     125,   192,   186,   187,   196,     7,    98,   125,   126,     7,
-      29,   124,   218,   149,    70,    96,   148,   125,   126,    32,
-      54,   188,   218,   150,   217,   125,   124,   187,    86,   189,
-     124,   125,   217,    64,    81,   217,   125,   125,    92,     7
+       0,     1,     3,    30,    46,    47,    53,    58,    77,    99,
+     106,   117,   123,   126,   135,   136,   137,   138,   139,   140,
+     141,   162,   163,   166,   167,   170,   171,   174,   227,   228,
+     110,     4,     6,   225,    75,   110,    68,   110,    80,    29,
+      56,   175,   225,   172,   173,   186,   225,     0,   126,   128,
+      77,   174,   126,   129,     3,   225,    68,   225,   225,   225,
+     225,   225,     5,     7,    21,    22,    23,    33,    34,    41,
+      42,    48,    49,    51,    57,    63,    66,    78,    79,    86,
+      89,   101,   109,   112,   113,   120,   125,   130,   144,   176,
+     177,   178,   180,   202,   203,   204,   205,   206,   207,   208,
+     215,   218,   221,   225,   107,   132,    31,   130,    80,    28,
+      58,     5,    92,   130,   122,   196,   197,   119,   130,   174,
+       7,     7,   121,   202,   211,   212,   130,    79,   130,     5,
+     130,    79,   174,   202,     5,    68,   179,   132,    21,    22,
+      31,   222,   225,    23,    24,   133,   223,    22,   205,    27,
+     130,   168,   169,   225,   173,   130,   180,   224,   225,   225,
+      44,    45,    44,    45,   123,   164,   225,   142,   143,   225,
+      10,    62,   130,   198,   199,   200,   201,   202,   218,   130,
+     224,   198,   121,   209,   210,    59,   212,   213,     7,    50,
+      73,    87,    88,   105,   124,   216,   216,     7,   131,   131,
+     130,   180,   183,   184,   187,   206,   225,   196,   178,   225,
+     203,   204,   225,    23,    56,   131,   202,   214,   132,   196,
+      11,   131,   132,   174,   142,    43,    67,    98,   116,   148,
+     225,   225,   130,   130,   151,   131,   132,    79,   144,   201,
+     180,   198,   202,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    74,   220,    20,   215,   217,
+     131,   111,   202,   210,   213,   202,    60,   131,    68,   131,
+     183,    31,   185,   186,    69,    76,    84,   103,   182,   132,
+     185,    37,   115,   181,    70,   188,   131,   214,   131,   132,
+     169,   202,   225,   130,    82,    82,   130,    54,    61,   165,
+     218,   219,   225,   118,   148,   149,   150,   142,    10,    43,
+      52,    89,    98,   102,   116,   145,   146,   147,   131,   199,
+     200,    17,    18,    19,    74,   202,   130,   180,   202,    10,
+      89,   131,   132,   119,   202,   111,    60,   202,   131,   186,
+      94,    94,    94,    81,   183,     7,     7,   185,    40,    72,
+     189,   131,   202,   198,   130,   130,   224,     5,    64,    91,
+      92,   114,   226,   131,   132,   131,   132,    35,    38,    39,
+     108,   160,   132,   123,   152,    89,   130,   215,    82,   225,
+     145,   202,   130,   180,     9,   214,    89,   215,   130,   202,
+     131,   184,    97,    97,   214,   198,    93,   190,   131,   224,
+     224,   131,    54,    61,   218,   130,   161,   148,    36,    95,
+     153,   198,   130,     9,   214,   202,   131,   217,    92,    40,
+      85,   191,   131,   131,     5,   226,   155,   156,   157,   158,
+     159,   225,   130,    40,   131,   225,   202,   131,   131,   198,
+     192,   193,   202,     7,   102,   131,   132,     7,    29,   130,
+     225,   155,    71,   100,   154,   131,   132,    32,    55,   194,
+     225,   156,   224,   131,   130,   193,    90,   195,   130,   131,
+     224,    65,    83,   224,   131,   131,    96,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,   128,   129,   129,   129,   129,   129,   129,   130,   130,
-     130,   130,   130,   130,   130,   130,   130,   130,   131,   132,
-     132,   132,   132,   133,   134,   135,   136,   137,   137,   138,
-     138,   138,   138,   138,   138,   138,   138,   138,   138,   138,
-     138,   138,   138,   138,   138,   138,   138,   139,   139,   139,
-     139,   139,   139,   139,   140,   140,   141,   141,   142,   142,
-     142,   142,   143,   143,   144,   144,   145,   145,   146,   146,
-     147,   147,   148,   148,   149,   149,   150,   150,   150,   151,
-     151,   152,   153,   154,   154,   154,   154,   155,   155,   156,
-     156,   156,   156,   157,   158,   158,   159,   159,   159,   159,
-     160,   161,   162,   162,   163,   164,   164,   165,   166,   166,
-     167,   168,   169,   169,   169,   170,   170,   171,   171,   172,
-     172,   172,   173,   174,   175,   175,   175,   176,   176,   176,
-     176,   176,   176,   176,   176,   177,   177,   178,   178,   178,
-     178,   178,   178,   179,   179,   180,   180,   181,   181,   182,
-     182,   183,   183,   184,   184,   185,   185,   186,   186,   187,
-     188,   188,   188,   189,   189,   189,   190,   190,   191,   192,
-     192,   193,   193,   194,   194,   195,   195,   195,   195,   195,
-     195,   195,   195,   195,   195,   195,   196,   196,   197,   197,
-     198,   198,   199,   199,   199,   199,   199,   199,   200,   200,
-     200,   200,   201,   202,   202,   203,   203,   204,   205,   205,
-     206,   207,   207,   208,   208,   209,   209,   209,   209,   209,
-     209,   209,   210,   210,   211,   211,   212,   212,   213,   213,
-     213,   213,   213,   213,   213,   213,   213,   213,   214,   215,
-     215,   216,   216,   216,   217,   217,   218,   218,   219,   219,
-     219,   219,   220,   221,   221
+       0,   134,   135,   135,   135,   135,   135,   135,   136,   136,
+     136,   136,   136,   136,   136,   136,   136,   136,   137,   138,
+     138,   138,   138,   139,   140,   141,   142,   143,   143,   144,
+     144,   144,   144,   144,   144,   144,   144,   144,   144,   144,
+     144,   144,   144,   144,   144,   144,   144,   145,   145,   145,
+     145,   145,   145,   145,   146,   146,   147,   147,   148,   148,
+     148,   148,   149,   149,   150,   150,   151,   151,   152,   152,
+     153,   153,   154,   154,   155,   155,   156,   156,   156,   157,
+     157,   158,   159,   160,   160,   160,   160,   161,   161,   162,
+     162,   162,   162,   163,   164,   164,   165,   165,   165,   165,
+     166,   167,   168,   168,   169,   170,   170,   171,   172,   172,
+     173,   174,   175,   175,   175,   176,   176,   177,   177,   178,
+     178,   178,   179,   180,   181,   181,   181,   182,   182,   182,
+     182,   182,   182,   182,   182,   183,   183,   184,   184,   184,
+     184,   184,   184,   185,   185,   186,   186,   187,   187,   188,
+     188,   189,   189,   190,   190,   191,   191,   192,   192,   193,
+     194,   194,   194,   195,   195,   195,   196,   196,   197,   198,
+     198,   199,   199,   200,   200,   201,   201,   201,   201,   201,
+     201,   201,   201,   201,   201,   201,   202,   202,   203,   203,
+     204,   204,   205,   205,   205,   205,   205,   205,   205,   206,
+     206,   206,   206,   207,   208,   208,   209,   209,   210,   211,
+     211,   212,   213,   213,   214,   214,   215,   215,   215,   215,
+     215,   215,   215,   215,   216,   216,   216,   216,   216,   216,
+     217,   217,   218,   218,   219,   219,   220,   220,   220,   220,
+     220,   220,   220,   220,   220,   220,   221,   222,   222,   223,
+     223,   223,   224,   224,   225,   225,   226,   226,   226,   226,
+     227,   228,   228
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -1323,13 +1381,14 @@
        0,     1,     1,     0,     2,     2,     0,     1,     2,     3,
        1,     3,     1,     2,     1,     5,     6,     4,     3,     3,
        3,     2,     3,     5,     4,     6,     3,     1,     3,     1,
-       2,     1,     1,     1,     1,     1,     1,     3,     3,     4,
-       4,     5,     6,     5,     4,     1,     2,     4,     1,     2,
-       4,     0,     2,     1,     3,     1,     1,     2,     2,     1,
-       2,     2,     1,     3,     1,     3,     1,     3,     1,     1,
-       1,     1,     1,     1,     1,     2,     1,     2,     1,     1,
-       1,     1,     1,     1,     1,     3,     1,     1,     1,     1,
-       1,     1,     2,     2,     0
+       2,     1,     1,     1,     1,     1,     1,     3,     1,     3,
+       4,     4,     5,     6,     5,     4,     1,     2,     4,     1,
+       2,     4,     0,     2,     1,     3,     1,     1,     2,     2,
+       1,     2,     3,     2,     1,     1,     1,     1,     1,     1,
+       1,     3,     1,     3,     1,     3,     1,     1,     1,     1,
+       1,     1,     1,     2,     1,     2,     1,     1,     1,     1,
+       1,     1,     1,     3,     1,     1,     1,     1,     1,     1,
+       2,     2,     0
 };
 
 
@@ -1826,909 +1885,919 @@
   switch (yytype)
     {
           case 3: /* TOKEN_COMMAND  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1836 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1895 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 4: /* TOKEN_NAME  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1846 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1905 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 5: /* TOKEN_STRING_SINGLE_QUOTED  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1856 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1915 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 6: /* TOKEN_STRING_DOUBLE_QUOTED  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1866 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1925 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 7: /* TOKEN_UNSIGNED_NUMVAL  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).numeric_literal_value_) != nullptr) {
     delete ((*yyvaluep).numeric_literal_value_);
   }
 }
-#line 1876 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1935 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 130: /* sql_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 136: /* sql_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).statement_) != nullptr) {
     delete ((*yyvaluep).statement_);
   }
 }
-#line 1886 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1945 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 131: /* quit_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 137: /* quit_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).quit_statement_) != nullptr) {
     delete ((*yyvaluep).quit_statement_);
   }
 }
-#line 1896 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1955 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 132: /* alter_table_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 138: /* alter_table_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).statement_) != nullptr) {
     delete ((*yyvaluep).statement_);
   }
 }
-#line 1906 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1965 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 133: /* create_table_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 139: /* create_table_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).create_table_statement_) != nullptr) {
     delete ((*yyvaluep).create_table_statement_);
   }
 }
-#line 1916 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1975 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 134: /* create_index_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 140: /* create_index_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).statement_) != nullptr) {
     delete ((*yyvaluep).statement_);
   }
 }
-#line 1926 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1985 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 135: /* drop_table_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 141: /* drop_table_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).drop_table_statement_) != nullptr) {
     delete ((*yyvaluep).drop_table_statement_);
   }
 }
-#line 1936 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1995 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 136: /* column_def  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 142: /* column_def  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_definition_) != nullptr) {
     delete ((*yyvaluep).attribute_definition_);
   }
 }
-#line 1946 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2005 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 137: /* column_def_commalist  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 143: /* column_def_commalist  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_definition_list_) != nullptr) {
     delete ((*yyvaluep).attribute_definition_list_);
   }
 }
-#line 1956 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2015 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 138: /* data_type  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 144: /* data_type  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).data_type_) != nullptr) {
     delete ((*yyvaluep).data_type_);
   }
 }
-#line 1966 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2025 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 139: /* column_constraint_def  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 145: /* column_constraint_def  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).column_constraint_) != nullptr) {
     delete ((*yyvaluep).column_constraint_);
   }
 }
-#line 1976 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2035 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 140: /* column_constraint_def_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 146: /* column_constraint_def_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).column_constraint_list_) != nullptr) {
     delete ((*yyvaluep).column_constraint_list_);
   }
 }
-#line 1986 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2045 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 141: /* opt_column_constraint_def_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 147: /* opt_column_constraint_def_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).column_constraint_list_) != nullptr) {
     delete ((*yyvaluep).column_constraint_list_);
   }
 }
-#line 1996 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2055 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 145: /* opt_column_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 151: /* opt_column_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_list_) != nullptr) {
     delete ((*yyvaluep).attribute_list_);
   }
 }
-#line 2006 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2065 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 146: /* opt_block_properties  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 152: /* opt_block_properties  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).block_properties_) != nullptr) {
     delete ((*yyvaluep).block_properties_);
   }
 }
-#line 2016 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2075 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 147: /* opt_partition_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 153: /* opt_partition_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).partition_clause_) != nullptr) {
     delete ((*yyvaluep).partition_clause_);
   }
 }
-#line 2026 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2085 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 148: /* partition_type  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 154: /* partition_type  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2036 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2095 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 149: /* key_value_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 155: /* key_value_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_value_list_) != nullptr) {
     delete ((*yyvaluep).key_value_list_);
   }
 }
-#line 2046 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2105 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 150: /* key_value  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 156: /* key_value  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_value_) != nullptr) {
     delete ((*yyvaluep).key_value_);
   }
 }
-#line 2056 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2115 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 151: /* key_string_value  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 157: /* key_string_value  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_string_value_) != nullptr) {
     delete ((*yyvaluep).key_string_value_);
   }
 }
-#line 2066 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2125 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 152: /* key_string_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 158: /* key_string_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_string_list_) != nullptr) {
     delete ((*yyvaluep).key_string_list_);
   }
 }
-#line 2076 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2135 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 153: /* key_integer_value  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 159: /* key_integer_value  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_integer_value_) != nullptr) {
     delete ((*yyvaluep).key_integer_value_);
   }
 }
-#line 2086 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2145 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 154: /* index_type  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 160: /* index_type  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2096 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2155 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 155: /* opt_index_properties  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 161: /* opt_index_properties  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_value_list_) != nullptr) {
     delete ((*yyvaluep).key_value_list_);
   }
 }
-#line 2106 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2165 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 156: /* insert_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 162: /* insert_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).insert_statement_) != nullptr) {
     delete ((*yyvaluep).insert_statement_);
   }
 }
-#line 2116 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2175 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 157: /* copy_from_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 163: /* copy_from_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).copy_from_statement_) != nullptr) {
     delete ((*yyvaluep).copy_from_statement_);
   }
 }
-#line 2126 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2185 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 158: /* opt_copy_from_params  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 164: /* opt_copy_from_params  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).copy_from_params_) != nullptr) {
     delete ((*yyvaluep).copy_from_params_);
   }
 }
-#line 2136 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2195 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 159: /* copy_from_params  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 165: /* copy_from_params  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).copy_from_params_) != nullptr) {
     delete ((*yyvaluep).copy_from_params_);
   }
 }
-#line 2146 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2205 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 160: /* update_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 166: /* update_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).update_statement_) != nullptr) {
     delete ((*yyvaluep).update_statement_);
   }
 }
-#line 2156 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2215 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 161: /* delete_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 167: /* delete_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).delete_statement_) != nullptr) {
     delete ((*yyvaluep).delete_statement_);
   }
 }
-#line 2166 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2225 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 162: /* assignment_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 168: /* assignment_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).assignment_list_) != nullptr) {
     delete ((*yyvaluep).assignment_list_);
   }
 }
-#line 2176 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2235 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 163: /* assignment_item  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 169: /* assignment_item  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).assignment_) != nullptr) {
     delete ((*yyvaluep).assignment_);
   }
 }
-#line 2186 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2245 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 164: /* select_statement  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 170: /* select_statement  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).select_statement_) != nullptr) {
     delete ((*yyvaluep).select_statement_);
   }
 }
-#line 2196 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2255 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 165: /* with_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 171: /* with_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).with_list_) != nullptr) {
     delete ((*yyvaluep).with_list_);
   }
 }
-#line 2206 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2265 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 166: /* with_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 172: /* with_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).with_list_) != nullptr) {
     delete ((*yyvaluep).with_list_);
   }
 }
-#line 2216 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2275 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 167: /* with_list_element  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 173: /* with_list_element  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).with_list_element_) != nullptr) {
     delete ((*yyvaluep).with_list_element_);
   }
 }
-#line 2226 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2285 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 168: /* select_query  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 174: /* select_query  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).select_query_) != nullptr) {
     delete ((*yyvaluep).select_query_);
   }
 }
-#line 2236 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2295 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 170: /* selection  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 176: /* selection  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).selection_) != nullptr) {
     delete ((*yyvaluep).selection_);
   }
 }
-#line 2246 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2305 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 171: /* selection_item_commalist  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 177: /* selection_item_commalist  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).selection_list_) != nullptr) {
     delete ((*yyvaluep).selection_list_);
   }
 }
-#line 2256 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2315 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 172: /* selection_item  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 178: /* selection_item  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).selection_item_) != nullptr) {
     delete ((*yyvaluep).selection_item_);
   }
 }
-#line 2266 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2325 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 173: /* from_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 179: /* from_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_list_) != nullptr) {
     delete ((*yyvaluep).table_reference_list_);
   }
 }
-#line 2276 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2335 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 174: /* subquery_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 180: /* subquery_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).subquery_expression_) != nullptr) {
     delete ((*yyvaluep).subquery_expression_);
   }
 }
-#line 2286 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2345 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 175: /* opt_sample_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 181: /* opt_sample_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_sample_clause_) != nullptr) {
     delete ((*yyvaluep).opt_sample_clause_);
   }
 }
-#line 2296 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2355 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 176: /* join_type  */
-#line 564 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 182: /* join_type  */
+#line 571 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2302 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2361 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 177: /* joined_table_reference  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 183: /* joined_table_reference  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_) != nullptr) {
     delete ((*yyvaluep).table_reference_);
   }
 }
-#line 2312 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2371 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 178: /* table_reference  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 184: /* table_reference  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_) != nullptr) {
     delete ((*yyvaluep).table_reference_);
   }
 }
-#line 2322 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2381 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 179: /* table_reference_signature  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 185: /* table_reference_signature  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_signature_) != nullptr) {
     delete ((*yyvaluep).table_reference_signature_);
   }
 }
-#line 2332 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2391 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 180: /* table_reference_signature_primary  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 186: /* table_reference_signature_primary  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_signature_) != nullptr) {
     delete ((*yyvaluep).table_reference_signature_);
   }
 }
-#line 2342 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2401 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 181: /* joined_table_reference_commalist  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 187: /* joined_table_reference_commalist  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_list_) != nullptr) {
     delete ((*yyvaluep).table_reference_list_);
   }
 }
-#line 2352 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2411 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 182: /* opt_group_by_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 188: /* opt_group_by_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_group_by_clause_) != nullptr) {
     delete ((*yyvaluep).opt_group_by_clause_);
   }
 }
-#line 2362 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2421 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 183: /* opt_having_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 189: /* opt_having_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_having_clause_) != nullptr) {
     delete ((*yyvaluep).opt_having_clause_);
   }
 }
-#line 2372 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2431 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 184: /* opt_order_by_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 190: /* opt_order_by_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_order_by_clause_) != nullptr) {
     delete ((*yyvaluep).opt_order_by_clause_);
   }
 }
-#line 2382 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2441 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 185: /* opt_limit_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 191: /* opt_limit_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_limit_clause_) != nullptr) {
     delete ((*yyvaluep).opt_limit_clause_);
   }
 }
-#line 2392 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2451 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 186: /* order_commalist  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 192: /* order_commalist  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_commalist_) != nullptr) {
     delete ((*yyvaluep).order_commalist_);
   }
 }
-#line 2402 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2461 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 187: /* order_item  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 193: /* order_item  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_item_) != nullptr) {
     delete ((*yyvaluep).order_item_);
   }
 }
-#line 2412 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2471 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 188: /* opt_order_direction  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 194: /* opt_order_direction  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_direction_) != nullptr) {
     delete ((*yyvaluep).order_direction_);
   }
 }
-#line 2422 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2481 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 189: /* opt_nulls_first  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 195: /* opt_nulls_first  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_direction_) != nullptr) {
     delete ((*yyvaluep).order_direction_);
   }
 }
-#line 2432 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2491 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 190: /* opt_where_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 196: /* opt_where_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2442 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2501 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 191: /* where_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 197: /* where_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2452 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2511 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 192: /* or_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 198: /* or_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2462 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2521 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 193: /* and_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 199: /* and_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2472 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2531 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 194: /* not_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 200: /* not_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2482 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2541 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 195: /* predicate_expression_base  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 201: /* predicate_expression_base  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2492 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2551 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 196: /* add_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 202: /* add_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2502 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2561 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 197: /* multiply_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 203: /* multiply_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2512 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2571 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 198: /* unary_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 204: /* unary_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2522 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2581 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 199: /* expression_base  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 205: /* expression_base  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2532 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2591 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 200: /* function_call  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 206: /* function_call  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).function_call_) != nullptr) {
     delete ((*yyvaluep).function_call_);
   }
 }
-#line 2542 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2601 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 201: /* extract_function  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 207: /* extract_function  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2552 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2611 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 202: /* case_expression  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 208: /* case_expression  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2562 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2621 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 203: /* simple_when_clause_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 209: /* simple_when_clause_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).simple_when_clause_list_) != nullptr) {
     delete ((*yyvaluep).simple_when_clause_list_);
   }
 }
-#line 2572 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2631 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 204: /* simple_when_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 210: /* simple_when_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).simple_when_clause_) != nullptr) {
     delete ((*yyvaluep).simple_when_clause_);
   }
 }
-#line 2582 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2641 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 205: /* searched_when_clause_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 211: /* searched_when_clause_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).searched_when_clause_list_) != nullptr) {
     delete ((*yyvaluep).searched_when_clause_list_);
   }
 }
-#line 2592 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2651 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 206: /* searched_when_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 212: /* searched_when_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).searched_when_clause_) != nullptr) {
     delete ((*yyvaluep).searched_when_clause_);
   }
 }
-#line 2602 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2661 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 207: /* opt_else_clause  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 213: /* opt_else_clause  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2612 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2671 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 208: /* expression_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 214: /* expression_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_list_) != nullptr) {
     delete ((*yyvaluep).expression_list_);
   }
 }
-#line 2622 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2681 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 209: /* literal_value  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 215: /* literal_value  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).literal_value_) != nullptr) {
     delete ((*yyvaluep).literal_value_);
   }
 }
-#line 2632 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2691 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 210: /* literal_value_commalist  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
-      {
-  if (((*yyvaluep).literal_value_list_) != nullptr) {
-    delete ((*yyvaluep).literal_value_list_);
-  }
-}
-#line 2642 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 211: /* attribute_ref  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
-      {
-  if (((*yyvaluep).attribute_) != nullptr) {
-    delete ((*yyvaluep).attribute_);
-  }
-}
-#line 2652 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 212: /* attribute_ref_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
-      {
-  if (((*yyvaluep).attribute_list_) != nullptr) {
-    delete ((*yyvaluep).attribute_list_);
-  }
-}
-#line 2662 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 213: /* comparison_operation  */
-#line 561 "../SqlParser.ypp" /* yacc.c:1257  */
-      { }
-#line 2668 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 214: /* unary_operation  */
-#line 562 "../SqlParser.ypp" /* yacc.c:1257  */
-      { }
-#line 2674 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 215: /* add_operation  */
-#line 563 "../SqlParser.ypp" /* yacc.c:1257  */
-      { }
-#line 2680 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 216: /* multiply_operation  */
-#line 563 "../SqlParser.ypp" /* yacc.c:1257  */
-      { }
-#line 2686 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 217: /* name_commalist  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
-      {
-  if (((*yyvaluep).string_list_) != nullptr) {
-    delete ((*yyvaluep).string_list_);
-  }
-}
-#line 2696 "SqlParser_gen.cpp" /* yacc.c:1257  */
-        break;
-
-    case 218: /* any_name  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 216: /* datetime_unit  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2706 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2701 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 219: /* boolean_value  */
-#line 560 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 217: /* literal_value_commalist  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).literal_value_list_) != nullptr) {
+    delete ((*yyvaluep).literal_value_list_);
+  }
+}
+#line 2711 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 218: /* attribute_ref  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).attribute_) != nullptr) {
+    delete ((*yyvaluep).attribute_);
+  }
+}
+#line 2721 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 219: /* attribute_ref_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).attribute_list_) != nullptr) {
+    delete ((*yyvaluep).attribute_list_);
+  }
+}
+#line 2731 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 220: /* comparison_operation  */
+#line 568 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2712 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2737 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 220: /* command  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 221: /* unary_operation  */
+#line 569 "../SqlParser.ypp" /* yacc.c:1257  */
+      { }
+#line 2743 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 222: /* add_operation  */
+#line 570 "../SqlParser.ypp" /* yacc.c:1257  */
+      { }
+#line 2749 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 223: /* multiply_operation  */
+#line 570 "../SqlParser.ypp" /* yacc.c:1257  */
+      { }
+#line 2755 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 224: /* name_commalist  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).string_list_) != nullptr) {
+    delete ((*yyvaluep).string_list_);
+  }
+}
+#line 2765 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 225: /* any_name  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).string_value_) != nullptr) {
+    delete ((*yyvaluep).string_value_);
+  }
+}
+#line 2775 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 226: /* boolean_value  */
+#line 567 "../SqlParser.ypp" /* yacc.c:1257  */
+      { }
+#line 2781 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 227: /* command  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).command_) != nullptr) {
     delete ((*yyvaluep).command_);
   }
 }
-#line 2722 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2791 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 221: /* command_argument_list  */
-#line 566 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 228: /* command_argument_list  */
+#line 573 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).command_argument_list_) != nullptr) {
     delete ((*yyvaluep).command_argument_list_);
   }
 }
-#line 2732 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2801 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
 
@@ -3020,148 +3089,148 @@
   switch (yyn)
     {
         case 2:
-#line 575 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 582 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].statement_);
     YYACCEPT;
   }
-#line 3029 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3098 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 3:
-#line 579 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 586 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].statement_);
     YYACCEPT;
   }
-#line 3038 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3107 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 4:
-#line 583 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 590 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].command_);
     YYACCEPT;
   }
-#line 3047 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3116 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 5:
-#line 587 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 594 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].command_);
     YYACCEPT;
   }
-#line 3056 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3125 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 6:
-#line 591 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 598 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     YYABORT;
   }
-#line 3064 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3133 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 7:
-#line 594 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 601 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     // Regular yyparse() return codes are non-negative, so use a negative one here.
     return -1;
   }
-#line 3073 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3142 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 8:
-#line 601 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 608 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].statement_);
   }
-#line 3081 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3150 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 9:
-#line 604 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 611 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].copy_from_statement_);
   }
-#line 3089 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3158 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 10:
-#line 607 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 614 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].create_table_statement_);
   }
-#line 3097 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3166 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 11:
-#line 610 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 617 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].statement_);
   }
-#line 3105 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3174 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 12:
-#line 613 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 620 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].delete_statement_);
   }
-#line 3113 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3182 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 13:
-#line 616 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 623 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].drop_table_statement_);
   }
-#line 3121 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3190 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 14:
-#line 619 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 626 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].insert_statement_);
   }
-#line 3129 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3198 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 15:
-#line 622 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 629 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].quit_statement_);
   }
-#line 3137 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3206 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 16:
-#line 625 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 632 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].select_statement_);
   }
-#line 3145 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3214 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 17:
-#line 628 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 635 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].update_statement_);
   }
-#line 3153 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3222 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 18:
-#line 634 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 641 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.quit_statement_) = new quickstep::ParseStatementQuit((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 3161 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3230 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 19:
-#line 640 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 647 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
     delete (yyvsp[0].attribute_definition_);
@@ -3169,33 +3238,21 @@
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3173 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3242 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 20:
-#line 647 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 654 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
     (yyval.statement_) = nullptr;
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3184 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3253 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 21:
-#line 653 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    delete (yyvsp[-3].string_value_);
-    delete (yyvsp[0].string_value_);
-    (yyval.statement_) = nullptr;
-    NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
-    YYERROR;
-  }
-#line 3196 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 22:
 #line 660 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
@@ -3204,19 +3261,31 @@
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3208 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3265 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 22:
+#line 667 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    delete (yyvsp[-3].string_value_);
+    delete (yyvsp[0].string_value_);
+    (yyval.statement_) = nullptr;
+    NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
+    YYERROR;
+  }
+#line 3277 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 23:
-#line 669 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 676 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.create_table_statement_) = new quickstep::ParseStatementCreateTable((yylsp[-8]).first_line, (yylsp[-8]).first_column, (yyvsp[-6].string_value_), (yyvsp[-4].attribute_definition_list_), (yyvsp[-1].block_properties_), (yyvsp[0].partition_clause_));
   }
-#line 3216 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3285 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 24:
-#line 674 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 681 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].key_value_list_)) {
       (yyval.statement_) = new quickstep::ParseStatementCreateIndex((yylsp[-8]).first_line, (yylsp[-8]).first_column, (yyvsp[-6].string_value_), (yyvsp[-4].string_value_), (yyvsp[-3].attribute_list_), (yyvsp[-1].string_value_), (yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].key_value_list_));
@@ -3224,153 +3293,153 @@
       (yyval.statement_) = new quickstep::ParseStatementCreateIndex((yylsp[-8]).first_line, (yylsp[-8]).first_column, (yyvsp[-6].string_value_), (yyvsp[-4].string_value_), (yyvsp[-3].attribute_list_), (yyvsp[-1].string_value_));
     }
   }
-#line 3228 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3297 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 25:
-#line 683 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 690 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.drop_table_statement_) = new quickstep::ParseStatementDropTable((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[0].string_value_));
   }
-#line 3236 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3305 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 26:
-#line 688 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 695 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_definition_) = new quickstep::ParseAttributeDefinition((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-2].string_value_), (yyvsp[-1].data_type_), (yyvsp[0].column_constraint_list_));
   }
-#line 3244 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3313 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 27:
-#line 693 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 700 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_definition_list_) = new quickstep::PtrList<quickstep::ParseAttributeDefinition>();
     (yyval.attribute_definition_list_)->push_back((yyvsp[0].attribute_definition_));
   }
-#line 3253 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3322 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 28:
-#line 697 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 704 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_definition_list_) = (yyvsp[-2].attribute_definition_list_);
     (yyval.attribute_definition_list_)->push_back((yyvsp[0].attribute_definition_));
   }
-#line 3262 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3331 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 29:
-#line 703 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 710 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = nullptr;
     NotSupported(&(yylsp[0]), yyscanner, "BIT data type");
     YYERROR;
   }
-#line 3272 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3341 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 30:
-#line 708 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 715 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
   }
-#line 3280 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3349 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 31:
-#line 711 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 718 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
   }
-#line 3288 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3357 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 32:
-#line 714 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 721 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = nullptr;
     NotSupported(&(yylsp[0]), yyscanner, "TIME data type");
     YYERROR;
   }
-#line 3298 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3367 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 33:
-#line 719 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 726 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
   }
-#line 3306 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3375 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 34:
-#line 722 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 729 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
   }
-#line 3314 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3383 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 35:
-#line 725 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 732 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
   }
-#line 3322 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3391 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 36:
-#line 728 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 735 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
   }
-#line 3330 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3399 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 37:
-#line 731 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 738 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kFloat));
   }
-#line 3338 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3407 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 38:
-#line 734 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 741 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt));
   }
-#line 3346 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3415 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 39:
-#line 737 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 744 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt));
   }
-#line 3354 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3423 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 40:
-#line 740 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 747 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong));
   }
-#line 3362 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3431 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 41:
-#line 743 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 750 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong));
   }
-#line 3370 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3439 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 42:
-#line 746 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 753 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This pattern exhibits a shift/reduce conflict with the
@@ -3383,27 +3452,27 @@
         "or YEARMONTH INTERVAL");
     YYERROR;
   }
-#line 3387 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3456 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 43:
-#line 758 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 765 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetimeInterval));
   }
-#line 3395 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3464 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 44:
-#line 761 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 768 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kYearMonthInterval));
   }
-#line 3403 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3472 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 45:
-#line 764 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 771 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-1].numeric_literal_value_)->float_like()) {
       delete (yyvsp[-1].numeric_literal_value_);
@@ -3422,11 +3491,11 @@
       }
     }
   }
-#line 3426 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3495 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 46:
-#line 782 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 789 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-1].numeric_literal_value_)->float_like()) {
       delete (yyvsp[-1].numeric_literal_value_);
@@ -3445,69 +3514,69 @@
       }
     }
   }
-#line 3449 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3518 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 47:
-#line 802 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 809 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = new quickstep::ParseColumnConstraintNull((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 3457 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3526 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 48:
-#line 805 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 812 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = new quickstep::ParseColumnConstraintNotNull((yylsp[-1]).first_line, (yylsp[-1]).first_column);
   }
-#line 3465 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3534 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 49:
-#line 808 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 815 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     NotSupported(&(yylsp[0]), yyscanner, "Column Constraints (UNIQUE)");
     YYERROR;
   }
-#line 3475 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3544 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 50:
-#line 813 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 820 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     NotSupported(&(yylsp[-1]), yyscanner, "Column Constraints (PRIMARY KEY)");
     YYERROR;
   }
-#line 3485 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3554 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 51:
-#line 818 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 825 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     delete (yyvsp[0].literal_value_);
     NotSupported(&(yylsp[-1]), yyscanner, "Column Constraints (DEFAULT)");
     YYERROR;
   }
-#line 3496 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3565 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 52:
-#line 824 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 831 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     delete (yyvsp[-1].predicate_);
     NotSupported(&(yylsp[-3]), yyscanner, "Column Constraints (CHECK)");
     YYERROR;
   }
-#line 3507 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3576 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 53:
-#line 830 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 837 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     delete (yyvsp[-3].string_value_);
@@ -3515,65 +3584,65 @@
     NotSupported(&(yylsp[-4]), yyscanner, "Foreign Keys");
     YYERROR;
   }
-#line 3519 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3588 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 54:
-#line 839 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 846 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_list_) = (yyvsp[-1].column_constraint_list_);
     (yyval.column_constraint_list_)->push_back((yyvsp[0].column_constraint_));
   }
-#line 3528 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3597 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 55:
-#line 843 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 850 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_list_) = new quickstep::PtrList<quickstep::ParseColumnConstraint>();
     (yyval.column_constraint_list_)->push_back((yyvsp[0].column_constraint_));
   }
-#line 3537 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3606 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 56:
-#line 849 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 856 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_list_) = nullptr;
   }
-#line 3545 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3614 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 57:
-#line 852 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 859 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_list_) = (yyvsp[0].column_constraint_list_);
   }
-#line 3553 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3622 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 58:
-#line 857 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 864 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-1].string_list_);
     NotSupported(&(yylsp[-3]), yyscanner, "Table Constraints (UNIQUE)");
     YYERROR;
   }
-#line 3563 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3632 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 59:
-#line 862 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 869 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-1].string_list_);
     NotSupported(&(yylsp[-4]), yyscanner, "Table Constraints (PRIMARY KEY)");
     YYERROR;
   }
-#line 3573 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3642 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 60:
-#line 867 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 874 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-6].string_list_);
     delete (yyvsp[-3].string_value_);
@@ -3581,95 +3650,95 @@
     NotSupported(&(yylsp[-9]), yyscanner, "Table Constraints (FOREIGN KEY)");
     YYERROR;
   }
-#line 3585 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3654 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 61:
-#line 874 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 881 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-1].predicate_);
     NotSupported(&(yylsp[-3]), yyscanner, "Table Constraints (CHECK)");
     YYERROR;
   }
-#line 3595 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3664 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 62:
-#line 881 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 888 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[-2]), yyscanner, "Table Constraints");
     YYERROR;
   }
-#line 3604 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3673 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 63:
-#line 885 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 892 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[0]), yyscanner, "Table Constraints");
     YYERROR;
   }
-#line 3613 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3682 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 64:
-#line 891 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 898 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /* $$ = nullptr; */
   }
-#line 3621 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3690 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 65:
-#line 894 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 901 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /* $$ = $1; */
   }
-#line 3629 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3698 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 66:
-#line 899 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 906 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = nullptr;
   }
-#line 3637 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3706 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 67:
-#line 902 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 909 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = (yyvsp[-1].attribute_list_);
   }
-#line 3645 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3714 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 68:
-#line 907 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 914 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.block_properties_) = nullptr;
   }
-#line 3653 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3722 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 69:
-#line 910 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 917 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.block_properties_) = new quickstep::ParseBlockProperties((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-1].key_value_list_));
   }
-#line 3661 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3730 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 70:
-#line 915 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 922 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.partition_clause_) = nullptr;
   }
-#line 3669 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3738 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 71:
-#line 918 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 925 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].numeric_literal_value_)->float_like()) {
       delete (yyvsp[0].numeric_literal_value_);
@@ -3687,97 +3756,97 @@
       }
     }
   }
-#line 3691 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3760 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 72:
-#line 937 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 944 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column,
            std::to_string(quickstep::PartitionSchemeHeader::PartitionType::kHash));
   }
-#line 3700 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3769 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 73:
-#line 941 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 948 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column,
            std::to_string(quickstep::PartitionSchemeHeader::PartitionType::kRange));
   }
-#line 3709 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3778 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 74:
-#line 947 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 954 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_list_) = new quickstep::PtrList<quickstep::ParseKeyValue>();
     (yyval.key_value_list_)->push_back((yyvsp[0].key_value_));
   }
-#line 3718 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3787 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 75:
-#line 951 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 958 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_list_) = (yyvsp[-2].key_value_list_);
     (yyval.key_value_list_)->push_back((yyvsp[0].key_value_));
   }
-#line 3727 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3796 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 76:
-#line 957 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 964 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_) = (yyvsp[0].key_string_value_);
   }
-#line 3735 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3804 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 77:
-#line 960 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 967 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_) = (yyvsp[0].key_string_list_);
   }
-#line 3743 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3812 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 78:
-#line 963 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 970 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_) = (yyvsp[0].key_integer_value_);
   }
-#line 3751 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3820 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 79:
-#line 968 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 975 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_string_value_) = new quickstep::ParseKeyStringValue((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].string_value_));
   }
-#line 3759 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3828 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 80:
-#line 971 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 978 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     // This is a special case to handle the COMPRESS ALL option of the BLOCK PROPERTIES.
     (yyval.key_string_value_) = new quickstep::ParseKeyStringValue((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].string_value_),
         new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, "ALL"));
   }
-#line 3769 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3838 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 81:
-#line 978 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 985 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_string_list_) = new quickstep::ParseKeyStringList((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].string_list_));
   }
-#line 3777 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3846 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 82:
-#line 983 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 990 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].numeric_literal_value_)->float_like()) {
       delete (yyvsp[0].numeric_literal_value_);
@@ -3787,64 +3856,64 @@
     }
     (yyval.key_integer_value_) = new quickstep::ParseKeyIntegerValue((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].numeric_literal_value_));
   }
-#line 3791 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3860 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 83:
-#line 994 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1001 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     // Defaults to BitWeavingV, but IndexProperties can change this to H.
     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column,
            std::to_string(quickstep::IndexSubBlockType::kBitWeavingV));
   }
-#line 3801 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3870 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 84:
-#line 999 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1006 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column,
            std::to_string(quickstep::IndexSubBlockType::kBloomFilter));
   }
-#line 3810 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3879 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 85:
-#line 1003 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1010 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column,
            std::to_string(quickstep::IndexSubBlockType::kCSBTree));
   }
-#line 3819 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3888 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 86:
-#line 1007 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1014 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column,
            std::to_string(quickstep::IndexSubBlockType::kSMA));
   }
-#line 3828 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3897 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 87:
-#line 1013 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1020 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_list_) = nullptr;
   }
-#line 3836 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3905 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 88:
-#line 1016 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1023 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_list_) = (yyvsp[-1].key_value_list_);
   }
-#line 3844 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3913 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 89:
-#line 1022 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1029 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-7].string_value_);
     delete (yyvsp[-5].string_list_);
@@ -3853,557 +3922,557 @@
     NotSupported(&(yylsp[-6]), yyscanner, "list of column names in INSERT statement");
     YYERROR;
   }
-#line 3857 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3926 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 90:
-#line 1030 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1037 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.insert_statement_) = new quickstep::ParseStatementInsertTuple((yylsp[-6]).first_line, (yylsp[-6]).first_column, (yyvsp[-4].string_value_), (yyvsp[-1].literal_value_list_));
   }
-#line 3865 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3934 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 91:
-#line 1033 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1040 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.insert_statement_) = new quickstep::ParseStatementInsertSelection((yylsp[-3]).first_line, (yylsp[-2]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].select_query_), nullptr);
   }
-#line 3873 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3942 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 92:
-#line 1036 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1043 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.insert_statement_) = new quickstep::ParseStatementInsertSelection((yylsp[-4]).first_line, (yylsp[-3]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].select_query_), (yyvsp[-4].with_list_));
   }
-#line 3881 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3950 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 93:
-#line 1042 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1049 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.copy_from_statement_) = new quickstep::ParseStatementCopyFrom((yylsp[-4]).first_line, (yylsp[-4]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].string_value_), (yyvsp[0].copy_from_params_));
   }
-#line 3889 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3958 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 94:
-#line 1047 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1054 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.copy_from_params_) = nullptr;
   }
-#line 3897 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 95:
-#line 1050 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.copy_from_params_) = (yyvsp[-1].copy_from_params_);
-  }
-#line 3905 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 96:
-#line 1055 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.copy_from_params_) = new quickstep::ParseCopyFromParams((yylsp[-1]).first_line, (yylsp[-1]).first_column);
-    (yyval.copy_from_params_)->set_delimiter((yyvsp[0].string_value_));
-  }
-#line 3914 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 97:
-#line 1059 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.copy_from_params_) = new quickstep::ParseCopyFromParams((yylsp[-1]).first_line, (yylsp[-1]).first_column);
-    (yyval.copy_from_params_)->escape_strings = (yyvsp[0].boolean_value_);
-  }
-#line 3923 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 98:
-#line 1063 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.copy_from_params_) = (yyvsp[-3].copy_from_params_);
-    (yyval.copy_from_params_)->set_delimiter((yyvsp[0].string_value_));
-  }
-#line 3932 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 99:
-#line 1067 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.copy_from_params_) = (yyvsp[-3].copy_from_params_);
-    (yyval.copy_from_params_)->escape_strings = (yyvsp[0].boolean_value_);
-  }
-#line 3941 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 100:
-#line 1073 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.update_statement_) = new quickstep::ParseStatementUpdate((yylsp[-4]).first_line, (yylsp[-4]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].assignment_list_), (yyvsp[0].predicate_));
-  }
-#line 3949 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 101:
-#line 1078 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.delete_statement_) = new quickstep::ParseStatementDelete((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].predicate_));
-  }
-#line 3957 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 102:
-#line 1083 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.assignment_list_) = (yyvsp[-2].assignment_list_);
-    (yyval.assignment_list_)->push_back((yyvsp[0].assignment_));
-  }
 #line 3966 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 103:
-#line 1087 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 95:
+#line 1057 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.assignment_list_) = new quickstep::PtrList<quickstep::ParseAssignment>();
-    (yyval.assignment_list_)->push_back((yyvsp[0].assignment_));
+    (yyval.copy_from_params_) = (yyvsp[-1].copy_from_params_);
   }
-#line 3975 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3974 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 104:
-#line 1093 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 96:
+#line 1062 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.assignment_) = new quickstep::ParseAssignment((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-2].string_value_), (yyvsp[0].expression_));
+    (yyval.copy_from_params_) = new quickstep::ParseCopyFromParams((yylsp[-1]).first_line, (yylsp[-1]).first_column);
+    (yyval.copy_from_params_)->set_delimiter((yyvsp[0].string_value_));
   }
 #line 3983 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
+  case 97:
+#line 1066 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.copy_from_params_) = new quickstep::ParseCopyFromParams((yylsp[-1]).first_line, (yylsp[-1]).first_column);
+    (yyval.copy_from_params_)->escape_strings = (yyvsp[0].boolean_value_);
+  }
+#line 3992 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 98:
+#line 1070 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.copy_from_params_) = (yyvsp[-3].copy_from_params_);
+    (yyval.copy_from_params_)->set_delimiter((yyvsp[0].string_value_));
+  }
+#line 4001 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 99:
+#line 1074 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.copy_from_params_) = (yyvsp[-3].copy_from_params_);
+    (yyval.copy_from_params_)->escape_strings = (yyvsp[0].boolean_value_);
+  }
+#line 4010 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 100:
+#line 1080 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.update_statement_) = new quickstep::ParseStatementUpdate((yylsp[-4]).first_line, (yylsp[-4]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].assignment_list_), (yyvsp[0].predicate_));
+  }
+#line 4018 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 101:
+#line 1085 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.delete_statement_) = new quickstep::ParseStatementDelete((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].predicate_));
+  }
+#line 4026 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 102:
+#line 1090 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.assignment_list_) = (yyvsp[-2].assignment_list_);
+    (yyval.assignment_list_)->push_back((yyvsp[0].assignment_));
+  }
+#line 4035 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 103:
+#line 1094 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.assignment_list_) = new quickstep::PtrList<quickstep::ParseAssignment>();
+    (yyval.assignment_list_)->push_back((yyvsp[0].assignment_));
+  }
+#line 4044 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 104:
+#line 1100 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.assignment_) = new quickstep::ParseAssignment((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-2].string_value_), (yyvsp[0].expression_));
+  }
+#line 4052 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
   case 105:
-#line 1099 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1106 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.select_statement_) = new quickstep::ParseStatementSelect((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].select_query_), nullptr);
   }
-#line 3991 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4060 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 106:
-#line 1102 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1109 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.select_statement_) = new quickstep::ParseStatementSelect((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[0].select_query_), (yyvsp[-1].with_list_));
   }
-#line 3999 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 107:
-#line 1107 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.with_list_) = (yyvsp[0].with_list_);
-  }
-#line 4007 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 108:
-#line 1112 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.with_list_) = new quickstep::PtrVector<quickstep::ParseSubqueryTableReference>();
-    (yyval.with_list_)->push_back((yyvsp[0].with_list_element_));
-  }
-#line 4016 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 109:
-#line 1116 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.with_list_) = (yyvsp[-2].with_list_);
-    (yyval.with_list_)->push_back((yyvsp[0].with_list_element_));
-  }
-#line 4025 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 110:
-#line 1122 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.with_list_element_) = new quickstep::ParseSubqueryTableReference((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[0].subquery_expression_));
-    (yyval.with_list_element_)->set_table_reference_signature((yyvsp[-2].table_reference_signature_));
-  }
-#line 4034 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 111:
-#line 1129 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.select_query_) = new quickstep::ParseSelect((yylsp[-8]).first_line, (yylsp[-8]).first_column, (yyvsp[-6].selection_), (yyvsp[-5].table_reference_list_), (yyvsp[-4].predicate_), (yyvsp[-3].opt_group_by_clause_), (yyvsp[-2].opt_having_clause_), (yyvsp[-1].opt_order_by_clause_), (yyvsp[0].opt_limit_clause_));
-  }
-#line 4042 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 112:
-#line 1134 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    /* $$ = nullptr; */
-  }
-#line 4050 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 113:
-#line 1137 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    NotSupported(&(yylsp[0]), yyscanner, "ALL in selection");
-    YYERROR;
-  }
-#line 4059 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 114:
-#line 1141 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    NotSupported(&(yylsp[0]), yyscanner, "DISTINCT in selection");
-    YYERROR;
-  }
 #line 4068 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 115:
-#line 1147 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 107:
+#line 1114 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.selection_) = new quickstep::ParseSelectionStar((yylsp[0]).first_line, (yylsp[0]).first_column);
+    (yyval.with_list_) = (yyvsp[0].with_list_);
   }
 #line 4076 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
+  case 108:
+#line 1119 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.with_list_) = new quickstep::PtrVector<quickstep::ParseSubqueryTableReference>();
+    (yyval.with_list_)->push_back((yyvsp[0].with_list_element_));
+  }
+#line 4085 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 109:
+#line 1123 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.with_list_) = (yyvsp[-2].with_list_);
+    (yyval.with_list_)->push_back((yyvsp[0].with_list_element_));
+  }
+#line 4094 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 110:
+#line 1129 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.with_list_element_) = new quickstep::ParseSubqueryTableReference((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[0].subquery_expression_));
+    (yyval.with_list_element_)->set_table_reference_signature((yyvsp[-2].table_reference_signature_));
+  }
+#line 4103 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 111:
+#line 1136 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.select_query_) = new quickstep::ParseSelect((yylsp[-8]).first_line, (yylsp[-8]).first_column, (yyvsp[-6].selection_), (yyvsp[-5].table_reference_list_), (yyvsp[-4].predicate_), (yyvsp[-3].opt_group_by_clause_), (yyvsp[-2].opt_having_clause_), (yyvsp[-1].opt_order_by_clause_), (yyvsp[0].opt_limit_clause_));
+  }
+#line 4111 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 112:
+#line 1141 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    /* $$ = nullptr; */
+  }
+#line 4119 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 113:
+#line 1144 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    NotSupported(&(yylsp[0]), yyscanner, "ALL in selection");
+    YYERROR;
+  }
+#line 4128 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 114:
+#line 1148 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    NotSupported(&(yylsp[0]), yyscanner, "DISTINCT in selection");
+    YYERROR;
+  }
+#line 4137 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 115:
+#line 1154 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.selection_) = new quickstep::ParseSelectionStar((yylsp[0]).first_line, (yylsp[0]).first_column);
+  }
+#line 4145 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
   case 116:
-#line 1150 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1157 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_) = (yyvsp[0].selection_list_);
   }
-#line 4084 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4153 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 117:
-#line 1155 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1162 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_list_) = new quickstep::ParseSelectionList((yylsp[0]).first_line, (yylsp[0]).first_column);
     (yyval.selection_list_)->add((yyvsp[0].selection_item_));
   }
-#line 4093 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4162 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 118:
-#line 1159 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1166 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_list_) = (yyvsp[-2].selection_list_);
     (yyval.selection_list_)->add((yyvsp[0].selection_item_));
   }
-#line 4102 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4171 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 119:
-#line 1165 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1172 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_item_) = new quickstep::ParseSelectionItem((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-2].expression_), (yyvsp[0].string_value_));
   }
-#line 4110 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4179 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 120:
-#line 1168 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1175 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_item_) = new quickstep::ParseSelectionItem((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].expression_), (yyvsp[0].string_value_));
   }
-#line 4118 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4187 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 121:
-#line 1171 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1178 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_item_) = new quickstep::ParseSelectionItem((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].expression_));
   }
-#line 4126 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4195 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 122:
-#line 1176 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1183 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_list_) = (yyvsp[0].table_reference_list_);
   }
-#line 4134 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4203 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 123:
-#line 1181 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1188 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.subquery_expression_) = new quickstep::ParseSubqueryExpression((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-1].select_query_));
   }
-#line 4142 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4211 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 124:
-#line 1186 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1193 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_sample_clause_) = NULL;
   }
-#line 4150 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4219 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 125:
-#line 1189 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1196 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_sample_clause_) = new quickstep::ParseSample((yylsp[-2]).first_line, (yylsp[-2]).first_column, true, (yyvsp[-1].numeric_literal_value_));
   }
-#line 4158 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4227 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 126:
-#line 1192 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1199 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_sample_clause_) = new quickstep::ParseSample((yylsp[-2]).first_line, (yylsp[-2]).first_column, false, (yyvsp[-1].numeric_literal_value_));
   }
-#line 4166 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4235 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 127:
-#line 1197 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1204 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kInnerJoin;
   }
-#line 4174 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4243 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 128:
-#line 1200 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1207 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kInnerJoin;
   }
-#line 4182 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4251 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 129:
-#line 1203 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1210 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kLeftOuterJoin;
   }
-#line 4190 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4259 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 130:
-#line 1206 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1213 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kLeftOuterJoin;
   }
-#line 4198 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4267 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 131:
-#line 1209 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1216 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kRightOuterJoin;
   }
-#line 4206 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4275 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 132:
-#line 1212 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1219 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kRightOuterJoin;
   }
-#line 4214 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4283 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 133:
-#line 1215 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1222 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kFullOuterJoin;
   }
-#line 4222 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4291 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 134:
-#line 1218 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1225 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.join_type_) = quickstep::ParseJoinedTableReference::JoinType::kFullOuterJoin;
   }
-#line 4230 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4299 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 135:
-#line 1223 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1230 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = new quickstep::ParseJoinedTableReference((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-4].join_type_), (yyvsp[-5].table_reference_), (yyvsp[-2].table_reference_), (yyvsp[0].predicate_));
   }
-#line 4238 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4307 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 136:
-#line 1226 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1233 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = (yyvsp[0].table_reference_);
   }
-#line 4246 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4315 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 137:
-#line 1231 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1238 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = new quickstep::ParseSubqueryTableReference((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].subquery_expression_));
     (yyval.table_reference_)->set_table_reference_signature((yyvsp[0].table_reference_signature_));
   }
-#line 4255 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4324 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 138:
-#line 1235 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1242 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = new quickstep::ParseSimpleTableReference((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-2].string_value_), (yyvsp[-1].opt_sample_clause_));
     (yyval.table_reference_)->set_table_reference_signature((yyvsp[0].table_reference_signature_));
   }
-#line 4264 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4333 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 139:
-#line 1239 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1246 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = new quickstep::ParseSimpleTableReference((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].opt_sample_clause_));
   }
-#line 4272 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4341 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 140:
-#line 1242 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1249 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = new quickstep::ParseGeneratorTableReference((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].function_call_));
     (yyval.table_reference_)->set_table_reference_signature((yyvsp[0].table_reference_signature_));
   }
-#line 4281 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4350 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 141:
-#line 1246 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1253 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = new quickstep::ParseGeneratorTableReference((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].function_call_));
   }
-#line 4289 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4358 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 142:
-#line 1249 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1256 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_) = (yyvsp[-1].table_reference_);
   }
-#line 4297 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4366 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 143:
-#line 1254 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1261 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_signature_) = (yyvsp[0].table_reference_signature_);
   }
-#line 4305 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4374 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 144:
-#line 1257 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1264 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_signature_) = (yyvsp[0].table_reference_signature_);
   }
-#line 4313 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4382 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 145:
-#line 1262 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1269 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_signature_) = new ::quickstep::ParseTableReferenceSignature((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].string_value_));
   }
-#line 4321 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4390 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 146:
-#line 1265 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1272 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_signature_) = new ::quickstep::ParseTableReferenceSignature((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].string_list_));
   }
-#line 4329 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4398 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 147:
-#line 1270 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1277 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_list_) = new quickstep::PtrList<quickstep::ParseTableReference>();
     (yyval.table_reference_list_)->push_back((yyvsp[0].table_reference_));
   }
-#line 4338 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4407 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 148:
-#line 1274 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1281 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_list_) = (yyvsp[-2].table_reference_list_);
     (yyval.table_reference_list_)->push_back((yyvsp[0].table_reference_));
   }
-#line 4347 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4416 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 149:
-#line 1280 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1287 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_group_by_clause_) = nullptr;
   }
-#line 4355 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4424 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 150:
-#line 1283 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1290 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_group_by_clause_) = new quickstep::ParseGroupBy((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[0].expression_list_));
   }
-#line 4363 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4432 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 151:
-#line 1288 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1295 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_having_clause_) = nullptr;
   }
-#line 4371 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4440 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 152:
-#line 1291 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1298 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_having_clause_) = new quickstep::ParseHaving((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[0].predicate_));
   }
-#line 4379 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4448 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 153:
-#line 1296 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1303 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_order_by_clause_) = nullptr;
   }
-#line 4387 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4456 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 154:
-#line 1299 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1306 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_order_by_clause_) = new quickstep::ParseOrderBy((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[0].order_commalist_));
   }
-#line 4395 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4464 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 155:
-#line 1304 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1311 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_limit_clause_) = nullptr;
   }
-#line 4403 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4472 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 156:
-#line 1307 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1314 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].numeric_literal_value_)->float_like()) {
       delete (yyvsp[0].numeric_literal_value_);
@@ -4421,111 +4490,111 @@
       }
     }
   }
-#line 4425 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4494 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 157:
-#line 1326 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1333 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_commalist_) = new quickstep::PtrList<quickstep::ParseOrderByItem>();
     (yyval.order_commalist_)->push_back((yyvsp[0].order_item_));
   }
-#line 4434 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4503 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 158:
-#line 1330 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1337 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_commalist_) = (yyvsp[-2].order_commalist_);
     (yyval.order_commalist_)->push_back((yyvsp[0].order_item_));
   }
-#line 4443 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4512 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 159:
-#line 1336 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1343 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_item_) = new quickstep::ParseOrderByItem((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-2].expression_), (yyvsp[-1].order_direction_), (yyvsp[0].order_direction_));
     delete (yyvsp[-1].order_direction_);
     delete (yyvsp[0].order_direction_);
   }
-#line 4453 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4522 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 160:
-#line 1343 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1350 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = nullptr;
   }
-#line 4461 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4530 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 161:
-#line 1346 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1353 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(true);
   }
-#line 4469 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4538 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 162:
-#line 1349 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1356 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(false);
   }
-#line 4477 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4546 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 163:
-#line 1354 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1361 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = nullptr;
   }
-#line 4485 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4554 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 164:
-#line 1357 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1364 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(true);
   }
-#line 4493 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4562 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 165:
-#line 1360 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1367 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(false);
   }
-#line 4501 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4570 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 166:
-#line 1366 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1373 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = nullptr;
   }
-#line 4509 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4578 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 167:
-#line 1369 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1376 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4517 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4586 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 168:
-#line 1374 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1381 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4525 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4594 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 169:
-#line 1379 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1386 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-2].predicate_)->getParsePredicateType() == quickstep::ParsePredicate::kDisjunction) {
       (yyval.predicate_) = (yyvsp[-2].predicate_);
@@ -4535,19 +4604,19 @@
     }
     static_cast<quickstep::ParsePredicateDisjunction *>((yyval.predicate_))->addPredicate((yyvsp[0].predicate_));
   }
-#line 4539 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4608 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 170:
-#line 1388 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1395 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4547 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4616 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 171:
-#line 1393 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1400 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-2].predicate_)->getParsePredicateType() == quickstep::ParsePredicate::kConjunction) {
       (yyval.predicate_) = (yyvsp[-2].predicate_);
@@ -4557,401 +4626,409 @@
     }
     static_cast<quickstep::ParsePredicateConjunction *>((yyval.predicate_))->addPredicate((yyvsp[0].predicate_));
   }
-#line 4561 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4630 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 172:
-#line 1402 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1409 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4569 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4638 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 173:
-#line 1407 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1414 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateNegation((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[0].predicate_));
   }
-#line 4577 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4646 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 174:
-#line 1410 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1417 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4585 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4654 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 175:
-#line 1415 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1422 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateBetween((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-4].expression_), (yyvsp[-2].expression_), (yyvsp[0].expression_));
   }
-#line 4593 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4662 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 176:
-#line 1418 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1425 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateNegation(
         (yylsp[-4]).first_line, (yylsp[-4]).first_column,
         new quickstep::ParsePredicateBetween((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-5].expression_), (yyvsp[-2].expression_), (yyvsp[0].expression_)));
   }
-#line 4603 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4672 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 177:
-#line 1423 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1430 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].attribute_);
     (yyval.predicate_) = nullptr;
     NotSupported(&(yylsp[-2]), yyscanner, "NULL comparison predicates");
     YYERROR;
   }
-#line 4614 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4683 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 178:
-#line 1429 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1436 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-2].attribute_);
     (yyval.predicate_) = nullptr;
     NotSupported(&(yylsp[-1]), yyscanner, "NULL comparison predicates");
     YYERROR;
   }
-#line 4625 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4694 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 179:
-#line 1435 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1442 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateComparison((yylsp[-1]).first_line, (yylsp[-1]).first_column, *(yyvsp[-1].comparison_), (yyvsp[-2].expression_), (yyvsp[0].expression_));
   }
-#line 4633 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4702 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 180:
-#line 1438 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1445 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[-1].predicate_);
   }
-#line 4641 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4710 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 181:
-#line 1441 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1448 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateExists((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[0].subquery_expression_));
   }
-#line 4649 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4718 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 182:
-#line 1444 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1451 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateInTableQuery((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-2].expression_), (yyvsp[0].subquery_expression_));
   }
-#line 4657 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4726 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 183:
-#line 1447 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1454 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateInValueList((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-4].expression_), (yyvsp[-1].expression_list_));
   }
-#line 4665 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4734 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 184:
-#line 1450 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1457 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateNegation(
         (yylsp[-2]).first_line,
         (yylsp[-2]).first_column,
         new quickstep::ParsePredicateInTableQuery((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-3].expression_), (yyvsp[0].subquery_expression_)));
   }
-#line 4676 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4745 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 185:
-#line 1456 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1463 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateNegation(
         (yylsp[-4]).first_line,
         (yylsp[-4]).first_column,
         new quickstep::ParsePredicateInValueList((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-5].expression_), (yyvsp[-1].expression_list_)));
   }
-#line 4687 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4756 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 186:
-#line 1465 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1472 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = new quickstep::ParseBinaryExpression((yylsp[-1]).first_line, (yylsp[-1]).first_column, *(yyvsp[-1].binary_operation_), (yyvsp[-2].expression_), (yyvsp[0].expression_));
   }
-#line 4695 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4764 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 187:
-#line 1468 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1475 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].expression_);
   }
-#line 4703 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4772 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 188:
-#line 1473 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1480 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = new quickstep::ParseBinaryExpression((yylsp[-1]).first_line, (yylsp[-1]).first_column, *(yyvsp[-1].binary_operation_), (yyvsp[-2].expression_), (yyvsp[0].expression_));
   }
-#line 4711 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4780 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 189:
-#line 1476 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1483 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].expression_);
   }
-#line 4719 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4788 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 190:
-#line 1481 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1488 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = new quickstep::ParseUnaryExpression((yylsp[-1]).first_line, (yylsp[-1]).first_column, *(yyvsp[-1].unary_operation_), (yyvsp[0].expression_));
   }
-#line 4727 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4796 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 191:
-#line 1484 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1491 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].expression_);
   }
-#line 4735 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4804 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 192:
-#line 1489 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1496 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].attribute_);
   }
-#line 4743 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4812 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 193:
-#line 1492 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1499 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = new quickstep::ParseScalarLiteral((yyvsp[0].literal_value_));
   }
-#line 4751 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4820 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 194:
-#line 1495 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1502 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].function_call_);
   }
-#line 4759 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4828 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 195:
-#line 1498 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1505 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].expression_);
   }
-#line 4767 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4836 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 196:
-#line 1501 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1508 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[0].expression_);
   }
-#line 4775 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4844 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 197:
-#line 1504 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1511 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_) = (yyvsp[-1].expression_);
   }
-#line 4783 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4852 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 198:
-#line 1509 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1514 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].subquery_expression_);
+  }
+#line 4860 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 199:
+#line 1519 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.function_call_) = new quickstep::ParseFunctionCall(
         (yylsp[-2]).first_line, (yylsp[-2]).first_column, false, (yyvsp[-2].string_value_), new quickstep::PtrList<quickstep::ParseExpression>());
   }
-#line 4792 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4869 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 199:
-#line 1513 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 200:
+#line 1523 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.function_call_) = new quickstep::ParseFunctionCall(
         (yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-3].string_value_), new quickstep::ParseStar((yylsp[-1]).first_line, (yylsp[-1]).first_column));
   }
-#line 4801 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 200:
-#line 1517 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.function_call_) = new quickstep::ParseFunctionCall((yylsp[-3]).first_line, (yylsp[-3]).first_column, false, (yyvsp[-3].string_value_), (yyvsp[-1].expression_list_));
-  }
-#line 4809 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4878 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 201:
-#line 1520 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1527 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.function_call_) = new quickstep::ParseFunctionCall((yylsp[-4]).first_line, (yylsp[-4]).first_column, true, (yyvsp[-4].string_value_), (yyvsp[-1].expression_list_));
+    (yyval.function_call_) = new quickstep::ParseFunctionCall((yylsp[-3]).first_line, (yylsp[-3]).first_column, false, (yyvsp[-3].string_value_), (yyvsp[-1].expression_list_));
   }
-#line 4817 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4886 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 202:
-#line 1525 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1530 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.expression_) = new quickstep::ParseExtractFunction((yylsp[-5]).first_line, (yylsp[-5]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].expression_));
+    (yyval.function_call_) = new quickstep::ParseFunctionCall((yylsp[-4]).first_line, (yylsp[-4]).first_column, true, (yyvsp[-4].string_value_), (yyvsp[-1].expression_list_));
   }
-#line 4825 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4894 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 203:
-#line 1530 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1535 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.expression_) = new quickstep::ParseSimpleCaseExpression((yylsp[-4]).first_line, (yylsp[-4]).first_column, (yyvsp[-3].expression_), (yyvsp[-2].simple_when_clause_list_), (yyvsp[-1].expression_));
+    (yyval.expression_) = new quickstep::ParseExtractFunction((yylsp[-5]).first_line, (yylsp[-5]).first_column, (yyvsp[-3].string_value_), (yyvsp[-1].expression_));
   }
-#line 4833 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4902 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 204:
-#line 1533 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1540 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.expression_) = new quickstep::ParseSearchedCaseExpression((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-2].searched_when_clause_list_), (yyvsp[-1].expression_));
+    (yyval.expression_) = new quickstep::ParseSimpleCaseExpression((yylsp[-4]).first_line, (yylsp[-4]).first_column, (yyvsp[-3].expression_), (yyvsp[-2].simple_when_clause_list_), (yyvsp[-1].expression_));
   }
-#line 4841 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4910 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 205:
-#line 1538 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1543 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.simple_when_clause_list_) = new quickstep::PtrVector<quickstep::ParseSimpleWhenClause>;
-    (yyval.simple_when_clause_list_)->push_back((yyvsp[0].simple_when_clause_));
-  }
-#line 4850 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 206:
-#line 1542 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.simple_when_clause_list_) = (yyvsp[-1].simple_when_clause_list_);
-    (yyval.simple_when_clause_list_)->push_back((yyvsp[0].simple_when_clause_));
-  }
-#line 4859 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 207:
-#line 1548 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.simple_when_clause_) = new quickstep::ParseSimpleWhenClause((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-2].expression_), (yyvsp[0].expression_));
-  }
-#line 4867 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 208:
-#line 1553 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.searched_when_clause_list_) = new quickstep::PtrVector<quickstep::ParseSearchedWhenClause>;
-    (yyval.searched_when_clause_list_)->push_back((yyvsp[0].searched_when_clause_));
-  }
-#line 4876 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 209:
-#line 1557 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.searched_when_clause_list_) = (yyvsp[-1].searched_when_clause_list_);
-    (yyval.searched_when_clause_list_)->push_back((yyvsp[0].searched_when_clause_));
-  }
-#line 4885 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 210:
-#line 1563 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.searched_when_clause_) = new quickstep::ParseSearchedWhenClause((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-2].predicate_), (yyvsp[0].expression_));
-  }
-#line 4893 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 211:
-#line 1568 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = NULL;
-  }
-#line 4901 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 212:
-#line 1571 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].expression_);
-  }
-#line 4909 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 213:
-#line 1576 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_list_) = new quickstep::PtrList<quickstep::ParseExpression>();
-    (yyval.expression_list_)->push_back((yyvsp[0].expression_));
+    (yyval.expression_) = new quickstep::ParseSearchedCaseExpression((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-2].searched_when_clause_list_), (yyvsp[-1].expression_));
   }
 #line 4918 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 214:
-#line 1580 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 206:
+#line 1548 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.expression_list_) = (yyvsp[-2].expression_list_);
-    (yyval.expression_list_)->push_back((yyvsp[0].expression_));
+    (yyval.simple_when_clause_list_) = new quickstep::PtrVector<quickstep::ParseSimpleWhenClause>;
+    (yyval.simple_when_clause_list_)->push_back((yyvsp[0].simple_when_clause_));
   }
 #line 4927 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 215:
+  case 207:
+#line 1552 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.simple_when_clause_list_) = (yyvsp[-1].simple_when_clause_list_);
+    (yyval.simple_when_clause_list_)->push_back((yyvsp[0].simple_when_clause_));
+  }
+#line 4936 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 208:
+#line 1558 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.simple_when_clause_) = new quickstep::ParseSimpleWhenClause((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-2].expression_), (yyvsp[0].expression_));
+  }
+#line 4944 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 209:
+#line 1563 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.searched_when_clause_list_) = new quickstep::PtrVector<quickstep::ParseSearchedWhenClause>;
+    (yyval.searched_when_clause_list_)->push_back((yyvsp[0].searched_when_clause_));
+  }
+#line 4953 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 210:
+#line 1567 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.searched_when_clause_list_) = (yyvsp[-1].searched_when_clause_list_);
+    (yyval.searched_when_clause_list_)->push_back((yyvsp[0].searched_when_clause_));
+  }
+#line 4962 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 211:
+#line 1573 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.searched_when_clause_) = new quickstep::ParseSearchedWhenClause((yylsp[-3]).first_line, (yylsp[-3]).first_column, (yyvsp[-2].predicate_), (yyvsp[0].expression_));
+  }
+#line 4970 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 212:
+#line 1578 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = NULL;
+  }
+#line 4978 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 213:
+#line 1581 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4986 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 214:
 #line 1586 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.literal_value_) = new quickstep::NullParseLiteralValue((yylsp[0]).first_line, (yylsp[0]).first_column);
+    (yyval.expression_list_) = new quickstep::PtrList<quickstep::ParseExpression>();
+    (yyval.expression_list_)->push_back((yyvsp[0].expression_));
   }
-#line 4935 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4995 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 215:
+#line 1590 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_list_) = (yyvsp[-2].expression_list_);
+    (yyval.expression_list_)->push_back((yyvsp[0].expression_));
+  }
+#line 5004 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 216:
-#line 1589 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1596 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
+    (yyval.literal_value_) = new quickstep::NullParseLiteralValue((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 4943 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5012 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 217:
-#line 1592 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1599 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
   }
-#line 4951 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5020 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 218:
-#line 1595 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1602 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
+  }
+#line 5028 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 219:
+#line 1605 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This case exhibits a shift/reduce conflict with the
@@ -4964,20 +5041,20 @@
     (yyvsp[0].numeric_literal_value_)->prependMinus();
     (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
   }
-#line 4968 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5045 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 219:
-#line 1607 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 220:
+#line 1617 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_) = new quickstep::StringParseLiteralValue((yyvsp[0].string_value_),
                                                 nullptr);  // No explicit type.
   }
-#line 4977 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5054 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 220:
-#line 1611 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 221:
+#line 1621 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This case exhibits a shift/reduce conflict with the
@@ -4997,11 +5074,29 @@
       YYERROR;
     }
   }
-#line 5001 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5078 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 221:
-#line 1630 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 222:
+#line 1640 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    quickstep::StringParseLiteralValue *parse_value;
+    const std::string& datetime_type_value = (yyvsp[0].string_value_)->value();
+    if (quickstep::StringParseLiteralValue::ParseAmbiguousInterval(&((yyvsp[-1].string_value_)->append((" " +
+        datetime_type_value).c_str(), datetime_type_value.length() + 1)),
+        &parse_value)) {
+      (yyval.literal_value_) = parse_value;
+    } else {
+      (yyval.literal_value_) = nullptr;
+      quickstep_yyerror(&(yylsp[0]), yyscanner, nullptr, "Failed to parse literal as specified type");
+      YYERROR;
+    }
+  }
+#line 5096 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 223:
+#line 1653 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     quickstep::StringParseLiteralValue *parse_value
         = new quickstep::StringParseLiteralValue((yyvsp[0].string_value_), &((yyvsp[-1].data_type_)->getType()));
@@ -5015,143 +5110,191 @@
       (yyval.literal_value_) = parse_value;
     }
   }
-#line 5019 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5114 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 222:
-#line 1645 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 224:
+#line 1668 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, std::string("year"));
+  }
+#line 5122 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 225:
+#line 1671 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, std::string("month"));
+  }
+#line 5130 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 226:
+#line 1674 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, std::string("day"));
+  }
+#line 5138 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 227:
+#line 1677 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, std::string("hour"));
+  }
+#line 5146 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 228:
+#line 1680 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, std::string("minute"));
+  }
+#line 5154 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 229:
+#line 1683 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+     (yyval.string_value_) = new quickstep::ParseString((yylsp[0]).first_line, (yylsp[0]).first_column, std::string("second"));
+  }
+#line 5162 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 230:
+#line 1688 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_list_) = new quickstep::PtrList<quickstep::ParseScalarLiteral>();
     (yyval.literal_value_list_)->push_back(new quickstep::ParseScalarLiteral((yyvsp[0].literal_value_)));
   }
-#line 5028 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5171 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 223:
-#line 1649 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 231:
+#line 1692 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_list_) = (yyvsp[-2].literal_value_list_);
     (yyval.literal_value_list_)->push_back(new quickstep::ParseScalarLiteral((yyvsp[0].literal_value_)));
   }
-#line 5037 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5180 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 224:
-#line 1655 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 232:
+#line 1698 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_) = new quickstep::ParseAttribute((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].string_value_));
   }
-#line 5045 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5188 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 225:
-#line 1658 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 233:
+#line 1701 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_) = new quickstep::ParseAttribute((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[0].string_value_), (yyvsp[-2].string_value_));
   }
-#line 5053 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5196 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 226:
-#line 1663 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 234:
+#line 1706 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = new quickstep::PtrList<quickstep::ParseAttribute>();
     (yyval.attribute_list_)->push_back((yyvsp[0].attribute_));
   }
-#line 5062 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5205 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 227:
-#line 1667 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 235:
+#line 1710 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = (yyvsp[-2].attribute_list_);
     (yyval.attribute_list_)->push_back((yyvsp[0].attribute_));
   }
-#line 5071 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 228:
-#line 1674 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kEqual);
-  }
-#line 5079 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 229:
-#line 1677 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotEqual);
-  }
-#line 5087 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 230:
-#line 1680 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLess);
-  }
-#line 5095 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 231:
-#line 1683 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLessOrEqual);
-  }
-#line 5103 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 232:
-#line 1686 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreater);
-  }
-#line 5111 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 233:
-#line 1689 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreaterOrEqual);
-  }
-#line 5119 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 234:
-#line 1692 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLike);
-  }
-#line 5127 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 235:
-#line 1695 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotLike);
-  }
-#line 5135 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5214 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 236:
-#line 1698 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1717 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kRegexMatch);
+    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kEqual);
   }
-#line 5143 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5222 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 237:
-#line 1701 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1720 "../SqlParser.ypp" /* yacc.c:1661  */
     {
-    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotRegexMatch);
+    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotEqual);
   }
-#line 5151 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5230 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 238:
-#line 1706 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1723 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLess);
+  }
+#line 5238 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 239:
+#line 1726 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLessOrEqual);
+  }
+#line 5246 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 240:
+#line 1729 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreater);
+  }
+#line 5254 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 241:
+#line 1732 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreaterOrEqual);
+  }
+#line 5262 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 242:
+#line 1735 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLike);
+  }
+#line 5270 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 243:
+#line 1738 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotLike);
+  }
+#line 5278 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 244:
+#line 1741 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kRegexMatch);
+  }
+#line 5286 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 245:
+#line 1744 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotRegexMatch);
+  }
+#line 5294 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 246:
+#line 1749 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This case exhibits a shift/reduce conflict with the
@@ -5161,146 +5304,146 @@
      **/
     (yyval.unary_operation_) = &quickstep::UnaryOperationFactory::GetUnaryOperation(quickstep::UnaryOperationID::kNegate);
   }
-#line 5165 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5308 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 239:
-#line 1717 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 247:
+#line 1760 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kAdd);
   }
-#line 5173 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5316 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 240:
-#line 1720 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 248:
+#line 1763 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kSubtract);
   }
-#line 5181 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5324 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 241:
-#line 1725 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 249:
+#line 1768 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kModulo);
   }
-#line 5189 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5332 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 242:
-#line 1728 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 250:
+#line 1771 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kMultiply);
   }
-#line 5197 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5340 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 243:
-#line 1731 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 251:
+#line 1774 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kDivide);
   }
-#line 5205 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5348 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 244:
-#line 1737 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 252:
+#line 1780 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_list_) = new quickstep::PtrList<quickstep::ParseString>();
     (yyval.string_list_)->push_back((yyvsp[0].string_value_));
   }
-#line 5214 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5357 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 245:
-#line 1741 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 253:
+#line 1784 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_list_) = (yyvsp[-2].string_list_);
     (yyval.string_list_)->push_back((yyvsp[0].string_value_));
   }
-#line 5223 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5366 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 246:
-#line 1747 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 254:
+#line 1790 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = (yyvsp[0].string_value_);
   }
-#line 5231 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5374 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 247:
-#line 1750 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 255:
+#line 1793 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].string_value_)->value().empty()) {
       quickstep_yyerror(&(yylsp[0]), yyscanner, nullptr, "Zero-length identifier");
     }
     (yyval.string_value_) = (yyvsp[0].string_value_);
   }
-#line 5242 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5385 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 248:
-#line 1758 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 256:
+#line 1801 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = true;
   }
-#line 5250 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5393 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 249:
-#line 1761 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 257:
+#line 1804 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = true;
   }
-#line 5258 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5401 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 250:
-#line 1764 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 258:
+#line 1807 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = false;
   }
-#line 5266 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5409 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 251:
-#line 1767 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 259:
+#line 1810 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = false;
   }
-#line 5274 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5417 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 252:
-#line 1773 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 260:
+#line 1816 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.command_) = new quickstep::ParseCommand((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[-1].string_value_), (yyvsp[0].command_argument_list_));
   }
-#line 5282 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5425 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 253:
-#line 1778 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 261:
+#line 1821 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     quickstep::PtrVector<quickstep::ParseString> *argument_list = (yyvsp[-1].command_argument_list_);
     argument_list->push_back((yyvsp[0].string_value_));
     (yyval.command_argument_list_) = argument_list;
   }
-#line 5292 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5435 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 254:
-#line 1783 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 262:
+#line 1826 "../SqlParser.ypp" /* yacc.c:1661  */
     { /* Epsilon, an empy match. */
     (yyval.command_argument_list_) = new quickstep::PtrVector<quickstep::ParseString>();
   }
-#line 5300 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5443 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
 
-#line 5304 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5447 "SqlParser_gen.cpp" /* yacc.c:1661  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -5535,7 +5678,7 @@
 #endif
   return yyresult;
 }
-#line 1787 "../SqlParser.ypp" /* yacc.c:1906  */
+#line 1830 "../SqlParser.ypp" /* yacc.c:1906  */
 
 
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature) {
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index b884861..72fa9ef 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -87,78 +87,84 @@
     TOKEN_CREATE = 297,
     TOKEN_DATE = 298,
     TOKEN_DATETIME = 299,
-    TOKEN_DECIMAL = 300,
-    TOKEN_DEFAULT = 301,
-    TOKEN_DELETE = 302,
-    TOKEN_DELIMITER = 303,
-    TOKEN_DESC = 304,
-    TOKEN_DISTINCT = 305,
-    TOKEN_DOUBLE = 306,
-    TOKEN_DROP = 307,
-    TOKEN_ELSE = 308,
-    TOKEN_END = 309,
-    TOKEN_ESCAPE_STRINGS = 310,
-    TOKEN_EXISTS = 311,
-    TOKEN_EXTRACT = 312,
-    TOKEN_FALSE = 313,
-    TOKEN_FIRST = 314,
-    TOKEN_FLOAT = 315,
-    TOKEN_FOREIGN = 316,
-    TOKEN_FROM = 317,
-    TOKEN_FULL = 318,
-    TOKEN_GROUP = 319,
-    TOKEN_HASH = 320,
-    TOKEN_HAVING = 321,
-    TOKEN_IN = 322,
-    TOKEN_INDEX = 323,
-    TOKEN_INNER = 324,
-    TOKEN_INSERT = 325,
-    TOKEN_INTEGER = 326,
-    TOKEN_INTERVAL = 327,
-    TOKEN_INTO = 328,
-    TOKEN_JOIN = 329,
-    TOKEN_KEY = 330,
-    TOKEN_LAST = 331,
-    TOKEN_LEFT = 332,
-    TOKEN_LIMIT = 333,
-    TOKEN_LONG = 334,
-    TOKEN_NULL = 335,
-    TOKEN_NULLS = 336,
-    TOKEN_OFF = 337,
-    TOKEN_ON = 338,
-    TOKEN_ORDER = 339,
-    TOKEN_OUTER = 340,
-    TOKEN_PARTITION = 341,
-    TOKEN_PARTITIONS = 342,
-    TOKEN_PERCENT = 343,
-    TOKEN_PRIMARY = 344,
-    TOKEN_QUIT = 345,
-    TOKEN_RANGE = 346,
-    TOKEN_REAL = 347,
-    TOKEN_REFERENCES = 348,
-    TOKEN_RIGHT = 349,
-    TOKEN_ROW_DELIMITER = 350,
-    TOKEN_SELECT = 351,
-    TOKEN_SET = 352,
-    TOKEN_SMA = 353,
-    TOKEN_SMALLINT = 354,
-    TOKEN_TABLE = 355,
-    TOKEN_THEN = 356,
-    TOKEN_TIME = 357,
-    TOKEN_TIMESTAMP = 358,
-    TOKEN_TRUE = 359,
-    TOKEN_TUPLESAMPLE = 360,
-    TOKEN_UNIQUE = 361,
-    TOKEN_UPDATE = 362,
-    TOKEN_USING = 363,
-    TOKEN_VALUES = 364,
-    TOKEN_VARCHAR = 365,
-    TOKEN_WHEN = 366,
-    TOKEN_WHERE = 367,
-    TOKEN_WITH = 368,
-    TOKEN_YEARMONTH = 369,
-    TOKEN_EOF = 370,
-    TOKEN_LEX_ERROR = 371
+    TOKEN_DAY = 300,
+    TOKEN_DECIMAL = 301,
+    TOKEN_DEFAULT = 302,
+    TOKEN_DELETE = 303,
+    TOKEN_DELIMITER = 304,
+    TOKEN_DESC = 305,
+    TOKEN_DISTINCT = 306,
+    TOKEN_DOUBLE = 307,
+    TOKEN_DROP = 308,
+    TOKEN_ELSE = 309,
+    TOKEN_END = 310,
+    TOKEN_ESCAPE_STRINGS = 311,
+    TOKEN_EXISTS = 312,
+    TOKEN_EXTRACT = 313,
+    TOKEN_FALSE = 314,
+    TOKEN_FIRST = 315,
+    TOKEN_FLOAT = 316,
+    TOKEN_FOREIGN = 317,
+    TOKEN_FROM = 318,
+    TOKEN_FULL = 319,
+    TOKEN_GROUP = 320,
+    TOKEN_HASH = 321,
+    TOKEN_HAVING = 322,
+    TOKEN_HOUR = 323,
+    TOKEN_IN = 324,
+    TOKEN_INDEX = 325,
+    TOKEN_INNER = 326,
+    TOKEN_INSERT = 327,
+    TOKEN_INTEGER = 328,
+    TOKEN_INTERVAL = 329,
+    TOKEN_INTO = 330,
+    TOKEN_JOIN = 331,
+    TOKEN_KEY = 332,
+    TOKEN_LAST = 333,
+    TOKEN_LEFT = 334,
+    TOKEN_LIMIT = 335,
+    TOKEN_LONG = 336,
+    TOKEN_MINUTE = 337,
+    TOKEN_MONTH = 338,
+    TOKEN_NULL = 339,
+    TOKEN_NULLS = 340,
+    TOKEN_OFF = 341,
+    TOKEN_ON = 342,
+    TOKEN_ORDER = 343,
+    TOKEN_OUTER = 344,
+    TOKEN_PARTITION = 345,
+    TOKEN_PARTITIONS = 346,
+    TOKEN_PERCENT = 347,
+    TOKEN_PRIMARY = 348,
+    TOKEN_QUIT = 349,
+    TOKEN_RANGE = 350,
+    TOKEN_REAL = 351,
+    TOKEN_REFERENCES = 352,
+    TOKEN_RIGHT = 353,
+    TOKEN_ROW_DELIMITER = 354,
+    TOKEN_SECOND = 355,
+    TOKEN_SELECT = 356,
+    TOKEN_SET = 357,
+    TOKEN_SMA = 358,
+    TOKEN_SMALLINT = 359,
+    TOKEN_TABLE = 360,
+    TOKEN_THEN = 361,
+    TOKEN_TIME = 362,
+    TOKEN_TIMESTAMP = 363,
+    TOKEN_TRUE = 364,
+    TOKEN_TUPLESAMPLE = 365,
+    TOKEN_UNIQUE = 366,
+    TOKEN_UPDATE = 367,
+    TOKEN_USING = 368,
+    TOKEN_VALUES = 369,
+    TOKEN_VARCHAR = 370,
+    TOKEN_WHEN = 371,
+    TOKEN_WHERE = 372,
+    TOKEN_WITH = 373,
+    TOKEN_YEAR = 374,
+    TOKEN_YEARMONTH = 375,
+    TOKEN_EOF = 376,
+    TOKEN_LEX_ERROR = 377
   };
 #endif
 
@@ -250,7 +256,7 @@
   quickstep::ParseOrderBy *opt_order_by_clause_;
   bool *order_direction_;
   quickstep::ParseLimit *opt_limit_clause_;
-  
+
   quickstep::ParseSample *opt_sample_clause_;
 
   quickstep::PtrList<quickstep::ParseOrderByItem> *order_commalist_;
@@ -259,7 +265,7 @@
   quickstep::PtrVector<quickstep::ParseSubqueryTableReference> *with_list_;
   quickstep::ParseSubqueryTableReference *with_list_element_;
 
-#line 263 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 269 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;
diff --git a/parser/tests/Select.test b/parser/tests/Select.test
index 8a10a12..e70ee5c 100644
--- a/parser/tests/Select.test
+++ b/parser/tests/Select.test
@@ -543,16 +543,40 @@
 # Subqueries are not supported yet in clauses other than the FROM clause.
 SELECT (select * FROM test) FROM test
 --
-ERROR: syntax error (1 : 9)
-SELECT (select * FROM test) FROM test
-        ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  |   +-SubqueryExpression
+  |     +-Select
+  |       +-select_clause=SelectStar
+  |       +-from_clause=
+  |         +-TableReference[table=test]
+  +-from_clause=
+    +-TableReference[table=test]
 ==
 
 SELECT 1 FROM test WHERE 1 > (select 1 FROM test)
 --
-ERROR: syntax error (1 : 31)
-SELECT 1 FROM test WHERE 1 > (select 1 FROM test)
-                              ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  |   +-Literal
+  |     +-NumericLiteral[numeric_string=1,float_like=false]
+  +-where_clause=Greater
+  | +-left_operand=Literal
+  | | +-NumericLiteral[numeric_string=1,float_like=false]
+  | +-right_operand=SubqueryExpression
+  |   +-Select
+  |     +-select_clause=SelectList
+  |     | +-SelectListItem
+  |     |   +-Literal
+  |     |     +-NumericLiteral[numeric_string=1,float_like=false]
+  |     +-from_clause=
+  |       +-TableReference[table=test]
+  +-from_clause=
+    +-TableReference[table=test]
 ==
 
 #
diff --git a/parser/tests/TPCH.test b/parser/tests/TPCH.test
index 2d12df5..7f4d911 100644
--- a/parser/tests/TPCH.test
+++ b/parser/tests/TPCH.test
@@ -148,9 +148,97 @@
   p_partkey
 LIMIT 100
 --
-ERROR: syntax error (25 : 5)
-    SELECT
-    ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=s_acctbal]
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=s_name]
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=n_name]
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=p_partkey]
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=p_mfgr]
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=s_address]
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=s_phone]
+  | +-SelectListItem
+  |   +-AttributeReference[attribute_name=s_comment]
+  +-where_clause=And
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=p_partkey]
+  | | +-right_operand=AttributeReference[attribute_name=ps_partkey]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=s_suppkey]
+  | | +-right_operand=AttributeReference[attribute_name=ps_suppkey]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=p_size]
+  | | +-right_operand=Literal
+  | |   +-NumericLiteral[numeric_string=48,float_like=false]
+  | +-Like
+  | | +-left_operand=AttributeReference[attribute_name=p_type]
+  | | +-right_operand=Literal
+  | |   +-StringLiteral[value=%NICKEL]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=s_nationkey]
+  | | +-right_operand=AttributeReference[attribute_name=n_nationkey]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=n_regionkey]
+  | | +-right_operand=AttributeReference[attribute_name=r_regionkey]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=r_name]
+  | | +-right_operand=Literal
+  | |   +-StringLiteral[value=ASIA]
+  | +-Equal
+  |   +-left_operand=AttributeReference[attribute_name=ps_supplycost]
+  |   +-right_operand=SubqueryExpression
+  |     +-Select
+  |       +-select_clause=SelectList
+  |       | +-SelectListItem
+  |       |   +-FunctionCall[name=MIN]
+  |       |     +-AttributeReference[attribute_name=ps_supplycost]
+  |       +-where_clause=And
+  |       | +-Equal
+  |       | | +-left_operand=AttributeReference[attribute_name=p_partkey]
+  |       | | +-right_operand=AttributeReference[attribute_name=ps_partkey]
+  |       | +-Equal
+  |       | | +-left_operand=AttributeReference[attribute_name=s_suppkey]
+  |       | | +-right_operand=AttributeReference[attribute_name=ps_suppkey]
+  |       | +-Equal
+  |       | | +-left_operand=AttributeReference[attribute_name=s_nationkey]
+  |       | | +-right_operand=AttributeReference[attribute_name=n_nationkey]
+  |       | +-Equal
+  |       | | +-left_operand=AttributeReference[attribute_name=n_regionkey]
+  |       | | +-right_operand=AttributeReference[attribute_name=r_regionkey]
+  |       | +-Equal
+  |       |   +-left_operand=AttributeReference[attribute_name=r_name]
+  |       |   +-right_operand=Literal
+  |       |     +-StringLiteral[value=ASIA]
+  |       +-from_clause=
+  |         +-TableReference[table=partsupp]
+  |         +-TableReference[table=supplier]
+  |         +-TableReference[table=nation]
+  |         +-TableReference[table=region]
+  +-order_by=OrderBy
+  | +-OrderByItem[is_asc=false,nulls_first=true]
+  | | +-AttributeReference[attribute_name=s_acctbal]
+  | +-OrderByItem[is_asc=true,nulls_first=false]
+  | | +-AttributeReference[attribute_name=n_name]
+  | +-OrderByItem[is_asc=true,nulls_first=false]
+  | | +-AttributeReference[attribute_name=s_name]
+  | +-OrderByItem[is_asc=true,nulls_first=false]
+  |   +-AttributeReference[attribute_name=p_partkey]
+  +-limit=LIMIT
+  | +-NumericLiteral[numeric_string=100,float_like=false]
+  +-from_clause=
+    +-TableReference[table=part]
+    +-TableReference[table=supplier]
+    +-TableReference[table=partsupp]
+    +-TableReference[table=nation]
+    +-TableReference[table=region]
 ==
 
 # Query 3
@@ -444,7 +532,7 @@
     SELECT
       n1.n_name AS supp_nation,
       n2.n_name AS cust_nation,
-      EXTRACT(year FROM l_shipdate) AS l_year,
+      EXTRACT(YEAR FROM l_shipdate) AS l_year,
       l_extendedprice * (1 - l_discount) AS volume
     FROM
       supplier,
@@ -508,7 +596,7 @@
           | +-SelectListItem[alias=cust_nation]
           | | +-AttributeReference[attribute_name=n_name,relation_name=n2]
           | +-SelectListItem[alias=l_year]
-          | | +-Extract[unit=year]
+          | | +-Extract[unit=YEAR]
           | |   +-date_expression=AttributeReference[attribute_name=l_shipdate]
           | +-SelectListItem[alias=volume]
           |   +-Multiply
@@ -585,7 +673,7 @@
 FROM
   (
     SELECT
-      EXTRACT(year FROM o_orderdate) AS o_year,
+      EXTRACT(YEAR FROM o_orderdate) AS o_year,
       l_extendedprice * (1 - l_discount) AS volume,
       n2.n_name AS nation
     FROM
@@ -646,7 +734,7 @@
         +-Select
           +-select_clause=SelectList
           | +-SelectListItem[alias=o_year]
-          | | +-Extract[unit=year]
+          | | +-Extract[unit=YEAR]
           | |   +-date_expression=AttributeReference[attribute_name=o_orderdate]
           | +-SelectListItem[alias=volume]
           | | +-Multiply
@@ -770,7 +858,7 @@
           | +-SelectListItem[alias=nation]
           | | +-AttributeReference[attribute_name=n_name]
           | +-SelectListItem[alias=o_year]
-          | | +-Extract[unit=year]
+          | | +-Extract[unit=YEAR]
           | |   +-date_expression=AttributeReference[attribute_name=o_orderdate]
           | +-SelectListItem[alias=amount]
           |   +-Subtract
@@ -949,9 +1037,70 @@
 ORDER BY
   value DESC
 --
-ERROR: syntax error (15 : 7)
-      SELECT
-      ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=ps_partkey]
+  | +-SelectListItem[alias=value]
+  |   +-FunctionCall[name=SUM]
+  |     +-Multiply
+  |       +-left_operand=AttributeReference[attribute_name=ps_supplycost]
+  |       +-right_operand=AttributeReference[attribute_name=ps_availqty]
+  +-where_clause=And
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=ps_suppkey]
+  | | +-right_operand=AttributeReference[attribute_name=s_suppkey]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=s_nationkey]
+  | | +-right_operand=AttributeReference[attribute_name=n_nationkey]
+  | +-Equal
+  |   +-left_operand=AttributeReference[attribute_name=n_name]
+  |   +-right_operand=Literal
+  |     +-StringLiteral[value=INDONESIA]
+  +-group_by=GroupBy
+  | +-AttributeReference[attribute_name=ps_partkey]
+  +-having=HAVING
+  | +-Greater
+  |   +-left_operand=FunctionCall[name=SUM]
+  |   | +-Multiply
+  |   |   +-left_operand=AttributeReference[attribute_name=ps_supplycost]
+  |   |   +-right_operand=AttributeReference[attribute_name=ps_availqty]
+  |   +-right_operand=SubqueryExpression
+  |     +-Select
+  |       +-select_clause=SelectList
+  |       | +-SelectListItem
+  |       |   +-Multiply
+  |       |     +-left_operand=FunctionCall[name=SUM]
+  |       |     | +-Multiply
+  |       |     |   +-left_operand=AttributeReference[
+  |       |     |   | attribute_name=ps_supplycost]
+  |       |     |   +-right_operand=AttributeReference[
+  |       |     |     attribute_name=ps_availqty]
+  |       |     +-right_operand=Literal
+  |       |       +-NumericLiteral[numeric_string=0.0000010000,float_like=true]
+  |       +-where_clause=And
+  |       | +-Equal
+  |       | | +-left_operand=AttributeReference[attribute_name=ps_suppkey]
+  |       | | +-right_operand=AttributeReference[attribute_name=s_suppkey]
+  |       | +-Equal
+  |       | | +-left_operand=AttributeReference[attribute_name=s_nationkey]
+  |       | | +-right_operand=AttributeReference[attribute_name=n_nationkey]
+  |       | +-Equal
+  |       |   +-left_operand=AttributeReference[attribute_name=n_name]
+  |       |   +-right_operand=Literal
+  |       |     +-StringLiteral[value=INDONESIA]
+  |       +-from_clause=
+  |         +-TableReference[table=partsupp]
+  |         +-TableReference[table=supplier]
+  |         +-TableReference[table=nation]
+  +-order_by=OrderBy
+  | +-OrderByItem[is_asc=false,nulls_first=true]
+  |   +-AttributeReference[attribute_name=value]
+  +-from_clause=
+    +-TableReference[table=partsupp]
+    +-TableReference[table=supplier]
+    +-TableReference[table=nation]
 ==
 
 # Query 12
@@ -1230,9 +1379,72 @@
 ORDER BY
   s_suppkey
 --
-ERROR: syntax error (23 : 1)
-SELECT
-^
+SelectStatement
++-select_query=Select
+| +-select_clause=SelectList
+| | +-SelectListItem
+| | | +-AttributeReference[attribute_name=s_suppkey]
+| | +-SelectListItem
+| | | +-AttributeReference[attribute_name=s_name]
+| | +-SelectListItem
+| | | +-AttributeReference[attribute_name=s_address]
+| | +-SelectListItem
+| | | +-AttributeReference[attribute_name=s_phone]
+| | +-SelectListItem
+| |   +-AttributeReference[attribute_name=total_revenue]
+| +-where_clause=And
+| | +-Equal
+| | | +-left_operand=AttributeReference[attribute_name=s_suppkey]
+| | | +-right_operand=AttributeReference[attribute_name=supplier_no]
+| | +-Equal
+| |   +-left_operand=AttributeReference[attribute_name=total_revenue]
+| |   +-right_operand=SubqueryExpression
+| |     +-Select
+| |       +-select_clause=SelectList
+| |       | +-SelectListItem
+| |       |   +-FunctionCall[name=MAX]
+| |       |     +-AttributeReference[attribute_name=total_revenue]
+| |       +-from_clause=
+| |         +-TableReference[table=revenue]
+| +-order_by=OrderBy
+| | +-OrderByItem[is_asc=true,nulls_first=false]
+| |   +-AttributeReference[attribute_name=s_suppkey]
+| +-from_clause=
+|   +-TableReference[table=supplier]
+|   +-TableReference[table=revenue]
++-with_clause=
+  +-SubqueryTable
+    +-table_signature=TableSignature[table_alias=revenue,
+    | columns=(supplier_no, total_revenue)]
+    +-SubqueryExpression
+      +-Select
+        +-select_clause=SelectList
+        | +-SelectListItem
+        | | +-AttributeReference[attribute_name=l_suppkey]
+        | +-SelectListItem
+        |   +-FunctionCall[name=sum]
+        |     +-Multiply
+        |       +-left_operand=AttributeReference[attribute_name=l_extendedprice]
+        |       +-right_operand=Subtract
+        |         +-left_operand=Literal
+        |         | +-NumericLiteral[numeric_string=1,float_like=false]
+        |         +-right_operand=AttributeReference[attribute_name=l_discount]
+        +-where_clause=And
+        | +-GreaterOrEqual
+        | | +-left_operand=AttributeReference[attribute_name=l_shipdate]
+        | | +-right_operand=Literal
+        | |   +-StringLiteral[value=1996-11-01,explicit_type=Datetime]
+        | +-Less
+        |   +-left_operand=AttributeReference[attribute_name=l_shipdate]
+        |   +-right_operand=Add
+        |     +-left_operand=Literal
+        |     | +-StringLiteral[value=1996-11-01,explicit_type=Datetime]
+        |     +-right_operand=Literal
+        |       +-StringLiteral[value=3 month,explicit_type=YearMonthInterval]
+        +-group_by=GroupBy
+        | +-AttributeReference[attribute_name=l_suppkey]
+        +-from_clause=
+          +-TableReference[table=lineitem]
 ==
 
 # Query 16
@@ -1361,9 +1573,46 @@
       l_partkey = p_partkey
   )
 --
-ERROR: syntax error (11 : 5)
-    SELECT
-    ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem[alias=avg_yearly]
+  |   +-Divide
+  |     +-left_operand=FunctionCall[name=SUM]
+  |     | +-AttributeReference[attribute_name=l_extendedprice]
+  |     +-right_operand=Literal
+  |       +-NumericLiteral[numeric_string=7.0,float_like=true]
+  +-where_clause=And
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=p_partkey]
+  | | +-right_operand=AttributeReference[attribute_name=l_partkey]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=p_brand]
+  | | +-right_operand=Literal
+  | |   +-StringLiteral[value=Brand#24]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=p_container]
+  | | +-right_operand=Literal
+  | |   +-StringLiteral[value=JUMBO BOX]
+  | +-Less
+  |   +-left_operand=AttributeReference[attribute_name=l_quantity]
+  |   +-right_operand=SubqueryExpression
+  |     +-Select
+  |       +-select_clause=SelectList
+  |       | +-SelectListItem
+  |       |   +-Multiply
+  |       |     +-left_operand=Literal
+  |       |     | +-NumericLiteral[numeric_string=0.2,float_like=true]
+  |       |     +-right_operand=FunctionCall[name=AVG]
+  |       |       +-AttributeReference[attribute_name=l_quantity]
+  |       +-where_clause=Equal
+  |       | +-left_operand=AttributeReference[attribute_name=l_partkey]
+  |       | +-right_operand=AttributeReference[attribute_name=p_partkey]
+  |       +-from_clause=
+  |         +-TableReference[table=lineitem]
+  +-from_clause=
+    +-TableReference[table=lineitem]
+    +-TableReference[table=part]
 ==
 
 # Query 18
@@ -1694,9 +1943,87 @@
 ORDER BY
   s_name
 --
-ERROR: syntax error (23 : 9)
-        SELECT
-        ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=s_name]
+  | +-SelectListItem
+  |   +-AttributeReference[attribute_name=s_address]
+  +-where_clause=And
+  | +-InTableQuery
+  | | +-test_expression=AttributeReference[attribute_name=s_suppkey]
+  | | +-table_query=SubqueryExpression
+  | |   +-Select
+  | |     +-select_clause=SelectList
+  | |     | +-SelectListItem
+  | |     |   +-AttributeReference[attribute_name=ps_suppkey]
+  | |     +-where_clause=And
+  | |     | +-InTableQuery
+  | |     | | +-test_expression=AttributeReference[attribute_name=ps_partkey]
+  | |     | | +-table_query=SubqueryExpression
+  | |     | |   +-Select
+  | |     | |     +-select_clause=SelectList
+  | |     | |     | +-SelectListItem
+  | |     | |     |   +-AttributeReference[attribute_name=p_partkey]
+  | |     | |     +-where_clause=Like
+  | |     | |     | +-left_operand=AttributeReference[attribute_name=p_name]
+  | |     | |     | +-right_operand=Literal
+  | |     | |     |   +-StringLiteral[value=sandy%]
+  | |     | |     +-from_clause=
+  | |     | |       +-TableReference[table=part]
+  | |     | +-Greater
+  | |     |   +-left_operand=AttributeReference[attribute_name=ps_availqty]
+  | |     |   +-right_operand=SubqueryExpression
+  | |     |     +-Select
+  | |     |       +-select_clause=SelectList
+  | |     |       | +-SelectListItem
+  | |     |       |   +-Multiply
+  | |     |       |     +-left_operand=Literal
+  | |     |       |     | +-NumericLiteral[numeric_string=0.5,float_like=true]
+  | |     |       |     +-right_operand=FunctionCall[name=SUM]
+  | |     |       |       +-AttributeReference[attribute_name=l_quantity]
+  | |     |       +-where_clause=And
+  | |     |       | +-Equal
+  | |     |       | | +-left_operand=AttributeReference[attribute_name=l_partkey]
+  | |     |       | | +-right_operand=AttributeReference[
+  | |     |       | |   attribute_name=ps_partkey]
+  | |     |       | +-Equal
+  | |     |       | | +-left_operand=AttributeReference[attribute_name=l_suppkey]
+  | |     |       | | +-right_operand=AttributeReference[
+  | |     |       | |   attribute_name=ps_suppkey]
+  | |     |       | +-GreaterOrEqual
+  | |     |       | | +-left_operand=AttributeReference[
+  | |     |       | | | attribute_name=l_shipdate]
+  | |     |       | | +-right_operand=Literal
+  | |     |       | |   +-StringLiteral[value=1993-01-01,explicit_type=Datetime]
+  | |     |       | +-Less
+  | |     |       |   +-left_operand=AttributeReference[
+  | |     |       |   | attribute_name=l_shipdate]
+  | |     |       |   +-right_operand=Add
+  | |     |       |     +-left_operand=Literal
+  | |     |       |     | +-StringLiteral[value=1993-01-01,
+  | |     |       |     |   explicit_type=Datetime]
+  | |     |       |     +-right_operand=Literal
+  | |     |       |       +-StringLiteral[value=1 year,
+  | |     |       |         explicit_type=YearMonthInterval]
+  | |     |       +-from_clause=
+  | |     |         +-TableReference[table=lineitem]
+  | |     +-from_clause=
+  | |       +-TableReference[table=partsupp]
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=s_nationkey]
+  | | +-right_operand=AttributeReference[attribute_name=n_nationkey]
+  | +-Equal
+  |   +-left_operand=AttributeReference[attribute_name=n_name]
+  |   +-right_operand=Literal
+  |     +-StringLiteral[value=GERMANY]
+  +-order_by=OrderBy
+  | +-OrderByItem[is_asc=true,nulls_first=false]
+  |   +-AttributeReference[attribute_name=s_name]
+  +-from_clause=
+    +-TableReference[table=supplier]
+    +-TableReference[table=nation]
 ==
 
 # Query 21
@@ -1870,6 +2197,106 @@
 ORDER BY
   cntrycode
 --
-ERROR: syntax error (16 : 9)
-        SELECT
-        ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=cntrycode]
+  | +-SelectListItem[alias=numcust]
+  | | +-FunctionCall[name=COUNT,is_star=true]
+  | +-SelectListItem[alias=totacctbal]
+  |   +-FunctionCall[name=SUM]
+  |     +-AttributeReference[attribute_name=c_acctbal]
+  +-group_by=GroupBy
+  | +-AttributeReference[attribute_name=cntrycode]
+  +-order_by=OrderBy
+  | +-OrderByItem[is_asc=true,nulls_first=false]
+  |   +-AttributeReference[attribute_name=cntrycode]
+  +-from_clause=
+    +-SubqueryTable
+      +-table_signature=TableSignature[table_alias=custsale]
+      +-SubqueryExpression
+        +-Select
+          +-select_clause=SelectList
+          | +-SelectListItem[alias=cntrycode]
+          | | +-FunctionCall[name=SUBSTR]
+          | |   +-AttributeReference[attribute_name=c_phone]
+          | |   +-Literal
+          | |   | +-NumericLiteral[numeric_string=1,float_like=false]
+          | |   +-Literal
+          | |     +-NumericLiteral[numeric_string=2,float_like=false]
+          | +-SelectListItem
+          |   +-AttributeReference[attribute_name=c_acctbal]
+          +-where_clause=And
+          | +-InValueList
+          | | +-test_expression=FunctionCall[name=SUBSTR]
+          | | | +-AttributeReference[attribute_name=c_phone]
+          | | | +-Literal
+          | | | | +-NumericLiteral[numeric_string=1,float_like=false]
+          | | | +-Literal
+          | | |   +-NumericLiteral[numeric_string=2,float_like=false]
+          | | +-value_list=
+          | |   +-Literal
+          | |   | +-StringLiteral[value=27]
+          | |   +-Literal
+          | |   | +-StringLiteral[value=44]
+          | |   +-Literal
+          | |   | +-StringLiteral[value=34]
+          | |   +-Literal
+          | |   | +-StringLiteral[value=25]
+          | |   +-Literal
+          | |   | +-StringLiteral[value=30]
+          | |   +-Literal
+          | |   | +-StringLiteral[value=33]
+          | |   +-Literal
+          | |     +-StringLiteral[value=23]
+          | +-Greater
+          | | +-left_operand=AttributeReference[attribute_name=c_acctbal]
+          | | +-right_operand=SubqueryExpression
+          | |   +-Select
+          | |     +-select_clause=SelectList
+          | |     | +-SelectListItem
+          | |     |   +-FunctionCall[name=AVG]
+          | |     |     +-AttributeReference[attribute_name=c_acctbal]
+          | |     +-where_clause=And
+          | |     | +-Greater
+          | |     | | +-left_operand=AttributeReference[attribute_name=c_acctbal]
+          | |     | | +-right_operand=Literal
+          | |     | |   +-NumericLiteral[numeric_string=0.00,float_like=true]
+          | |     | +-InValueList
+          | |     |   +-test_expression=FunctionCall[name=SUBSTR]
+          | |     |   | +-AttributeReference[attribute_name=c_phone]
+          | |     |   | +-Literal
+          | |     |   | | +-NumericLiteral[numeric_string=1,float_like=false]
+          | |     |   | +-Literal
+          | |     |   |   +-NumericLiteral[numeric_string=2,float_like=false]
+          | |     |   +-value_list=
+          | |     |     +-Literal
+          | |     |     | +-StringLiteral[value=27]
+          | |     |     +-Literal
+          | |     |     | +-StringLiteral[value=44]
+          | |     |     +-Literal
+          | |     |     | +-StringLiteral[value=34]
+          | |     |     +-Literal
+          | |     |     | +-StringLiteral[value=25]
+          | |     |     +-Literal
+          | |     |     | +-StringLiteral[value=30]
+          | |     |     +-Literal
+          | |     |     | +-StringLiteral[value=33]
+          | |     |     +-Literal
+          | |     |       +-StringLiteral[value=23]
+          | |     +-from_clause=
+          | |       +-TableReference[table=customer]
+          | +-Not
+          |   +-Exists
+          |     +-subquery=SubqueryExpression
+          |       +-Select
+          |         +-select_clause=SelectStar
+          |         +-where_clause=Equal
+          |         | +-left_operand=AttributeReference[attribute_name=o_custkey]
+          |         | +-right_operand=AttributeReference[
+          |         |   attribute_name=c_custkey]
+          |         +-from_clause=
+          |           +-TableReference[table=orders]
+          +-from_clause=
+            +-TableReference[table=customer]
diff --git a/query_optimizer/CMakeLists.txt b/query_optimizer/CMakeLists.txt
index 44c8750..2d09bee 100644
--- a/query_optimizer/CMakeLists.txt
+++ b/query_optimizer/CMakeLists.txt
@@ -15,6 +15,15 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 
+if (ENABLE_DISTRIBUTED)
+  set(QUICKSTEP_DISTRIBUTED TRUE)
+endif()
+
+configure_file (
+  "${CMAKE_CURRENT_SOURCE_DIR}/QueryOptimizerConfig.h.in"
+  "${CMAKE_CURRENT_BINARY_DIR}/QueryOptimizerConfig.h"
+)
+
 add_subdirectory(cost_model)
 add_subdirectory(expressions)
 add_subdirectory(logical)
@@ -126,6 +135,10 @@
                       quickstep_types_containers_Tuple_proto
                       quickstep_utility_Macros
                       quickstep_utility_SqlError)
+if (ENABLE_DISTRIBUTED)
+  target_link_libraries(quickstep_queryoptimizer_ExecutionGenerator
+                        quickstep_catalog_Catalog_proto)
+endif()
 target_link_libraries(quickstep_queryoptimizer_LogicalGenerator
                       glog
                       quickstep_parser_ParseStatement
@@ -171,6 +184,7 @@
                       quickstep_queryoptimizer_Validator
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_QueryHandle
+                      quickstep_catalog_Catalog_proto
                       quickstep_queryexecution_QueryContext_proto
                       quickstep_queryoptimizer_QueryPlan
                       quickstep_utility_Macros)
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index 38ab09e..abcdd6c 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -25,9 +25,18 @@
 #include <string>
 #include <type_traits>
 #include <unordered_map>
+
+#ifdef QUICKSTEP_DISTRIBUTED
+#include <unordered_set>
+#endif
+
 #include <utility>
 #include <vector>
 
+#ifdef QUICKSTEP_DISTRIBUTED
+#include "catalog/Catalog.pb.h"
+#endif
+
 #include "catalog/CatalogAttribute.hpp"
 #include "catalog/CatalogDatabase.hpp"
 #include "catalog/CatalogRelation.hpp"
@@ -185,6 +194,20 @@
         drop_table_index,
         temporary_relation_info.producer_operator_index);
   }
+
+#ifdef QUICKSTEP_DISTRIBUTED
+  catalog_database_cache_proto_->set_name(optimizer_context_->catalog_database()->getName());
+
+  LOG(INFO) << "CatalogDatabaseCache proto has " << referenced_relation_ids_.size() << " relation(s)";
+  for (const relation_id rel_id : referenced_relation_ids_) {
+    const CatalogRelationSchema &relation =
+        optimizer_context_->catalog_database()->getRelationSchemaById(rel_id);
+    LOG(INFO) << "RelationSchema " << rel_id
+              << ", name: " << relation.getName()
+              << ", " << relation.size()  << " attribute(s)";
+    catalog_database_cache_proto_->add_relations()->MergeFrom(relation.getProto());
+  }
+#endif
 }
 
 void ExecutionGenerator::generatePlanInternal(
@@ -289,6 +312,10 @@
   const relation_id output_rel_id = optimizer_context_->catalog_database()->addRelation(
       catalog_relation.release());
 
+#ifdef QUICKSTEP_DISTRIBUTED
+  referenced_relation_ids_.insert(output_rel_id);
+#endif
+
   insert_destination_proto->set_insert_destination_type(S::InsertDestinationType::BLOCK_POOL);
   insert_destination_proto->set_relation_id(output_rel_id);
 }
@@ -335,6 +362,11 @@
   // parent (e.g. the substitution map from an AttributeReference
   // to a CatalogAttribute).
   const CatalogRelation *catalog_relation = physical_table_reference->relation();
+
+#ifdef QUICKSTEP_DISTRIBUTED
+  referenced_relation_ids_.insert(catalog_relation->getID());
+#endif
+
   const std::vector<E::AttributeReferencePtr> &attribute_references =
       physical_table_reference->attribute_list();
   DCHECK_EQ(attribute_references.size(), catalog_relation->size());
@@ -607,6 +639,18 @@
   const CatalogRelationInfo *probe_operator_info =
       findRelationInfoOutputByPhysical(probe_physical);
 
+  // Create a vector that indicates whether each project expression is using
+  // attributes from the build relation as input. This information is required
+  // by the current implementation of hash left outer join
+  std::unique_ptr<std::vector<bool>> is_selection_on_build;
+  if (physical_plan->join_type() == P::HashJoin::JoinType::kLeftOuterJoin) {
+    is_selection_on_build.reset(
+        new std::vector<bool>(
+            E::MarkExpressionsReferingAnyAttribute(
+                physical_plan->project_expressions(),
+                build_physical->getOutputAttributes())));
+  }
+
   // FIXME(quickstep-team): Add support for self-join.
   if (build_relation_info->relation == probe_operator_info->relation) {
     THROW_SQL_ERROR() << "Self-join is not supported";
@@ -664,6 +708,9 @@
     case P::HashJoin::JoinType::kLeftAntiJoin:
       join_type = HashJoinOperator::JoinType::kLeftAntiJoin;
       break;
+    case P::HashJoin::JoinType::kLeftOuterJoin:
+      join_type = HashJoinOperator::JoinType::kLeftOuterJoin;
+      break;
     default:
       LOG(FATAL) << "Invalid physical::HashJoin::JoinType: "
                  << static_cast<typename std::underlying_type<P::HashJoin::JoinType>::type>(
@@ -684,6 +731,7 @@
               join_hash_table_index,
               residual_predicate_index,
               project_expressions_group_index,
+              is_selection_on_build.get(),
               join_type));
   insert_destination_proto->set_relational_op_index(join_operator_index);
 
@@ -978,8 +1026,14 @@
 void ExecutionGenerator::convertDropTable(
     const P::DropTablePtr &physical_plan) {
   // DropTable is converted to a DropTable operator.
+  const CatalogRelation &catalog_relation = *physical_plan->catalog_relation();
+
+#ifdef QUICKSTEP_DISTRIBUTED
+  referenced_relation_ids_.insert(catalog_relation.getID());
+#endif
+
   execution_plan_->addRelationalOperator(
-      new DropTableOperator(*physical_plan->catalog_relation(),
+      new DropTableOperator(catalog_relation,
                             optimizer_context_->catalog_database()));
 }
 
diff --git a/query_optimizer/ExecutionGenerator.hpp b/query_optimizer/ExecutionGenerator.hpp
index 11de106..df47b31 100644
--- a/query_optimizer/ExecutionGenerator.hpp
+++ b/query_optimizer/ExecutionGenerator.hpp
@@ -1,6 +1,6 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
- *   Copyright 2015 Pivotal Software, Inc.
+ *   Copyright 2015-2016 Pivotal Software, Inc.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -21,6 +21,11 @@
 #include <memory>
 #include <string>
 #include <unordered_map>
+
+#ifdef QUICKSTEP_DISTRIBUTED
+#include <unordered_set>
+#endif
+
 #include <vector>
 
 #include "catalog/CatalogTypedefs.hpp"
@@ -54,6 +59,8 @@
 #include "query_optimizer/physical/UpdateTable.hpp"
 #include "utility/Macros.hpp"
 
+#include "glog/logging.h"
+
 namespace quickstep {
 
 class CatalogAttribute;
@@ -61,6 +68,11 @@
 class Predicate;
 
 namespace serialization {
+
+#ifdef QUICKSTEP_DISTRIBUTED
+class CatalogDatabase;
+#endif
+
 class InsertDestination;
 }  // namespace serialization
 
@@ -85,10 +97,14 @@
    */
   ExecutionGenerator(OptimizerContext *optimizer_context,
                      QueryHandle *query_handle)
-      : optimizer_context_(optimizer_context),
-        query_handle_(query_handle),
-        execution_plan_(query_handle->getQueryPlanMutable()),
-        query_context_proto_(query_handle->getQueryContextProtoMutable()) {
+      : optimizer_context_(DCHECK_NOTNULL(optimizer_context)),
+        query_handle_(DCHECK_NOTNULL(query_handle)),
+        execution_plan_(DCHECK_NOTNULL(query_handle->getQueryPlanMutable())),
+        query_context_proto_(DCHECK_NOTNULL(query_handle->getQueryContextProtoMutable())) {
+#ifdef QUICKSTEP_DISTRIBUTED
+    catalog_database_cache_proto_ = DCHECK_NOTNULL(query_handle->getCatalogDatabaseCacheProtoMutable());
+#endif
+
     setupCostModel();
   }
 
@@ -368,6 +384,13 @@
   QueryPlan *execution_plan_;  // A part of QueryHandle.
   serialization::QueryContext *query_context_proto_;  // A part of QueryHandle.
 
+#ifdef QUICKSTEP_DISTRIBUTED
+  serialization::CatalogDatabase *catalog_database_cache_proto_;  // A part of QueryHandle.
+
+  // Used to bookkeep relation ids for 'catalog_database_cache_proto_'.
+  std::unordered_set<relation_id> referenced_relation_ids_;
+#endif
+
   /**
    * @brief Used to generate distinct relation names for temporary relations.
    */
diff --git a/query_optimizer/QueryHandle.hpp b/query_optimizer/QueryHandle.hpp
index 8819cc3..a17d3e8 100644
--- a/query_optimizer/QueryHandle.hpp
+++ b/query_optimizer/QueryHandle.hpp
@@ -1,5 +1,5 @@
 /**
- *   Copyright 2015 Pivotal Software, Inc.
+ *   Copyright 2015-2016 Pivotal Software, Inc.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 #include <memory>
 #include <utility>
 
+#include "catalog/Catalog.pb.h"
 #include "query_execution/QueryContext.pb.h"
 #include "query_optimizer/QueryPlan.hpp"
 #include "utility/Macros.hpp"
@@ -41,7 +42,7 @@
   /**
    * @brief Constructor.
    *
-   * @param The given query id.
+   * @param query_id The given query id.
    */
   explicit QueryHandle(const std::size_t query_id)
       : query_id_(query_id),
@@ -81,6 +82,20 @@
   }
 
   /**
+    * @return The catalog database cache in the protobuf format.
+    */
+  const serialization::CatalogDatabase& getCatalogDatabaseCacheProto() const {
+    return catalog_database_cache_proto_;
+  }
+
+  /**
+   * @return The mutable catalog database cache in the protobuf format.
+   */
+  serialization::CatalogDatabase* getCatalogDatabaseCacheProtoMutable() {
+    return &catalog_database_cache_proto_;
+  }
+
+  /**
    * @brief Get the query result relation.
    */
   const CatalogRelation* getQueryResultRelation() const {
@@ -101,6 +116,9 @@
 
   serialization::QueryContext query_context_proto_;
 
+  // TODO(quickstep-team): Use Catalog to support multiple databases.
+  serialization::CatalogDatabase catalog_database_cache_proto_;
+
   // NOTE(zuyu): The relation gets created by the optimizer,
   //             and deleted by the Cli shell.
   const CatalogRelation *query_result_relation_;
diff --git a/query_optimizer/QueryOptimizerConfig.h.in b/query_optimizer/QueryOptimizerConfig.h.in
new file mode 100644
index 0000000..da0fa18
--- /dev/null
+++ b/query_optimizer/QueryOptimizerConfig.h.in
@@ -0,0 +1,17 @@
+/**
+ *   Copyright 2016 Pivotal Software, Inc.
+ *
+ *   Licensed 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.
+ **/
+
+#cmakedefine QUICKSTEP_DISTRIBUTED
diff --git a/query_optimizer/expressions/ExpressionUtil.cpp b/query_optimizer/expressions/ExpressionUtil.cpp
index 5cf7759..3ccd3c9 100644
--- a/query_optimizer/expressions/ExpressionUtil.cpp
+++ b/query_optimizer/expressions/ExpressionUtil.cpp
@@ -37,6 +37,25 @@
                                     AttributeReferenceScope::kLocal);
 }
 
+std::vector<AttributeReferencePtr> GetNullableAttributeVector(
+    const std::vector<AttributeReferencePtr> &attributes) {
+  std::vector<AttributeReferencePtr> nullable_attributes;
+  for (const auto &attr : attributes) {
+    if (!attr->getValueType().isNullable()) {
+      nullable_attributes.emplace_back(
+          AttributeReference::Create(attr->id(),
+                                     attr->attribute_name(),
+                                     attr->attribute_alias(),
+                                     attr->relation_name(),
+                                     attr->getValueType().getNullableVersion(),
+                                     attr->scope()));
+    } else {
+      nullable_attributes.emplace_back(attr);
+    }
+  }
+  return nullable_attributes;
+}
+
 std::vector<AttributeReferencePtr> GetAttributeReferencesWithinScope(
     const std::vector<AttributeReferencePtr> &attributes,
     const AttributeReferenceScope scope) {
diff --git a/query_optimizer/expressions/ExpressionUtil.hpp b/query_optimizer/expressions/ExpressionUtil.hpp
index cc9fbbe..4c35719 100644
--- a/query_optimizer/expressions/ExpressionUtil.hpp
+++ b/query_optimizer/expressions/ExpressionUtil.hpp
@@ -117,6 +117,16 @@
 }
 
 /**
+ * @brief Make a copy of the input attribute vector with each attribute's type
+ *        converted as nullable.
+ *
+ * @param attributes The input attribute vector.
+ * @return The nullable copy of the input attribute vector.
+ */
+std::vector<AttributeReferencePtr> GetNullableAttributeVector(
+    const std::vector<AttributeReferencePtr> &attributes);
+
+/**
  * @brief Returns a reference to this named expression.
  *
  * @return An AttributeReference of this named expression.
@@ -124,6 +134,35 @@
 AttributeReferencePtr ToRef(const NamedExpressionPtr &expression);
 
 /**
+ * @brief Given a vector of expressions and a vector of attributes, return a
+ *        bool vector that indicates whether each expression is refering to
+ *        ANY attribute in the attribute vector.
+ *
+ * @param expressions The vector of expressions to be checked.
+ * @param attributes The vector of attributes to be checked.
+ * @return A vector of bools indicating whether each expression is refering to
+ *         any attribute in the attribute vector. Note that the length of this
+ *         bool vector equals the length of \p expressions.
+ */
+template <class NamedExpressionType>
+std::vector<bool> MarkExpressionsReferingAnyAttribute(
+    const std::vector<std::shared_ptr<const NamedExpressionType>> &expressions,
+    const std::vector<AttributeReferencePtr> &attributes) {
+  std::vector<bool> matches;
+  UnorderedAttributeSet attr_set(attributes.begin(), attributes.end());
+  for (std::size_t i = 0; i < expressions.size(); ++i) {
+    for (const auto referenced_attr : expressions[i]->getReferencedAttributes()) {
+      if (attr_set.find(referenced_attr) != attr_set.end()) {
+        matches.emplace_back(true);
+      } else {
+        matches.emplace_back(false);
+      }
+    }
+  }
+  return matches;
+}
+
+/**
  * @brief Filter a vector of AttributeReferencePtr to get those which are in
  *        the specified scope.
  *
diff --git a/query_optimizer/expressions/SubqueryExpression.cpp b/query_optimizer/expressions/SubqueryExpression.cpp
index 0459212..3a33fe1 100644
--- a/query_optimizer/expressions/SubqueryExpression.cpp
+++ b/query_optimizer/expressions/SubqueryExpression.cpp
@@ -40,9 +40,14 @@
 }
 
 std::vector<AttributeReferencePtr> SubqueryExpression::getReferencedAttributes() const {
-  // SubqueryExpression should be eliminated before any place that needs
-  // a call of getReferencedAttributes.
-  LOG(FATAL) << "SubqueryExpression::getReferencedAttributes() is not implemented";
+  // Note(jianqiao): Here simply return an empty set so that we skip the validation
+  // for this expression at the end of the resolving phase (otherwise we need to
+  // revise the Validate() function to deal with OUTER scoped attributes). Note
+  // that SubqueryExpression will always be eliminated by UnnestSubqueries as the
+  // first logical optimization pass in LogicalGenerator. So any dangling attribute
+  // will still be detected by Validate() at the end of the logical optimization
+  // phase.
+  return {};
 }
 
 void SubqueryExpression::getFieldStringItems(
diff --git a/query_optimizer/logical/CMakeLists.txt b/query_optimizer/logical/CMakeLists.txt
index 0467233..61c6234 100644
--- a/query_optimizer/logical/CMakeLists.txt
+++ b/query_optimizer/logical/CMakeLists.txt
@@ -125,6 +125,7 @@
                       glog
                       quickstep_queryoptimizer_OptimizerTree
                       quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_ExpressionUtil
                       quickstep_queryoptimizer_expressions_Predicate
                       quickstep_queryoptimizer_logical_BinaryJoin
                       quickstep_queryoptimizer_logical_Logical
diff --git a/query_optimizer/logical/HashJoin.hpp b/query_optimizer/logical/HashJoin.hpp
index 2ae30cf..9052a23 100644
--- a/query_optimizer/logical/HashJoin.hpp
+++ b/query_optimizer/logical/HashJoin.hpp
@@ -27,6 +27,7 @@
 
 #include "query_optimizer/OptimizerTree.hpp"
 #include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ExpressionUtil.hpp"
 #include "query_optimizer/expressions/Predicate.hpp"
 #include "query_optimizer/logical/BinaryJoin.hpp"
 #include "query_optimizer/logical/Logical.hpp"
@@ -57,10 +58,10 @@
   enum class JoinType {
     kInnerJoin = 0,
     kLeftSemiJoin,
-    kLeftAntiJoin
+    kLeftAntiJoin,
+    kLeftOuterJoin
   };
 
-
   LogicalType getLogicalType() const override { return LogicalType::kHashJoin; }
 
   std::string getName() const override {
@@ -71,6 +72,8 @@
         return "HashLeftSemiJoin";
       case JoinType::kLeftAntiJoin:
         return "HashLeftAntiJoin";
+      case JoinType::kLeftOuterJoin:
+        return "HashLeftOuterJoin";
       default:
         LOG(FATAL) << "Invalid JoinType: "
                    << static_cast<typename std::underlying_type<JoinType>::type>(join_type_);
@@ -116,12 +119,36 @@
                             join_type_);
   }
 
+  std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override {
+    if (join_type_ != JoinType::kLeftOuterJoin) {
+      return BinaryJoin::getOutputAttributes();
+    }
+
+    // For left outer join, all the output attributes from the right relation
+    // must be nullable.
+    std::vector<expressions::AttributeReferencePtr> output_attributes =
+        left()->getOutputAttributes();
+    const std::vector<expressions::AttributeReferencePtr> right_nullable_output_attributes =
+        GetNullableAttributeVector(right()->getOutputAttributes());
+    output_attributes.insert(output_attributes.end(),
+                             right_nullable_output_attributes.begin(),
+                             right_nullable_output_attributes.end());
+    return output_attributes;
+  }
+
   std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override {
     std::vector<expressions::AttributeReferencePtr> referenced_attributes =
         left_join_attributes_;
     referenced_attributes.insert(referenced_attributes.end(),
                                  right_join_attributes_.begin(),
                                  right_join_attributes_.end());
+    if (residual_predicate_ != nullptr) {
+      const std::vector<expressions::AttributeReferencePtr> referenced_attributes_in_residual =
+          residual_predicate_->getReferencedAttributes();
+      referenced_attributes.insert(referenced_attributes.end(),
+                                   referenced_attributes_in_residual.begin(),
+                                   referenced_attributes_in_residual.end());
+    }
     return referenced_attributes;
   }
 
@@ -170,6 +197,11 @@
                                     container_child_field_names,
                                     container_child_fields);
 
+    if (residual_predicate_ != nullptr) {
+      non_container_child_field_names->push_back("residual_predicate");
+      non_container_child_fields->push_back(residual_predicate_);
+    }
+
     container_child_field_names->push_back("left_join_attributes");
     container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(left_join_attributes_));
     container_child_field_names->push_back("right_join_attributes");
@@ -189,7 +221,7 @@
         residual_predicate_(residual_predicate),
         join_type_(join_type) {
     DCHECK_EQ(left_join_attributes.size(), right_join_attributes.size());
-    DCHECK(!left_join_attributes.empty());
+    DCHECK(!left_join_attributes.empty() || residual_predicate != nullptr);
 
     if (residual_predicate_ != nullptr) {
       addInputExpression(residual_predicate_);
diff --git a/query_optimizer/physical/HashJoin.hpp b/query_optimizer/physical/HashJoin.hpp
index 80e7c2f..b904b5f 100644
--- a/query_optimizer/physical/HashJoin.hpp
+++ b/query_optimizer/physical/HashJoin.hpp
@@ -56,7 +56,8 @@
   enum class JoinType {
     kInnerJoin = 0,
     kLeftSemiJoin,
-    kLeftAntiJoin
+    kLeftAntiJoin,
+    kLeftOuterJoin
   };
 
   PhysicalType getPhysicalType() const override { return PhysicalType::kHashJoin; }
@@ -69,6 +70,8 @@
         return "HashLeftSemiJoin";
       case JoinType::kLeftAntiJoin:
         return "HashLeftAntiJoin";
+      case JoinType::kLeftOuterJoin:
+        return "HashLeftOuterJoin";
       default:
         LOG(FATAL) << "Invalid JoinType: "
                    << static_cast<typename std::underlying_type<JoinType>::type>(join_type_);
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index 854ace1..db2a8af 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -26,6 +26,7 @@
                       quickstep_catalog_CatalogRelation
                       quickstep_parser_ParseString
                       quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_ExpressionUtil
                       quickstep_queryoptimizer_logical_Logical
                       quickstep_utility_Macros
                       quickstep_utility_SqlError
@@ -94,6 +95,7 @@
                       quickstep_queryoptimizer_logical_DeleteTuples
                       quickstep_queryoptimizer_logical_DropTable
                       quickstep_queryoptimizer_logical_Filter
+                      quickstep_queryoptimizer_logical_HashJoin
                       quickstep_queryoptimizer_logical_InsertSelection
                       quickstep_queryoptimizer_logical_InsertTuple
                       quickstep_queryoptimizer_logical_Logical
diff --git a/query_optimizer/resolver/NameResolver.hpp b/query_optimizer/resolver/NameResolver.hpp
index ea3f1e4..1618f4e 100644
--- a/query_optimizer/resolver/NameResolver.hpp
+++ b/query_optimizer/resolver/NameResolver.hpp
@@ -25,6 +25,7 @@
 #include <vector>
 
 #include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ExpressionUtil.hpp"
 #include "query_optimizer/logical/Logical.hpp"
 #include "utility/Macros.hpp"
 #include "utility/StringUtil.hpp"
@@ -118,6 +119,29 @@
     return std::string("$").append(name);
   }
 
+  /**
+   * @return Get the index in the NameResolver for the next relation.
+   */
+  std::size_t nextScopedRelationPosition() const {
+    return relations_.size();
+  }
+
+  /**
+   * @brief Make the output attributes of all the relations with indices between
+   *        start_relation_id and end_relation_id (excluded) to be nullable.
+   *
+   * @param start_relation_id The starting index of the relation for which
+   *        the nullability of output attributes should be changed.
+   * @param end_relation_id The ending relation index.
+   */
+  void makeOutputAttributesNullable(std::size_t start_relation_id,
+                                    std::size_t end_relation_id) {
+    for (std::size_t idx = start_relation_id; idx < end_relation_id; ++idx) {
+      relations_[idx]->attributes =
+          expressions::GetNullableAttributeVector(relations_[idx]->attributes);
+    }
+  }
+
  private:
   /**
    * @brief Info of a relation and its visible attributes in the name scope.
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 242a1f0..8ddcf3f 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -19,6 +19,7 @@
 
 #include "query_optimizer/resolver/Resolver.hpp"
 
+#include <algorithm>
 #include <map>
 #include <memory>
 #include <set>
@@ -90,6 +91,7 @@
 #include "query_optimizer/logical/DeleteTuples.hpp"
 #include "query_optimizer/logical/DropTable.hpp"
 #include "query_optimizer/logical/Filter.hpp"
+#include "query_optimizer/logical/HashJoin.hpp"
 #include "query_optimizer/logical/InsertSelection.hpp"
 #include "query_optimizer/logical/InsertTuple.hpp"
 #include "query_optimizer/logical/MultiwayCartesianJoin.hpp"
@@ -1606,24 +1608,52 @@
 L::LogicalPtr Resolver::resolveJoinedTableReference(
     const ParseJoinedTableReference &joined_table_reference,
     NameResolver *name_resolver) {
-  const L::LogicalPtr left_table =
+  std::size_t start_relation_idx_for_left = name_resolver->nextScopedRelationPosition();
+  L::LogicalPtr left_table =
       resolveTableReference(*joined_table_reference.left_table(), name_resolver);
-  const L::LogicalPtr right_table =
+
+  std::size_t start_relation_idx_for_right = name_resolver->nextScopedRelationPosition();
+  L::LogicalPtr right_table =
       resolveTableReference(*joined_table_reference.right_table(), name_resolver);
 
+  std::size_t end_relation_idx = name_resolver->nextScopedRelationPosition();
+
   ExpressionResolutionInfo resolution_info(*name_resolver,
                                            "join clause" /* clause_name */,
                                            nullptr /* select_list_info */);
   const E::PredicatePtr on_predicate =
       resolvePredicate(*joined_table_reference.join_predicate(), &resolution_info);
 
-  if (joined_table_reference.join_type() == ParseJoinedTableReference::JoinType::kInnerJoin) {
-    return L::Filter::Create(
-        L::MultiwayCartesianJoin::Create({ left_table, right_table }),
-        on_predicate);
+  switch (joined_table_reference.join_type()) {
+    case ParseJoinedTableReference::JoinType::kInnerJoin: {
+      return L::Filter::Create(
+          L::MultiwayCartesianJoin::Create({ left_table, right_table }),
+          on_predicate);
+    }
+    case ParseJoinedTableReference::JoinType::kRightOuterJoin: {
+      // Swap the two tables so it becomes a left outer join.
+      std::swap(left_table, right_table);
+      end_relation_idx = start_relation_idx_for_right;
+      start_relation_idx_for_right = start_relation_idx_for_left;
+    }  // Fall through
+    case ParseJoinedTableReference::JoinType::kLeftOuterJoin: {
+      name_resolver->makeOutputAttributesNullable(start_relation_idx_for_right,
+                                                  end_relation_idx);
+
+      // left_join_attributes and right_join_attributes will be identified by
+      // GenerateJoins during logical optimization.
+      return L::HashJoin::Create(left_table,
+                                 right_table,
+                                 {} /* left_join_attributes */,
+                                 {} /* right_join_attributes */,
+                                 on_predicate,
+                                 L::HashJoin::JoinType::kLeftOuterJoin);
+    }
+    default:
+      break;
   }
 
-  THROW_SQL_ERROR_AT(&joined_table_reference) << "Outer joins are not supported yet";
+  THROW_SQL_ERROR_AT(&joined_table_reference) << "Full outer join is not supported yet";
 }
 
 void Resolver::resolveSelectClause(
@@ -1967,8 +1997,12 @@
           expression_resolution_info);
     }
     case ParseExpression::kSubqueryExpression: {
-      THROW_SQL_ERROR_AT(&parse_expression)
-          << "Subquery expression in a non-FROM clause is not supported yet";
+      const std::vector<const Type*> type_hints = { type_hint };
+      return resolveSubqueryExpression(
+          static_cast<const ParseSubqueryExpression&>(parse_expression),
+          &type_hints,
+          expression_resolution_info,
+          true /* has_single_column */);
     }
     case ParseExpression::kExtract: {
       const ParseExtractFunction &parse_extract =
diff --git a/query_optimizer/rules/CMakeLists.txt b/query_optimizer/rules/CMakeLists.txt
index 3461a5e..7032af5 100644
--- a/query_optimizer/rules/CMakeLists.txt
+++ b/query_optimizer/rules/CMakeLists.txt
@@ -51,7 +51,9 @@
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_ExpressionUtil
+                      quickstep_queryoptimizer_expressions_LogicalAnd
                       quickstep_queryoptimizer_expressions_PatternMatcher
+                      quickstep_queryoptimizer_expressions_Predicate
                       quickstep_queryoptimizer_logical_Filter
                       quickstep_queryoptimizer_logical_HashJoin
                       quickstep_queryoptimizer_logical_Logical
@@ -64,6 +66,7 @@
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID
                       quickstep_utility_Macros
+                      quickstep_utility_SqlError
                       quickstep_utility_VectorUtil)
 target_link_libraries(quickstep_queryoptimizer_rules_PruneColumns
                       quickstep_queryoptimizer_expressions_AttributeReference
@@ -79,6 +82,7 @@
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_ExpressionUtil
                       quickstep_queryoptimizer_logical_Filter
+                      quickstep_queryoptimizer_logical_HashJoin
                       quickstep_queryoptimizer_logical_Logical
                       quickstep_queryoptimizer_logical_PatternMatcher
                       quickstep_queryoptimizer_rules_Rule
@@ -131,6 +135,7 @@
                       quickstep_queryoptimizer_logical_HashJoin
                       quickstep_queryoptimizer_logical_Logical
                       quickstep_queryoptimizer_logical_LogicalType
+                      quickstep_queryoptimizer_logical_MultiwayCartesianJoin
                       quickstep_queryoptimizer_logical_PatternMatcher
                       quickstep_queryoptimizer_logical_Project
                       quickstep_queryoptimizer_logical_TopLevelPlan
diff --git a/query_optimizer/rules/GenerateJoins.cpp b/query_optimizer/rules/GenerateJoins.cpp
index 05fa397..174cf03 100644
--- a/query_optimizer/rules/GenerateJoins.cpp
+++ b/query_optimizer/rules/GenerateJoins.cpp
@@ -19,6 +19,7 @@
 
 #include "query_optimizer/rules/GenerateJoins.hpp"
 
+#include <memory>
 #include <unordered_map>
 #include <utility>
 #include <vector>
@@ -26,7 +27,9 @@
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/ComparisonExpression.hpp"
 #include "query_optimizer/expressions/ExpressionUtil.hpp"
+#include "query_optimizer/expressions/LogicalAnd.hpp"
 #include "query_optimizer/expressions/PatternMatcher.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
 #include "query_optimizer/logical/Filter.hpp"
 #include "query_optimizer/logical/HashJoin.hpp"
 #include "query_optimizer/logical/Logical.hpp"
@@ -37,6 +40,7 @@
 #include "query_optimizer/rules/RuleHelper.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"
+#include "utility/SqlError.hpp"
 #include "utility/VectorUtil.hpp"
 
 #include "glog/logging.h"
@@ -245,6 +249,7 @@
 L::LogicalPtr GenerateJoins::applyToNode(const L::LogicalPtr &input) {
   L::FilterPtr filter;
   L::MultiwayCartesianJoinPtr cartesian_join;
+  L::HashJoinPtr hash_join;
 
   // Merge filter predicates with cartesian joins to generate NestedLoopsJoin or
   // HashJoin.
@@ -391,6 +396,91 @@
     L::LogicalPtr output = MaybeGenerateNestedLoopsCartesianJoin(cartesian_join->operands());
     LOG_APPLYING_RULE(input, output);
     return output;
+  } else if (L::SomeHashJoin::MatchesWithConditionalCast(input, &hash_join) &&
+             hash_join->join_type() == L::HashJoin::JoinType::kLeftOuterJoin) {
+    L::LogicalPtr left_logical = hash_join->left();
+    L::LogicalPtr right_logical = hash_join->right();
+
+    const std::vector<E::AttributeReferencePtr> left_relation_attributes =
+        left_logical->getOutputAttributes();
+    const std::vector<E::AttributeReferencePtr> right_relation_attributes =
+        right_logical->getOutputAttributes();
+
+    DCHECK(hash_join->residual_predicate() != nullptr);
+    const std::vector<E::PredicatePtr> on_predicate_items =
+        GetConjunctivePredicates(hash_join->residual_predicate());
+
+    std::vector<E::AttributeReferencePtr> left_join_attributes;
+    std::vector<E::AttributeReferencePtr> right_join_attributes;
+    std::vector<E::PredicatePtr> left_filter_predicates;
+    std::vector<E::PredicatePtr> right_filter_predicates;
+
+    for (const E::PredicatePtr &predicate_item : on_predicate_items) {
+      std::vector<E::AttributeReferencePtr> referenced_attrs =
+          predicate_item->getReferencedAttributes();
+
+      if (E::SubsetOfExpressions(referenced_attrs, left_relation_attributes)) {
+        // The predicate refers attributes only from the left relation.
+        left_filter_predicates.emplace_back(predicate_item);
+      } else if (E::SubsetOfExpressions(referenced_attrs, right_relation_attributes)) {
+        // The predicate refers attributes only from the right relation.
+        right_filter_predicates.emplace_back(predicate_item);
+      } else {
+        // The predicate refers attributes from both relations.
+        //
+        // NOTE(jianqiao): In this case, since currently in the backend we do not
+        // support residual predicates for hash outer joins, so the predicate can
+        // only be an equal comparison between two attributes (one from left and
+        // one from right).
+        E::ComparisonExpressionPtr comp_expr;
+        if (E::SomeComparisonExpression::MatchesWithConditionalCast(predicate_item,
+                                                                    &comp_expr)) {
+          E::AttributeReferencePtr left_attr;
+          E::AttributeReferencePtr right_attr;
+          if (comp_expr->isEqualityComparisonPredicate() &&
+              E::SomeAttributeReference::MatchesWithConditionalCast(comp_expr->left(), &left_attr) &&
+              E::SomeAttributeReference::MatchesWithConditionalCast(comp_expr->right(), &right_attr)) {
+            if (E::ContainsExpression(left_relation_attributes, left_attr)) {
+              DCHECK(E::ContainsExpression(right_relation_attributes, right_attr));
+
+              left_join_attributes.emplace_back(left_attr);
+              right_join_attributes.emplace_back(right_attr);
+            } else {
+              DCHECK(E::ContainsExpression(left_relation_attributes, right_attr));
+              DCHECK(E::ContainsExpression(right_relation_attributes, left_attr));
+
+              left_join_attributes.emplace_back(right_attr);
+              right_join_attributes.emplace_back(left_attr);
+            }
+          } else {
+            THROW_SQL_ERROR() << "Join predicate for outer joins must be an "
+                              << "equality comparison between attributes";
+          }
+        } else {
+          THROW_SQL_ERROR() << "Non-equality join predicate is not allowed for outer joins";
+        }
+      }
+    }
+
+    if (!left_filter_predicates.empty()) {
+        // NOTE(jianqiao): Filter predicates on left table cannot be pushed down
+        // but can be treated as residual predicates once we have support for that.
+        THROW_SQL_ERROR() << "Filter predicates on left table is not allowed for outer joins";
+    }
+
+    if (!right_filter_predicates.empty()) {
+      const E::PredicatePtr right_predicate =
+          (right_filter_predicates.size() == 1u ? right_filter_predicates[0]
+                                                : E::LogicalAnd::Create(right_filter_predicates));
+      right_logical = L::Filter::Create(right_logical, right_predicate);
+    }
+
+    return L::HashJoin::Create(left_logical,
+                               right_logical,
+                               left_join_attributes,
+                               right_join_attributes,
+                               nullptr /* residual_predicate */,
+                               L::HashJoin::JoinType::kLeftOuterJoin);
   }
 
   LOG_IGNORING_RULE(input);
diff --git a/query_optimizer/rules/PushDownFilter.cpp b/query_optimizer/rules/PushDownFilter.cpp
index 41c21e7..5bf5545 100644
--- a/query_optimizer/rules/PushDownFilter.cpp
+++ b/query_optimizer/rules/PushDownFilter.cpp
@@ -1,6 +1,8 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
  *   Copyright 2015 Pivotal Software, Inc.
+ *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
+ *     University of Wisconsin—Madison.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -17,11 +19,13 @@
 
 #include "query_optimizer/rules/PushDownFilter.hpp"
 
+#include <cstddef>
 #include <vector>
 
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/ExpressionUtil.hpp"
 #include "query_optimizer/logical/Filter.hpp"
+#include "query_optimizer/logical/HashJoin.hpp"
 #include "query_optimizer/logical/PatternMatcher.hpp"
 #include "query_optimizer/rules/Rule.hpp"
 #include "query_optimizer/rules/RuleHelper.hpp"
@@ -48,13 +52,23 @@
     // We consider if the filter predicates can be pushed under the input of the
     // Filter.
     const L::LogicalPtr &input = filter->input();
-    const std::vector<L::LogicalPtr> input_children = input->children();
+    const std::vector<L::LogicalPtr> &input_children = input->children();
 
     // Store the predicates that can be pushed down to be upon each child node
     // of the Filter input.
     std::vector<std::vector<E::PredicatePtr>> predicates_to_be_pushed(
         input_children.size());
     if (!input_children.empty()) {
+      std::size_t last_input_index = input_children.size();
+
+      // Cannot push down a Filter down the right child of LeftOuterJoin.
+      L::HashJoinPtr hash_join;
+      if (L::SomeHashJoin::MatchesWithConditionalCast(input, &hash_join) &&
+          hash_join->join_type() == L::HashJoin::JoinType::kLeftOuterJoin) {
+        DCHECK_EQ(2u, input_children.size());
+        last_input_index = 1u;
+      }
+
       for (const E::PredicatePtr &conjuntion_item : conjunction_items) {
         bool can_be_pushed = false;
         const std::vector<E::AttributeReferencePtr> referenced_attributes =
@@ -64,7 +78,7 @@
         // referenced by the predicate is a subset of output attributes
         // of a child.
         for (std::vector<L::LogicalPtr>::size_type input_index = 0;
-             input_index < input_children.size();
+             input_index < last_input_index;
              ++input_index) {
           if (SubsetOfExpressions(
                   referenced_attributes,
diff --git a/query_optimizer/rules/PushDownSemiAntiJoin.cpp b/query_optimizer/rules/PushDownSemiAntiJoin.cpp
index 54af764..d53970e 100644
--- a/query_optimizer/rules/PushDownSemiAntiJoin.cpp
+++ b/query_optimizer/rules/PushDownSemiAntiJoin.cpp
@@ -64,7 +64,14 @@
   std::vector<L::LogicalPtr> left_input_children = left_input->children();
 
   if (!left_input_children.empty()) {
-    const std::vector<L::LogicalPtr>::size_type last_input_index = left_input_children.size();
+    std::vector<L::LogicalPtr>::size_type last_input_index = left_input_children.size();
+    // Cannot push down a Filter down the right child of LeftOuterJoin.
+    L::HashJoinPtr hash_join;
+    if (L::SomeHashJoin::MatchesWithConditionalCast(left_input, &hash_join) &&
+        hash_join->join_type() == L::HashJoin::JoinType::kLeftOuterJoin) {
+      DCHECK_EQ(2u, left_input_children.size());
+      last_input_index = 1u;
+    }
 
     std::vector<L::LogicalPtr>::size_type input_index = 0;
     while (input_index < last_input_index) {
diff --git a/query_optimizer/rules/UnnestSubqueries.cpp b/query_optimizer/rules/UnnestSubqueries.cpp
index 7852577..d22ab8e 100644
--- a/query_optimizer/rules/UnnestSubqueries.cpp
+++ b/query_optimizer/rules/UnnestSubqueries.cpp
@@ -18,7 +18,9 @@
 #include "query_optimizer/rules/UnnestSubqueries.hpp"
 
 #include <algorithm>
+#include <functional>
 #include <memory>
+#include <set>
 #include <utility>
 #include <vector>
 
@@ -41,6 +43,7 @@
 #include "query_optimizer/logical/HashJoin.hpp"
 #include "query_optimizer/logical/Logical.hpp"
 #include "query_optimizer/logical/LogicalType.hpp"
+#include "query_optimizer/logical/MultiwayCartesianJoin.hpp"
 #include "query_optimizer/logical/PatternMatcher.hpp"
 #include "query_optimizer/logical/Project.hpp"
 #include "query_optimizer/logical/TopLevelPlan.hpp"
@@ -62,7 +65,8 @@
   enum class JoinType {
     kInnerJoin = 0,
     kLeftSemiJoin,
-    kLeftAntiJoin
+    kLeftAntiJoin,
+    kCartesianJoin
   };
 
   CorrelatedQueryInfo(const JoinType join_type_in,
@@ -464,9 +468,29 @@
         new_child = node->children()[0];
       }
 
-      for (CorrelatedQueryInfo &correlated_query_info : correlated_query_info_vec) {
-        DCHECK(!correlated_query_info.probe_join_attributes.empty());
+      // Join uncorrelated subqueries early.
+      L::LogicalPtr uncorrelated_query_child;
+      for (const CorrelatedQueryInfo &correlated_query_info : correlated_query_info_vec) {
+        if (correlated_query_info.join_type == CorrelatedQueryInfo::JoinType::kCartesianJoin) {
+          // The only case for this nested loop join is that it is an uncorrelated
+          // subquery which returns a scalar (single column and single row) result.
+          DCHECK(correlated_query_info.probe_join_attributes.empty());
+          DCHECK_EQ(0u, correlated_query_info.non_hash_join_predicates.size());
+          if (uncorrelated_query_child == nullptr) {
+            uncorrelated_query_child = correlated_query_info.correlated_query;
+          } else {
+            uncorrelated_query_child = L::MultiwayCartesianJoin::Create(
+                { uncorrelated_query_child, correlated_query_info.correlated_query });
+          }
+        }
+      }
+      if (uncorrelated_query_child != nullptr) {
+        new_child = L::MultiwayCartesianJoin::Create({ new_child, uncorrelated_query_child });
+      }
+
+      for (const CorrelatedQueryInfo &correlated_query_info : correlated_query_info_vec) {
         if (correlated_query_info.join_type == CorrelatedQueryInfo::JoinType::kInnerJoin) {
+          DCHECK(!correlated_query_info.probe_join_attributes.empty());
           DCHECK(correlated_query_info.non_hash_join_predicates.empty())
               << correlated_query_info.non_hash_join_predicates[0]->toString();
           new_child = L::HashJoin::Create(new_child,
@@ -475,7 +499,9 @@
                                           correlated_query_info.build_join_attributes,
                                           nullptr, /* residual_predicate */
                                           L::HashJoin::JoinType::kInnerJoin);
-        } else {
+        } else if (correlated_query_info.join_type == CorrelatedQueryInfo::JoinType::kLeftSemiJoin ||
+                   correlated_query_info.join_type == CorrelatedQueryInfo::JoinType::kLeftAntiJoin) {
+          DCHECK(!correlated_query_info.probe_join_attributes.empty());
           E::PredicatePtr filter_predicate;
           if (correlated_query_info.non_hash_join_predicates.size() > 1u) {
             filter_predicate = E::LogicalAnd::Create(correlated_query_info.non_hash_join_predicates);
@@ -545,16 +571,11 @@
       if (probe_join_attributes.empty()) {
         DCHECK(non_hash_join_predicates.empty());
         DCHECK_EQ(1u, new_subquery->getOutputAttributes().size()) << node->toString();
-        const E::AttributeReferencePtr new_outer_attribute_reference =
-            E::AttributeReference::Create(context_->nextExprId(),
-                                          output_attribute->attribute_name(),
-                                          output_attribute->attribute_alias(),
-                                          output_attribute->relation_name(),
-                                          output_attribute->getValueType(),
-                                          E::AttributeReferenceScope::kOuter);
-        uncorrelated_subqueries_->emplace(new_outer_attribute_reference->id(),
-                                          new_subquery);
-        return new_outer_attribute_reference;
+        correlated_query_info_vec_->emplace_back(CorrelatedQueryInfo::JoinType::kCartesianJoin,
+                                                 new_subquery,
+                                                 std::move(probe_join_attributes),
+                                                 std::move(build_join_attributes),
+                                                 std::move(non_hash_join_predicates));
       } else {
         correlated_query_info_vec_->emplace_back(CorrelatedQueryInfo::JoinType::kInnerJoin,
                                                  new_subquery,
diff --git a/query_optimizer/strategy/Join.cpp b/query_optimizer/strategy/Join.cpp
index becea61..ceb3f4f 100644
--- a/query_optimizer/strategy/Join.cpp
+++ b/query_optimizer/strategy/Join.cpp
@@ -314,6 +314,9 @@
     case L::HashJoin::JoinType::kLeftAntiJoin:
       join_type = P::HashJoin::JoinType::kLeftAntiJoin;
       break;
+    case L::HashJoin::JoinType::kLeftOuterJoin:
+      join_type = P::HashJoin::JoinType::kLeftOuterJoin;
+      break;
     default:
       LOG(FATAL) << "Invalid logical::HashJoin::JoinType: "
                  << static_cast<typename std::underlying_type<L::HashJoin::JoinType>::type>(
diff --git a/query_optimizer/tests/CMakeLists.txt b/query_optimizer/tests/CMakeLists.txt
index eb64070..1d2fa10 100644
--- a/query_optimizer/tests/CMakeLists.txt
+++ b/query_optimizer/tests/CMakeLists.txt
@@ -86,9 +86,9 @@
                "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.hpp")
 
 target_link_libraries(quickstep_queryoptimizer_tests_ExecutionGeneratorTest
+                      gflags_nothreads-static
                       glog
                       gtest
-                      gtest_main
                       quickstep_catalog_CatalogDatabase
                       quickstep_cli_DropRelation
                       quickstep_cli_PrintToScreen
diff --git a/query_optimizer/tests/ExecutionGeneratorTest.cpp b/query_optimizer/tests/ExecutionGeneratorTest.cpp
index 92e9e7c..42b246b 100644
--- a/query_optimizer/tests/ExecutionGeneratorTest.cpp
+++ b/query_optimizer/tests/ExecutionGeneratorTest.cpp
@@ -1,6 +1,6 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
- *   Copyright 2015 Pivotal Software, Inc.
+ *   Copyright 2015-2016 Pivotal Software, Inc.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
 #include "query_optimizer/tests/ExecutionGeneratorTestRunner.hpp"
 #include "utility/textbased_test/TextBasedTestDriver.hpp"
 
+#include "gflags/gflags.h"
 #include "glog/logging.h"
 
 using quickstep::TextBasedTest;
@@ -30,6 +31,8 @@
 
 int main(int argc, char** argv) {
   google::InitGoogleLogging(argv[0]);
+  // Honor FLAGS_buffer_pool_slots in StorageManager.
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
 
   if (argc < 4) {
     LOG(ERROR) << "Must have at least 3 arguments, but " << argc - 1
diff --git a/query_optimizer/tests/execution_generator/Join.test b/query_optimizer/tests/execution_generator/Join.test
index 6d6d2e1..011d365 100644
--- a/query_optimizer/tests/execution_generator/Join.test
+++ b/query_optimizer/tests/execution_generator/Join.test
@@ -130,3 +130,102 @@
 |          6|                  61|                     601|              C6|
 |         18|                 181|                    1799|             C18|
 +-----------+--------------------+------------------------+----------------+
+==
+
+SELECT a.w AS "a.w", b.x AS "b.x", c.y AS "c.y", d.z AS "d.z"
+FROM a LEFT JOIN b ON a.w = b.w
+       LEFT JOIN c ON a.x = c.x
+       LEFT JOIN d ON a.y = d.y
+ORDER BY a.w;
+--
++-----------+--------------------+------------------------+----------------+
+|a.w        |b.x                 |c.y                     |d.z             |
++-----------+--------------------+------------------------+----------------+
+|          0|                   0|                      -1|              C0|
+|          1|                NULL|                    NULL|              C1|
+|          2|                  21|                    NULL|              C2|
+|          3|                NULL|                     300|              C3|
+|          4|                  40|                    NULL|              C4|
+|          5|                NULL|                    NULL|              C5|
+|          6|                  61|                     601|              C6|
+|          7|                NULL|                    NULL|              C7|
+|          8|                  80|                    NULL|              C8|
+|          9|                NULL|                     899|              C9|
+|         10|                 101|                    NULL|             C10|
+|         11|                NULL|                    NULL|             C11|
+|         12|                 120|                    1200|             C12|
+|         13|                NULL|                    NULL|             C13|
+|         14|                 141|                    NULL|             C14|
+|         15|                NULL|                    1501|             C15|
+|         16|                 160|                    NULL|             C16|
+|         17|                NULL|                    NULL|             C17|
+|         18|                 181|                    1799|             C18|
+|         19|                NULL|                    NULL|             C19|
++-----------+--------------------+------------------------+----------------+
+==
+
+SELECT a.w AS "a.w", b.x AS "b.x", c.y AS "c.y", d.z AS "d.z"
+FROM a LEFT JOIN b ON a.w = b.w
+       LEFT JOIN c ON b.x = c.x
+       LEFT JOIN d ON c.y = d.y
+ORDER BY a.w;
+--
++-----------+--------------------+------------------------+----------------+
+|a.w        |b.x                 |c.y                     |d.z             |
++-----------+--------------------+------------------------+----------------+
+|          0|                   0|                      -1|            NULL|
+|          1|                NULL|                    NULL|            NULL|
+|          2|                  21|                    NULL|            NULL|
+|          3|                NULL|                    NULL|            NULL|
+|          4|                  40|                    NULL|            NULL|
+|          5|                NULL|                    NULL|            NULL|
+|          6|                  61|                    NULL|            NULL|
+|          7|                NULL|                    NULL|            NULL|
+|          8|                  80|                    NULL|            NULL|
+|          9|                NULL|                    NULL|            NULL|
+|         10|                 101|                    NULL|            NULL|
+|         11|                NULL|                    NULL|            NULL|
+|         12|                 120|                    1200|             C12|
+|         13|                NULL|                    NULL|            NULL|
+|         14|                 141|                    NULL|            NULL|
+|         15|                NULL|                    NULL|            NULL|
+|         16|                 160|                    NULL|            NULL|
+|         17|                NULL|                    NULL|            NULL|
+|         18|                 181|                    NULL|            NULL|
+|         19|                NULL|                    NULL|            NULL|
++-----------+--------------------+------------------------+----------------+
+==
+
+SELECT b.x AS "b.x", c1.x AS "c1.x", c2.x AS "c2.x"
+FROM b LEFT JOIN c c1 ON (b.x = c1.x)
+       LEFT JOIN c c2 ON (b.x = c2.x AND c2.x > 10)
+ORDER BY b.x;
+--
++--------------------+--------------------+--------------------+
+|b.x                 |c1.x                |c2.x                |
++--------------------+--------------------+--------------------+
+|                   0|                   0|                NULL|
+|                  21|                NULL|                NULL|
+|                  40|                NULL|                NULL|
+|                  61|                NULL|                NULL|
+|                  80|                NULL|                NULL|
+|                 101|                NULL|                NULL|
+|                 120|                 120|                 120|
+|                 141|                NULL|                NULL|
+|                 160|                NULL|                NULL|
+|                 181|                NULL|                NULL|
++--------------------+--------------------+--------------------+
+==
+
+SELECT a.w AS "a.w", b.x AS "b.x", c.y AS "c.y", d.z AS "d.z"
+FROM a RIGHT JOIN b ON a.w = b.w
+       JOIN c ON a.x = c.x
+       LEFT JOIN d ON a.y = d.y
+WHERE b.x > 10
+  AND c.y < 1000;
+--
++-----------+--------------------+------------------------+----------------+
+|a.w        |b.x                 |c.y                     |d.z             |
++-----------+--------------------+------------------------+----------------+
+|          6|                  61|                     601|              C6|
++-----------+--------------------+------------------------+----------------+
diff --git a/query_optimizer/tests/execution_generator/Select.test b/query_optimizer/tests/execution_generator/Select.test
index 0618ae2..438546c 100644
--- a/query_optimizer/tests/execution_generator/Select.test
+++ b/query_optimizer/tests/execution_generator/Select.test
@@ -662,11 +662,11 @@
 +-------------------------------+
 ==
 
-SELECT EXTRACT(hour FROM value + INTERVAL '1 hour')
+SELECT EXTRACT(HOUR FROM value + INTERVAL '1 hour')
 FROM dates;
 --
 +-----------------------------------------------------+
-|EXTRACT(hour FROM (value+DatetimeInterval('1 hour')))|
+|EXTRACT(HOUR FROM (value+DatetimeInterval('1 hour')))|
 +-----------------------------------------------------+
 |                                                   11|
 |                                                   12|
@@ -820,11 +820,56 @@
 +-----------+
 ==
 
-# TODO(team): Support uncorrelated queries.
-# SELECT COUNT(*)
-# FROM test
-# WHERE double_col < 0
-#   AND long_col > (SELECT AVG(long_col) FROM test)
+# Scalar subquery expression
+SELECT *
+FROM test
+WHERE double_col < 0
+  AND long_col > (SELECT AVG(long_col) FROM test);
+--
++-----------+--------------------+---------------+------------------------+--------------------+
+|int_col    |long_col            |float_col      |double_col              |char_col            |
++-----------+--------------------+---------------+------------------------+--------------------+
+|        -15|                 225|     3.87298346|     -58.094750193111253|        -15 3.872983|
+|        -17|                 289|     4.12310553|     -70.092795635500224|        -17 4.123106|
+|        -19|                 361|     4.35889912|      -82.81907992727281|        -19 4.358899|
+|        -21|                 441|      4.5825758|     -96.234089594072643|        -21 4.582576|
+|        -23|                 529|     4.79583168|     -110.30412503619254|        -23 4.795832|
++-----------+--------------------+---------------+------------------------+--------------------+
+==
+
+SELECT i + (
+  SELECT SUM(j)
+  FROM generate_series(1, 10) AS gs(j))
+FROM generate_series(1, 5) AS gs(i);
+--
++----------------------+
+|(i+SubqueryExpression)|
++----------------------+
+|                    56|
+|                    57|
+|                    58|
+|                    59|
+|                    60|
++----------------------+
+==
+
+SELECT i + (
+  SELECT SUM(j)
+  FROM generate_series(1, 10) AS gs1(j),
+       generate_series(1, 10) AS gs2(k)
+  WHERE i = k AND j <= k)
+FROM generate_series(1, 5) AS gs(i);
+--
++----------------------+
+|(i+SubqueryExpression)|
++----------------------+
+|                     2|
+|                     5|
+|                     9|
+|                    14|
+|                    20|
++----------------------+
+==
 
 # TODO(team): Fix Issue #9 to enable COUNT(*).
 SELECT COUNT(long_col)
diff --git a/query_optimizer/tests/logical_generator/Join.test b/query_optimizer/tests/logical_generator/Join.test
index d48df4c..a6452cc 100644
--- a/query_optimizer/tests/logical_generator/Join.test
+++ b/query_optimizer/tests/logical_generator/Join.test
@@ -215,3 +215,185 @@
 |   +-AttributeReference[id=3,name=z,relation=a1,type=Int]
 +-output_attributes=
   +-AttributeReference[id=3,name=z,relation=a1,type=Int]
+==
+
+
+# Outer joins
+SELECT a.w, b.x, c.y, d.z
+FROM a LEFT JOIN b ON a.w = b.w
+       LEFT JOIN c ON a.x = c.x
+       LEFT JOIN d ON a.y = d.y;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=HashLeftOuterJoin
+| | | +-left=HashLeftOuterJoin
+| | | | +-left=TableReference[relation_name=a]
+| | | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | | | +-AttributeReference[id=3,name=z,relation=a,type=Int]
+| | | | +-right=TableReference[relation_name=b]
+| | | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | +-left_join_attributes=
+| | | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | +-right_join_attributes=
+| | | |   +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | +-right=TableReference[relation_name=c]
+| | | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | | +-left_join_attributes=
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | +-right_join_attributes=
+| | |   +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | +-right=TableReference[relation_name=d]
+| | | +-AttributeReference[id=8,name=y,relation=d,type=Int]
+| | | +-AttributeReference[id=9,name=z,relation=d,type=Int]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=8,name=y,relation=d,type=Int]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=a,type=Int]
+|   +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+|   +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+|   +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=a,type=Int]
+  +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+  +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+  +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
+==
+
+# Push down filtering
+SELECT a.w, b.x, c.y, d.z
+FROM a RIGHT JOIN b ON a.w = b.w
+       JOIN c ON a.x = c.x
+       LEFT JOIN d ON a.y = d.y
+WHERE b.x > 10
+  AND c.y > 20;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=HashJoin
+| | | +-left=HashLeftOuterJoin
+| | | | +-left=Filter
+| | | | | +-input=TableReference[relation_name=b]
+| | | | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | | +-filter_predicate=Greater
+| | | | |   +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | |   +-Literal[value=10,type=Int]
+| | | | +-right=TableReference[relation_name=a]
+| | | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | | | +-AttributeReference[id=3,name=z,relation=a,type=Int]
+| | | | +-left_join_attributes=
+| | | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | +-right_join_attributes=
+| | | |   +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | +-right=Filter
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | | | +-filter_predicate=Greater
+| | | |   +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | | |   +-Literal[value=20,type=Int]
+| | | +-left_join_attributes=
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int NULL]
+| | | +-right_join_attributes=
+| | |   +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | +-right=TableReference[relation_name=d]
+| | | +-AttributeReference[id=8,name=y,relation=d,type=Int]
+| | | +-AttributeReference[id=9,name=z,relation=d,type=Int]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=2,name=y,relation=a,type=Int NULL]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=8,name=y,relation=d,type=Int]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+|   +-AttributeReference[id=5,name=x,relation=b,type=Int]
+|   +-AttributeReference[id=7,name=y,relation=c,type=Int]
+|   +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+  +-AttributeReference[id=5,name=x,relation=b,type=Int]
+  +-AttributeReference[id=7,name=y,relation=c,type=Int]
+  +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
+==
+
+SELECT *
+FROM b LEFT JOIN c ON (b.x = c.x AND c.x > 10);
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Filter
+| | | +-input=TableReference[relation_name=c]
+| | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-filter_predicate=Greater
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | |   +-Literal[value=10,type=Int]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+|   +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+  +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+  +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
+==
+
+# Consider the semantics of this query, a value of b.x WILL BE in the output even if it is no greater than 10.
+SELECT *
+FROM b LEFT JOIN c ON (b.x = c.x AND b.x > 10);
+--
+ERROR: Filter predicates on left table is not allowed for outer joins
+==
+
+# Consider the semantics of this query, a value of b.x WILL NOT BE in the output if it is no greater than 10.
+SELECT *
+FROM b LEFT JOIN c ON b.x = c.x
+WHERE b.x > 10;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=Filter
+| | | +-input=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | | +-filter_predicate=Greater
+| | |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | |   +-Literal[value=10,type=Int]
+| | +-right=TableReference[relation_name=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+|   +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+  +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+  +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
diff --git a/query_optimizer/tests/logical_generator/Select.test b/query_optimizer/tests/logical_generator/Select.test
index c6d4201..6dff3e7 100644
--- a/query_optimizer/tests/logical_generator/Select.test
+++ b/query_optimizer/tests/logical_generator/Select.test
@@ -896,3 +896,373 @@
 |   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 +-output_attributes=
   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+==
+
+# Scalar subquery expressions
+SELECT x + (SELECT SUM(y) FROM c)
+FROM b;
+--
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-[]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-join_predicate=Literal[value=true]
+| +-project_list=
+|   +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT x + (SELECT SUM(y) FROM c WHERE b.w = c.x)
+FROM b;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| +-project_list=
+|   +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT *
+FROM b
+WHERE b.x > (SELECT SUM(y) FROM c);
+--
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-[]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-join_predicate=Greater
+| |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |   +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+==
+
+SELECT *
+FROM b
+WHERE b.x > (SELECT SUM(y) FROM c WHERE b.w = c.x);
+--
+TopLevelPlan
++-plan=Project
+| +-input=Filter
+| | +-input=HashJoin
+| | | +-left=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | | +-right=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=c]
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Long NULL]
+| | | | |     +-AggregateFunction[function=SUM]
+| | | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-project_list=
+| | | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | | |     +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Long NULL]
+| | | +-left_join_attributes=
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-right_join_attributes=
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | +-filter_predicate=Greater
+| |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |   +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+==
+
+SELECT x + (
+  SELECT SUM(y) + (SELECT SUM(w) FROM a WHERE a.y > 10)
+  FROM c
+  WHERE b.w = c.x AND c.x < 10)
+FROM b;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=NestedLoopsJoin
+| | | | +-left=Aggregate
+| | | | | +-input=Filter
+| | | | | | +-input=TableReference[relation_name=c]
+| | | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | | | +-filter_predicate=Less
+| | | | | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | |   +-Literal[value=10,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Long NULL]
+| | | | |     +-AggregateFunction[function=SUM]
+| | | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-right=Project
+| | | | | +-input=Aggregate
+| | | | | | +-input=Filter
+| | | | | | | +-input=TableReference[relation_name=a]
+| | | | | | | | +-AttributeReference[id=5,name=w,relation=a,type=Int]
+| | | | | | | | +-AttributeReference[id=6,name=x,relation=a,type=Int]
+| | | | | | | | +-AttributeReference[id=7,name=y,relation=a,type=Int]
+| | | | | | | | +-AttributeReference[id=8,name=z,relation=a,type=Int]
+| | | | | | | +-filter_predicate=Greater
+| | | | | | |   +-AttributeReference[id=7,name=y,relation=a,type=Int]
+| | | | | | |   +-Literal[value=10,type=Int]
+| | | | | | +-grouping_expressions=
+| | | | | | | +-[]
+| | | | | | +-aggregate_expressions=
+| | | | | |   +-Alias[id=9,name=,alias=$aggregate0,relation=$aggregate,
+| | | | | |     type=Long NULL]
+| | | | | |     +-AggregateFunction[function=SUM]
+| | | | | |       +-AttributeReference[id=5,name=w,relation=a,type=Int]
+| | | | | +-project_list=
+| | | | |   +-Alias[id=9,name=,alias=SUM(w),relation=,type=Long NULL]
+| | | | |     +-AttributeReference[id=9,name=,alias=$aggregate0,
+| | | | |       relation=$aggregate,type=Long NULL]
+| | | | +-join_predicate=Literal[value=true]
+| | | +-project_list=
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | |   +-Alias[id=10,name=,alias=(SUM(y)+SubqueryExpression),relation=,
+| | |     type=Long NULL]
+| | |     +-Add
+| | |       +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | |       | relation=$aggregate,type=Long NULL]
+| | |       +-AttributeReference[id=9,name=,alias=SUM(w),relation=,
+| | |         type=Long NULL]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| +-project_list=
+|   +-Alias[id=11,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=10,name=,alias=(SUM(y)+SubqueryExpression),
+|         relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=11,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT x * (SELECT SUM(y) FROM c) + (SELECT AVG(y) FROM d)
+FROM b;
+--
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=NestedLoopsJoin
+| | | +-left=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=c]
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-[]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Long NULL]
+| | | | |     +-AggregateFunction[function=SUM]
+| | | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-project_list=
+| | | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | | |     +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Long NULL]
+| | | +-right=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=d]
+| | | | | | +-AttributeReference[id=5,name=y,relation=d,type=Int]
+| | | | | | +-AttributeReference[id=6,name=z,relation=d,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-[]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Double NULL]
+| | | | |     +-AggregateFunction[function=AVG]
+| | | | |       +-AttributeReference[id=5,name=y,relation=d,type=Int]
+| | | | +-project_list=
+| | | |   +-Alias[id=7,name=,alias=AVG(y),relation=,type=Double NULL]
+| | | |     +-AttributeReference[id=7,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Double NULL]
+| | | +-join_predicate=Literal[value=true]
+| | +-join_predicate=Literal[value=true]
+| +-project_list=
+|   +-Alias[id=8,name=,alias=((x*SubqueryExpression)+SubqueryExpression),
+|     relation=,type=Double NULL]
+|     +-Add
+|       +-Multiply
+|       | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       | +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+|       +-AttributeReference[id=7,name=,alias=AVG(y),relation=,type=Double NULL]
++-output_attributes=
+  +-AttributeReference[id=8,name=,
+    alias=((x*SubqueryExpression)+SubqueryExpression),relation=,type=Double NULL]
+==
+
+SELECT x * (SELECT SUM(y) FROM c)
+FROM b
+WHERE w < (SELECT AVG(y) FROM d);
+--
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=NestedLoopsJoin
+| | | +-left=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | | +-right=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=d]
+| | | | | | +-AttributeReference[id=2,name=y,relation=d,type=Int]
+| | | | | | +-AttributeReference[id=3,name=z,relation=d,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-[]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Double NULL]
+| | | | |     +-AggregateFunction[function=AVG]
+| | | | |       +-AttributeReference[id=2,name=y,relation=d,type=Int]
+| | | | +-project_list=
+| | | |   +-Alias[id=4,name=,alias=AVG(y),relation=,type=Double NULL]
+| | | |     +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Double NULL]
+| | | +-join_predicate=Less
+| | |   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | |   +-AttributeReference[id=4,name=,alias=AVG(y),relation=,type=Double NULL]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=5,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=6,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-[]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=6,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=7,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-join_predicate=Literal[value=true]
+| +-project_list=
+|   +-Alias[id=8,name=,alias=(x*SubqueryExpression),relation=,type=Long NULL]
+|     +-Multiply
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=7,name=,alias=SUM(y),relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=8,name=,alias=(x*SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT x + (SELECT SUM(y) FROM c WHERE b.w > c.x)
+FROM b;
+--
+ERROR: Non-equality join predicate is not allowed in scalar subqueries
+==
+
+SELECT x + (SELECT SUM(y) FROM c WHERE b.w = c.x AND b.x > c.y)
+FROM b;
+--
+ERROR: Non-equality join predicate is not allowed in scalar subqueries
+==
+
+SELECT x + (
+  SELECT SUM(y) + (
+    SELECT SUM(w)
+    FROM a WHERE a.y = b.x)
+  FROM c
+  WHERE b.w = c.x AND c.x < 10)
+FROM b;
+--
+ERROR: Nested queries can only reference attributes in the outer query one level above
diff --git a/query_optimizer/tests/physical_generator/Join.test b/query_optimizer/tests/physical_generator/Join.test
index c1f49b0..45c9cbd 100644
--- a/query_optimizer/tests/physical_generator/Join.test
+++ b/query_optimizer/tests/physical_generator/Join.test
@@ -235,3 +235,167 @@
 |   +-AttributeReference[id=9,name=z,relation=d1,type=Int]
 +-output_attributes=
   +-AttributeReference[id=3,name=z,relation=a1,type=Int]
+==
+
+SELECT a.w, b.x, c.y, d.z
+FROM a LEFT JOIN b ON a.w = b.w
+       LEFT JOIN c ON a.x = c.x
+       LEFT JOIN d ON a.y = d.y;
+--
+TopLevelPlan
++-plan=HashLeftOuterJoin
+| +-left=HashLeftOuterJoin
+| | +-left=HashLeftOuterJoin
+| | | +-left=TableReference[relation=a]
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | | +-AttributeReference[id=3,name=z,relation=a,type=Int]
+| | | +-right=TableReference[relation=b]
+| | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | +-project_expressions=
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | | +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+| | | +-left_join_attributes=
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | +-right_join_attributes=
+| | |   +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | +-right=TableReference[relation=c]
+| | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | +-project_expressions=
+| | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+| | | +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| +-right=TableReference[relation=d]
+| | +-AttributeReference[id=8,name=y,relation=d,type=Int]
+| | +-AttributeReference[id=9,name=z,relation=d,type=Int]
+| +-project_expressions=
+| | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+| | +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+| | +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
+| +-left_join_attributes=
+| | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| +-right_join_attributes=
+|   +-AttributeReference[id=8,name=y,relation=d,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=a,type=Int]
+  +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+  +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+  +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
+==
+
+SELECT a.w, b.x, c.y, d.z
+FROM a RIGHT JOIN b ON a.w = b.w
+       JOIN c ON a.x = c.x
+       LEFT JOIN d ON a.y = d.y
+WHERE b.x > 10
+  AND c.y > 20;
+--
+TopLevelPlan
++-plan=HashLeftOuterJoin
+| +-left=HashJoin
+| | +-left=HashLeftOuterJoin
+| | | +-left=Selection
+| | | | +-input=TableReference[relation=b]
+| | | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | +-filter_predicate=Greater
+| | | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | | +-Literal[value=10,type=Int]
+| | | | +-project_expressions=
+| | | |   +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | |   +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | +-right=TableReference[relation=a]
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | | +-AttributeReference[id=3,name=z,relation=a,type=Int]
+| | | +-project_expressions=
+| | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int NULL]
+| | | | +-AttributeReference[id=2,name=y,relation=a,type=Int NULL]
+| | | +-left_join_attributes=
+| | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | +-right_join_attributes=
+| | |   +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | +-right=Selection
+| | | +-input=TableReference[relation=c]
+| | | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | | +-filter_predicate=Greater
+| | | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | | | +-Literal[value=20,type=Int]
+| | | +-project_expressions=
+| | |   +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | |   +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | +-project_expressions=
+| | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+| | | +-AttributeReference[id=2,name=y,relation=a,type=Int NULL]
+| | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=1,name=x,relation=a,type=Int NULL]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| +-right=TableReference[relation=d]
+| | +-AttributeReference[id=8,name=y,relation=d,type=Int]
+| | +-AttributeReference[id=9,name=z,relation=d,type=Int]
+| +-project_expressions=
+| | +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+| | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
+| +-left_join_attributes=
+| | +-AttributeReference[id=2,name=y,relation=a,type=Int NULL]
+| +-right_join_attributes=
+|   +-AttributeReference[id=8,name=y,relation=d,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+  +-AttributeReference[id=5,name=x,relation=b,type=Int]
+  +-AttributeReference[id=7,name=y,relation=c,type=Int]
+  +-AttributeReference[id=9,name=z,relation=d,type=Int NULL]
+==
+
+SELECT *
+FROM b LEFT JOIN c ON (b.x = c.x AND c.x > 10);
+--
+TopLevelPlan
++-plan=HashLeftOuterJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=Selection
+| | +-input=TableReference[relation=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-filter_predicate=Greater
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-Literal[value=10,type=Int]
+| | +-project_expressions=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| |   +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| +-project_expressions=
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+| | +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
+| +-left_join_attributes=
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right_join_attributes=
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+  +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+  +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
diff --git a/query_optimizer/tests/physical_generator/Select.test b/query_optimizer/tests/physical_generator/Select.test
index 2fa3720..b405bc9 100644
--- a/query_optimizer/tests/physical_generator/Select.test
+++ b/query_optimizer/tests/physical_generator/Select.test
@@ -2113,3 +2113,617 @@
 |   +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
 +-output_attributes=
   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+==
+
+
+# Scalar subquery expressions
+SELECT x + (SELECT SUM(y) FROM c)
+FROM b;
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-[]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-join_predicate=Literal[value=true]
+| +-project_list=
+|   +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+[Physical Plan]
+TopLevelPlan
++-plan=NestedLoopsJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=Aggregate
+| | +-input=TableReference[relation=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-grouping_expressions=
+| | | +-[]
+| | +-aggregate_expressions=
+| |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| |     +-AggregateFunction[function=SUM]
+| |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| +-join_predicate=Literal[value=true]
+| +-project_expressions=
+|   +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+|         type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT x + (SELECT SUM(y) FROM c WHERE b.w = c.x)
+FROM b;
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=HashJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| +-project_list=
+|   +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+[Physical Plan]
+TopLevelPlan
++-plan=HashJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=Aggregate
+| | +-input=TableReference[relation=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-grouping_expressions=
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | +-aggregate_expressions=
+| |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| |     +-AggregateFunction[function=SUM]
+| |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| +-project_expressions=
+| | +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+| |   +-Add
+| |     +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| |       type=Long NULL]
+| +-left_join_attributes=
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| +-right_join_attributes=
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT *
+FROM b
+WHERE b.x > (SELECT SUM(y) FROM c);
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-[]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-join_predicate=Greater
+| |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |   +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+[Physical Plan]
+TopLevelPlan
++-plan=NestedLoopsJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=Aggregate
+| | +-input=TableReference[relation=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-grouping_expressions=
+| | | +-[]
+| | +-aggregate_expressions=
+| |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| |     +-AggregateFunction[function=SUM]
+| |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| +-join_predicate=Greater
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| |   type=Long NULL]
+| +-project_expressions=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+==
+
+SELECT *
+FROM b
+WHERE b.x > (SELECT SUM(y) FROM c WHERE b.w = c.x);
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=Filter
+| | +-input=HashJoin
+| | | +-left=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | | +-right=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=c]
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Long NULL]
+| | | | |     +-AggregateFunction[function=SUM]
+| | | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-project_list=
+| | | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | | |     +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Long NULL]
+| | | +-left_join_attributes=
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-right_join_attributes=
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | +-filter_predicate=Greater
+| |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |   +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+[Physical Plan]
+TopLevelPlan
++-plan=HashJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=Aggregate
+| | +-input=TableReference[relation=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-grouping_expressions=
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | +-aggregate_expressions=
+| |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| |     +-AggregateFunction[function=SUM]
+| |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| +-residual_predicate=Greater
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| |   type=Long NULL]
+| +-project_expressions=
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-left_join_attributes=
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| +-right_join_attributes=
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+==
+
+SELECT x + (
+  SELECT SUM(y) + (SELECT SUM(w) FROM a WHERE a.y > 10)
+  FROM c
+  WHERE b.w = c.x AND c.x < 10)
+FROM b;
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=HashJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Project
+| | | +-input=NestedLoopsJoin
+| | | | +-left=Aggregate
+| | | | | +-input=Filter
+| | | | | | +-input=TableReference[relation_name=c]
+| | | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | | | +-filter_predicate=Less
+| | | | | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | |   +-Literal[value=10,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Long NULL]
+| | | | |     +-AggregateFunction[function=SUM]
+| | | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-right=Project
+| | | | | +-input=Aggregate
+| | | | | | +-input=Filter
+| | | | | | | +-input=TableReference[relation_name=a]
+| | | | | | | | +-AttributeReference[id=5,name=w,relation=a,type=Int]
+| | | | | | | | +-AttributeReference[id=6,name=x,relation=a,type=Int]
+| | | | | | | | +-AttributeReference[id=7,name=y,relation=a,type=Int]
+| | | | | | | | +-AttributeReference[id=8,name=z,relation=a,type=Int]
+| | | | | | | +-filter_predicate=Greater
+| | | | | | |   +-AttributeReference[id=7,name=y,relation=a,type=Int]
+| | | | | | |   +-Literal[value=10,type=Int]
+| | | | | | +-grouping_expressions=
+| | | | | | | +-[]
+| | | | | | +-aggregate_expressions=
+| | | | | |   +-Alias[id=9,name=,alias=$aggregate0,relation=$aggregate,
+| | | | | |     type=Long NULL]
+| | | | | |     +-AggregateFunction[function=SUM]
+| | | | | |       +-AttributeReference[id=5,name=w,relation=a,type=Int]
+| | | | | +-project_list=
+| | | | |   +-Alias[id=9,name=,alias=SUM(w),relation=,type=Long NULL]
+| | | | |     +-AttributeReference[id=9,name=,alias=$aggregate0,
+| | | | |       relation=$aggregate,type=Long NULL]
+| | | | +-join_predicate=Literal[value=true]
+| | | +-project_list=
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | |   +-Alias[id=10,name=,alias=(SUM(y)+SubqueryExpression),relation=,
+| | |     type=Long NULL]
+| | |     +-Add
+| | |       +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | |       | relation=$aggregate,type=Long NULL]
+| | |       +-AttributeReference[id=9,name=,alias=SUM(w),relation=,
+| | |         type=Long NULL]
+| | +-left_join_attributes=
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-right_join_attributes=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| +-project_list=
+|   +-Alias[id=11,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=10,name=,alias=(SUM(y)+SubqueryExpression),
+|         relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=11,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+[Physical Plan]
+TopLevelPlan
++-plan=HashJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=NestedLoopsJoin
+| | +-left=Aggregate
+| | | +-input=TableReference[relation=c]
+| | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-filter_predicate=Less
+| | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | +-Literal[value=10,type=Int]
+| | | +-grouping_expressions=
+| | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-aggregate_expressions=
+| | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| | |     +-AggregateFunction[function=SUM]
+| | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-right=Aggregate
+| | | +-input=TableReference[relation=a]
+| | | | +-AttributeReference[id=5,name=w,relation=a,type=Int]
+| | | | +-AttributeReference[id=6,name=x,relation=a,type=Int]
+| | | | +-AttributeReference[id=7,name=y,relation=a,type=Int]
+| | | | +-AttributeReference[id=8,name=z,relation=a,type=Int]
+| | | +-filter_predicate=Greater
+| | | | +-AttributeReference[id=7,name=y,relation=a,type=Int]
+| | | | +-Literal[value=10,type=Int]
+| | | +-grouping_expressions=
+| | | | +-[]
+| | | +-aggregate_expressions=
+| | |   +-Alias[id=9,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| | |     +-AggregateFunction[function=SUM]
+| | |       +-AttributeReference[id=5,name=w,relation=a,type=Int]
+| | +-join_predicate=Literal[value=true]
+| | +-project_expressions=
+| |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| |   +-Alias[id=10,name=,alias=(SUM(y)+SubqueryExpression),relation=,
+| |     type=Long NULL]
+| |     +-Add
+| |       +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| |       | type=Long NULL]
+| |       +-AttributeReference[id=9,name=,alias=$aggregate0,relation=$aggregate,
+| |         type=Long NULL]
+| +-project_expressions=
+| | +-Alias[id=11,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+| |   +-Add
+| |     +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |     +-AttributeReference[id=10,name=,alias=(SUM(y)+SubqueryExpression),
+| |       relation=,type=Long NULL]
+| +-left_join_attributes=
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| +-right_join_attributes=
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int]
++-output_attributes=
+  +-AttributeReference[id=11,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT x * (SELECT SUM(y) FROM c) + (SELECT AVG(y) FROM d)
+FROM b;
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=NestedLoopsJoin
+| | | +-left=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=c]
+| | | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-[]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Long NULL]
+| | | | |     +-AggregateFunction[function=SUM]
+| | | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | | +-project_list=
+| | | |   +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| | | |     +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Long NULL]
+| | | +-right=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=d]
+| | | | | | +-AttributeReference[id=5,name=y,relation=d,type=Int]
+| | | | | | +-AttributeReference[id=6,name=z,relation=d,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-[]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Double NULL]
+| | | | |     +-AggregateFunction[function=AVG]
+| | | | |       +-AttributeReference[id=5,name=y,relation=d,type=Int]
+| | | | +-project_list=
+| | | |   +-Alias[id=7,name=,alias=AVG(y),relation=,type=Double NULL]
+| | | |     +-AttributeReference[id=7,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Double NULL]
+| | | +-join_predicate=Literal[value=true]
+| | +-join_predicate=Literal[value=true]
+| +-project_list=
+|   +-Alias[id=8,name=,alias=((x*SubqueryExpression)+SubqueryExpression),
+|     relation=,type=Double NULL]
+|     +-Add
+|       +-Multiply
+|       | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       | +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+|       +-AttributeReference[id=7,name=,alias=AVG(y),relation=,type=Double NULL]
++-output_attributes=
+  +-AttributeReference[id=8,name=,
+    alias=((x*SubqueryExpression)+SubqueryExpression),relation=,type=Double NULL]
+[Physical Plan]
+TopLevelPlan
++-plan=NestedLoopsJoin
+| +-left=TableReference[relation=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=NestedLoopsJoin
+| | +-left=Aggregate
+| | | +-input=TableReference[relation=c]
+| | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | | +-grouping_expressions=
+| | | | +-[]
+| | | +-aggregate_expressions=
+| | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| | |     +-AggregateFunction[function=SUM]
+| | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-right=Aggregate
+| | | +-input=TableReference[relation=d]
+| | | | +-AttributeReference[id=5,name=y,relation=d,type=Int]
+| | | | +-AttributeReference[id=6,name=z,relation=d,type=Int]
+| | | +-grouping_expressions=
+| | | | +-[]
+| | | +-aggregate_expressions=
+| | |   +-Alias[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | |     type=Double NULL]
+| | |     +-AggregateFunction[function=AVG]
+| | |       +-AttributeReference[id=5,name=y,relation=d,type=Int]
+| | +-join_predicate=Literal[value=true]
+| | +-project_expressions=
+| |   +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| |   | type=Long NULL]
+| |   +-AttributeReference[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| |     type=Double NULL]
+| +-join_predicate=Literal[value=true]
+| +-project_expressions=
+|   +-Alias[id=8,name=,alias=((x*SubqueryExpression)+SubqueryExpression),
+|     relation=,type=Double NULL]
+|     +-Add
+|       +-Multiply
+|       | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       | +-AttributeReference[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+|       +-AttributeReference[id=7,name=,alias=AVG(y),relation=,type=Double NULL]
++-output_attributes=
+  +-AttributeReference[id=8,name=,
+    alias=((x*SubqueryExpression)+SubqueryExpression),relation=,type=Double NULL]
+==
+
+SELECT x * (SELECT SUM(y) FROM c)
+FROM b
+WHERE w < (SELECT AVG(y) FROM d);
+--
+[Optimized Logical Plan]
+TopLevelPlan
++-plan=Project
+| +-input=NestedLoopsJoin
+| | +-left=NestedLoopsJoin
+| | | +-left=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | | +-right=Project
+| | | | +-input=Aggregate
+| | | | | +-input=TableReference[relation_name=d]
+| | | | | | +-AttributeReference[id=2,name=y,relation=d,type=Int]
+| | | | | | +-AttributeReference[id=3,name=z,relation=d,type=Int]
+| | | | | +-grouping_expressions=
+| | | | | | +-[]
+| | | | | +-aggregate_expressions=
+| | | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | | | |     type=Double NULL]
+| | | | |     +-AggregateFunction[function=AVG]
+| | | | |       +-AttributeReference[id=2,name=y,relation=d,type=Int]
+| | | | +-project_list=
+| | | |   +-Alias[id=4,name=,alias=AVG(y),relation=,type=Double NULL]
+| | | |     +-AttributeReference[id=4,name=,alias=$aggregate0,
+| | | |       relation=$aggregate,type=Double NULL]
+| | | +-join_predicate=Less
+| | |   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | |   +-AttributeReference[id=4,name=,alias=AVG(y),relation=,type=Double NULL]
+| | +-right=Project
+| | | +-input=Aggregate
+| | | | +-input=TableReference[relation_name=c]
+| | | | | +-AttributeReference[id=5,name=x,relation=c,type=Int]
+| | | | | +-AttributeReference[id=6,name=y,relation=c,type=Int]
+| | | | +-grouping_expressions=
+| | | | | +-[]
+| | | | +-aggregate_expressions=
+| | | |   +-Alias[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | | |     type=Long NULL]
+| | | |     +-AggregateFunction[function=SUM]
+| | | |       +-AttributeReference[id=6,name=y,relation=c,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=7,name=,alias=SUM(y),relation=,type=Long NULL]
+| | |     +-AttributeReference[id=7,name=,alias=$aggregate0,relation=$aggregate,
+| | |       type=Long NULL]
+| | +-join_predicate=Literal[value=true]
+| +-project_list=
+|   +-Alias[id=8,name=,alias=(x*SubqueryExpression),relation=,type=Long NULL]
+|     +-Multiply
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=7,name=,alias=SUM(y),relation=,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=8,name=,alias=(x*SubqueryExpression),relation=,
+    type=Long NULL]
+[Physical Plan]
+TopLevelPlan
++-plan=NestedLoopsJoin
+| +-left=NestedLoopsJoin
+| | +-left=TableReference[relation=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=Aggregate
+| | | +-input=TableReference[relation=d]
+| | | | +-AttributeReference[id=2,name=y,relation=d,type=Int]
+| | | | +-AttributeReference[id=3,name=z,relation=d,type=Int]
+| | | +-grouping_expressions=
+| | | | +-[]
+| | | +-aggregate_expressions=
+| | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |     type=Double NULL]
+| | |     +-AggregateFunction[function=AVG]
+| | |       +-AttributeReference[id=2,name=y,relation=d,type=Int]
+| | +-join_predicate=Less
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| | |   type=Double NULL]
+| | +-project_expressions=
+| |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-right=Aggregate
+| | +-input=TableReference[relation=c]
+| | | +-AttributeReference[id=5,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=6,name=y,relation=c,type=Int]
+| | +-grouping_expressions=
+| | | +-[]
+| | +-aggregate_expressions=
+| |   +-Alias[id=7,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| |     +-AggregateFunction[function=SUM]
+| |       +-AttributeReference[id=6,name=y,relation=c,type=Int]
+| +-join_predicate=Literal[value=true]
+| +-project_expressions=
+|   +-Alias[id=8,name=,alias=(x*SubqueryExpression),relation=,type=Long NULL]
+|     +-Multiply
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-AttributeReference[id=7,name=,alias=$aggregate0,relation=$aggregate,
+|         type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=8,name=,alias=(x*SubqueryExpression),relation=,
+    type=Long NULL]
diff --git a/query_optimizer/tests/resolver/Join.test b/query_optimizer/tests/resolver/Join.test
index f501f97..3443e2b 100644
--- a/query_optimizer/tests/resolver/Join.test
+++ b/query_optimizer/tests/resolver/Join.test
@@ -156,17 +156,144 @@
   +-AttributeReference[id=3,name=z,relation=a1,type=Int]
 ==
 
+
+# Outer joins
 SELECT *
-FROM b LEFT JOIN c ON b.x = c.x JOIN d ON c.y = d.y;
+FROM b LEFT JOIN c ON (b.x = c.x AND c.x > 10);
 --
-ERROR: Outer joins are not supported yet (2 : 13)
-FROM b LEFT JOIN c ON b.x = c.x JOIN d ON ...
-            ^
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-right=TableReference[relation_name=c]
+| | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| | +-residual_predicate=And
+| | | +-Equal
+| | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | | +-Greater
+| | |   +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| | |   +-Literal[value=10,type=Int]
+| | +-left_join_attributes=
+| | | +-[]
+| | +-right_join_attributes=
+| |   +-[]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|   +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+|   +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+  +-AttributeReference[id=2,name=x,relation=c,type=Int NULL]
+  +-AttributeReference[id=3,name=y,relation=c,type=Int NULL]
+==
+
+SELECT a.w, b.x, c.y, a.w + b.x + c.y
+FROM a LEFT JOIN b ON a.w = b.w RIGHT JOIN c ON b.x = c.x;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=TableReference[relation_name=c]
+| | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | +-right=HashLeftOuterJoin
+| | | +-left=TableReference[relation_name=a]
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | | +-AttributeReference[id=3,name=z,relation=a,type=Int]
+| | | +-right=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | +-residual_predicate=Equal
+| | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | +-left_join_attributes=
+| | | | +-[]
+| | | +-right_join_attributes=
+| | |   +-[]
+| | +-residual_predicate=Equal
+| | | +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+| | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | +-left_join_attributes=
+| | | +-[]
+| | +-right_join_attributes=
+| |   +-[]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+|   +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+|   +-AttributeReference[id=7,name=y,relation=c,type=Int]
+|   +-Alias[id=8,name=,alias=((a.w+b.x)+c.y),relation=,type=Int NULL]
+|     +-Add
+|       +-Add
+|       | +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+|       | +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+|       +-AttributeReference[id=7,name=y,relation=c,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=a,type=Int NULL]
+  +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+  +-AttributeReference[id=7,name=y,relation=c,type=Int]
+  +-AttributeReference[id=8,name=,alias=((a.w+b.x)+c.y),relation=,type=Int NULL]
+==
+
+SELECT a.w, b.x, c.y, a.w + b.x + c.y
+FROM a LEFT JOIN (b RIGHT JOIN c ON b.x = c.x) ON a.w = b.w;
+--
+TopLevelPlan
++-plan=Project
+| +-input=HashLeftOuterJoin
+| | +-left=TableReference[relation_name=a]
+| | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
+| | | +-AttributeReference[id=2,name=y,relation=a,type=Int]
+| | | +-AttributeReference[id=3,name=z,relation=a,type=Int]
+| | +-right=HashLeftOuterJoin
+| | | +-left=TableReference[relation_name=c]
+| | | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
+| | | +-right=TableReference[relation_name=b]
+| | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
+| | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | +-residual_predicate=Equal
+| | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
+| | | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
+| | | +-left_join_attributes=
+| | | | +-[]
+| | | +-right_join_attributes=
+| | |   +-[]
+| | +-residual_predicate=Equal
+| | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+| | | +-AttributeReference[id=4,name=w,relation=b,type=Int NULL]
+| | +-left_join_attributes=
+| | | +-[]
+| | +-right_join_attributes=
+| |   +-[]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=a,type=Int]
+|   +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+|   +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+|   +-Alias[id=8,name=,alias=((a.w+b.x)+c.y),relation=,type=Int NULL]
+|     +-Add
+|       +-Add
+|       | +-AttributeReference[id=0,name=w,relation=a,type=Int]
+|       | +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+|       +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=a,type=Int]
+  +-AttributeReference[id=5,name=x,relation=b,type=Int NULL]
+  +-AttributeReference[id=7,name=y,relation=c,type=Int NULL]
+  +-AttributeReference[id=8,name=,alias=((a.w+b.x)+c.y),relation=,type=Int NULL]
 ==
 
 SELECT *
-FROM b LEFT JOIN (c JOIN d ON c.y = d.y) ON b.x = c.x;
+FROM b FULL JOIN c ON b.x = c.x;
 --
-ERROR: Outer joins are not supported yet (2 : 13)
-FROM b LEFT JOIN (c JOIN d ON c.y = d.y) O...
+ERROR: Full outer join is not supported yet (2 : 13)
+FROM b FULL JOIN c ON b.x = c.x;
             ^
diff --git a/query_optimizer/tests/resolver/Select.test b/query_optimizer/tests/resolver/Select.test
index 82bdb55..00ff18a 100644
--- a/query_optimizer/tests/resolver/Select.test
+++ b/query_optimizer/tests/resolver/Select.test
@@ -2793,3 +2793,147 @@
 ERROR: Subquery must return exactly one column (3 : 12)
 WHERE i IN (
            ^
+==
+
+# Scalar subquery expressions
+SELECT x + (SELECT SUM(y) FROM c)
+FROM b;
+--
+TopLevelPlan
++-plan=Project
+| +-input=TableReference[relation_name=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-project_list=
+|   +-Alias[id=5,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-SubqueryExpression
+|         +-subquery=Project
+|           +-input=Aggregate
+|           | +-input=TableReference[relation_name=c]
+|           | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+|           | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+|           | +-grouping_expressions=
+|           | | +-[]
+|           | +-aggregate_expressions=
+|           |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+|           |     type=Long NULL]
+|           |     +-AggregateFunction[function=SUM]
+|           |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+|           +-project_list=
+|             +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+|               +-AttributeReference[id=4,name=,alias=$aggregate0,
+|                 relation=$aggregate,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=5,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
+==
+
+SELECT *
+FROM b
+WHERE b.x > (SELECT SUM(y) FROM c);
+--
+TopLevelPlan
++-plan=Project
+| +-input=Filter
+| | +-input=TableReference[relation_name=b]
+| | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| | +-filter_predicate=Greater
+| |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| |   +-SubqueryExpression
+| |     +-subquery=Project
+| |       +-input=Aggregate
+| |       | +-input=TableReference[relation_name=c]
+| |       | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+| |       | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| |       | +-grouping_expressions=
+| |       | | +-[]
+| |       | +-aggregate_expressions=
+| |       |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+| |       |     type=Long NULL]
+| |       |     +-AggregateFunction[function=SUM]
+| |       |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+| |       +-project_list=
+| |         +-Alias[id=4,name=,alias=SUM(y),relation=,type=Long NULL]
+| |           +-AttributeReference[id=4,name=,alias=$aggregate0,
+| |             relation=$aggregate,type=Long NULL]
+| +-project_list=
+|   +-AttributeReference[id=0,name=w,relation=b,type=Int]
+|   +-AttributeReference[id=1,name=x,relation=b,type=Int]
++-output_attributes=
+  +-AttributeReference[id=0,name=w,relation=b,type=Int]
+  +-AttributeReference[id=1,name=x,relation=b,type=Int]
+==
+
+SELECT x + (
+  SELECT SUM(y) + (SELECT SUM(w) FROM a WHERE a.y > 10)
+  FROM c
+  WHERE b.w = c.x AND c.x < 10)
+FROM b;
+--
+TopLevelPlan
++-plan=Project
+| +-input=TableReference[relation_name=b]
+| | +-AttributeReference[id=0,name=w,relation=b,type=Int]
+| | +-AttributeReference[id=1,name=x,relation=b,type=Int]
+| +-project_list=
+|   +-Alias[id=11,name=,alias=(x+SubqueryExpression),relation=,type=Long NULL]
+|     +-Add
+|       +-AttributeReference[id=1,name=x,relation=b,type=Int]
+|       +-SubqueryExpression
+|         +-subquery=Project
+|           +-input=Aggregate
+|           | +-input=Filter
+|           | | +-input=TableReference[relation_name=c]
+|           | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+|           | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
+|           | | +-filter_predicate=And
+|           | |   +-Equal
+|           | |   | +-AttributeReference[id=0,name=w,relation=b,type=Int,
+|           | |   | | is_outer_reference=true]
+|           | |   | +-AttributeReference[id=2,name=x,relation=c,type=Int]
+|           | |   +-Less
+|           | |     +-AttributeReference[id=2,name=x,relation=c,type=Int]
+|           | |     +-Literal[value=10,type=Int]
+|           | +-grouping_expressions=
+|           | | +-[]
+|           | +-aggregate_expressions=
+|           |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,
+|           |     type=Long NULL]
+|           |     +-AggregateFunction[function=SUM]
+|           |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
+|           +-project_list=
+|             +-Alias[id=10,name=,alias=(SUM(y)+SubqueryExpression),relation=,
+|               type=Long NULL]
+|               +-Add
+|                 +-AttributeReference[id=4,name=,alias=$aggregate0,
+|                 | relation=$aggregate,type=Long NULL]
+|                 +-SubqueryExpression
+|                   +-subquery=Project
+|                     +-input=Aggregate
+|                     | +-input=Filter
+|                     | | +-input=TableReference[relation_name=a]
+|                     | | | +-AttributeReference[id=5,name=w,relation=a,type=Int]
+|                     | | | +-AttributeReference[id=6,name=x,relation=a,type=Int]
+|                     | | | +-AttributeReference[id=7,name=y,relation=a,type=Int]
+|                     | | | +-AttributeReference[id=8,name=z,relation=a,type=Int]
+|                     | | +-filter_predicate=Greater
+|                     | |   +-AttributeReference[id=7,name=y,relation=a,type=Int]
+|                     | |   +-Literal[value=10,type=Int]
+|                     | +-grouping_expressions=
+|                     | | +-[]
+|                     | +-aggregate_expressions=
+|                     |   +-Alias[id=9,name=,alias=$aggregate0,
+|                     |     relation=$aggregate,type=Long NULL]
+|                     |     +-AggregateFunction[function=SUM]
+|                     |       +-AttributeReference[id=5,name=w,relation=a,
+|                     |         type=Int]
+|                     +-project_list=
+|                       +-Alias[id=9,name=,alias=SUM(w),relation=,type=Long NULL]
+|                         +-AttributeReference[id=9,name=,alias=$aggregate0,
+|                           relation=$aggregate,type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=11,name=,alias=(x+SubqueryExpression),relation=,
+    type=Long NULL]
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index b02bc6b..759a233 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -177,12 +177,12 @@
                       quickstep_storage_StorageBlockInfo
                       quickstep_storage_StorageManager
                       quickstep_storage_SubBlocksReference
+                      quickstep_storage_TupleIdSequence
                       quickstep_storage_TupleReference
                       quickstep_storage_TupleStorageSubBlock
                       quickstep_storage_ValueAccessor
                       quickstep_types_containers_ColumnVectorsValueAccessor
                       quickstep_utility_Macros
-                      quickstep_utility_PtrList
                       tmb)
 target_link_libraries(quickstep_relationaloperators_InsertOperator
                       glog
@@ -462,9 +462,9 @@
 add_executable(AggregationOperator_unittest
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/AggregationOperator_unittest.cpp")
 target_link_libraries(AggregationOperator_unittest
+                      gflags_nothreads-static
                       glog
                       gtest
-                      gtest_main
                       quickstep_catalog_CatalogAttribute
                       quickstep_catalog_CatalogDatabase
                       quickstep_catalog_CatalogRelation
@@ -515,9 +515,9 @@
 add_executable(HashJoinOperator_unittest
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/HashJoinOperator_unittest.cpp")
 target_link_libraries(HashJoinOperator_unittest
+                      gflags_nothreads-static
                       glog
                       gtest
-                      gtest_main
                       quickstep_catalog_CatalogAttribute
                       quickstep_catalog_CatalogDatabase
                       quickstep_catalog_CatalogRelation
@@ -565,9 +565,9 @@
 add_executable(SortMergeRunOperator_unittest
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/SortMergeRunOperator_unittest.cpp")
 target_link_libraries(SortMergeRunOperator_unittest
+                      gflags_nothreads-static
                       glog
                       gtest
-                      gtest_main
                       quickstep_catalog_CatalogAttribute
                       quickstep_catalog_CatalogDatabase
                       quickstep_catalog_CatalogRelation
@@ -616,9 +616,9 @@
 add_executable(SortRunGenerationOperator_unittest
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/SortRunGenerationOperator_unittest.cpp")
 target_link_libraries(SortRunGenerationOperator_unittest
+                      gflags_nothreads-static
                       glog
                       gtest
-                      gtest_main
                       quickstep_catalog_CatalogAttribute
                       quickstep_catalog_CatalogDatabase
                       quickstep_catalog_CatalogRelation
@@ -664,6 +664,7 @@
 add_executable(TextScanOperator_unittest
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/TextScanOperator_unittest.cpp")
 target_link_libraries(TextScanOperator_unittest
+                      gflags_nothreads-static
                       glog
                       gtest
                       quickstep_catalog_CatalogAttribute
diff --git a/relational_operators/HashJoinOperator.cpp b/relational_operators/HashJoinOperator.cpp
index e0076e3..82f6b2a 100644
--- a/relational_operators/HashJoinOperator.cpp
+++ b/relational_operators/HashJoinOperator.cpp
@@ -1,6 +1,8 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
  *   Copyright 2015-2016 Pivotal Software, Inc.
+ *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
+ *     University of Wisconsin—Madison.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -36,6 +38,7 @@
 #include "storage/StorageBlockInfo.hpp"
 #include "storage/StorageManager.hpp"
 #include "storage/SubBlocksReference.hpp"
+#include "storage/TupleIdSequence.hpp"
 #include "storage/TupleReference.hpp"
 #include "storage/TupleStorageSubBlock.hpp"
 #include "storage/ValueAccessor.hpp"
@@ -203,6 +206,38 @@
   std::unique_ptr<TupleIdSequence> filter_;
 };
 
+class OuterJoinTupleCollector {
+ public:
+  explicit OuterJoinTupleCollector(const TupleStorageSubBlock &tuple_store) {
+    filter_.reset(tuple_store.getExistenceMap());
+  }
+
+  template <typename ValueAccessorT>
+  inline void operator()(const ValueAccessorT &accessor,
+                         const TupleReference &tref) {
+    joined_tuples_[tref.block].emplace_back(tref.tuple, accessor.getCurrentPosition());
+  }
+
+  template <typename ValueAccessorT>
+  inline void recordMatch(const ValueAccessorT &accessor) {
+    filter_->set(accessor.getCurrentPosition(), false);
+  }
+
+  inline std::unordered_map<block_id, std::vector<std::pair<tuple_id, tuple_id>>>*
+      getJoinedTupleMap() {
+    return &joined_tuples_;
+  }
+
+  const TupleIdSequence* filter() const {
+    return filter_.get();
+  }
+
+ private:
+  std::unordered_map<block_id, std::vector<std::pair<tuple_id, tuple_id>>> joined_tuples_;
+  // BitVector on the probe relation. 1 if the corresponding tuple has no match.
+  std::unique_ptr<TupleIdSequence> filter_;
+};
+
 }  // namespace
 
 bool HashJoinOperator::getAllWorkOrders(
@@ -221,9 +256,13 @@
     case JoinType::kLeftAntiJoin:
       return getAllNonOuterJoinWorkOrders<HashAntiJoinWorkOrder>(
           container, query_context, storage_manager);
+    case JoinType::kLeftOuterJoin:
+      return getAllOuterJoinWorkOrders(
+          container, query_context, storage_manager);
     default:
       LOG(FATAL) << "Unknown join type in HashJoinOperator::getAllWorkOrders()";
   }
+  return false;
 }
 
 template <class JoinWorkOrderClass>
@@ -285,6 +324,65 @@
   return false;
 }
 
+bool HashJoinOperator::getAllOuterJoinWorkOrders(
+    WorkOrdersContainer *container,
+    QueryContext *query_context,
+    StorageManager *storage_manager) {
+  // We wait until the building of global hash table is complete.
+  if (blocking_dependencies_met_) {
+    DCHECK(query_context != nullptr);
+
+    const vector<unique_ptr<const Scalar>> &selection =
+        query_context->getScalarGroup(selection_index_);
+
+    InsertDestination *output_destination =
+        query_context->getInsertDestination(output_destination_index_);
+    const JoinHashTable &hash_table =
+        *(query_context->getJoinHashTable(hash_table_index_));
+
+    if (probe_relation_is_stored_) {
+      if (!started_) {
+        for (const block_id probe_block_id : probe_relation_block_ids_) {
+          container->addNormalWorkOrder(
+              new HashOuterJoinWorkOrder(
+                  build_relation_,
+                  probe_relation_,
+                  join_key_attributes_,
+                  any_join_key_attributes_nullable_,
+                  probe_block_id,
+                  selection,
+                  is_selection_on_build_,
+                  hash_table,
+                  output_destination,
+                  storage_manager),
+              op_index_);
+        }
+        started_ = true;
+      }
+      return started_;
+    } else {
+      while (num_workorders_generated_ < probe_relation_block_ids_.size()) {
+        container->addNormalWorkOrder(
+            new HashOuterJoinWorkOrder(
+                build_relation_,
+                probe_relation_,
+                join_key_attributes_,
+                any_join_key_attributes_nullable_,
+                probe_relation_block_ids_[num_workorders_generated_],
+                selection,
+                is_selection_on_build_,
+                hash_table,
+                output_destination,
+                storage_manager),
+            op_index_);
+        ++num_workorders_generated_;
+      }
+      return done_feeding_input_relation_;
+    }  // end else (probe_relation_is_stored_)
+  }  // end if (blocking_dependencies_met_)
+  return false;
+}
+
 void HashInnerJoinWorkOrder::execute() {
   if (FLAGS_vector_based_joined_tuple_collector) {
     executeWithCollectorType<VectorBasedJoinedTupleCollector>();
@@ -641,11 +739,107 @@
   for (vector<unique_ptr<const Scalar>>::const_iterator selection_it = selection_.begin();
        selection_it != selection_.end();
        ++selection_it) {
-    temp_result.addColumn((*selection_it)->getAllValues(probe_accessor_with_filter.get(),
-                                                     &sub_blocks_ref));
+    temp_result.addColumn(
+        (*selection_it)->getAllValues(probe_accessor_with_filter.get(),
+                                      &sub_blocks_ref));
   }
 
   output_destination_->bulkInsertTuples(&temp_result);
 }
 
+void HashOuterJoinWorkOrder::execute() {
+  const relation_id build_relation_id = build_relation_.getID();
+  const relation_id probe_relation_id = probe_relation_.getID();
+
+  const BlockReference probe_block = storage_manager_->getBlock(block_id_,
+                                                                probe_relation_);
+  const TupleStorageSubBlock &probe_store = probe_block->getTupleStorageSubBlock();
+
+  std::unique_ptr<ValueAccessor> probe_accessor(probe_store.createValueAccessor());
+  OuterJoinTupleCollector collector(probe_store);
+  if (join_key_attributes_.size() == 1) {
+    hash_table_.getAllFromValueAccessorWithExtraWorkForFirstMatch(
+        probe_accessor.get(),
+        join_key_attributes_.front(),
+        any_join_key_attributes_nullable_,
+        &collector);
+  } else {
+    hash_table_.getAllFromValueAccessorCompositeKeyWithExtraWorkForFirstMatch(
+        probe_accessor.get(),
+        join_key_attributes_,
+        any_join_key_attributes_nullable_,
+        &collector);
+  }
+
+  // Populate the output tuples for matches.
+  for (const std::pair<const block_id, std::vector<std::pair<tuple_id, tuple_id>>>
+           &build_block_entry : *collector.getJoinedTupleMap()) {
+    const BlockReference build_block =
+        storage_manager_->getBlock(build_block_entry.first, build_relation_);
+    const TupleStorageSubBlock &build_store =
+        build_block->getTupleStorageSubBlock();
+
+    std::unique_ptr<ValueAccessor> build_accessor(
+        build_store.createValueAccessor());
+    ColumnVectorsValueAccessor temp_result;
+    for (auto selection_it = selection_.begin();
+         selection_it != selection_.end();
+         ++selection_it) {
+      temp_result.addColumn(
+          (*selection_it)->getAllValuesForJoin(
+              build_relation_id,
+              build_accessor.get(),
+              probe_relation_id,
+              probe_accessor.get(),
+              build_block_entry.second));
+    }
+    output_destination_->bulkInsertTuples(&temp_result);
+  }
+
+  SubBlocksReference sub_blocks_ref(probe_store,
+                                    probe_block->getIndices(),
+                                    probe_block->getIndicesConsistent());
+
+  // Populate the output tuples for non-matches.
+  const TupleIdSequence *filter = collector.filter();
+  const TupleIdSequence::size_type num_tuples_without_matches = filter->size();
+  if (num_tuples_without_matches > 0) {
+    std::unique_ptr<ValueAccessor> probe_accessor_with_filter(
+        probe_store.createValueAccessor(filter));
+    ColumnVectorsValueAccessor temp_result;
+
+    for (std::size_t i = 0; i < selection_.size(); ++i) {
+      if (is_selection_on_build_[i]) {
+        // NOTE(harshad, jianqiao): The assumption here is that any operation
+        // involving NULL as operands will return NULL result. This assumption
+        // will become invalid if later we add support for functions that can
+        // produce non-NULL result with NULL operands, e.g.
+        //   CASE WHEN x IS NOT NULL THEN x ELSE 0
+        // or equivalently
+        //   COALESCE(x, 0)
+        // where x is an attribute of the build relation.
+        // In that case, this HashOuterJoinWorkOrder needs to be updated to
+        // correctly handle the selections.
+        const Type& column_type = selection_[i]->getType().getNullableVersion();
+        if (NativeColumnVector::UsableForType(column_type)) {
+          NativeColumnVector *result = new NativeColumnVector(
+              column_type, num_tuples_without_matches);
+          result->fillWithNulls();
+          temp_result.addColumn(result);
+        } else {
+          IndirectColumnVector *result = new IndirectColumnVector(
+              column_type, num_tuples_without_matches);
+          result->fillWithValue(TypedValue(column_type.getTypeID()));
+          temp_result.addColumn(result);
+        }
+      } else {
+        temp_result.addColumn(
+            selection_[i]->getAllValues(probe_accessor_with_filter.get(),
+                                        &sub_blocks_ref));
+      }
+    }
+    output_destination_->bulkInsertTuples(&temp_result);
+  }
+}
+
 }  // namespace quickstep
diff --git a/relational_operators/HashJoinOperator.hpp b/relational_operators/HashJoinOperator.hpp
index c22f435..fcc087a 100644
--- a/relational_operators/HashJoinOperator.hpp
+++ b/relational_operators/HashJoinOperator.hpp
@@ -1,6 +1,8 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
  *   Copyright 2015-2016 Pivotal Software, Inc.
+ *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
+ *     University of Wisconsin—Madison.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -31,7 +33,6 @@
 #include "storage/HashTable.hpp"
 #include "storage/StorageBlockInfo.hpp"
 #include "utility/Macros.hpp"
-#include "utility/PtrList.hpp"
 
 #include "glog/logging.h"
 
@@ -61,7 +62,8 @@
   enum class JoinType {
     kInnerJoin = 0,
     kLeftSemiJoin,
-    kLeftAntiJoin
+    kLeftAntiJoin,
+    kLeftOuterJoin
   };
 
   /**
@@ -101,10 +103,14 @@
    *        additional filter to pairs of tuples that match the hash-join (i.e.
    *        key equality) predicate. Effectively, this makes the join predicate
    *        the conjunction of the key-equality predicate and residual predicate.
+   *        Note that this field does not apply to outer joins.
    * @param selection_index The group index of Scalars in QueryContext,
    *        corresponding to the attributes of the relation referred by
    *        output_relation_id. Each Scalar is evaluated for the joined tuples,
    *        and the resulting value is inserted into the join result.
+   * @param is_selection_on_build Whether each selection Scalar is using attributes
+   *        from the build relation as input. Can be NULL for inner/semi/anti
+   *        joins since this information is not utilized by these joins.
    * @param join_type The type of join corresponding to this operator.
    **/
   HashJoinOperator(const CatalogRelation &build_relation,
@@ -117,6 +123,7 @@
                    const QueryContext::join_hash_table_id hash_table_index,
                    const QueryContext::predicate_id residual_predicate_index,
                    const QueryContext::scalar_group_id selection_index,
+                   const std::vector<bool> *is_selection_on_build = nullptr,
                    const JoinType join_type = JoinType::kInnerJoin)
       : build_relation_(build_relation),
         probe_relation_(probe_relation),
@@ -128,12 +135,19 @@
         hash_table_index_(hash_table_index),
         residual_predicate_index_(residual_predicate_index),
         selection_index_(selection_index),
+        is_selection_on_build_(is_selection_on_build == nullptr
+                                   ? std::vector<bool>()
+                                   : *is_selection_on_build),
         join_type_(join_type),
         probe_relation_block_ids_(probe_relation_is_stored
                                       ? probe_relation.getBlocksSnapshot()
                                       : std::vector<block_id>()),
         num_workorders_generated_(0),
-        started_(false) {}
+        started_(false) {
+    DCHECK(join_type != JoinType::kLeftOuterJoin ||
+               (is_selection_on_build != nullptr &&
+                residual_predicate_index == QueryContext::kInvalidPredicateId));
+  }
 
   ~HashJoinOperator() override {}
 
@@ -180,6 +194,10 @@
                                     QueryContext *query_context,
                                     StorageManager *storage_manager);
 
+  bool getAllOuterJoinWorkOrders(WorkOrdersContainer *container,
+                                 QueryContext *query_context,
+                                 StorageManager *storage_manager);
+
   const CatalogRelation &build_relation_;
   const CatalogRelation &probe_relation_;
   const bool probe_relation_is_stored_;
@@ -190,6 +208,7 @@
   const QueryContext::join_hash_table_id hash_table_index_;
   const QueryContext::predicate_id residual_predicate_index_;
   const QueryContext::scalar_group_id selection_index_;
+  const std::vector<bool> is_selection_on_build_;
   const JoinType join_type_;
 
   std::vector<block_id> probe_relation_block_ids_;
@@ -521,7 +540,7 @@
                         StorageManager *storage_manager)
       : build_relation_(build_relation),
         probe_relation_(probe_relation),
-        join_key_attributes_(join_key_attributes),
+        join_key_attributes_(std::move(join_key_attributes)),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
@@ -560,6 +579,115 @@
   DISALLOW_COPY_AND_ASSIGN(HashAntiJoinWorkOrder);
 };
 
+/**
+ * @brief A left outer join WorkOrder produced by the HashJoinOperator.
+ **/
+class HashOuterJoinWorkOrder : public WorkOrder {
+ public:
+  /**
+   * @brief Constructor.
+   *
+   * @param build_relation The relation that the hash table was originally built
+   *        on (i.e. the inner relation in the join).
+   * @param probe_relation The relation to probe the hash table with (i.e. the
+   *        outer relation in the join).
+   * @param join_key_attributes The IDs of equijoin attributes in \c
+   *        probe_relation.
+   * @param any_join_key_attributes_nullable If any attribute is nullable.
+   * @param hash_table The JoinHashTable to use.
+   * @param selection A list of Scalars corresponding to the relation attributes
+   *        in \c output_destination. Each Scalar is evaluated for the joined
+   *        tuples, and the resulting value is inserted into the join result.
+   * @param is_selection_on_build Whether each Scalar in the \p selection vector
+   *        is using attributes from the build relation as input. Note that the
+   *        length of this vector should equal the length of \p selection.
+   * @param lookup_block_id The block id of the probe_relation.
+   * @param output_destination The InsertDestination to insert the join results.
+   * @param storage_manager The StorageManager to use.
+   **/
+  HashOuterJoinWorkOrder(const CatalogRelationSchema &build_relation,
+                         const CatalogRelationSchema &probe_relation,
+                         const std::vector<attribute_id> &join_key_attributes,
+                         const bool any_join_key_attributes_nullable,
+                         const block_id lookup_block_id,
+                         const std::vector<std::unique_ptr<const Scalar>> &selection,
+                         const std::vector<bool> &is_selection_on_build,
+                         const JoinHashTable &hash_table,
+                         InsertDestination *output_destination,
+                         StorageManager *storage_manager)
+      : build_relation_(build_relation),
+        probe_relation_(probe_relation),
+        join_key_attributes_(join_key_attributes),
+        any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
+        block_id_(lookup_block_id),
+        selection_(selection),
+        is_selection_on_build_(is_selection_on_build),
+        hash_table_(hash_table),
+        output_destination_(output_destination),
+        storage_manager_(storage_manager) {}
+
+  /**
+   * @brief Constructor for the distributed version.
+   *
+   * @param build_relation The relation that the hash table was originally built
+   *        on (i.e. the inner relation in the join).
+   * @param probe_relation The relation to probe the hash table with (i.e. the
+   *        outer relation in the join).
+   * @param join_key_attributes The IDs of equijoin attributes in \c
+   *        probe_relation.
+   * @param any_join_key_attributes_nullable If any attribute is nullable.
+   * @param hash_table The JoinHashTable to use.
+   * @param selection A list of Scalars corresponding to the relation attributes
+   *        in \c output_destination. Each Scalar is evaluated for the joined
+   *        tuples, and the resulting value is inserted into the join result.
+   * @param is_selection_on_build Whether each Scalar in the \p selection vector
+   *        is using attributes from the build relation as input. Note that the
+   *        length of this vector should equal the length of \p selection.
+   * @param lookup_block_id The block id of the probe_relation.
+   * @param output_destination The InsertDestination to insert the join results.
+   * @param storage_manager The StorageManager to use.
+   **/
+  HashOuterJoinWorkOrder(const CatalogRelationSchema &build_relation,
+                         const CatalogRelationSchema &probe_relation,
+                         std::vector<attribute_id> &&join_key_attributes,
+                         const bool any_join_key_attributes_nullable,
+                         const block_id lookup_block_id,
+                         const std::vector<std::unique_ptr<const Scalar>> &selection,
+                         std::vector<bool> &&is_selection_on_build,
+                         const JoinHashTable &hash_table,
+                         InsertDestination *output_destination,
+                         StorageManager *storage_manager)
+      : build_relation_(build_relation),
+        probe_relation_(probe_relation),
+        join_key_attributes_(std::move(join_key_attributes)),
+        any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
+        block_id_(lookup_block_id),
+        selection_(selection),
+        is_selection_on_build_(std::move(is_selection_on_build)),
+        hash_table_(hash_table),
+        output_destination_(output_destination),
+        storage_manager_(storage_manager) {}
+
+  ~HashOuterJoinWorkOrder() override {}
+
+  void execute() override;
+
+ private:
+  const CatalogRelationSchema &build_relation_;
+  const CatalogRelationSchema &probe_relation_;
+  const std::vector<attribute_id> join_key_attributes_;
+  const bool any_join_key_attributes_nullable_;
+  const block_id block_id_;
+  const std::vector<std::unique_ptr<const Scalar>> &selection_;
+  const std::vector<bool> is_selection_on_build_;
+  const JoinHashTable &hash_table_;
+
+  InsertDestination *output_destination_;
+  StorageManager *storage_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(HashOuterJoinWorkOrder);
+};
+
 /** @} */
 
 }  // namespace quickstep
diff --git a/relational_operators/TextScanOperator.cpp b/relational_operators/TextScanOperator.cpp
index 80cf953..5ede6f7 100644
--- a/relational_operators/TextScanOperator.cpp
+++ b/relational_operators/TextScanOperator.cpp
@@ -300,6 +300,10 @@
         output_destination_->insertTupleInBatch(tuple);
       }
     } while (have_row);
+
+    // Drop the consumed blob produced by TextSplitWorkOrder.
+    blob.release();
+    storage_manager_->deleteBlockOrBlobFile(text_blob_);
   }
 }
 
diff --git a/relational_operators/WorkOrder.proto b/relational_operators/WorkOrder.proto
index 1a0bcd1..8ed2080 100644
--- a/relational_operators/WorkOrder.proto
+++ b/relational_operators/WorkOrder.proto
@@ -29,20 +29,21 @@
   DESTROY_HASH = 6;
   DROP_TABLE = 7;
   FINALIZE_AGGREGATION = 8;
-  HASH_INNER_JOIN = 9;
-  HASH_SEMI_JOIN = 10;
-  HASH_ANTI_JOIN = 11;
-  INSERT = 12;
-  NESTED_LOOP_JOIN = 13;
-  SAMPLE = 14;
-  SAVE_BLOCKS = 15;
-  SELECT = 16;
-  SORT_MERGE_RUN = 17;
-  SORT_RUN_GENERATION = 18;
-  TABLE_GENERATOR = 19;
-  TEXT_SCAN = 20;
-  TEXT_SPLIT = 21;
-  UPDATE = 22;
+  HASH_ANTI_JOIN = 9;
+  HASH_INNER_JOIN = 10;
+  HASH_OUTER_JOIN = 11;
+  HASH_SEMI_JOIN = 12;
+  INSERT = 13;
+  NESTED_LOOP_JOIN = 14;
+  SAMPLE = 15;
+  SAVE_BLOCKS = 16;
+  SELECT = 17;
+  SORT_MERGE_RUN = 18;
+  SORT_RUN_GENERATION = 19;
+  TABLE_GENERATOR = 20;
+  TEXT_SCAN = 21;
+  TEXT_SPLIT = 22;
+  UPDATE = 23;
 }
 
 message WorkOrder {
@@ -151,6 +152,21 @@
   }
 }
 
+message HashOuterJoinWorkOrder {
+  extend WorkOrder {
+    // All required.
+    optional int32 build_relation_id = 370;
+    optional int32 probe_relation_id = 371;
+    repeated int32 join_key_attributes = 372;
+    optional bool any_join_key_attributes_nullable = 373;
+    optional int32 insert_destination_index = 374;
+    optional uint32 join_hash_table_index = 375;
+    optional int32 selection_index = 376;
+    repeated bool is_selection_on_build = 377;
+    optional fixed64 block_id = 378;
+  }
+}
+
 message InsertWorkOrder {
   extend WorkOrder {
     // All required.
diff --git a/relational_operators/WorkOrderFactory.cpp b/relational_operators/WorkOrderFactory.cpp
index 92c1140..964c11c 100644
--- a/relational_operators/WorkOrderFactory.cpp
+++ b/relational_operators/WorkOrderFactory.cpp
@@ -135,62 +135,6 @@
           query_context->getInsertDestination(
               proto.GetExtension(serialization::FinalizeAggregationWorkOrder::insert_destination_index)));
     }
-    case serialization::HASH_INNER_JOIN: {
-      LOG(INFO) << "Creating HashInnerJoinWorkOrder";
-      vector<attribute_id> join_key_attributes;
-      const int join_key_attributes_size =
-          proto.ExtensionSize(serialization::HashAntiJoinWorkOrder::join_key_attributes);
-      for (int i = 0; i < join_key_attributes_size; ++i) {
-        join_key_attributes.push_back(
-            proto.GetExtension(serialization::HashInnerJoinWorkOrder::join_key_attributes, i));
-      }
-
-      return new HashInnerJoinWorkOrder(
-          catalog_database->getRelationSchemaById(
-              proto.GetExtension(serialization::HashInnerJoinWorkOrder::build_relation_id)),
-          catalog_database->getRelationSchemaById(
-              proto.GetExtension(serialization::HashInnerJoinWorkOrder::probe_relation_id)),
-          move(join_key_attributes),
-          proto.GetExtension(serialization::HashInnerJoinWorkOrder::any_join_key_attributes_nullable),
-          proto.GetExtension(serialization::HashInnerJoinWorkOrder::block_id),
-          query_context->getPredicate(
-              proto.GetExtension(serialization::HashInnerJoinWorkOrder::residual_predicate_index)),
-          query_context->getScalarGroup(
-              proto.GetExtension(serialization::HashInnerJoinWorkOrder::selection_index)),
-          *query_context->getJoinHashTable(
-              proto.GetExtension(serialization::HashInnerJoinWorkOrder::join_hash_table_index)),
-          query_context->getInsertDestination(
-              proto.GetExtension(serialization::HashInnerJoinWorkOrder::insert_destination_index)),
-          storage_manager);
-    }
-    case serialization::HASH_SEMI_JOIN: {
-      LOG(INFO) << "Creating HashSemiJoinWorkOrder";
-      vector<attribute_id> join_key_attributes;
-      const int join_key_attributes_size =
-          proto.ExtensionSize(serialization::HashAntiJoinWorkOrder::join_key_attributes);
-      for (int i = 0; i < join_key_attributes_size; ++i) {
-        join_key_attributes.push_back(
-            proto.GetExtension(serialization::HashSemiJoinWorkOrder::join_key_attributes, i));
-      }
-
-      return new HashSemiJoinWorkOrder(
-          catalog_database->getRelationSchemaById(
-              proto.GetExtension(serialization::HashSemiJoinWorkOrder::build_relation_id)),
-          catalog_database->getRelationSchemaById(
-              proto.GetExtension(serialization::HashSemiJoinWorkOrder::probe_relation_id)),
-          move(join_key_attributes),
-          proto.GetExtension(serialization::HashSemiJoinWorkOrder::any_join_key_attributes_nullable),
-          proto.GetExtension(serialization::HashSemiJoinWorkOrder::block_id),
-          query_context->getPredicate(
-              proto.GetExtension(serialization::HashSemiJoinWorkOrder::residual_predicate_index)),
-          query_context->getScalarGroup(
-              proto.GetExtension(serialization::HashSemiJoinWorkOrder::selection_index)),
-          *query_context->getJoinHashTable(
-              proto.GetExtension(serialization::HashSemiJoinWorkOrder::join_hash_table_index)),
-          query_context->getInsertDestination(
-              proto.GetExtension(serialization::HashSemiJoinWorkOrder::insert_destination_index)),
-          storage_manager);
-    }
     case serialization::HASH_ANTI_JOIN: {
       LOG(INFO) << "Creating HashAntiJoinWorkOrder";
       vector<attribute_id> join_key_attributes;
@@ -219,6 +163,96 @@
               proto.GetExtension(serialization::HashAntiJoinWorkOrder::insert_destination_index)),
           storage_manager);
     }
+    case serialization::HASH_INNER_JOIN: {
+      LOG(INFO) << "Creating HashInnerJoinWorkOrder";
+      vector<attribute_id> join_key_attributes;
+      const int join_key_attributes_size =
+          proto.ExtensionSize(serialization::HashInnerJoinWorkOrder::join_key_attributes);
+      for (int i = 0; i < join_key_attributes_size; ++i) {
+        join_key_attributes.push_back(
+            proto.GetExtension(serialization::HashInnerJoinWorkOrder::join_key_attributes, i));
+      }
+
+      return new HashInnerJoinWorkOrder(
+          catalog_database->getRelationSchemaById(
+              proto.GetExtension(serialization::HashInnerJoinWorkOrder::build_relation_id)),
+          catalog_database->getRelationSchemaById(
+              proto.GetExtension(serialization::HashInnerJoinWorkOrder::probe_relation_id)),
+          move(join_key_attributes),
+          proto.GetExtension(serialization::HashInnerJoinWorkOrder::any_join_key_attributes_nullable),
+          proto.GetExtension(serialization::HashInnerJoinWorkOrder::block_id),
+          query_context->getPredicate(
+              proto.GetExtension(serialization::HashInnerJoinWorkOrder::residual_predicate_index)),
+          query_context->getScalarGroup(
+              proto.GetExtension(serialization::HashInnerJoinWorkOrder::selection_index)),
+          *query_context->getJoinHashTable(
+              proto.GetExtension(serialization::HashInnerJoinWorkOrder::join_hash_table_index)),
+          query_context->getInsertDestination(
+              proto.GetExtension(serialization::HashInnerJoinWorkOrder::insert_destination_index)),
+          storage_manager);
+    }
+    case serialization::HASH_OUTER_JOIN: {
+      LOG(INFO) << "Creating HashOuterJoinWorkOrder";
+      vector<attribute_id> join_key_attributes;
+      const int join_key_attributes_size =
+          proto.ExtensionSize(serialization::HashOuterJoinWorkOrder::join_key_attributes);
+      for (int i = 0; i < join_key_attributes_size; ++i) {
+        join_key_attributes.push_back(
+            proto.GetExtension(serialization::HashOuterJoinWorkOrder::join_key_attributes, i));
+      }
+      vector<bool> is_selection_on_build;
+      const int is_selection_on_build_size =
+          proto.ExtensionSize(serialization::HashOuterJoinWorkOrder::is_selection_on_build);
+      for (int i = 0; i < is_selection_on_build_size; ++i) {
+        is_selection_on_build.push_back(
+            proto.GetExtension(serialization::HashOuterJoinWorkOrder::is_selection_on_build, i));
+      }
+
+      return new HashOuterJoinWorkOrder(
+          catalog_database->getRelationSchemaById(
+              proto.GetExtension(serialization::HashOuterJoinWorkOrder::build_relation_id)),
+          catalog_database->getRelationSchemaById(
+              proto.GetExtension(serialization::HashOuterJoinWorkOrder::probe_relation_id)),
+          move(join_key_attributes),
+          proto.GetExtension(serialization::HashOuterJoinWorkOrder::any_join_key_attributes_nullable),
+          proto.GetExtension(serialization::HashOuterJoinWorkOrder::block_id),
+          query_context->getScalarGroup(
+              proto.GetExtension(serialization::HashOuterJoinWorkOrder::selection_index)),
+          move(is_selection_on_build),
+          *query_context->getJoinHashTable(
+              proto.GetExtension(serialization::HashOuterJoinWorkOrder::join_hash_table_index)),
+          query_context->getInsertDestination(
+              proto.GetExtension(serialization::HashOuterJoinWorkOrder::insert_destination_index)),
+          storage_manager);
+    }
+    case serialization::HASH_SEMI_JOIN: {
+      LOG(INFO) << "Creating HashSemiJoinWorkOrder";
+      vector<attribute_id> join_key_attributes;
+      const int join_key_attributes_size =
+          proto.ExtensionSize(serialization::HashSemiJoinWorkOrder::join_key_attributes);
+      for (int i = 0; i < join_key_attributes_size; ++i) {
+        join_key_attributes.push_back(
+            proto.GetExtension(serialization::HashSemiJoinWorkOrder::join_key_attributes, i));
+      }
+
+      return new HashSemiJoinWorkOrder(
+          catalog_database->getRelationSchemaById(
+              proto.GetExtension(serialization::HashSemiJoinWorkOrder::build_relation_id)),
+          catalog_database->getRelationSchemaById(
+              proto.GetExtension(serialization::HashSemiJoinWorkOrder::probe_relation_id)),
+          move(join_key_attributes),
+          proto.GetExtension(serialization::HashSemiJoinWorkOrder::any_join_key_attributes_nullable),
+          proto.GetExtension(serialization::HashSemiJoinWorkOrder::block_id),
+          query_context->getPredicate(
+              proto.GetExtension(serialization::HashSemiJoinWorkOrder::residual_predicate_index)),
+          query_context->getScalarGroup(
+              proto.GetExtension(serialization::HashSemiJoinWorkOrder::selection_index)),
+          *query_context->getJoinHashTable(
+              proto.GetExtension(serialization::HashSemiJoinWorkOrder::join_hash_table_index)),
+          query_context->getInsertDestination(
+              proto.GetExtension(serialization::HashSemiJoinWorkOrder::insert_destination_index)),
+          storage_manager);
+    }
     case serialization::INSERT: {
       LOG(INFO) << "Creating InsertWorkOrder";
       return new InsertWorkOrder(
@@ -452,6 +486,50 @@
              query_context.isValidInsertDestinationId(
                  proto.GetExtension(serialization::FinalizeAggregationWorkOrder::insert_destination_index));
     }
+    case serialization::HASH_ANTI_JOIN: {
+      if (!proto.HasExtension(serialization::HashAntiJoinWorkOrder::build_relation_id) ||
+          !proto.HasExtension(serialization::HashAntiJoinWorkOrder::probe_relation_id)) {
+        return false;
+      }
+
+      const relation_id build_relation_id =
+          proto.GetExtension(serialization::HashAntiJoinWorkOrder::build_relation_id);
+      if (!catalog_database.hasRelationWithId(build_relation_id)) {
+        return false;
+      }
+
+      const relation_id probe_relation_id =
+          proto.GetExtension(serialization::HashAntiJoinWorkOrder::probe_relation_id);
+      if (!catalog_database.hasRelationWithId(probe_relation_id)) {
+        return false;
+      }
+
+      const CatalogRelationSchema &build_relation = catalog_database.getRelationSchemaById(build_relation_id);
+      const CatalogRelationSchema &probe_relation = catalog_database.getRelationSchemaById(probe_relation_id);
+      for (int i = 0; i < proto.ExtensionSize(serialization::HashAntiJoinWorkOrder::join_key_attributes); ++i) {
+        const attribute_id attr_id =
+            proto.GetExtension(serialization::HashAntiJoinWorkOrder::join_key_attributes, i);
+        if (!build_relation.hasAttributeWithId(attr_id) ||
+            !probe_relation.hasAttributeWithId(attr_id)) {
+          return false;
+        }
+      }
+
+      return proto.HasExtension(serialization::HashAntiJoinWorkOrder::any_join_key_attributes_nullable) &&
+             proto.HasExtension(serialization::HashAntiJoinWorkOrder::insert_destination_index) &&
+             query_context.isValidInsertDestinationId(
+                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::insert_destination_index)) &&
+             proto.HasExtension(serialization::HashAntiJoinWorkOrder::join_hash_table_index) &&
+             query_context.isValidJoinHashTableId(
+                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::join_hash_table_index)) &&
+             proto.HasExtension(serialization::HashAntiJoinWorkOrder::residual_predicate_index) &&
+             query_context.isValidPredicate(
+                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::residual_predicate_index)) &&
+             proto.HasExtension(serialization::HashAntiJoinWorkOrder::selection_index) &&
+             query_context.isValidScalarGroupId(
+                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::selection_index)) &&
+             proto.HasExtension(serialization::HashAntiJoinWorkOrder::block_id);
+    }
     case serialization::HASH_INNER_JOIN: {
       if (!proto.HasExtension(serialization::HashInnerJoinWorkOrder::build_relation_id) ||
           !proto.HasExtension(serialization::HashInnerJoinWorkOrder::probe_relation_id)) {
@@ -496,6 +574,48 @@
                  proto.GetExtension(serialization::HashInnerJoinWorkOrder::selection_index)) &&
              proto.HasExtension(serialization::HashInnerJoinWorkOrder::block_id);
     }
+    case serialization::HASH_OUTER_JOIN: {
+      if (!proto.HasExtension(serialization::HashOuterJoinWorkOrder::build_relation_id) ||
+          !proto.HasExtension(serialization::HashOuterJoinWorkOrder::probe_relation_id)) {
+        return false;
+      }
+
+      const relation_id build_relation_id =
+          proto.GetExtension(serialization::HashOuterJoinWorkOrder::build_relation_id);
+      if (!catalog_database.hasRelationWithId(build_relation_id)) {
+        return false;
+      }
+
+      const relation_id probe_relation_id =
+          proto.GetExtension(serialization::HashOuterJoinWorkOrder::probe_relation_id);
+      if (!catalog_database.hasRelationWithId(probe_relation_id)) {
+        return false;
+      }
+
+      const CatalogRelationSchema &build_relation = catalog_database.getRelationSchemaById(build_relation_id);
+      const CatalogRelationSchema &probe_relation = catalog_database.getRelationSchemaById(probe_relation_id);
+      for (int i = 0; i < proto.ExtensionSize(serialization::HashOuterJoinWorkOrder::join_key_attributes); ++i) {
+        const attribute_id attr_id =
+            proto.GetExtension(serialization::HashOuterJoinWorkOrder::join_key_attributes, i);
+        if (!build_relation.hasAttributeWithId(attr_id) ||
+            !probe_relation.hasAttributeWithId(attr_id)) {
+          return false;
+        }
+      }
+
+      return proto.HasExtension(serialization::HashOuterJoinWorkOrder::any_join_key_attributes_nullable) &&
+             proto.HasExtension(serialization::HashOuterJoinWorkOrder::insert_destination_index) &&
+             query_context.isValidInsertDestinationId(
+                 proto.GetExtension(serialization::HashOuterJoinWorkOrder::insert_destination_index)) &&
+             proto.HasExtension(serialization::HashOuterJoinWorkOrder::join_hash_table_index) &&
+             query_context.isValidJoinHashTableId(
+                 proto.GetExtension(serialization::HashOuterJoinWorkOrder::join_hash_table_index)) &&
+             proto.HasExtension(serialization::HashOuterJoinWorkOrder::selection_index) &&
+             query_context.isValidScalarGroupId(
+                 proto.GetExtension(serialization::HashOuterJoinWorkOrder::selection_index)) &&
+             proto.HasExtension(serialization::HashOuterJoinWorkOrder::is_selection_on_build) &&
+             proto.HasExtension(serialization::HashOuterJoinWorkOrder::block_id);
+    }
     case serialization::HASH_SEMI_JOIN: {
       if (!proto.HasExtension(serialization::HashSemiJoinWorkOrder::build_relation_id) ||
           !proto.HasExtension(serialization::HashSemiJoinWorkOrder::probe_relation_id)) {
@@ -540,50 +660,6 @@
                  proto.GetExtension(serialization::HashSemiJoinWorkOrder::selection_index)) &&
              proto.HasExtension(serialization::HashSemiJoinWorkOrder::block_id);
     }
-    case serialization::HASH_ANTI_JOIN: {
-      if (!proto.HasExtension(serialization::HashAntiJoinWorkOrder::build_relation_id) ||
-          !proto.HasExtension(serialization::HashAntiJoinWorkOrder::probe_relation_id)) {
-        return false;
-      }
-
-      const relation_id build_relation_id =
-          proto.GetExtension(serialization::HashAntiJoinWorkOrder::build_relation_id);
-      if (!catalog_database.hasRelationWithId(build_relation_id)) {
-        return false;
-      }
-
-      const relation_id probe_relation_id =
-          proto.GetExtension(serialization::HashAntiJoinWorkOrder::probe_relation_id);
-      if (!catalog_database.hasRelationWithId(probe_relation_id)) {
-        return false;
-      }
-
-      const CatalogRelationSchema &build_relation = catalog_database.getRelationSchemaById(build_relation_id);
-      const CatalogRelationSchema &probe_relation = catalog_database.getRelationSchemaById(probe_relation_id);
-      for (int i = 0; i < proto.ExtensionSize(serialization::HashAntiJoinWorkOrder::join_key_attributes); ++i) {
-        const attribute_id attr_id =
-            proto.GetExtension(serialization::HashAntiJoinWorkOrder::join_key_attributes, i);
-        if (!build_relation.hasAttributeWithId(attr_id) ||
-            !probe_relation.hasAttributeWithId(attr_id)) {
-          return false;
-        }
-      }
-
-      return proto.HasExtension(serialization::HashAntiJoinWorkOrder::any_join_key_attributes_nullable) &&
-             proto.HasExtension(serialization::HashAntiJoinWorkOrder::insert_destination_index) &&
-             query_context.isValidInsertDestinationId(
-                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::insert_destination_index)) &&
-             proto.HasExtension(serialization::HashAntiJoinWorkOrder::join_hash_table_index) &&
-             query_context.isValidJoinHashTableId(
-                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::join_hash_table_index)) &&
-             proto.HasExtension(serialization::HashAntiJoinWorkOrder::residual_predicate_index) &&
-             query_context.isValidPredicate(
-                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::residual_predicate_index)) &&
-             proto.HasExtension(serialization::HashAntiJoinWorkOrder::selection_index) &&
-             query_context.isValidScalarGroupId(
-                 proto.GetExtension(serialization::HashAntiJoinWorkOrder::selection_index)) &&
-             proto.HasExtension(serialization::HashAntiJoinWorkOrder::block_id);
-    }
     case serialization::INSERT: {
       return proto.HasExtension(serialization::InsertWorkOrder::insert_destination_index) &&
              query_context.isValidInsertDestinationId(
diff --git a/relational_operators/tests/AggregationOperator_unittest.cpp b/relational_operators/tests/AggregationOperator_unittest.cpp
index 5b4ae6e..f2207c2 100644
--- a/relational_operators/tests/AggregationOperator_unittest.cpp
+++ b/relational_operators/tests/AggregationOperator_unittest.cpp
@@ -66,8 +66,8 @@
 #include "types/operations/comparisons/ComparisonID.hpp"
 #include "utility/PtrList.hpp"
 
+#include "gflags/gflags.h"
 #include "glog/logging.h"
-
 #include "gtest/gtest.h"
 
 #include "tmb/id_typedefs.h"
@@ -170,6 +170,17 @@
 
   virtual void TearDown() {
     thread_id_map_->removeValue();
+
+    // Drop blocks from relations.
+    const std::vector<block_id> table_blocks = table_->getBlocksSnapshot();
+    for (const block_id block : table_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const std::vector<block_id> result_table_blocks = result_table_->getBlocksSnapshot();
+    for (const block_id block : result_table_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
   }
 
   Tuple* createTuple(const CatalogRelation &relation, const std::int64_t val) {
@@ -420,6 +431,10 @@
         sub_block.getAttributeValueTyped(0, result_table_->getAttributeByName("result-1")->getID());
     test(expected0, actual0);
     test(expected1, actual1);
+
+    // Drop the block.
+    block.release();
+    storage_manager_->deleteBlockOrBlobFile(result[0]);
   }
 
   template <class FinalDataType>
@@ -463,6 +478,10 @@
         check_fn(group_by_id, actual0, actual1);
       }
       total_tuples += sub_block.numTuples();
+
+      // Drop the block.
+      block.release();
+      storage_manager_->deleteBlockOrBlobFile(result[bid]);
     }
     EXPECT_EQ(num_tuples, total_tuples);
   }
@@ -500,7 +519,7 @@
 
 const char AggregationOperatorTest::kDatabaseName[] = "database";
 const char AggregationOperatorTest::kTableName[] = "table";
-const char AggregationOperatorTest::kStoragePath[] = "./test_data";
+const char AggregationOperatorTest::kStoragePath[] = "./aggregation_operator_test_data";
 
 namespace {
 
@@ -1773,5 +1792,13 @@
 }
 
 }  // namespace
-
 }  // namespace quickstep
+
+int main(int argc, char* argv[]) {
+  google::InitGoogleLogging(argv[0]);
+  // Honor FLAGS_buffer_pool_slots in StorageManager.
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/relational_operators/tests/HashJoinOperator_unittest.cpp b/relational_operators/tests/HashJoinOperator_unittest.cpp
index 3118b73..333c3f0 100644
--- a/relational_operators/tests/HashJoinOperator_unittest.cpp
+++ b/relational_operators/tests/HashJoinOperator_unittest.cpp
@@ -69,8 +69,8 @@
 #include "types/operations/comparisons/ComparisonID.hpp"
 #include "utility/Macros.hpp"
 
+#include "gflags/gflags.h"
 #include "glog/logging.h"
-
 #include "gtest/gtest.h"
 
 #include "tmb/id_typedefs.h"
@@ -114,7 +114,7 @@
     bus_.RegisterClientAsSender(foreman_client_id_, kCatalogRelationNewBlockMessage);
     bus_.RegisterClientAsReceiver(foreman_client_id_, kCatalogRelationNewBlockMessage);
 
-    storage_manager_.reset(new StorageManager("./test_data/"));
+    storage_manager_.reset(new StorageManager("./hash_join_operator_test_data/"));
 
     // Create a database.
     db_.reset(new CatalogDatabase(nullptr, "database"));
@@ -193,6 +193,17 @@
 
   virtual void TearDown() {
     thread_id_map_->removeValue();
+
+    // Drop blocks from relations.
+    const std::vector<block_id> dim_blocks = dim_table_->getBlocksSnapshot();
+    for (const block_id block : dim_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const std::vector<block_id> fact_blocks = fact_table_->getBlocksSnapshot();
+    for (const block_id block : fact_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
   }
 
   StorageBlockLayout* createStorageLayout(const CatalogRelation &relation) {
@@ -398,6 +409,10 @@
         ++counts[value];
       }
     }
+
+    // Drop the block.
+    result_block.release();
+    storage_manager_->deleteBlockOrBlobFile(result_blocks[bid]);
   }
   EXPECT_EQ(static_cast<std::size_t>(kNumDimTuples), num_result_tuples);
 
@@ -550,6 +565,10 @@
         ++fact_counts[value];
       }
     }
+
+    // Drop the block.
+    result_block.release();
+    storage_manager_->deleteBlockOrBlobFile(result_blocks[bid]);
   }
   EXPECT_EQ(static_cast<std::size_t>(kNumDimTuples), num_result_tuples);
 
@@ -689,6 +708,10 @@
         ++counts[value];
       }
     }
+
+    // Drop the block.
+    result_block.release();
+    storage_manager_->deleteBlockOrBlobFile(result_blocks[bid]);
   }
   EXPECT_EQ(static_cast<std::size_t>(kNumDimTuples * kNumFactTuples),
             num_result_tuples);
@@ -835,6 +858,10 @@
         ++fact_counts[value];
       }
     }
+
+    // Drop the block.
+    result_block.release();
+    storage_manager_->deleteBlockOrBlobFile(result_blocks[bid]);
   }
   EXPECT_EQ(static_cast<std::size_t>(kNumDimTuples), num_result_tuples);
 
@@ -1004,6 +1031,10 @@
         ++fact_counts[value];
       }
     }
+
+    // Drop the block.
+    result_block.release();
+    storage_manager_->deleteBlockOrBlobFile(result_blocks[bid]);
   }
   EXPECT_EQ(static_cast<std::size_t>(kNumDimTuples) / 2, num_result_tuples);
 
@@ -1184,6 +1215,10 @@
         ++fact_counts[value];
       }
     }
+
+    // Drop the block.
+    result_block.release();
+    storage_manager_->deleteBlockOrBlobFile(result_blocks[bid]);
   }
   EXPECT_EQ(8u, num_result_tuples);
 
@@ -1227,3 +1262,12 @@
         HashTableImplType::kSimpleScalarSeparateChaining),);  // NOLINT(whitespace/comma)
 
 }  // namespace quickstep
+
+int main(int argc, char* argv[]) {
+  google::InitGoogleLogging(argv[0]);
+  // Honor FLAGS_buffer_pool_slots in StorageManager.
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/relational_operators/tests/SortMergeRunOperator_unittest.cpp b/relational_operators/tests/SortMergeRunOperator_unittest.cpp
index ef896d3..50c508d 100644
--- a/relational_operators/tests/SortMergeRunOperator_unittest.cpp
+++ b/relational_operators/tests/SortMergeRunOperator_unittest.cpp
@@ -69,8 +69,8 @@
 #include "utility/SortConfiguration.hpp"
 #include "utility/SortConfiguration.pb.h"
 
+#include "gflags/gflags.h"
 #include "glog/logging.h"
-
 #include "gtest/gtest.h"
 
 #include "tmb/id_typedefs.h"
@@ -196,6 +196,17 @@
     // Usually the worker thread makes the following call. In this test setup,
     // we don't have a worker thread hence we have to explicitly make the call.
     thread_id_map_->removeValue();
+
+    // Drop blocks from relations and InsertDestination.
+    const vector<block_id> tmp_blocks = insert_destination_->getTouchedBlocks();
+    for (const block_id block : tmp_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const vector<block_id> blocks = table_->getBlocksSnapshot();
+    for (const block_id block : blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
   }
 
   // Helper method to insert test tuples.
@@ -225,7 +236,7 @@
 };
 
 const char RunTest::kTableName[] = "table";
-const char RunTest::kStoragePath[] = "./test_data";
+const char RunTest::kStoragePath[] = "./sort_merge_run_operator_test_data";
 const tuple_id RunTest::kNumTuples = 100;
 const tuple_id RunTest::kNumTuplesPerBlock = 10;
 
@@ -429,6 +440,17 @@
     // Usually the worker thread makes the following call. In this test setup,
     // we don't have a worker thread hence we have to explicitly make the call.
     thread_id_map_->removeValue();
+
+    // Drop blocks from relations and InsertDestination.
+    const vector<block_id> tmp_blocks = insert_destination_->getTouchedBlocks();
+    for (const block_id block : tmp_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const vector<block_id> blocks = table_->getBlocksSnapshot();
+    for (const block_id block : blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
   }
 
   // Helper method to create test tuples.
@@ -642,7 +664,7 @@
 };
 
 const char RunMergerTest::kTableName[] = "table";
-const char RunMergerTest::kStoragePath[] = "./test_data";
+const char RunMergerTest::kStoragePath[] = "./sort_merge_run_operator_test_data";
 const std::size_t RunMergerTest::kNumTuplesPerBlock = 10;
 const tuple_id RunMergerTest::kNumBlocksPerRun = 10;
 const std::size_t RunMergerTest::kNumRuns = 10;
@@ -1285,6 +1307,22 @@
     // Usually the worker thread makes the following call. In this test setup,
     // we don't have a worker thread hence we have to explicitly make the call.
     thread_id_map_->removeValue();
+
+    // Drop blocks from relations.
+    const vector<block_id> input_blocks = input_table_->getBlocksSnapshot();
+    for (const block_id block : input_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const vector<block_id> result_blocks = result_table_->getBlocksSnapshot();
+    for (const block_id block : result_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const vector<block_id> run_blocks = run_table_->getBlocksSnapshot();
+    for (const block_id block : run_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
   }
 
   CatalogRelation *createTable(const char *name, const relation_id rel_id) {
@@ -1681,7 +1719,7 @@
 const char SortMergeRunOperatorTest::kTableName[] = "table";
 const char SortMergeRunOperatorTest::kResultTableName[] = "result-table";
 const char SortMergeRunOperatorTest::kRunTableName[] = "run-table";
-const char SortMergeRunOperatorTest::kStoragePath[] = "./test_data";
+const char SortMergeRunOperatorTest::kStoragePath[] = "./sort_merge_run_operator_test_data";
 const char SortMergeRunOperatorTest::kDatabaseName[] = "database";
 
 namespace {
@@ -2260,3 +2298,12 @@
 }
 
 }  // namespace quickstep
+
+int main(int argc, char* argv[]) {
+  google::InitGoogleLogging(argv[0]);
+  // Honor FLAGS_buffer_pool_slots in StorageManager.
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/relational_operators/tests/SortRunGenerationOperator_unittest.cpp b/relational_operators/tests/SortRunGenerationOperator_unittest.cpp
index 76ea40a..7491778 100644
--- a/relational_operators/tests/SortRunGenerationOperator_unittest.cpp
+++ b/relational_operators/tests/SortRunGenerationOperator_unittest.cpp
@@ -64,8 +64,8 @@
 #include "utility/SortConfiguration.hpp"
 #include "utility/SortConfiguration.pb.h"
 
+#include "gflags/gflags.h"
 #include "glog/logging.h"
-
 #include "gtest/gtest.h"
 
 #include "tmb/id_typedefs.h"
@@ -193,6 +193,17 @@
     // Usually the worker thread makes the following call. In this test setup,
     // we don't have a worker thread hence we have to explicitly make the call.
     thread_id_map_->removeValue();
+
+    // Drop blocks from relations.
+    const vector<block_id> input_blocks = input_table_->getBlocksSnapshot();
+    for (const block_id block : input_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
+
+    const vector<block_id> result_blocks = result_table_->getBlocksSnapshot();
+    for (const block_id block : result_blocks) {
+      storage_manager_->deleteBlockOrBlobFile(block);
+    }
   }
 
   // Helper method to create catalog relation.
@@ -414,7 +425,7 @@
 
 const char SortRunGenerationOperatorTest::kTableName[] = "table";
 const char SortRunGenerationOperatorTest::kResultTableName[] = "result-table";
-const char SortRunGenerationOperatorTest::kStoragePath[] = "./test_data";
+const char SortRunGenerationOperatorTest::kStoragePath[] = "./sort_run_generation_operator_test_data";
 
 namespace {
 
@@ -770,3 +781,12 @@
 }
 
 }  // namespace quickstep
+
+int main(int argc, char* argv[]) {
+  google::InitGoogleLogging(argv[0]);
+  // Honor FLAGS_buffer_pool_slots in StorageManager.
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/relational_operators/tests/TextScanOperator_unittest.cpp b/relational_operators/tests/TextScanOperator_unittest.cpp
index c43a127..1dfad7b 100644
--- a/relational_operators/tests/TextScanOperator_unittest.cpp
+++ b/relational_operators/tests/TextScanOperator_unittest.cpp
@@ -39,8 +39,8 @@
 #include "types/TypeID.hpp"
 #include "utility/MemStream.hpp"
 
+#include "gflags/gflags.h"
 #include "glog/logging.h"
-
 #include "gtest/gtest.h"
 
 #include "tmb/id_typedefs.h"
@@ -94,7 +94,7 @@
     relation_->addAttribute(
         new CatalogAttribute(relation_, "varchar_attr", TypeFactory::GetType(kVarChar, 20, true)));
 
-    storage_manager_.reset(new StorageManager("./test_data/"));
+    storage_manager_.reset(new StorageManager("./text_scan_operator_test_data/"));
   }
 
   virtual void TearDown() {
diff --git a/storage/CMakeLists.txt b/storage/CMakeLists.txt
index ed23802..dad32b9 100644
--- a/storage/CMakeLists.txt
+++ b/storage/CMakeLists.txt
@@ -1528,12 +1528,15 @@
 add_executable(StorageManager_unittest
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/StorageManager_unittest.cpp")
 target_link_libraries(StorageManager_unittest
+                      glog
                       gtest
                       gtest_main
                       quickstep_storage_EvictionPolicy
                       quickstep_storage_StorageBlob
                       quickstep_storage_StorageBlockInfo
                       quickstep_storage_StorageManager
+                      quickstep_threading_Thread
+                      quickstep_utility_PtrVector
                       quickstep_utility_ShardedLockManager)
 if (QUICKSTEP_HAVE_LIBNUMA)
   target_link_libraries(StorageManager_unittest
diff --git a/storage/HashTable.hpp b/storage/HashTable.hpp
index ef79d11..667848e 100644
--- a/storage/HashTable.hpp
+++ b/storage/HashTable.hpp
@@ -1,6 +1,8 @@
 /**
  *   Copyright 2011-2015 Quickstep Technologies LLC.
  *   Copyright 2015-2016 Pivotal Software, Inc.
+ *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
+ *     University of Wisconsin—Madison.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -707,8 +709,8 @@
                                FunctorT *functor) const;
 
   /**
-   * @brief Lookup (multiple) keys from a ValueAccessor, apply a functor to
-   *        the matching values and additionally call a hasMatch() function of
+   * @brief Lookup (multiple) keys from a ValueAccessor, apply a functor to the
+   *        matching values and additionally call a recordMatch() function of
    *        the functor when the first match for a key is found.
    * @warning This method assumes that no concurrent calls to put(),
    *          putCompositeKey(), putValueAccessor(),
@@ -749,8 +751,8 @@
       FunctorT *functor) const;
 
   /**
-   * @brief Lookup (multiple) keys from a ValueAccessor, apply a functor to
-   *        the matching values and additionally call a hasMatch() function of
+   * @brief Lookup (multiple) keys from a ValueAccessor, apply a functor to the
+   *        matching values and additionally call a recordMatch() function of
    *        the functor when the first match for a key is found. Composite key
    *        version.
    * @warning This method assumes that no concurrent calls to put(),
@@ -1905,17 +1907,19 @@
       if (check_for_null_keys && key.isNull()) {
         continue;
       }
-      const std::size_t hash_code = adjust_hashes_ ? AdjustHash(key.getHash())
-                                                   : key.getHash();
+      const std::size_t hash_code =
+          adjust_hashes_ ? HashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
+                               ::AdjustHash(key.getHash())
+                         : key.getHash();
       std::size_t entry_num = 0;
       const ValueT *value;
-      if (getNextEntryForKey(key, hash_code, &value, &entry_num)) {
+      if (this->getNextEntryForKey(key, hash_code, &value, &entry_num)) {
         functor->recordMatch(*accessor);
         (*functor)(*accessor, *value);
         if (!allow_duplicate_keys) {
            continue;
         }
-        while (getNextEntryForKey(key, hash_code, &value, &entry_num)) {
+        while (this->getNextEntryForKey(key, hash_code, &value, &entry_num)) {
           (*functor)(*accessor, *value);
         }
       }
@@ -1956,17 +1960,19 @@
         continue;
       }
 
-      const std::size_t hash_code = adjust_hashes_ ? AdjustHash(hashCompositeKey(key_vector))
-                                                   : hashCompositeKey(key_vector);
+      const std::size_t hash_code =
+          adjust_hashes_ ? HashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
+                               ::AdjustHash(this->hashCompositeKey(key_vector))
+                         : this->hashCompositeKey(key_vector);
       std::size_t entry_num = 0;
       const ValueT *value;
-      if (getNextEntryForCompositeKey(key_vector, hash_code, &value, &entry_num)) {
+      if (this->getNextEntryForCompositeKey(key_vector, hash_code, &value, &entry_num)) {
         functor->recordMatch(*accessor);
         (*functor)(*accessor, *value);
         if (!allow_duplicate_keys) {
           continue;
         }
-        while (getNextEntryForCompositeKey(key_vector, hash_code, &value, &entry_num)) {
+        while (this->getNextEntryForCompositeKey(key_vector, hash_code, &value, &entry_num)) {
           (*functor)(*accessor, *value);
         }
       }
diff --git a/storage/PreloaderThread.cpp b/storage/PreloaderThread.cpp
index a870837..d5dc55b 100644
--- a/storage/PreloaderThread.cpp
+++ b/storage/PreloaderThread.cpp
@@ -34,12 +34,28 @@
     ThreadUtil::BindToCPU(cpu_id_);
   }
 
+  const std::size_t num_slots = storage_manager_->getMaxBufferPoolSlots();
+  std::size_t blocks_loaded = 0;
+
   for (const CatalogRelation &relation : database_) {
     std::vector<block_id> blocks = relation.getBlocksSnapshot();
     for (block_id current_block_id : blocks) {
-      BlockReference current_block = storage_manager_->getBlock(current_block_id, relation);
+      try {
+        BlockReference current_block = storage_manager_->getBlock(current_block_id, relation);
+      } catch (...) {
+        LOG(ERROR) << "Error after loading " << blocks_loaded << "blocks\n";
+        throw;
+      }
+      ++blocks_loaded;
+      if (blocks_loaded == num_slots) {
+        // The buffer pool has filled up. But, some database blocks are not loaded.
+        printf(" The database is larger than the buffer pool. Only %lu blocks were loaded ",
+               blocks_loaded);
+        return;
+      }
     }
   }
+  printf(" Loaded %lu blocks ", blocks_loaded);
 }
 
 }  // namespace quickstep
diff --git a/storage/StorageManager.cpp b/storage/StorageManager.cpp
index 410eeb1..ad3a8cf 100644
--- a/storage/StorageManager.cpp
+++ b/storage/StorageManager.cpp
@@ -369,7 +369,6 @@
   size_t num_slots = file_manager_->numSlots(block);
   DEBUG_ASSERT(num_slots != 0);
   void* block_buffer = allocateSlots(num_slots, numa_node);
-
   const bool status = file_manager_->readBlockOrBlob(block, block_buffer, kSlotSizeBytes * num_slots);
   CHECK(status) << "Failed to read block from persistent storage: " << block;
 
@@ -491,6 +490,7 @@
       ret = MutableBlockReference(static_cast<StorageBlock*>(it->second.block), eviction_policy_.get());
     }
   }
+  // To be safe, release the shard for the block after its read lock destructs.
   lock_manager_.release(block);
 
   // Note that there is no way for the block to be evicted between the call to
@@ -513,6 +513,7 @@
     // No other thread loaded the block before us.
     ret = MutableBlockReference(loadBlock(block, relation, numa_node), eviction_policy_.get());
   }
+  // To be safe, release the shard for the block after its write lock destructs.
   lock_manager_.release(block);
 
   return ret;
@@ -530,6 +531,7 @@
       ret = MutableBlobReference(static_cast<StorageBlob*>(it->second.block), eviction_policy_.get());
     }
   }
+  // To be safe, release the shard for the blob after its read lock destructs.
   lock_manager_.release(blob);
 
   if (!ret.valid()) {
@@ -551,6 +553,7 @@
     // No other thread loaded the blob before us.
     ret = MutableBlobReference(loadBlob(blob, numa_node), eviction_policy_.get());
   }
+  // To be safe, release the shard for the blob after its write lock destructs.
   lock_manager_.release(blob);
 
   return ret;
@@ -565,10 +568,10 @@
       bool has_collision = false;
       SpinSharedMutexExclusiveLock<false> eviction_lock(*lock_manager_.get(block_index, &has_collision));
       if (has_collision) {
-        // We have a collision in the shared lock manager, where the caller of
-        // this function has acquired a lock, and we are trying to evict a block
-        // that hashes to the same location. This will cause a self-deadlock.
-
+        // We have a collision in the shared lock manager, where some callers
+        // of this function (i.e., getBlockInternal or getBlobInternal) has
+        // acquired an exclusive lock, and we are trying to evict a block that
+        // hashes to the same location. This will cause a deadlock.
         // For now simply treat this situation as the case where there is not
         // enough memory and we temporarily go over the memory limit.
         break;
@@ -579,6 +582,11 @@
         SpinSharedMutexSharedLock<false> read_lock(blocks_shared_mutex_);
         if (blocks_.find(block_index) == blocks_.end()) {
           // another thread must have jumped in and evicted it before us
+
+          // NOTE(zuyu): It is ok to release the shard for a block or blob,
+          // before its write lock destructs, because we will never encounter a
+          // self-deadlock in a single thread, and in multiple-thread case some
+          // thread will block but not deadlock if there is a shard collision.
           lock_manager_.release(block_index);
           continue;
         }
@@ -586,6 +594,11 @@
       }
       if (eviction_policy_->getRefCount(block->getID()) > 0) {
         // Someone sneaked in and referenced the block before we could evict it.
+
+        // NOTE(zuyu): It is ok to release the shard for a block or blob, before
+        // its write lock destructs, because we will never encounter a
+        // self-deadlock in a single thread, and in multiple-thread case some
+        // thread will block but not deadlock if there is a shard collision.
         lock_manager_.release(block_index);
         continue;
       }
@@ -593,6 +606,10 @@
         evictBlockOrBlob(block->getID());
       }  // else : Someone sneaked in and evicted the block before we could.
 
+      // NOTE(zuyu): It is ok to release the shard for a block or blob, before
+      // its write lock destructs, because we will never encounter a
+      // self-deadlock in a single thread, and in multiple-thread case some
+      // thread will block but not deadlock if there is a shard collision.
       lock_manager_.release(block_index);
     } else {
       // If status was not ok, then we must not have been able to evict enough
diff --git a/storage/StorageManager.hpp b/storage/StorageManager.hpp
index 805e885..dab33f6 100644
--- a/storage/StorageManager.hpp
+++ b/storage/StorageManager.hpp
@@ -166,6 +166,22 @@
   }
 
   /**
+   * @brief Return the upper limit on the number of buffer pool slots that the
+   *        StorageManager can allocate. This number is specified during the
+   *        initialization of the StorageManager. The size of each slot is
+   *        kSlotSizeBytes.
+   * @note This information is provided for informational purposes. The memory
+   *       pool may grow larger than this upper limite temporarily, depending
+   *       on the path that is followed in a call to createBlock() or
+   *       loadBlock().
+   *
+   * @return The number of buffer pool slots managed by this StorageManager.
+   **/
+  std::size_t getMaxBufferPoolSlots() const {
+    return max_memory_usage_;
+  }
+
+  /**
    * @brief Create a new empty block.
    *
    * @param relation The relation which the new block will belong to (you must
@@ -391,7 +407,7 @@
    *
    * @param slots Number of slots to make room for.
    */
-  void makeRoomForBlock(const size_t slots);
+  void makeRoomForBlock(const std::size_t slots);
 
   /**
    * @brief Load a block from the persistent storage into memory.
diff --git a/storage/tests/StorageManager_unittest.cpp b/storage/tests/StorageManager_unittest.cpp
index 4c252a1..106a2e7 100644
--- a/storage/tests/StorageManager_unittest.cpp
+++ b/storage/tests/StorageManager_unittest.cpp
@@ -14,12 +14,16 @@
  *   limitations under the License.
  **/
 
+#include <algorithm>
 #include <atomic>
 #include <cstddef>
+#include <cstdlib>
 #include <memory>
 #include <string>
 #include <vector>
+#include <unordered_map>
 
+#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "catalog/CatalogConfig.h"
@@ -28,6 +32,8 @@
 #include "storage/StorageBlockInfo.hpp"
 #include "storage/StorageConstants.hpp"
 #include "storage/StorageManager.hpp"
+#include "threading/Thread.hpp"
+#include "utility/PtrVector.hpp"
 #include "utility/ShardedLockManager.hpp"
 
 #ifdef QUICKSTEP_HAVE_LIBNUMA
@@ -36,6 +42,132 @@
 
 namespace quickstep {
 
+namespace storage_manager_test_internal {
+
+static int client_id = 0;
+
+static const int NUM_BLOBS_PER_CLIENT = 10;
+static const int BLOB_SIZE_SLOTS = 1;
+static const int CLIENT_CYCLES = 1000;
+
+class StorageClient : public Thread {
+ public:
+  StorageClient(StorageManager &storage_manager)
+      : storage_manager_(storage_manager),
+        id_(client_id++) {}
+
+  void run() {
+    createBlobs();
+    for (int i = 0; i < CLIENT_CYCLES; ++i) {
+      cycle();
+      if (id_ == 1) {
+        std::ostringstream msg_stream;
+        msg_stream << "Thread " << id_ << " completed cycle " << i << "\n";
+        LOG(INFO) << msg_stream.str();
+      }
+    }
+    deleteBlobs();
+  }
+
+ private:
+  void createBlobs() {
+    for (int i = 0; i < NUM_BLOBS_PER_CLIENT; ++i) {
+      block_id new_blob = storage_manager_.createBlob(BLOB_SIZE_SLOTS);
+      blobs_.push_back(new_blob);
+      blobs_status_[new_blob] = false;
+    }
+  }
+
+  void cycle() {
+    // Shuffle the vector of references and ids.
+    std::random_shuffle(blob_refs_.begin(), blob_refs_.end());
+    std::random_shuffle(blobs_.begin(), blobs_.end());
+
+    // Release half of the checked out blobs.
+    while (blob_refs_.size() > NUM_BLOBS_PER_CLIENT/4) {
+      // TODO(marc): Blob may be marked dirty at this point.
+      blobs_status_[blob_refs_.back()->getID()] = false;
+      blob_refs_.pop_back();
+    }
+
+    // Checkout blobs until we reach the threshold.
+    int blob_index = 0;
+    while (blob_refs_.size() < NUM_BLOBS_PER_CLIENT/2) {
+      CHECK(blob_index < blobs_.size());
+
+      // See if we have not checked out this blob. If not, make a reference.
+      const block_id candidate_blob = blobs_[blob_index];
+      if (!blobs_status_[candidate_blob]) {
+        blob_refs_.push_back(storage_manager_.getBlobMutable(candidate_blob));
+        blobs_status_[candidate_blob] = true;
+      }
+      blob_index++;
+    }
+  }
+
+  void deleteBlobs() {
+    // Go through all the blobs and dereference them.
+    while(blob_refs_.size() > 0) {
+      blobs_status_[blob_refs_.back()->getID()] = false;
+      blob_refs_.pop_back();
+    }
+
+    // Ensure everything has been checked in.
+    for (const auto& id_status : blobs_status_) {
+      CHECK(id_status.second == false);
+    }
+
+    // Delete all the blob files.
+    for (block_id bid : blobs_) {
+     storage_manager_.deleteBlockOrBlobFile(bid);
+    }
+  }
+
+  StorageManager &storage_manager_;
+
+  // Blobs created and owned by this client. 
+  std::vector<block_id> blobs_;
+
+  // A value of true means that we have checked out the block.
+  std::unordered_map<block_id, bool> blobs_status_;
+
+  // Blob references by this client.
+  std::vector<MutableBlobReference> blob_refs_;
+
+  int id_;
+};
+
+}  // namespace storage_manager_test_internal
+
+using namespace storage_manager_test_internal;
+
+// Create a large number of threads which concurrently access the StorageManager,
+// trying to force a bad interleaving. Test is meant to stress the storage manager
+// but does not expose all possible interleavings.
+TEST(StorageManagerTest, BruteForceDeadLockTest) {
+  // Init StorageManager.
+  std::unique_ptr<StorageManager> storage_manager;
+  // Use a small number of slots.
+  storage_manager.reset(new StorageManager("temp_storage", 32));
+  
+  // Init some threads.
+  const int num_clients = 20;
+  PtrVector<StorageClient> clients;
+  for (int i = 0; i < num_clients; ++i) {
+    clients.push_back(new StorageClient(*storage_manager));
+  }
+
+  // Start all threads.
+  for (int i = 0; i < num_clients; ++i) {
+    clients[i].start();
+  }
+
+  // Wait for all threads to finish.
+  for (int i = 0; i < num_clients; ++i) {
+    clients[i].join();
+  }
+}
+
 TEST(StorageManagerTest, NUMAAgnosticBlobTest) {
   std::unique_ptr<StorageManager> storage_manager;
   static constexpr std::size_t kNumSlots = 10;
@@ -205,46 +337,4 @@
 }
 #endif  // QUICKSTEP_HAVE_LIBNUMA
 
-// Trigger an eviction from the same shard in StorageManager's
-// ShardedLockManager while attempting to load a blob. Previously, a bug
-// existed that caused a self-deadlock in such situations. This test reproduces
-// the issue and validates the fix.
-TEST(StorageManagerTest, EvictFromSameShardTest) {
-  // Set up a StorageManager with a soft memory limit of only one slot.
-  StorageManager storage_manager("eviction_test_storage", 1);
-
-  // Create a blob.
-  const block_id blob_a_id = storage_manager.createBlob(1);
-
-  // Blob "a" is now memory-resident in StorageManager, but has a reference
-  // count of zero.
-  EXPECT_TRUE(storage_manager.blockOrBlobIsLoaded(blob_a_id));
-  EXPECT_EQ(kSlotSizeBytes, storage_manager.getMemorySize());
-
-  // Manually alter 'block_index_' inside 'storage_manager' so that the next
-  // block_id generated will be in the same shard as 'blob_id_a'.
-  storage_manager.block_index_.fetch_add(StorageManager::kLockManagerNumShards - 1);
-
-  // Create another blob and verify that it is in the same shard.
-  const block_id blob_b_id = storage_manager.createBlob(1);
-  EXPECT_EQ(storage_manager.lock_manager_.get(blob_a_id),
-            storage_manager.lock_manager_.get(blob_b_id));
-
-  // Creating a second blob should have triggered an eviction that kicked
-  // blob A out.
-  EXPECT_FALSE(storage_manager.blockOrBlobIsLoaded(blob_a_id));
-  EXPECT_TRUE(storage_manager.blockOrBlobIsLoaded(blob_b_id));
-  EXPECT_EQ(kSlotSizeBytes, storage_manager.getMemorySize());
-
-  // Try and get a reference to blob A. Blob A must be reloaded from disk.
-  // This will trigger an eviction of blob B. This is the point where the
-  // self-deadlock bug could be observed.
-  BlobReference blob_a_ref = storage_manager.getBlob(blob_a_id);
-
-  // Reaching this point means we have not self-deadlocked. Now clean up.
-  blob_a_ref.release();
-  storage_manager.deleteBlockOrBlobFile(blob_a_id);
-  storage_manager.deleteBlockOrBlobFile(blob_b_id);
-}
-
 }  // namespace quickstep
diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt
index 30f01ef..4ff9254 100644
--- a/utility/CMakeLists.txt
+++ b/utility/CMakeLists.txt
@@ -243,6 +243,7 @@
                       quickstep_expressions_Expressions_proto
                       ${PROTOBUF_LIBRARY})
 target_link_libraries(quickstep_utility_ShardedLockManager
+                      quickstep_storage_StorageConstants
                       quickstep_threading_SharedMutex
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_utility_StringUtil
diff --git a/utility/ShardedLockManager.hpp b/utility/ShardedLockManager.hpp
index 550a7ba..e5c12f6 100644
--- a/utility/ShardedLockManager.hpp
+++ b/utility/ShardedLockManager.hpp
@@ -52,38 +52,52 @@
 
   /**
    * @brief Get the SharedMutex corresponding to the provided key.
-   * @param  key The key to map to a SharedMutex.
+   * @param key The key to map to a SharedMutex.
+   * @param has_collision Whether accessing the given key would result in a
+   *        hash collision.
    * @return     The corresponding SharedMutex.
    */
   SharedMutexT* get(const T key, bool *has_collision = nullptr) {
-    const std::size_t hashed_value = hash_(key) % N;
+    const std::size_t shard = hash_(key) % N;
+
     if (has_collision != nullptr) {
-      SpinSharedMutexSharedLock<false> read_lock(collisions_mutex_);
-      *has_collision =
-          collisions_.find(hashed_value) != collisions_.end();
+      {
+        SpinSharedMutexSharedLock<false> read_lock(shards_mutex_);
+        *has_collision =
+            shards_.find(shard) != shards_.end();
+      }
+
       if (*has_collision) {
-        return &dummy_mutex_;
+        return &collision_mutex_;
       }
     }
 
-    SpinSharedMutexExclusiveLock<false> write_lock(collisions_mutex_);
-    collisions_.insert(hashed_value);
-    return &shards[hashed_value];
+    {
+      SpinSharedMutexExclusiveLock<false> write_lock(shards_mutex_);
+      shards_.insert(shard);
+    }
+    return &shards[shard];
   }
 
+  /**
+   * @brief Release the shard corresponding to the provided key.
+   * @param key The key to compute the shard.
+   */
   void release(const T key) {
-    SpinSharedMutexExclusiveLock<false> write_lock(collisions_mutex_);
-    collisions_.erase(hash_(key) % N);
+    SpinSharedMutexExclusiveLock<false> write_lock(shards_mutex_);
+    shards_.erase(hash_(key) % N);
   }
 
  private:
   std::hash<T> hash_;
   std::array<SharedMutexT, N> shards;
 
-  SharedMutexT dummy_mutex_;
+  // The mutex used whenever there is a hash collision.
+  SharedMutexT collision_mutex_;
 
-  alignas(kCacheLineBytes) mutable SpinSharedMutex<false> collisions_mutex_;
-  std::unordered_set<std::size_t> collisions_;
+  // Account for all shards referenced in multiple threads.
+  std::unordered_set<std::size_t> shards_;
+  alignas(kCacheLineBytes) mutable SpinSharedMutex<false> shards_mutex_;
 
   DISALLOW_COPY_AND_ASSIGN(ShardedLockManager);
 };