Merge branch 'master' into query-manager
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7e2d806..f3d3a83 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -681,6 +681,7 @@
                       gflags_nothreads-static
                       glog
                       quickstep_catalog_CatalogRelation
+                      quickstep_cli_CommandExecutor
                       quickstep_cli_DefaultsConfigurator
                       quickstep_cli_DropRelation
                       quickstep_cli_InputParserUtil
diff --git a/catalog/IndexScheme.hpp b/catalog/IndexScheme.hpp
index 95d36a3..d4d67dc 100644
--- a/catalog/IndexScheme.hpp
+++ b/catalog/IndexScheme.hpp
@@ -22,6 +22,7 @@
 #include <cstddef>
 #include <string>
 #include <unordered_map>
+#include <vector>
 
 #include "catalog/Catalog.pb.h"
 #include "storage/StorageBlockLayout.pb.h"
@@ -41,6 +42,8 @@
  **/
 class IndexScheme {
  public:
+  typedef std::unordered_map<std::string, IndexSubBlockDescription>::const_iterator const_iterator;
+
   /**
    * @brief Constructor.
    **/
@@ -139,6 +142,24 @@
   }
 
   /**
+   * @brief Get an iterator at beginning of the index map.
+   *
+   * @return An iterator at beginning of the index map.
+   **/
+  inline const_iterator begin() const {
+    return index_map_.begin();
+  }
+
+  /**
+   * @brief Get an iterator at one-past-the-end of the index map.
+   *
+   * @return An iterator one-past-the-end of the index map.
+   **/
+  inline const_iterator end() const {
+    return index_map_.end();
+  }
+
+  /**
    * @brief Adds a new index entry to the index map.
    * @warning Must call before hasIndexWithName() and hasIndexWithDescription().
    * @note This method assumes that the caller has already acquired the
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
index a3545c9..9c4073b 100644
--- a/cli/CMakeLists.txt
+++ b/cli/CMakeLists.txt
@@ -14,6 +14,7 @@
 #   limitations under the License.
 
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_subdirectory(tests)
 
 if (WIN32)
   set(QUICKSTEP_OS_WINDOWS TRUE)
@@ -31,6 +32,7 @@
   "${CMAKE_CURRENT_SOURCE_DIR}/CliConfig.h.in"
   "${CMAKE_CURRENT_BINARY_DIR}/CliConfig.h"
 )
+add_library(quickstep_cli_CommandExecutor CommandExecutor.cpp CommandExecutor.hpp)
 
 # Declare micro-libs and link dependencies:
 add_library(quickstep_cli_DropRelation DropRelation.cpp DropRelation.hpp)
@@ -65,6 +67,18 @@
 add_library(quickstep_cli_PrintToScreen PrintToScreen.cpp PrintToScreen.hpp)
 
 # Link dependencies:
+target_link_libraries(quickstep_cli_CommandExecutor
+                      glog
+                      quickstep_catalog_CatalogAttribute
+                      quickstep_catalog_CatalogDatabase
+                      quickstep_catalog_CatalogRelation
+                      quickstep_catalog_CatalogRelationSchema
+                      quickstep_parser_ParseStatement
+                      quickstep_cli_PrintToScreen
+                      quickstep_utility_Macros
+                      quickstep_utility_PtrVector                        
+                      quickstep_utility_SqlError)
+
 target_link_libraries(quickstep_cli_DefaultsConfigurator
                       quickstep_utility_Macros)
 if(QUICKSTEP_HAVE_LIBNUMA)
@@ -96,6 +110,7 @@
 add_library(quickstep_cli ../empty_src.cpp CliModule.hpp)
 
 target_link_libraries(quickstep_cli
+                      quickstep_cli_CommandExecutor
                       quickstep_cli_DefaultsConfigurator
                       quickstep_cli_DropRelation
                       quickstep_cli_InputParserUtil
diff --git a/cli/CommandExecutor.cpp b/cli/CommandExecutor.cpp
new file mode 100644
index 0000000..e9db628
--- /dev/null
+++ b/cli/CommandExecutor.cpp
@@ -0,0 +1,186 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "cli/CommandExecutor.hpp"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdio>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "catalog/CatalogAttribute.hpp"
+#include "catalog/CatalogDatabase.hpp"
+#include "catalog/CatalogRelation.hpp"
+#include "catalog/CatalogRelationSchema.hpp"
+#include "cli/PrintToScreen.hpp"
+#include "parser/ParseStatement.hpp"
+#include "utility/PtrVector.hpp"
+#include "utility/Macros.hpp"
+#include "utility/SqlError.hpp"
+
+#include "gflags/gflags.h"
+#include "glog/logging.h"
+
+using std::fprintf;
+using std::fputc;
+using std::fputs;
+using std::size_t;
+using std::string;
+using std::vector;
+
+namespace quickstep {
+namespace cli {
+namespace {
+
+namespace C = ::quickstep::cli;
+
+void executeDescribeDatabase(
+    const PtrVector<ParseString> *arguments,
+    const CatalogDatabase &catalog_database, FILE *out) {
+  // Column width initialized to 6 to take into account the header name
+  // and the column value table
+  int max_column_width = C::kInitMaxColumnWidth;
+  const CatalogRelation *relation;
+  if (arguments->size() == 0) {
+    for (const CatalogRelation &rel : catalog_database) {
+      max_column_width =
+          std::max(static_cast<int>(rel.getName().length()), max_column_width);
+    }
+  } else {
+    const ParseString &table_name = arguments->front();
+    const std::string &table_name_val = table_name.value();
+    relation = catalog_database.getRelationByName(table_name_val);
+
+    if (relation == nullptr) {
+      THROW_SQL_ERROR_AT(&(arguments->front())) << " Unrecognized relation " << table_name_val;
+    }
+    max_column_width = std::max(static_cast<int>(relation->getName().length()),
+                                    max_column_width);
+  }
+  // Only if we have relations work on the printing logic.
+  if (catalog_database.size() > 0) {
+    vector<int> column_widths;
+    column_widths.push_back(max_column_width+1);
+    column_widths.push_back(C::kInitMaxColumnWidth+1);
+    fputs("       List of relations\n\n", out);
+    fprintf(out, "%-*s |", max_column_width+1, " Name");
+    fprintf(out, "%-*s\n", C::kInitMaxColumnWidth, " Type");
+    PrintToScreen::printHBar(column_widths, out);
+    //  If there are no argument print the entire list of tables
+    //  else print the particular table only.
+    if (arguments->size() == 0) {
+      for (const CatalogRelation &rel : catalog_database) {
+        fprintf(out, " %-*s |", max_column_width, rel.getName().c_str());
+        fprintf(out, " %-*s\n", C::kInitMaxColumnWidth, "table");
+      }
+    } else {
+      fprintf(out, " %-*s |", max_column_width, relation->getName().c_str());
+      fprintf(out, " %-*s\n", C::kInitMaxColumnWidth, "table");
+    }
+    fputc('\n', out);
+  }
+}
+
+void executeDescribeTable(
+    const PtrVector<ParseString> *arguments,
+    const CatalogDatabase &catalog_database, FILE *out) {
+  const ParseString &table_name = arguments->front();
+  const std::string &table_name_val = table_name.value();
+  const CatalogRelation *relation =
+      catalog_database.getRelationByName(table_name_val);
+  if (relation == nullptr) {
+    THROW_SQL_ERROR_AT(&(arguments->front())) << " Unrecognized relation "  << table_name_val;
+  }
+  vector<int> column_widths;
+  int max_attr_column_width = C::kInitMaxColumnWidth;
+  int max_type_column_width = C::kInitMaxColumnWidth;
+
+  for (const CatalogAttribute &attr : *relation) {
+    // Printed column needs to be wide enough to print:
+    //   1. The attribute name (in the printed "header").
+    //   2. Any value of the attribute's Type.
+    max_attr_column_width =
+        std::max(max_attr_column_width,
+            static_cast<int>(attr.getDisplayName().length()));
+    max_type_column_width =
+        std::max(max_type_column_width,
+            static_cast<int>(attr.getType().getName().length()));
+  }
+  // Add room for one extra character to allow spacing between the column ending and the vertical bar
+  column_widths.push_back(max_attr_column_width+1);
+  column_widths.push_back(max_type_column_width+1);
+
+  fprintf(out, "%*s \"%s\"\n", C::kInitMaxColumnWidth, "Table", table_name_val.c_str());
+  fprintf(out, "%-*s |", max_attr_column_width+1, " Column");
+  fprintf(out, "%-*s\n", max_type_column_width+1, " Type");
+  PrintToScreen::printHBar(column_widths, out);
+  for (const CatalogAttribute &attr : *relation) {
+    fprintf(out, " %-*s |", max_attr_column_width,
+            attr.getDisplayName().c_str());
+    fprintf(out, " %-*s\n", max_type_column_width,
+            attr.getType().getName().c_str());
+  }
+  // TODO(rogers): Add handlers for partitioning information.
+  if (relation->hasIndexScheme()) {
+    fprintf(out, "%*s\n", C::kInitMaxColumnWidth+2, " Indexes");
+    const quickstep::IndexScheme &index_scheme = relation->getIndexScheme();
+    for (auto index_it = index_scheme.begin(); index_it != index_scheme.end();
+         ++index_it) {
+      fprintf(out, "  \"%-*s\" %s", static_cast<int>(index_it->first.length()),
+              index_it->first.c_str(),
+              index_it->second.IndexSubBlockType_Name(
+                  index_it->second.sub_block_type()).c_str());
+      fputc(' ', out);
+      fputc('(', out);
+      fprintf(out, "%s", relation->getAttributeById(index_it->second.indexed_attribute_ids(0))
+                             ->getDisplayName().c_str());
+      for (std::size_t i = 1; i < static_cast<std::size_t>(index_it->second.indexed_attribute_ids_size()); ++i) {
+        const char *attribute_display_name = relation->getAttributeById(
+                                                 index_it->second.indexed_attribute_ids(i))
+                                                     ->getDisplayName().c_str();
+        fprintf(out, ", %s", attribute_display_name);
+      }
+      fputc(')', out);
+      fputc('\n', out);
+    }
+  }
+}
+
+}  // namespace
+
+void executeCommand(const ParseStatement &statement,
+                    const CatalogDatabase &catalog_database,
+                    FILE *out) {
+  const ParseCommand &command = static_cast<const ParseCommand &>(statement);
+  const PtrVector<ParseString> *arguments = command.arguments();
+  const std::string &command_str = command.command()->value();
+  if (command_str == C::kDescribeDatabaseCommand) {
+    executeDescribeDatabase(arguments, catalog_database, out);
+  } else if (command_str == C::kDescribeTableCommand) {
+    if (arguments->size() == 0) {
+      executeDescribeDatabase(arguments, catalog_database, out);
+    } else {
+      executeDescribeTable(arguments, catalog_database, out);
+    }
+  } else {
+    THROW_SQL_ERROR_AT(command.command()) << "Invalid Command";
+  }
+}
+}  // namespace cli
+}  // namespace quickstep
diff --git a/cli/CommandExecutor.hpp b/cli/CommandExecutor.hpp
new file mode 100644
index 0000000..21eee6a
--- /dev/null
+++ b/cli/CommandExecutor.hpp
@@ -0,0 +1,66 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_CLI_COMMAND_COMMAND_EXECUTOR_HPP_
+#define QUICKSTEP_CLI_COMMAND_COMMAND_EXECUTOR_HPP_
+
+#include <cstdio>
+#include <string>
+
+#include "parser/ParseStatement.hpp"
+#include "utility/Macros.hpp"
+
+using std::fprintf;
+using std::fputc;
+using std::string;
+
+namespace quickstep {
+
+class CatalogDatabase;
+class CatalogAttribute;
+class CatalogRelation;
+
+namespace cli {
+/** \addtogroup CLI
+ *  @{
+ */
+
+// Adding the max column width as 6  as the default initializer
+// as the length of the word Column is 6 characters.
+// This is used while describing the table.
+constexpr int kInitMaxColumnWidth = 6;
+
+constexpr char kDescribeDatabaseCommand[] = "\\dt";
+constexpr char kDescribeTableCommand[] = "\\d";
+
+/**
+  * @brief Executes the command by calling the command handler.
+  *        
+  * @param statement The parsed statement from the cli.
+  * @param catalog_database The catalog information about the current database.
+  * @param out The stream where the output of the command has to be redirected to.      
+*/
+void executeCommand(const ParseStatement &statement,
+                    const CatalogDatabase &catalog_database,
+                    FILE *out);
+
+/** @} */
+
+}  // namespace cli
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_CLI_COMMAND_COMMAND_EXECUTOR_HPP_
diff --git a/cli/PrintToScreen.hpp b/cli/PrintToScreen.hpp
index e47e7ce..3c9afae 100644
--- a/cli/PrintToScreen.hpp
+++ b/cli/PrintToScreen.hpp
@@ -44,13 +44,13 @@
                             StorageManager *storage_manager,
                             FILE *out);
 
+  static void printHBar(const std::vector<int> &column_widths,
+                        FILE *out);
  private:
   // Undefined default constructor. Class is all-static and should not be
   // instantiated.
   PrintToScreen();
 
-  static void printHBar(const std::vector<int> &column_widths,
-                        FILE *out);
   static void printTuple(const TupleStorageSubBlock &tuple_store,
                          const tuple_id tid,
                          const std::vector<int> &column_widths,
diff --git a/cli/QuickstepCli.cpp b/cli/QuickstepCli.cpp
index ad918a5..b0b98a3 100644
--- a/cli/QuickstepCli.cpp
+++ b/cli/QuickstepCli.cpp
@@ -35,6 +35,7 @@
 #endif
 
 #include "cli/CliConfig.h"  // For QUICKSTEP_USE_LINENOISE.
+#include "cli/CommandExecutor.hpp"
 #include "cli/DropRelation.hpp"
 
 #ifdef QUICKSTEP_USE_LINENOISE
@@ -345,8 +346,17 @@
         }
 
         if (result.parsed_statement->getStatementType() == ParseStatement::kCommand) {
-          // TODO(marc): Add executer to this parsed command statement.
-          continue;
+          try {
+            quickstep::cli::executeCommand(
+                *result.parsed_statement,
+                *(query_processor->getDefaultDatabase()), stdout);
+          } catch (const quickstep::SqlError &sql_error) {
+            fprintf(stderr, "%s",
+                    sql_error.formatMessage(*command_string).c_str());
+            reset_parser = true;
+            break;
+          }
+        continue;
         }
 
         std::unique_ptr<QueryHandle> query_handle;
diff --git a/cli/tests/CMakeLists.txt b/cli/tests/CMakeLists.txt
new file mode 100644
index 0000000..ca37e4a
--- /dev/null
+++ b/cli/tests/CMakeLists.txt
@@ -0,0 +1,54 @@
+#   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.
+#   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.
+ 
+add_subdirectory(command_executor)
+
+add_executable(quickstep_cli_tests_CommandExecutorTest
+               CommandExecutorTest.cpp
+               CommandExecutorTestRunner.cpp
+               CommandExecutorTestRunner.hpp
+               "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.cpp"
+               "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.hpp")
+
+target_link_libraries(quickstep_cli_tests_CommandExecutorTest
+                      glog
+                      gtest
+                      gtest_main
+                      quickstep_catalog_CatalogDatabase
+                      quickstep_cli_CommandExecutor
+                      quickstep_cli_DropRelation
+                      quickstep_cli_PrintToScreen
+                      quickstep_parser_ParseStatement
+                      quickstep_parser_SqlParserWrapper
+                      quickstep_queryexecution_Foreman
+                      quickstep_queryexecution_QueryContext
+                      quickstep_queryexecution_QueryExecutionTypedefs
+                      quickstep_queryexecution_Worker
+                      quickstep_queryexecution_WorkerDirectory
+                      quickstep_queryexecution_WorkerMessage
+                      quickstep_queryoptimizer_ExecutionGenerator
+                      quickstep_queryoptimizer_LogicalGenerator
+                      quickstep_queryoptimizer_OptimizerContext
+                      quickstep_queryoptimizer_PhysicalGenerator
+                      quickstep_queryoptimizer_QueryHandle
+                      quickstep_queryoptimizer_QueryPlan
+                      quickstep_queryoptimizer_physical_Physical
+                      quickstep_queryoptimizer_tests_TestDatabaseLoader
+                      quickstep_utility_Macros
+                      quickstep_utility_MemStream
+                      quickstep_utility_SqlError
+                      quickstep_utility_TextBasedTestDriver
+                      tmb
+                      ${LIBS})
diff --git a/cli/tests/CommandExecutorTest.cpp b/cli/tests/CommandExecutorTest.cpp
new file mode 100644
index 0000000..7b78cff
--- /dev/null
+++ b/cli/tests/CommandExecutorTest.cpp
@@ -0,0 +1,56 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include <iostream>
+#include <fstream>
+#include <memory>
+
+#include "cli/tests/CommandExecutorTestRunner.hpp"
+#include "utility/textbased_test/TextBasedTestDriver.hpp"
+
+#include "glog/logging.h"
+
+using quickstep::TextBasedTest;
+
+QUICKSTEP_GENERATE_TEXT_TEST(COMMAND_EXECUTOR_TEST);
+
+int main(int argc, char** argv) {
+  google::InitGoogleLogging(argv[0]);
+
+  if (argc < 4) {
+    LOG(ERROR) << "Must have at least 3 arguments, but " << argc - 1
+               << " are provided";
+  }
+
+  std::ifstream input_file(argv[1]);
+  CHECK(input_file.is_open()) << argv[1];
+  std::unique_ptr<quickstep::CommandExecutorTestRunner>
+      test_runner(
+          new quickstep::CommandExecutorTestRunner(argv[3]));
+  test_driver.reset(
+      new quickstep::TextBasedTestDriver(&input_file, test_runner.get()));
+  test_driver->registerOption(
+      quickstep::CommandExecutorTestRunner::kResetOption);
+
+  ::testing::InitGoogleTest(&argc, argv);
+  const int success = RUN_ALL_TESTS();
+  if (success != 0) {
+    test_driver->writeActualOutputToFile(argv[2]);
+  }
+
+  return success;
+}
diff --git a/cli/tests/CommandExecutorTestRunner.cpp b/cli/tests/CommandExecutorTestRunner.cpp
new file mode 100644
index 0000000..49930e1
--- /dev/null
+++ b/cli/tests/CommandExecutorTestRunner.cpp
@@ -0,0 +1,130 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "cli/tests/CommandExecutorTestRunner.hpp"
+
+#include <cstdio>
+#include <set>
+#include <string>
+
+#include "cli/CommandExecutor.hpp"
+#include "cli/DropRelation.hpp"
+#include "cli/PrintToScreen.hpp"
+#include "parser/ParseStatement.hpp"
+#include "query_execution/Foreman.hpp"
+#include "query_execution/Worker.hpp"
+#include "query_optimizer/ExecutionGenerator.hpp"
+#include "query_optimizer/LogicalGenerator.hpp"
+#include "query_optimizer/OptimizerContext.hpp"
+#include "query_optimizer/PhysicalGenerator.hpp"
+#include "query_optimizer/QueryHandle.hpp"
+#include "query_optimizer/QueryPlan.hpp"
+#include "query_optimizer/physical/Physical.hpp"
+#include "utility/Macros.hpp"
+#include "utility/MemStream.hpp"
+#include "utility/PtrList.hpp"
+#include "utility/SqlError.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class CatalogRelation;
+
+namespace O = ::quickstep::optimizer;
+namespace P = ::quickstep::optimizer::physical;
+namespace L = ::quickstep::optimizer::logical;
+
+const char CommandExecutorTestRunner::kResetOption[] =
+    "reset_before_execution";
+
+void CommandExecutorTestRunner::runTestCase(
+    const std::string &input, const std::set<std::string> &options,
+    std::string *output) {
+  // TODO(qzeng): Test multi-threaded query execution when we have a Sort operator.
+
+  VLOG(4) << "Test SQL(s): " << input;
+
+  if (options.find(kResetOption) != options.end()) {
+    test_database_loader_.clear();
+    test_database_loader_.createTestRelation(false /* allow_vchar */);
+    test_database_loader_.loadTestRelation();
+  }
+
+  MemStream output_stream;
+  sql_parser_.feedNextBuffer(new std::string(input));
+
+  while (true) {
+    ParseResult result = sql_parser_.getNextStatement();
+
+    O::OptimizerContext optimizer_context(0 /* query_id */,
+                                          test_database_loader_.catalog_database(),
+                                          test_database_loader_.storage_manager());
+
+    if (result.condition != ParseResult::kSuccess) {
+      if (result.condition == ParseResult::kError) {
+        *output = result.error_message;
+      }
+      break;
+    } else {
+      std::printf("%s\n", result.parsed_statement->toString().c_str());
+      try {
+        if (result.parsed_statement->getStatementType() == ParseStatement::kCommand) {
+          quickstep::cli::executeCommand(
+              *result.parsed_statement,
+              *(test_database_loader_.catalog_database()),
+              output_stream.file());
+        } else  {
+          QueryHandle query_handle(optimizer_context.query_id());
+          O::LogicalGenerator logical_generator(&optimizer_context);
+          O::PhysicalGenerator physical_generator;
+          O::ExecutionGenerator execution_generator(&optimizer_context, &query_handle);
+          const P::PhysicalPtr physical_plan =
+              physical_generator.generatePlan(
+                  logical_generator.generatePlan(*result.parsed_statement));
+          execution_generator.generatePlan(physical_plan);
+          foreman_->setQueryPlan(
+              query_handle.getQueryPlanMutable()->getQueryPlanDAGMutable());
+
+          foreman_->reconstructQueryContextFromProto(query_handle.getQueryContextProto());
+
+          foreman_->start();
+          foreman_->join();
+
+          const CatalogRelation *query_result_relation = query_handle.getQueryResultRelation();
+          if (query_result_relation) {
+            PrintToScreen::PrintRelation(*query_result_relation,
+                                         test_database_loader_.storage_manager(),
+                                         output_stream.file());
+            DropRelation::Drop(*query_result_relation,
+                               test_database_loader_.catalog_database(),
+                               test_database_loader_.storage_manager());
+          }
+        }
+      } catch (const SqlError &error) {
+        *output = error.formatMessage(input);
+        break;
+      }
+    }
+  }
+
+  if (output->empty()) {
+    *output = output_stream.str();
+  }
+}
+
+}  // namespace quickstep
diff --git a/cli/tests/CommandExecutorTestRunner.hpp b/cli/tests/CommandExecutorTestRunner.hpp
new file mode 100644
index 0000000..94b1d6a
--- /dev/null
+++ b/cli/tests/CommandExecutorTestRunner.hpp
@@ -0,0 +1,116 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_CLI_TESTS_COMMAND_EXECUTOR_TEST_RUNNER_HPP_
+#define QUICKSTEP_CLI_TESTS_COMMAND_EXECUTOR_TEST_RUNNER_HPP_
+
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "parser/SqlParserWrapper.hpp"
+#include "query_execution/Foreman.hpp"
+#include "query_execution/QueryExecutionTypedefs.hpp"
+#include "query_execution/Worker.hpp"
+#include "query_execution/WorkerDirectory.hpp"
+#include "query_execution/WorkerMessage.hpp"
+#include "query_optimizer/tests/TestDatabaseLoader.hpp"
+#include "utility/Macros.hpp"
+#include "utility/textbased_test/TextBasedTestDriver.hpp"
+
+namespace quickstep {
+
+/**
+ * @brief TextBasedTestRunner for testing the ExecutionGenerator.
+ */
+class CommandExecutorTestRunner : public TextBasedTestRunner {
+ public:
+  /**
+   * @brief If this option is enabled, recreate the entire database and
+   * repopulate the data before every test.
+   */
+  static const char kResetOption[];
+
+  /**
+   * @brief Constructor.
+   */
+  explicit CommandExecutorTestRunner(const std::string &storage_path)
+      : test_database_loader_(storage_path) {
+    test_database_loader_.createTestRelation(false /* allow_vchar */);
+    test_database_loader_.loadTestRelation();
+
+    bus_.Initialize();
+
+    foreman_.reset(new Foreman(&bus_,
+                               test_database_loader_.catalog_database(),
+                               test_database_loader_.storage_manager()));
+    worker_.reset(new Worker(0, &bus_));
+
+    std::vector<client_id> worker_client_ids;
+    worker_client_ids.push_back(worker_->getBusClientID());
+
+    // We don't use the NUMA aware version of foreman code.
+    std::vector<int> numa_nodes;
+    numa_nodes.push_back(-1);
+
+    workers_.reset(new WorkerDirectory(1 /* number of workers */,
+                                       worker_client_ids, numa_nodes));
+    foreman_->setWorkerDirectory(workers_.get());
+
+    worker_->start();
+  }
+
+  ~CommandExecutorTestRunner() {
+    std::unique_ptr<WorkerMessage> poison_message(WorkerMessage::PoisonMessage());
+    TaggedMessage poison_tagged_message(poison_message.get(),
+                                        sizeof(*poison_message),
+                                        quickstep::kPoisonMessage);
+
+    Address worker_address;
+    MessageStyle single_receiver_style;
+
+    worker_address.AddRecipient(worker_->getBusClientID());
+    bus_.Send(foreman_->getBusClientID(),
+              worker_address,
+              single_receiver_style,
+              std::move(poison_tagged_message));
+
+    worker_->join();
+  }
+
+  void runTestCase(const std::string &input,
+                   const std::set<std::string> &options,
+                   std::string *output) override;
+
+ private:
+  SqlParserWrapper sql_parser_;
+  optimizer::TestDatabaseLoader test_database_loader_;
+
+  MessageBusImpl bus_;
+  std::unique_ptr<Foreman> foreman_;
+  std::unique_ptr<Worker> worker_;
+
+  std::unique_ptr<WorkerDirectory> workers_;
+
+  DISALLOW_COPY_AND_ASSIGN(CommandExecutorTestRunner);
+};
+
+}  // namespace quickstep
+
+#endif  //  QUICKSTEP_CLI_TESTS_COMMAND_EXECUTOR_TEST_RUNNER_HPP_
diff --git a/cli/tests/command_executor/CMakeLists.txt b/cli/tests/command_executor/CMakeLists.txt
new file mode 100644
index 0000000..c9bcb36
--- /dev/null
+++ b/cli/tests/command_executor/CMakeLists.txt
@@ -0,0 +1,31 @@
+#   Copyright 2011-2015 Quickstep Technologies LLC.
+#   Copyright 2015 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.
+
+add_test(quickstep_cli_tests_commandexecutor_d
+         "../quickstep_cli_tests_CommandExecutorTest"
+         "${CMAKE_CURRENT_SOURCE_DIR}/D.test"
+         "${CMAKE_CURRENT_BINARY_DIR}/Dt.test"
+         "${CMAKE_CURRENT_BINARY_DIR}/D/")
+add_test(quickstep_cli_tests_commandexecutor_dt
+         "../quickstep_cli_tests_CommandExecutorTest"
+         "${CMAKE_CURRENT_SOURCE_DIR}/Dt.test"
+         "${CMAKE_CURRENT_BINARY_DIR}/Dt.test"
+         "${CMAKE_CURRENT_BINARY_DIR}/Dt/")
+
+# Create the folders where the unit tests will store their data blocks for the
+# duration of their test.
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Dt)
+
diff --git a/cli/tests/command_executor/D.test b/cli/tests/command_executor/D.test
new file mode 100644
index 0000000..1d500df
--- /dev/null
+++ b/cli/tests/command_executor/D.test
@@ -0,0 +1,109 @@
+#   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.
+#   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.
+
+CREATE TABLE foo (col1 INT,
+                  col2 LONG,
+                  col3 DOUBLE,
+                  col4 FLOAT,
+                  col5 CHAR(5));
+CREATE TABLE foo2 (col1 INT,
+                   col2 LONG,
+                   col3 DOUBLE,
+                   col4 FLOAT,
+                   averyverylongcolumnnamefortest CHAR(5));
+CREATE TABLE foo3 (col1 INT,
+                   col2 LONG,
+                   col3 DOUBLE,
+                   col4 FLOAT,
+                   col5 CHAR(5));
+CREATE INDEX foo3_index_1 ON foo3 (col1) USING CSBTREE;
+CREATE TABLE foo4 (col1 INT,
+                   col2 LONG,
+                   col3 DOUBLE,
+                   col4 FLOAT,
+                   col5 CHAR(5));
+CREATE INDEX foo4_index_1 ON foo4 (col1, col2) USING CSBTREE; 
+CREATE INDEX foo4_index_2 ON foo4 (col3, col4) USING CSBTREE; 
+CREATE TABLE averylongtablenamethatseemstoneverend (col1 INT);
+--
+==
+\d foo
+--
+ Table "foo"
+ Column | Type   
++-------+--------+
+ col1   | Int    
+ col2   | Long   
+ col3   | Double 
+ col4   | Float  
+ col5   | Char(5)
+==
+\d foo2                   
+--
+ Table "foo2"
+ Column                         | Type   
++-------------------------------+--------+
+ col1                           | Int    
+ col2                           | Long   
+ col3                           | Double 
+ col4                           | Float  
+ averyverylongcolumnnamefortest | Char(5)
+==
+\d foo3
+--
+ Table "foo3"
+ Column | Type   
++-------+--------+
+ col1   | Int    
+ col2   | Long   
+ col3   | Double 
+ col4   | Float  
+ col5   | Char(5)
+ Indexes
+  "foo3_index_1" CSB_TREE (col1)
+==                    
+\d foo4
+--
+ Table "foo4"
+ Column | Type   
++-------+--------+
+ col1   | Int    
+ col2   | Long   
+ col3   | Double 
+ col4   | Float  
+ col5   | Char(5)
+ Indexes
+  "foo4_index_2" CSB_TREE (col3, col4)
+  "foo4_index_1" CSB_TREE (col1, col2)
+==
+\d
+--
+       List of relations
+
+ Name                                  | Type 
++--------------------------------------+-------+
+ Test                                  | table 
+ foo                                   | table 
+ foo2                                  | table 
+ foo3                                  | table 
+ foo4                                  | table 
+ averylongtablenamethatseemstoneverend | table 
+
+==
+\d invalidtable
+--
+ERROR:  Unrecognized relation invalidtable (1 : 4)
+\d invalidtable
+   ^
diff --git a/cli/tests/command_executor/Dt.test b/cli/tests/command_executor/Dt.test
new file mode 100644
index 0000000..6458e15
--- /dev/null
+++ b/cli/tests/command_executor/Dt.test
@@ -0,0 +1,57 @@
+#   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.
+#   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.
+
+CREATE TABLE foo (col1 INT,
+                  col2 LONG,
+                  col3 DOUBLE,
+                  col4 FLOAT,
+                  col5 CHAR(5));
+CREATE TABLE foo2 (col1 INT,
+                   col2 LONG,
+                   col3 DOUBLE,
+                   col4 FLOAT,
+                   averyverylongcolumnnamefortest CHAR(5));
+CREATE TABLE foo3 (col1 INT,
+                   col2 LONG,
+                   col3 DOUBLE,
+                   col4 FLOAT,
+                   col5 CHAR(5));
+CREATE TABLE foo4 (col1 INT,
+                   col2 LONG,
+                   col3 DOUBLE,
+                   col4 FLOAT,
+                   col5 CHAR(5));
+CREATE TABLE averylongtablenamethatseemstoneverend (col1 INT);
+--
+==
+\dt
+--
+       List of relations
+
+ Name                                  | Type 
++--------------------------------------+-------+
+ Test                                  | table 
+ foo                                   | table 
+ foo2                                  | table 
+ foo3                                  | table 
+ foo4                                  | table 
+ averylongtablenamethatseemstoneverend | table 
+
+==
+\dt invalidtable
+--
+ERROR:  Unrecognized relation invalidtable (1 : 5)
+\dt invalidtable
+    ^
diff --git a/parser/CMakeLists.txt b/parser/CMakeLists.txt
index 2c8f099..8206caf 100644
--- a/parser/CMakeLists.txt
+++ b/parser/CMakeLists.txt
@@ -86,6 +86,7 @@
 add_library(quickstep_parser_ParseAttributeDefinition ParseAttributeDefinition.cpp ParseAttributeDefinition.hpp)
 add_library(quickstep_parser_ParseBasicExpressions ParseBasicExpressions.cpp ParseBasicExpressions.hpp)
 add_library(quickstep_parser_ParseBlockProperties ParseBlockProperties.cpp ParseBlockProperties.hpp)
+add_library(quickstep_parser_ParseCaseExpressions ParseCaseExpressions.cpp ParseCaseExpressions.hpp)
 add_library(quickstep_parser_ParseExpression ../empty_src.cpp ParseExpression.hpp)
 add_library(quickstep_parser_ParseGeneratorTableReference ParseGeneratorTableReference.cpp ParseGeneratorTableReference.hpp)
 add_library(quickstep_parser_ParseGroupBy ParseGroupBy.cpp ParseGroupBy.hpp)
@@ -142,6 +143,12 @@
                       quickstep_utility_Macros
                       quickstep_utility_PtrList
                       quickstep_utility_StringUtil)
+target_link_libraries(quickstep_parser_ParseCaseExpressions
+                      quickstep_parser_ParseExpression
+                      quickstep_parser_ParsePredicate
+                      quickstep_parser_ParseTreeNode
+                      quickstep_utility_Macros
+                      quickstep_utility_PtrVector)
 target_link_libraries(quickstep_parser_ParseExpression
                       quickstep_parser_ParseTreeNode
                       quickstep_utility_Macros)
@@ -292,6 +299,7 @@
                       quickstep_parser_ParseAttributeDefinition
                       quickstep_parser_ParseBasicExpressions
                       quickstep_parser_ParseBlockProperties
+                      quickstep_parser_ParseCaseExpressions
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseGeneratorTableReference
                       quickstep_parser_ParseGroupBy
@@ -364,6 +372,7 @@
                       quickstep_parser_ParseAttributeDefinition
                       quickstep_parser_ParseBasicExpressions
                       quickstep_parser_ParseBlockProperties
+                      quickstep_parser_ParseCaseExpressions
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseGeneratorTableReference
                       quickstep_parser_ParseGroupBy
diff --git a/parser/ParseCaseExpressions.cpp b/parser/ParseCaseExpressions.cpp
new file mode 100644
index 0000000..800266d
--- /dev/null
+++ b/parser/ParseCaseExpressions.cpp
@@ -0,0 +1,129 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "parser/ParseCaseExpressions.hpp"
+
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "parser/ParseExpression.hpp"
+#include "parser/ParsePredicate.hpp"
+#include "parser/ParseTreeNode.hpp"
+
+namespace quickstep {
+
+void ParseSimpleWhenClause::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  non_container_child_field_names->push_back("condition_operand");
+  non_container_child_fields->push_back(condition_operand_.get());
+
+  non_container_child_field_names->push_back("result_expression");
+  non_container_child_fields->push_back(result_expression_.get());
+}
+
+void ParseSearchedWhenClause::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  non_container_child_field_names->push_back("condition_predicate");
+  non_container_child_fields->push_back(condition_predicate_.get());
+
+  non_container_child_field_names->push_back("result_expression");
+  non_container_child_fields->push_back(result_expression_.get());
+}
+
+std::string ParseSimpleCaseExpression::generateName() const {
+  std::ostringstream out;
+  out << "CASE " << case_operand_->generateName();
+  for (const ParseSimpleWhenClause &when_clause : *when_clauses_) {
+    out << " WHEN " << when_clause.condition_operand()->generateName()
+        << " THEN " << when_clause.result_expression()->generateName();
+  }
+  if (else_result_expression_ != nullptr) {
+    out << " ELSE " << else_result_expression_->generateName();
+  }
+  out << " END";
+  return out.str();
+}
+
+void ParseSimpleCaseExpression::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  non_container_child_field_names->push_back("case_operand");
+  non_container_child_fields->push_back(case_operand_.get());
+
+  container_child_field_names->push_back("when_clauses");
+  container_child_fields->emplace_back();
+  for (const ParseSimpleWhenClause &when_clause : *when_clauses_) {
+    container_child_fields->back().push_back(&when_clause);
+  }
+
+  if (else_result_expression_ != nullptr) {
+    non_container_child_field_names->push_back("else_result_expression");
+    non_container_child_fields->push_back(else_result_expression_.get());
+  }
+}
+
+std::string ParseSearchedCaseExpression::generateName() const {
+  std::ostringstream out;
+  out << "CASE";
+  for (const ParseSearchedWhenClause &when_clause : *when_clauses_) {
+    // TODO(jianqiao): implement generateName() for Predicate.
+    out << " WHEN " << when_clause.condition_predicate()->getShortString()
+        << " THEN " << when_clause.result_expression()->generateName();
+  }
+  if (else_result_expression_ != nullptr) {
+    out << " ELSE " << else_result_expression_->generateName();
+  }
+  out << " END";
+  return out.str();
+}
+
+void ParseSearchedCaseExpression::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  container_child_field_names->push_back("when_clauses");
+  container_child_fields->emplace_back();
+  for (const ParseSearchedWhenClause &when_clause : *when_clauses_) {
+    container_child_fields->back().push_back(&when_clause);
+  }
+
+  if (else_result_expression_ != nullptr) {
+    non_container_child_field_names->push_back("else_result_expression");
+    non_container_child_fields->push_back(else_result_expression_.get());
+  }
+}
+
+}  // namespace quickstep
diff --git a/parser/ParseCaseExpressions.hpp b/parser/ParseCaseExpressions.hpp
new file mode 100644
index 0000000..91d815e
--- /dev/null
+++ b/parser/ParseCaseExpressions.hpp
@@ -0,0 +1,313 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_PARSER_PARSE_CASE_EXPRESSIONS_HPP_
+#define QUICKSTEP_PARSER_PARSE_CASE_EXPRESSIONS_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "parser/ParseExpression.hpp"
+#include "parser/ParsePredicate.hpp"
+#include "parser/ParseTreeNode.hpp"
+#include "utility/Macros.hpp"
+#include "utility/PtrVector.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Parser
+ *  @{
+ */
+
+/**
+ * @brief The parsed representation of a WHEN clause in a simple CASE
+ *        expression (WHEN <condition operand> THEN <result expression>).
+ */
+class ParseSimpleWhenClause : public ParseTreeNode {
+ public:
+  /**
+   * @brief Constructor. Takes ownership of all pointers.
+   *
+   * @param line_number The line number of "WHEN" in the SQL statement.
+   * @param column_number The column number of "WHEN" in the SQL statement.
+   * @param check_operand The condition operand to be compared with the
+   *                      CASE operand (not in this class) of the CASE
+   *                      expression.
+   * @param result_expression The result expression for this condition.
+   */
+  ParseSimpleWhenClause(int line_number,
+                        int column_number,
+                        ParseExpression *condition_operand,
+                        ParseExpression *result_expression)
+      : ParseTreeNode(line_number, column_number),
+        condition_operand_(condition_operand),
+        result_expression_(result_expression) {
+  }
+
+  std::string getName() const override {
+    return "SimpleWhenClause";
+  }
+
+  /**
+   * @return The condition operand.
+   */
+  const ParseExpression* condition_operand() const {
+    return condition_operand_.get();
+  }
+
+  /**
+   * @return The result expression for this condition.
+   */
+  const ParseExpression* result_expression() const {
+    return result_expression_.get();
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<ParseExpression> condition_operand_;
+  std::unique_ptr<ParseExpression> result_expression_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseSimpleWhenClause);
+};
+
+/**
+ * @brief The parsed representation of a WHEN clause in a searched CASE
+ *        expression (WHEN <condition predicate> THEN <result expression>).
+ *
+ */
+class ParseSearchedWhenClause : public ParseTreeNode {
+ public:
+  /**
+   * @brief Constructor. Takes ownership of all pointers.
+   *
+   * @param line_number The line number of "WHEN" in the SQL statement.
+   * @param column_number The column number of "WHEN" in the SQL statement.
+   * @param condition_predicate The condition predicate.
+   * @param result_expression The result expression for this condition.
+   */
+  ParseSearchedWhenClause(int line_number,
+                          int column_number,
+                          ParsePredicate *condition_predicate,
+                          ParseExpression *result_expression)
+      : ParseTreeNode(line_number, column_number),
+        condition_predicate_(condition_predicate),
+        result_expression_(result_expression) {
+  }
+
+  std::string getName() const override {
+    return "SearchedWhenClause";
+  }
+
+  /**
+   * @return The condition predicate.
+   */
+  const ParsePredicate* condition_predicate() const {
+    return condition_predicate_.get();
+  }
+
+  /**
+   * @return The result expression.
+   */
+  const ParseExpression* result_expression() const {
+    return result_expression_.get();
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<ParsePredicate> condition_predicate_;
+  std::unique_ptr<ParseExpression> result_expression_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseSearchedWhenClause);
+};
+
+/**
+ * @brief The parsed representation of a simple CASE expression:
+ *           CASE <case operand>
+ *               WHEN <condition_operand> THEN <result_expression>
+ *               [...n]
+ *               [ELSE <else_result_expression>]
+ *           END
+ *        It returns the <result_expression> of the first <case operand> = <when_operand>
+ *        that evaluates to true; if none is found and <else_result_expression> exists,
+ *        returns <else_result_expression>; otherwise, returns NULL.
+ **/
+class ParseSimpleCaseExpression : public ParseExpression {
+ public:
+  /**
+   * @brief Constructor. Takes ownership of all pointers.
+   *
+   * @param line_number The line number of "CASE" in the SQL statement.
+   * @param column_number The column number of "CASE" in the SQL statement.
+   * @param case_operand The CASE operand.
+   * @param when_clauses A vector of WHEN clauses, each having a check operand to
+   *                     be compared with the CASE operand and a result expression
+   *                     to be evaluated if the condition is satisfied.
+   * @param else_result_expression Optional ELSE result expression.
+   */
+  ParseSimpleCaseExpression(int line_number,
+                            int column_number,
+                            ParseExpression *case_operand,
+                            PtrVector<ParseSimpleWhenClause> *when_clauses,
+                            ParseExpression *else_result_expression)
+      : ParseExpression(line_number, column_number),
+        case_operand_(case_operand),
+        when_clauses_(when_clauses),
+        else_result_expression_(else_result_expression) {
+  }
+
+  std::string getName() const override {
+    return "SimpleCaseExpression";
+  }
+
+  ExpressionType getExpressionType() const override {
+    return kSimpleCaseExpression;
+  }
+
+  /**
+   * @return The CASE operand.
+   */
+  const ParseExpression* case_operand() const {
+    return case_operand_.get();
+  }
+
+  /**
+   * @return The vector of WHEN clauses.
+   */
+  const PtrVector<ParseSimpleWhenClause>* when_clauses() const {
+    return when_clauses_.get();
+  }
+
+  /**
+   * @return The ELSE result expression. Can be NULL.
+   */
+  const ParseExpression* else_result_expression() const {
+    return else_result_expression_.get();
+  }
+
+  std::string generateName() const override;
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<ParseExpression> case_operand_;
+  std::unique_ptr<PtrVector<ParseSimpleWhenClause>> when_clauses_;
+  std::unique_ptr<ParseExpression> else_result_expression_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseSimpleCaseExpression);
+};
+
+/**
+ * @brief The parsed representation of a searched CASE expression:
+ *           CASE
+ *               WHEN <condition_predicate> THEN <result_expression>
+ *               [...n]
+ *               [ELSE <else_result_expression>]
+ *           END
+ *        It returns the <result_expression> of the first <condition_predicate>
+ *        that evaluates to true; if none is found and <else_result_expression> exists,
+ *        returns <else_result_expression>; otherwise, returns NULL.
+ */
+class ParseSearchedCaseExpression : public ParseExpression {
+ public:
+  /**
+   * @brief Constructor. Takes ownership of all pointers.
+   *
+   * @param line_number The line number of "CASE" in the SQL statement.
+   * @param column_number The column number of "CASE" in the SQL statement.
+   * @param when_clauses A vector of WHEN clauses, each having a predicate
+   *                     and a result expression to be evaluate if
+   *                     the predicate evaluates to true.
+   * @param else_result_expression Optional ELSE result expression.
+   */
+  ParseSearchedCaseExpression(int line_number,
+                              int column_number,
+                              PtrVector<ParseSearchedWhenClause> *when_clauses,
+                              ParseExpression *else_result_expression)
+      : ParseExpression(line_number, column_number),
+        when_clauses_(when_clauses),
+        else_result_expression_(else_result_expression) {
+  }
+
+  std::string getName() const override {
+    return "SearchedCaseExpression";
+  }
+
+  ExpressionType getExpressionType() const override {
+    return kSearchedCaseExpression;
+  }
+
+  /**
+   * @return The vector of WHEN clauses.
+   */
+  const PtrVector<ParseSearchedWhenClause>* when_clauses() const {
+    return when_clauses_.get();
+  }
+
+  /**
+   * @return The ELSE result expression. Can be NULL.
+   */
+  const ParseExpression* else_result_expression() const {
+    return else_result_expression_.get();
+  }
+
+  std::string generateName() const override;
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<PtrVector<ParseSearchedWhenClause>> when_clauses_;
+  std::unique_ptr<ParseExpression> else_result_expression_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseSearchedCaseExpression);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif /* QUICKSTEP_PARSER_PARSE_CASE_EXPRESSIONS_HPP_ */
diff --git a/parser/ParseExpression.hpp b/parser/ParseExpression.hpp
index 8e4efee..e959e72 100644
--- a/parser/ParseExpression.hpp
+++ b/parser/ParseExpression.hpp
@@ -42,6 +42,8 @@
     kExtract,
     kFunctionCall,
     kScalarLiteral,
+    kSearchedCaseExpression,
+    kSimpleCaseExpression,
     kSubqueryExpression,
     kUnaryExpression,
   };
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index 0886926..354db86 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -61,12 +61,14 @@
 class ParsePredicate;
 class ParseSample;
 class ParseScalarLiteral;
+class ParseSearchedWhenClause;
 class ParseSelect;
 class ParseSelectionClause;
 class ParseSelectionItem;
 class ParseSelectionItemScalar;
 class ParseSelectionList;
 class ParseSimpleTableReference;
+class ParseSimpleWhenClause;
 class ParseStringKeyLiteralValues;
 class ParseStatement;
 class ParseStatementCopyFrom;
@@ -175,6 +177,7 @@
   "blockproperties"  return TOKEN_BLOCKPROPERTIES;
   "blocksample"      return TOKEN_BLOCKSAMPLE;
   "bloomfilter"      return TOKEN_BLOOM_FILTER;
+  "case"             return TOKEN_CASE;
   "csbtree"          return TOKEN_CSB_TREE;
   "by"               return TOKEN_BY;
   "char"             return TOKEN_CHARACTER;
@@ -195,6 +198,8 @@
   "distinct"         return TOKEN_DISTINCT;
   "double"           return TOKEN_DOUBLE;
   "drop"             return TOKEN_DROP;
+  "else"             return TOKEN_ELSE;
+  "end"              return TOKEN_END;
   "escape_strings"   return TOKEN_ESCAPE_STRINGS;
   "exists"           return TOKEN_EXISTS;
   "extract"          return TOKEN_EXTRACT;
@@ -245,6 +250,7 @@
   "set"              return TOKEN_SET;
   "smallint"         return TOKEN_SMALLINT;
   "table"            return TOKEN_TABLE;
+  "then"             return TOKEN_THEN;
   "time"             return TOKEN_TIME;
   "timestamp"        return TOKEN_TIMESTAMP;
   "true"             return TOKEN_TRUE;
@@ -254,6 +260,7 @@
   "using"            return TOKEN_USING;
   "values"           return TOKEN_VALUES;
   "varchar"          return TOKEN_VARCHAR;
+  "when"             return TOKEN_WHEN;
   "where"            return TOKEN_WHERE;
   "with"             return TOKEN_WITH;
   "yearmonth"        return TOKEN_YEARMONTH;
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 4adc1c5..56f50b6 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -71,6 +71,7 @@
 #include "parser/ParseAttributeDefinition.hpp"
 #include "parser/ParseBasicExpressions.hpp"
 #include "parser/ParseBlockProperties.hpp"
+#include "parser/ParseCaseExpressions.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseGeneratorTableReference.hpp"
 #include "parser/ParseGroupBy.hpp"
@@ -133,6 +134,12 @@
 
   quickstep::ParseSubqueryExpression *subquery_expression_;
 
+  quickstep::PtrVector<quickstep::ParseSimpleWhenClause> *simple_when_clause_list_;
+  quickstep::ParseSimpleWhenClause *simple_when_clause_;
+
+  quickstep::PtrVector<quickstep::ParseSearchedWhenClause> *searched_when_clause_list_;
+  quickstep::ParseSearchedWhenClause *searched_when_clause_;
+
   quickstep::ParseSelectionClause *selection_;
   quickstep::ParseSelectionItem *selection_item_;
   quickstep::ParseSelectionList *selection_list_;
@@ -235,6 +242,7 @@
 %token TOKEN_BLOOM_FILTER;
 %token TOKEN_CSB_TREE;
 %token TOKEN_BY;
+%token TOKEN_CASE;
 %token TOKEN_CHARACTER;
 %token TOKEN_CHECK;
 %token TOKEN_COLUMN;
@@ -251,6 +259,8 @@
 %token TOKEN_DISTINCT;
 %token TOKEN_DOUBLE;
 %token TOKEN_DROP;
+%token TOKEN_ELSE;
+%token TOKEN_END;
 %token TOKEN_ESCAPE_STRINGS;
 %token TOKEN_EXISTS;
 %token TOKEN_EXTRACT;
@@ -298,6 +308,7 @@
 %token TOKEN_SET;
 %token TOKEN_SMALLINT;
 %token TOKEN_TABLE;
+%token TOKEN_THEN;
 %token TOKEN_TIME;
 %token TOKEN_TIMESTAMP;
 %token TOKEN_TRUE;
@@ -307,6 +318,7 @@
 %token TOKEN_USING;
 %token TOKEN_VALUES;
 %token TOKEN_VARCHAR;
+%token TOKEN_WHEN;
 %token TOKEN_WHERE;
 %token TOKEN_WITH;
 %token TOKEN_YEARMONTH;
@@ -332,6 +344,8 @@
   unary_expression
   multiply_expression
   add_expression
+  case_expression
+  opt_else_clause
   extract_function
 
 %type <attribute_>
@@ -352,6 +366,18 @@
 %type <subquery_expression_>
   subquery_expression
 
+%type <simple_when_clause_list_>
+  simple_when_clause_list
+
+%type <simple_when_clause_>
+  simple_when_clause
+
+%type <searched_when_clause_list_>
+  searched_when_clause_list
+
+%type <searched_when_clause_>
+  searched_when_clause
+
 %type <selection_>
   selection
 
@@ -1470,6 +1496,9 @@
   | extract_function {
     $$ = $1;
   }
+  | case_expression {
+    $$ = $1;
+  }
   | '(' add_expression ')' {
     $$ = $2;
   };
@@ -1495,6 +1524,52 @@
     $$ = new quickstep::ParseExtractFunction(@1.first_line, @1.first_column, $3, $5);
   };
 
+case_expression:
+  TOKEN_CASE add_expression simple_when_clause_list opt_else_clause TOKEN_END {
+    $$ = new quickstep::ParseSimpleCaseExpression(@1.first_line, @1.first_column, $2, $3, $4);
+  }
+  | TOKEN_CASE searched_when_clause_list opt_else_clause TOKEN_END {
+    $$ = new quickstep::ParseSearchedCaseExpression(@1.first_line, @1.first_column, $2, $3);
+  };
+
+simple_when_clause_list:
+  simple_when_clause {
+    $$ = new quickstep::PtrVector<quickstep::ParseSimpleWhenClause>;
+    $$->push_back($1);
+  }
+  | simple_when_clause_list simple_when_clause {
+    $$ = $1;
+    $$->push_back($2);
+  };
+
+simple_when_clause:
+  TOKEN_WHEN add_expression TOKEN_THEN add_expression {
+    $$ = new quickstep::ParseSimpleWhenClause(@1.first_line, @1.first_column, $2, $4);
+  };
+
+searched_when_clause_list:
+  searched_when_clause {
+    $$ = new quickstep::PtrVector<quickstep::ParseSearchedWhenClause>;
+    $$->push_back($1);
+  }
+  | searched_when_clause_list searched_when_clause {
+    $$ = $1;
+    $$->push_back($2);
+  };
+
+searched_when_clause:
+  TOKEN_WHEN or_expression TOKEN_THEN add_expression {
+    $$ = new quickstep::ParseSearchedWhenClause(@1.first_line, @1.first_column, $2, $4);
+  };
+
+opt_else_clause:
+  {
+    $$ = NULL;
+  }
+  | TOKEN_ELSE add_expression {
+    $$ = $2;
+  };
+
 expression_list:
   add_expression {
     $$ = new quickstep::PtrList<quickstep::ParseExpression>();
diff --git a/parser/SqlParserWrapper.cpp b/parser/SqlParserWrapper.cpp
index e590291..c6e6bcc 100644
--- a/parser/SqlParserWrapper.cpp
+++ b/parser/SqlParserWrapper.cpp
@@ -46,10 +46,12 @@
 class ParsePartitionClause;
 class ParsePredicate;
 class ParseSample;
+class ParseSearchedWhenClause;
 class ParseScalarLiteral;
 class ParseSelection;
 class ParseSelectionItem;
 class ParseSelectionList;
+class ParseSimpleWhenClause;
 class ParseTableReference;
 class Type;
 class UnaryOperation;
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index 5a3d58f..a6173d7 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 136
-#define YY_END_OF_BUFFER 137
+#define YY_NUM_RULES 141
+#define YY_END_OF_BUFFER 142
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -390,64 +390,65 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[508] =
+static yyconst flex_int16_t yy_accept[520] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  137,    2,    2,  135,  135,  134,  133,  135,
-      112,  108,  111,  108,  108,  131,  104,  101,  105,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  130,  130,  109,    4,    5,    5,    3,  127,  127,
-      124,  128,  128,  122,  129,  129,  126,    1,  134,  102,
-      132,  131,  131,  131,    0,  106,  103,  107,  130,  130,
-      130,  130,   10,  130,  130,  130,   20,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  110,  130,  130,  130,
+        0,    0,  142,    2,    2,  140,  140,  139,  138,  140,
+      117,  113,  116,  113,  113,  136,  109,  106,  110,  135,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,  114,    4,    5,    5,    3,  132,  132,
+      129,  133,  133,  127,  134,  134,  131,    1,  139,  107,
+      137,  136,  136,  136,    0,  111,  108,  112,  135,  135,
+      135,  135,   10,  135,  135,  135,   21,  135,  135,  135,
+      135,  135,  135,  135,  135,  135,  135,  115,  135,  135,
 
-      130,  130,  130,  130,  130,  130,  130,  130,   58,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,   70,   71,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  130,    4,    5,    3,  127,  123,  128,  121,  121,
-      113,  115,  116,  117,  118,  119,  120,  121,  129,  125,
-      132,  131,    0,  131,    6,    7,  130,    9,   11,  130,
-      130,   15,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,   61,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,   73,   74,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,  135,  135,  135,    4,    5,    3,  132,
+      128,  133,  126,  126,  118,  120,  121,  122,  123,  124,
+      125,  126,  134,  130,  137,  136,    0,  136,    6,    7,
+      135,    9,   11,  135,  135,   15,  135,  135,  135,  135,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,  135,   41,  135,  135,  135,  135,  135,
 
-      130,  130,  130,   54,  130,   60,  130,  130,  130,  130,
-      130,   66,  130,   69,  130,  130,  130,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,   86,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,  113,  115,  114,  130,  130,  130,  130,  130,  130,
-       21,  130,  130,  130,   26,  130,  130,   28,  130,  130,
-      130,  130,   34,  130,  130,   38,  130,  130,  130,  130,
-      130,  130,  130,   46,   47,  130,   49,  130,  130,  130,
-      130,  130,   57,   59,   61,   62,   63,  130,   65,   67,
-      130,  130,  130,  130,  130,   78,  130,   80,  130,  130,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+       57,  135,   63,  135,  135,  135,  135,  135,   69,  135,
+       72,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,  135,   89,  135,  135,  135,  135,  135,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  118,
+      120,  119,  135,  135,  135,  135,  135,  135,   19,   22,
+      135,  135,  135,   27,  135,  135,   29,  135,  135,  135,
+      135,   35,  135,  135,   39,   40,  135,  135,  135,  135,
+      135,  135,  135,   49,   50,  135,   52,  135,  135,  135,
+      135,  135,   60,   62,   64,   65,   66,  135,   68,   70,
 
-      130,  130,  130,  130,  130,   89,   91,  130,  130,  130,
-      130,  130,  130,  130,   99,  130,  113,  114,    8,  130,
-      130,  130,  130,  130,  130,   23,  130,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
-      130,   42,   43,   44,  130,   48,  130,   51,   52,  130,
-      130,  130,   64,   68,   72,   73,  130,  130,  130,   79,
-      130,  130,   83,  130,  130,  130,   88,  130,  130,  130,
-      130,   95,  130,  130,   98,  130,  130,  130,   14,  130,
-      130,  130,  130,   24,  130,   27,  130,  130,  130,  130,
-       32,  130,  130,  130,   37,  130,   40,  130,  130,   50,
+      135,  135,  135,  135,  135,   81,  135,   83,  135,  135,
+      135,  135,  135,  135,  135,   92,   93,   95,  135,  135,
+      135,  135,  135,  135,  102,  135,  104,  135,  118,  119,
+        8,  135,  135,  135,  135,  135,  135,   24,  135,  135,
+      135,  135,  135,  135,  135,  135,  135,  135,  135,  135,
+      135,  135,  135,   45,   46,   47,  135,   51,  135,   54,
+       55,  135,  135,  135,   67,   71,   75,   76,  135,  135,
+      135,   82,  135,  135,   86,  135,  135,  135,   91,  135,
+      135,  135,  135,   99,  135,  135,  103,  135,  135,  135,
+       14,  135,  135,  135,  135,   25,  135,   28,  135,  135,
 
-       53,  130,  130,  130,  130,  130,  130,   82,  130,   85,
-      130,  130,  130,   93,   94,   96,  130,  130,  130,   13,
-      130,  130,  130,  130,  130,   19,  130,   30,   31,  130,
-      130,  130,  130,   41,   45,   55,  130,  130,   76,   77,
-      130,  130,  130,  130,  130,   97,  130,  130,  130,  130,
-      130,  130,  130,   29,  130,  130,   36,  130,   56,  130,
-      130,  130,   87,  130,  130,  130,   12,  130,  130,  130,
-       22,  130,   33,  130,  130,   74,  130,  130,   90,  130,
-      100,  130,  130,  130,   25,   35,  130,   75,   81,  130,
-      130,  130,   17,   18,  130,  130,   92,  130,  130,  130,
+      135,  135,   33,  135,  135,  135,   38,  135,   43,  135,
+      135,   53,   56,  135,  135,  135,  135,  135,  135,   85,
+      135,   88,  135,  135,  135,   97,   98,  100,  135,  135,
+      135,   13,  135,  135,  135,  135,  135,   20,  135,   31,
+       32,  135,  135,  135,  135,   44,   48,   58,  135,  135,
+       79,   80,  135,  135,  135,  135,  135,  101,  135,  135,
+      135,  135,  135,  135,  135,   30,  135,  135,   37,  135,
+       59,  135,  135,  135,   90,  135,  135,  135,   12,  135,
+      135,  135,   23,  135,   34,  135,  135,   77,  135,  135,
+       94,  135,  105,  135,  135,  135,   26,   36,  135,   78,
 
-      130,  130,   84,  130,   39,   16,    0
+       84,  135,  135,  135,   17,   18,  135,  135,   96,  135,
+      135,  135,  135,  135,   87,  135,   42,   16,    0
     } ;
 
 static yyconst YY_CHAR yy_ec[256] =
@@ -494,137 +495,139 @@
         8
     } ;
 
-static yyconst flex_uint16_t yy_base[523] =
+static yyconst flex_uint16_t yy_base[535] =
     {   0,
         0,    1,   46,    0,  117,  163,    2,    3,  128,  132,
-        6,   10,  198, 1141, 1141,    0, 1141,   13, 1141,  181,
-     1141, 1141, 1141,  183,    6,  130,    4, 1141,  172,  124,
-      161,  160,  204,  150,  251,   92,  110,  163,   98,  124,
-      209,    0,  173,  214,  182,  109,  253,  231,  258,  261,
-      195,  218,  196, 1141,  152,    4,   19,    0,    0,    0,
-      143,    0,    0,  323,    0,    0,  144,    0,   22, 1141,
-        0,  289,  316,  319,   18, 1141, 1141, 1141,    0,  217,
-      258,  241,  268,  273,  296,  287,    0,  325,  322,  312,
-      318,  307,  345,  314,  318,  325, 1141,  339,  364,  340,
+        6,   10,  260, 1157, 1157,    0, 1157,   13, 1157,  241,
+     1157, 1157, 1157,  239,    6,  130,    4, 1157,  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, 1157,  184,    4,   19,    0,    0,    0,
+      146,    0,    0,  340,    0,    0,  145,    0,   22, 1157,
+        0,  249,  284,  334,   18, 1157, 1157, 1157,    0,  232,
+      262,  234,  270,  267,  285,  278,    0,  276,  307,  331,
+      291,  307,  299,  347,  313,  312,  325, 1157,  325,  345,
 
-      342,  346,  356,  360,  366,  364,  363,  396,    0,  374,
-      363,  372,  386,  383,  381,  377,  386,  393,    0,  397,
-      385,  388,  391,  409,  410,  408,  430,  425,  410,  429,
-      439,  440,  430,  425,  434,  443,  449,  445,  445,  450,
-      436,  457,  142,   29,    0,    0, 1141,    0, 1141, 1141,
-       22,   24, 1141, 1141, 1141, 1141, 1141,    0,    0, 1141,
-        0,  472,   26,   28,    0,    0,  454,    0,  459,  450,
-      465,    0,  486,  458,  477,  469,  472,  469,  494,  476,
-      492,  489,  498,  495,  504,  488,  508,  495,  511,  494,
-      496,  496,  497,  516,  516,  509,  519,  511,  526,  526,
+      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,
+     1157,    0, 1157, 1157,   22,   24, 1157, 1157, 1157, 1157,
+     1157,    0,    0, 1157,    0,  474,   26,   28,    0,    0,
+      467,    0,  468,  451,  466,    0,  478,  471,  462,  495,
+      478,  487,  482,  510,  492,  508,  505,  514,  511,  514,
+      498,  517,  505,  518,    0,  523,  506,  508,  510,  511,
 
-      533,  542,  543,  544,  538,    0,  533,  534,  550,  547,
-      550,    0,  546,    0,  557,  560,  546,  565,  556,  550,
-      564,  560,  568,  569,  567,   93,  574,    0,  568,  577,
-      585,  587,  581,  579,  604,  592,  586,  607,  593,  604,
-      595,   30,  125,    0,  596,  601,  611,  603,  609,  610,
-      623,  615,  614,  608,    0,  609,  612,  611,  619,  612,
-      617,  625,  642,  639,  638,    0,  635,  634,  662,  659,
-      645,  648,  660,    0,    0,  654,    0,  657,  648,  655,
-      656,  668,    0,    0,    0,    0,    0,  658,    0,  662,
-      664,  666,  676,  682,  687,    0,  684,    0,  672,  667,
+      530,  527,  520,  522,  516,  530,  530,  546,  551,  552,
+      559,  551,    0,  549,  550,  566,  563,  566,    0,  563,
+        0,  571,  572,  558,  576,  568,  562,  576,  572,  582,
+      583,  581,   98,  585,    0,  579,  580,  581,  591,  592,
+      597,  597,  614,  608,  602,  624,  614,  621,  612,   30,
+      125,    0,  613,  619,  629,  621,  625,  624,    0,  638,
+      629,  628,  622,    0,  625,  628,  627,  635,  628,  630,
+      640,  649,  646,  655,    0,    0,  656,  653,  679,  676,
+      665,  666,  678,    0,    0,  672,    0,  675,  666,  673,
+      674,  686,    0,    0,    0,    0,    0,  674,    0,  676,
 
-      675,  692,  702,  694,  703,  690,    0,  707,  700,  702,
-      716,  721,  719,  723,    0,  716,  136, 1141,    0,  726,
-      726,  712,  717,  733,  737,    0,  728,  725,  739,  740,
-      737,  746,  736,  744,  744,  740,  749,  759,  761,  748,
-      767,    0,    0,    0,  772,    0,  773,    0,    0,  761,
-      779,  763,    0,    0,    0,    0,  766,  773,  770,    0,
-      784,  774,    0,  786,  774,  788,    0,  778,  781,  796,
-      797,    0,  784,  803,    0,  790,  797,  793,    0,  793,
-      811,  812,  802,    0,  823,    0,  820,  815,  825,  818,
-        0,  819,  838,  840,    0,   83,    0,  824,  831,    0,
+      679,  680,  690,  695,  702,    0,  700,    0,  688,  683,
+      688,  707,  709,  701,  720,    0,  711,    0,  726,  717,
+      719,  736,  739,  737,    0,  741,    0,  734,  136, 1157,
+        0,  744,  744,  730,  736,  745,  750,    0,  742,  739,
+      753,  756,  753,  762,  752,  760,  757,  755,  756,  766,
+      778,  769,  786,    0,    0,    0,  789,    0,  790,    0,
+        0,  781,  797,  781,    0,    0,    0,    0,  784,  791,
+      788,    0,  802,  792,    0,  804,  790,  802,    0,  793,
+      795,  810,  811,    0,  800,  819,    0,  806,  813,  809,
+        0,  806,  826,  819,  809,    0,  840,    0,  841,  834,
 
-        0,  828,  846,  839,  829,  827,  841,    0,  844,    0,
-      844,  858,  859,    0,    0,    0,  843,  848,  849,    0,
-      849,  852,  857,  865,  870,    0,  875,    0,    0,  877,
-      874,  866,  876,    0,    0,    0,  884,  882,    0,    0,
-      897,  892,  882,  890,  891,    0,  885,  899,  891,  894,
-      893,  896,  902,    0,  899,  904,    0,  899,    0,  906,
-      916,  909,    0,  907,  911,  920,    0,  932,  926,  935,
-        0,  921,    0,  937,  935,  935,  936,  949,    0,  947,
-        0,  942,  956,  944,    0,    0,  954,    0,    0,  944,
-      960,  948,    0,    0,  957,  967,    0,  965,  968,  958,
+      842,  835,    0,  839,  856,  858,    0,   93,    0,  842,
+      849,    0,    0,  846,  864,  857,  847,  843,  855,    0,
+      859,    0,  858,  872,  873,    0,    0,    0,  859,  864,
+      865,    0,  865,  868,  870,  880,  877,    0,  882,    0,
+        0,  894,  895,  885,  893,    0,    0,    0,  901,  902,
+        0,    0,  915,  910,  900,  908,  909,    0,  903,  917,
+      909,  910,  907,  911,  916,    0,  913,  918,    0,  915,
+        0,  922,  932,  925,    0,  923,  924,  935,    0,  939,
+      933,  952,    0,  942,    0,  956,  952,  952,  956,  967,
+        0,  965,    0,  960,  974,  962,    0,    0,  972,    0,
 
-      972,  959,    0,  960,    0,    0, 1141, 1025, 1035, 1045,
-     1055, 1065, 1069, 1072, 1078, 1086, 1096, 1106, 1116, 1126,
-     1131, 1133
+        0,  962,  978,  964,    0,    0,  971,  982,    0,  979,
+      982,  972,  988,  975,    0,  976,    0,    0, 1157, 1041,
+     1051, 1061, 1071, 1081, 1085, 1088, 1094, 1102, 1112, 1122,
+     1132, 1142, 1147, 1149
     } ;
 
-static yyconst flex_int16_t yy_def[523] =
+static yyconst flex_int16_t yy_def[535] =
     {   0,
-      508,  508,  507,    3,  509,  509,  510,  510,  511,  511,
-      512,  512,  507,  507,  507,  513,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  507,  507,  507,  507,  515,  516,  516,
-      507,  517,  517,  518,  519,  519,  507,  513,  507,  507,
-      520,  507,  507,  507,  507,  507,  507,  507,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  507,  514,  514,  514,
+      520,  520,  519,    3,  521,  521,  522,  522,  523,  523,
+      524,  524,  519,  519,  519,  525,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  526,
+      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+      526,  526,  526,  519,  519,  519,  519,  527,  528,  528,
+      519,  529,  529,  530,  531,  531,  519,  525,  519,  519,
+      532,  519,  519,  519,  519,  519,  519,  519,  526,  526,
+      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+      526,  526,  526,  526,  526,  526,  526,  519,  526,  526,
 
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  507,  507,  515,  516,  507,  517,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  521,  519,  507,
-      520,  507,  507,  507,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
+      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,  519,  519,  527,  528,
+      519,  529,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  533,  531,  519,  532,  519,  519,  519,  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,
 
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  507,  507,  522,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
+      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,  526,  519,
+      519,  534,  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,
 
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  507,  507,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
+      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,  519,  519,
+      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,  526,  526,
+      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
 
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
-      514,  514,  514,  514,  514,  514,  514,  514,  514,  514,
+      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,  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,  526,  526,  526,  526,
 
-      514,  514,  514,  514,  514,  514,    0,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507
+      526,  526,  526,  526,  526,  526,  526,  526,  526,  526,
+      526,  526,  526,  526,  526,  526,  526,  526,    0,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519
     } ;
 
-static yyconst flex_uint16_t yy_nxt[1213] =
+static yyconst flex_uint16_t yy_nxt[1229] =
     {   0,
-      507,  507,   15,   15,   60,   60,  144,  144,   66,   61,
-       61,   67,   66,  507,   69,   67,   69,   72,   72,   76,
-       77,  144,  144,   69,  507,   69,  163,  163,  507,  164,
-      164,  144,  144,  242,  243,  243,  243,  164,  164,  164,
-      164,  317,  243,  507,   16,   16,   17,   18,   19,   18,
+      519,  519,   15,   15,   60,   60,  148,  148,   66,   61,
+       61,   67,   66,  519,   69,   67,   69,   72,   72,   76,
+       77,  148,  148,   69,  519,   69,  167,  167,  519,  168,
+      168,  148,  148,  250,  251,  251,  251,  168,  168,  168,
+      168,  329,  251,  519,   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,
@@ -633,136 +636,137 @@
 
        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,  106,  107,  433,  110,
-       63,   17,   17,   17,   63,   61,  243,  243,  302,   61,
-       73,   74,   74,  143,   80,  111,  125,  243,  243,  160,
-      147,   75,   81,  143,   82,  106,  107,   97,  110,   83,
+       57,   17,   17,   17,   17,   17,  109,  110,  113,  114,
+       63,   17,   17,   17,   63,   61,  251,  251,  445,   61,
+       73,   74,   74,  312,   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,  111,  125,   64,   17,   17,   17,
-       75,   81,   84,   82,   88,   98,   85,   78,   83,   86,
-       99,   89,   71,  108,   90,   91,   70,  507,  109,  122,
+       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,
 
-      507,  507,   87,  123,  116,  507,   17,   17,   17,  507,
-      117,   84,  139,   88,   98,   85,  124,  142,   86,   99,
-       89,   92,  108,   90,   91,   93,  112,  109,  122,   94,
-      113,   87,  123,  116,  114,   95,  118,  165,   96,  117,
-      115,  139,  140,  141,  119,  124,  142,  507,  120,  507,
-       92,  121,  130,  507,   93,  112,  507,  507,   94,  113,
-      131,  168,  507,  114,   95,  118,  165,   96,  100,  115,
-      126,  140,  141,  119,  127,  132,  101,  120,  128,  102,
-      121,  130,  103,  133,  129,  104,  166,  169,  105,  131,
-      168,  136,  134,  137,  167,  135,  138,  100,  507,  126,
+      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,  519,
+       72,   72,  519,  132,   99,  115,  100,  519,  519,  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,
 
-       72,   72,  507,  127,  132,  101,  507,  128,  102,  170,
-       75,  103,  133,  129,  104,  166,  169,  105,  173,  171,
-      136,  134,  137,  167,  135,  138,  150,  162,  162,   73,
-       74,   74,  172,  179,  151,  152,  180,   75,  170,   75,
-       75,  153,  174,  181,  507,  154,  175,  173,  171,  186,
-      176,  507,  177,  155,  178,  187,  188,  156,  189,  157,
-      507,  172,  179,  158,  182,  180,   75,  183,  192,   75,
-      153,  174,  181,  184,  154,  175,  193,  194,  186,  176,
-      185,  177,  155,  178,  187,  188,  156,  189,  157,  190,
-      195,  196,  158,  182,  197,  198,  183,  192,  199,  205,
+      136,  137,  140,  174,  141,   75,  103,  142,  175,  177,
+      138,  178,  184,  139,  104,  519,  519,  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,  519,  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,
 
-      191,  200,  184,  507,  206,  193,  194,  207,  208,  185,
-      209,  211,  210,  212,  213,  214,  201,  215,  190,  195,
-      196,  216,  217,  197,  198,  218,  202,  199,  205,  191,
-      200,  203,  204,  206,  219,  220,  207,  208,  221,  209,
-      211,  210,  212,  213,  214,  201,  215,  222,  225,  226,
-      216,  217,  223,  224,  218,  202,  229,  227,  230,  231,
-      203,  204,  232,  219,  220,  228,  233,  221,  234,  235,
-      236,  239,  240,  237,  241,  245,  222,  225,  226,  238,
-      246,  223,  224,  162,  162,  229,  227,  230,  231,  247,
-      248,  232,  251,   75,  228,  233,  252,  234,  235,  236,
+      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,
+      519,  519,  206,  208,  519,  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,  259,  229,  234,   75,  260,  257,  230,  231,
 
-      239,  240,  237,  241,  245,  249,  253,  254,  238,  246,
-      255,  256,  257,  258,  259,  260,  261,  250,  247,  248,
-      262,  251,   75,  263,  264,  252,  265,  266,  267,  268,
-      269,  270,  271,  272,  249,  253,  254,  273,  274,  255,
-      256,  257,  258,  259,  260,  261,  250,  275,  276,  262,
-      277,  278,  263,  264,  279,  265,  266,  267,  268,  269,
-      270,  271,  272,  280,  281,  282,  273,  274,  284,  285,
-      286,  287,  288,  289,  290,  283,  275,  276,  291,  277,
-      278,  292,  293,  279,  294,  295,  296,  297,  298,  299,
-      300,  301,  280,  281,  282,  303,  304,  284,  285,  286,
+      237,  238,  235,  239,  240,  241,  242,  243,  244,  258,
+      245,  247,  248,  249,  261,  262,  246,  253,  254,  255,
+      256,  259,  263,  264,   75,  260,  257,  265,  266,  267,
+      268,  269,  270,  272,  273,  274,  271,  275,  258,  276,
+      277,  278,  279,  261,  262,  280,  281,  282,  283,  284,
+      285,  263,  264,  286,  287,  288,  265,  266,  267,  268,
+      269,  270,  272,  273,  274,  271,  275,  289,  276,  277,
+      278,  279,  290,  291,  280,  281,  282,  283,  284,  285,
+      292,  294,  286,  287,  288,  295,  296,  297,  298,  299,
+      293,  300,  301,  302,  303,  304,  289,  305,  306,  307,
 
-      287,  288,  289,  290,  283,  305,  306,  291,  307,  308,
-      292,  293,  309,  294,  295,  296,  297,  298,  299,  300,
-      301,  310,  311,  312,  303,  304,  313,  314,  315,  316,
-      319,  320,  321,  322,  305,  306,  323,  307,  308,  324,
-      325,  309,  326,  327,  328,  329,  330,  331,  332,  333,
-      310,  311,  312,  334,  335,  313,  314,  315,  316,  319,
-      320,  321,  322,  336,  337,  323,  338,  339,  324,  325,
-      340,  326,  327,  328,  329,  330,  331,  332,  333,  341,
-      342,  343,  334,  335,  344,  345,  346,  347,  348,  349,
-      350,  351,  336,  337,  353,  338,  339,  354,  355,  340,
+      308,  290,  291,  309,  310,  311,  313,  314,  315,  292,
+      294,  316,  317,  318,  295,  296,  297,  298,  299,  293,
+      300,  301,  302,  303,  304,  319,  305,  306,  307,  308,
+      320,  321,  309,  310,  311,  313,  314,  315,  322,  323,
+      316,  317,  318,  324,  325,  327,  328,  331,  326,  332,
+      333,  334,  335,  336,  319,  337,  338,  339,  340,  320,
+      321,  341,  342,  343,  344,  345,  346,  322,  323,  347,
+      348,  349,  324,  325,  327,  328,  331,  326,  332,  333,
+      334,  335,  336,  350,  337,  338,  339,  340,  351,  352,
+      341,  342,  343,  344,  345,  346,  353,  354,  347,  348,
 
-      356,  357,  352,  358,  359,  360,  361,  362,  341,  342,
-      343,  363,  364,  344,  345,  346,  347,  348,  349,  350,
-      351,  365,  366,  353,  367,  368,  354,  355,  369,  356,
-      357,  352,  358,  359,  360,  361,  362,  370,  371,  372,
-      363,  364,  373,  374,  375,  376,  377,  378,  379,  380,
-      365,  366,  381,  367,  368,  382,  383,  369,  384,  385,
-      386,  387,  388,  389,  390,  391,  370,  371,  372,  392,
-      393,  373,  374,  375,  376,  377,  378,  379,  380,  394,
-      395,  381,  396,  397,  382,  383,  398,  384,  385,  386,
-      387,  388,  389,  390,  391,  399,  400,  401,  392,  393,
+      349,  355,  356,  357,  358,  359,  360,  361,  362,  363,
+      365,  366,  350,  367,  368,  369,  370,  351,  352,  371,
+      364,  372,  373,  374,  375,  353,  354,  376,  377,  378,
+      355,  356,  357,  358,  359,  360,  361,  362,  363,  365,
+      366,  379,  367,  368,  369,  370,  380,  381,  371,  364,
+      372,  373,  374,  375,  382,  383,  376,  377,  378,  384,
+      385,  386,  387,  388,  389,  390,  391,  394,  392,  395,
+      379,  393,  396,  397,  398,  380,  381,  399,  400,  401,
+      402,  403,  404,  382,  383,  405,  406,  407,  384,  385,
+      386,  387,  388,  389,  390,  391,  394,  392,  395,  408,
 
-      402,  403,  404,  405,  406,  407,  408,  409,  394,  395,
-      410,  396,  397,  411,  412,  398,  413,  414,  415,  416,
-      417,  418,  419,  420,  399,  400,  401,  421,  422,  402,
-      403,  404,  405,  406,  407,  408,  409,  423,  424,  410,
-      425,  426,  411,  412,  427,  413,  414,  415,  416,  417,
-      418,  419,  420,  428,  429,  430,  421,  422,  431,  432,
-      434,  435,  436,  437,  438,  439,  423,  424,  440,  425,
-      426,  441,  442,  427,  443,  444,  445,  446,  447,  448,
-      449,  450,  428,  429,  430,  451,  452,  431,  432,  434,
-      435,  436,  437,  438,  439,  453,  454,  440,  455,  456,
+      393,  396,  397,  398,  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,  446,  447,
+      448,  449,  450,  451,  452,  453,  437,  454,  455,  456,
+      457,  438,  439,  458,  459,  460,  461,  462,  463,  440,
 
-      441,  442,  457,  443,  444,  445,  446,  447,  448,  449,
-      450,  458,  459,  460,  451,  452,  461,  462,  463,  464,
-      465,  466,  467,  468,  453,  454,  469,  455,  456,  470,
-      471,  457,  472,  473,  474,  475,  476,  477,  478,  479,
-      458,  459,  460,  480,  481,  461,  462,  463,  464,  465,
-      466,  467,  468,  482,  483,  469,  484,  485,  470,  471,
-      486,  472,  473,  474,  475,  476,  477,  478,  479,  487,
-      488,  489,  480,  481,  490,  491,  492,  493,  494,  495,
-      496,  497,  482,  483,  498,  484,  485,  499,  500,  486,
-      501,  502,  503,  504,  505,  506,  507,  507,  487,  488,
+      441,  464,  465,  466,  442,  443,  444,  446,  447,  448,
+      449,  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,
 
-      489,  507,  507,  490,  491,  492,  493,  494,  495,  496,
-      497,  507,  507,  498,  507,  507,  499,  500,  507,  501,
-      502,  503,  504,  505,  506,   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,   62,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   68,   68,   79,   79,   79,
-      507,   79,  145,  145,  145,  145,  146,  146,  146,  507,
-      146,  146,  146,  146,  146,  146,  148,  148,  148,  507,
+      510,  511,  496,  512,  513,  514,  515,  497,  498,  516,
+      517,  518,  519,  519,  519,  499,  500,  519,  519,  519,
+      501,  502,  503,  504,  505,  506,  507,  508,  509,  510,
+      511,  519,  512,  513,  514,  515,  519,  519,  516,  517,
+      518,   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,
+       62,   65,   65,   65,   65,   65,   65,   65,   65,   65,
+       65,   68,   68,   79,   79,   79,  519,   79,  149,  149,
 
-      148,  148,  148,  148,  507,  148,  149,  149,  149,  149,
-      149,  149,  149,  149,  149,  149,  159,  159,  507,  159,
-      159,  159,  159,  159,  159,  159,  161,  507,  161,  161,
-      161,  161,  161,  161,  161,  161,  244,  244,  318,  318,
-       13,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
+      149,  149,  150,  150,  150,  519,  150,  150,  150,  150,
+      150,  150,  152,  152,  152,  519,  152,  152,  152,  152,
+      519,  152,  153,  153,  153,  153,  153,  153,  153,  153,
+      153,  153,  163,  163,  519,  163,  163,  163,  163,  163,
+      163,  163,  165,  519,  165,  165,  165,  165,  165,  165,
+      165,  165,  252,  252,  330,  330,   13,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
 
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519
     } ;
 
-static yyconst flex_int16_t yy_chk[1213] =
+static yyconst flex_int16_t yy_chk[1229] =
     {   0,
         0,    0,    1,    2,    7,    8,   56,   56,   11,    7,
         8,   11,   12,    0,   18,   12,   18,   25,   25,   27,
        27,   57,   57,   69,    0,   69,   75,   75,    0,   75,
-       75,  144,  144,  151,  151,  152,  152,  163,  163,  164,
-      164,  242,  242,    0,    1,    2,    3,    3,    3,    3,
+       75,  148,  148,  155,  155,  156,  156,  167,  167,  168,
+      168,  250,  250,    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,
@@ -771,131 +775,132 @@
 
         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,  396,   39,
-        9,    5,    5,    5,   10,    9,  243,  243,  226,   10,
-       26,   26,   26,  143,   30,   40,   46,  317,  317,   67,
-       61,   26,   30,   55,   30,   36,   37,   34,   39,   30,
+        5,    5,    5,    5,    5,    5,   36,   37,   39,   40,
+        9,    5,    5,    5,   10,    9,  251,  251,  408,   10,
+       26,   26,   26,  233,   30,   46,   51,  329,  329,  147,
+       67,   26,   30,   61,   30,   36,   37,   39,   40,   30,
         5,    5,    5,    6,    6,    6,    6,    6,    6,    6,
-        6,    6,    9,   30,   40,   46,   10,    6,    6,    6,
-       26,   30,   31,   30,   32,   34,   31,   29,   30,   31,
-       34,   32,   24,   38,   32,   32,   20,   13,   38,   45,
+        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,
 
-        0,    0,   31,   45,   43,    0,    6,    6,    6,    0,
-       43,   31,   51,   32,   34,   31,   45,   53,   31,   34,
-       32,   33,   38,   32,   32,   33,   41,   38,   45,   33,
-       41,   31,   45,   43,   41,   33,   44,   80,   33,   43,
-       41,   51,   52,   52,   44,   45,   53,    0,   44,    0,
-       33,   44,   48,    0,   33,   41,    0,    0,   33,   41,
-       48,   82,    0,   41,   33,   44,   80,   33,   35,   41,
-       47,   52,   52,   44,   47,   49,   35,   44,   47,   35,
-       44,   48,   35,   49,   47,   35,   81,   83,   35,   48,
-       82,   50,   49,   50,   81,   49,   50,   35,    0,   47,
+       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,
 
-       72,   72,    0,   47,   49,   35,    0,   47,   35,   84,
-       72,   35,   49,   47,   35,   81,   83,   35,   86,   85,
-       50,   49,   50,   81,   49,   50,   64,   73,   73,   74,
-       74,   74,   85,   90,   64,   64,   91,   73,   84,   72,
-       74,   64,   88,   92,    0,   64,   88,   86,   85,   94,
-       89,    0,   89,   64,   89,   95,   96,   64,   98,   64,
-        0,   85,   90,   64,   93,   91,   73,   93,  100,   74,
-       64,   88,   92,   93,   64,   88,  101,  102,   94,   89,
-       93,   89,   64,   89,   95,   96,   64,   98,   64,   99,
-      103,  104,   64,   93,  105,  106,   93,  100,  107,  110,
+       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,
 
-       99,  107,   93,    0,  111,  101,  102,  112,  113,   93,
-      114,  115,  114,  116,  117,  118,  108,  120,   99,  103,
-      104,  121,  122,  105,  106,  123,  108,  107,  110,   99,
-      107,  108,  108,  111,  124,  125,  112,  113,  126,  114,
-      115,  114,  116,  117,  118,  108,  120,  127,  128,  129,
-      121,  122,  127,  127,  123,  108,  131,  130,  132,  133,
-      108,  108,  134,  124,  125,  130,  135,  126,  136,  137,
-      138,  140,  141,  139,  142,  167,  127,  128,  129,  139,
-      169,  127,  127,  162,  162,  131,  130,  132,  133,  170,
-      171,  134,  174,  162,  130,  135,  175,  136,  137,  138,
+      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,  178,  130,  133,  166,  179,  177,  130,  130,
 
-      140,  141,  139,  142,  167,  173,  176,  177,  139,  169,
-      178,  179,  180,  181,  182,  183,  184,  173,  170,  171,
-      184,  174,  162,  185,  186,  175,  187,  188,  189,  190,
-      191,  192,  193,  194,  173,  176,  177,  195,  196,  178,
-      179,  180,  181,  182,  183,  184,  173,  197,  198,  184,
-      199,  200,  185,  186,  201,  187,  188,  189,  190,  191,
-      192,  193,  194,  202,  203,  204,  195,  196,  205,  207,
-      208,  209,  210,  211,  213,  204,  197,  198,  215,  199,
-      200,  216,  217,  201,  218,  219,  220,  221,  222,  223,
-      224,  225,  202,  203,  204,  227,  229,  205,  207,  208,
+      135,  136,  133,  137,  138,  139,  140,  141,  142,  177,
+      143,  144,  145,  146,  180,  181,  143,  171,  173,  174,
+      175,  178,  182,  183,  166,  179,  177,  184,  185,  186,
+      187,  188,  189,  190,  191,  192,  189,  193,  177,  194,
+      196,  197,  198,  180,  181,  199,  200,  201,  202,  203,
+      204,  182,  183,  205,  206,  207,  184,  185,  186,  187,
+      188,  189,  190,  191,  192,  189,  193,  208,  194,  196,
+      197,  198,  209,  210,  199,  200,  201,  202,  203,  204,
+      211,  212,  205,  206,  207,  214,  215,  216,  217,  218,
+      211,  220,  222,  223,  224,  225,  208,  226,  227,  228,
 
-      209,  210,  211,  213,  204,  230,  231,  215,  232,  233,
-      216,  217,  234,  218,  219,  220,  221,  222,  223,  224,
-      225,  235,  236,  237,  227,  229,  238,  239,  240,  241,
-      245,  246,  247,  248,  230,  231,  249,  232,  233,  250,
-      251,  234,  252,  253,  254,  256,  257,  258,  259,  260,
-      235,  236,  237,  261,  262,  238,  239,  240,  241,  245,
-      246,  247,  248,  263,  264,  249,  265,  267,  250,  251,
-      268,  252,  253,  254,  256,  257,  258,  259,  260,  269,
-      270,  271,  261,  262,  272,  273,  276,  278,  279,  280,
-      281,  282,  263,  264,  288,  265,  267,  290,  291,  268,
+      229,  209,  210,  230,  231,  232,  234,  236,  237,  211,
+      212,  238,  239,  240,  214,  215,  216,  217,  218,  211,
+      220,  222,  223,  224,  225,  241,  226,  227,  228,  229,
+      242,  243,  230,  231,  232,  234,  236,  237,  244,  245,
+      238,  239,  240,  246,  247,  248,  249,  253,  247,  254,
+      255,  256,  257,  258,  241,  260,  261,  262,  263,  242,
+      243,  265,  266,  267,  268,  269,  270,  244,  245,  271,
+      272,  273,  246,  247,  248,  249,  253,  247,  254,  255,
+      256,  257,  258,  274,  260,  261,  262,  263,  277,  278,
+      265,  266,  267,  268,  269,  270,  279,  280,  271,  272,
 
-      292,  293,  282,  294,  295,  297,  299,  300,  269,  270,
-      271,  301,  302,  272,  273,  276,  278,  279,  280,  281,
-      282,  303,  304,  288,  305,  306,  290,  291,  308,  292,
-      293,  282,  294,  295,  297,  299,  300,  309,  310,  311,
-      301,  302,  312,  313,  314,  316,  320,  321,  322,  323,
-      303,  304,  323,  305,  306,  324,  325,  308,  327,  328,
-      329,  330,  331,  332,  333,  334,  309,  310,  311,  335,
-      336,  312,  313,  314,  316,  320,  321,  322,  323,  337,
-      338,  323,  339,  340,  324,  325,  341,  327,  328,  329,
-      330,  331,  332,  333,  334,  345,  347,  350,  335,  336,
+      273,  281,  282,  283,  286,  288,  289,  290,  291,  292,
+      298,  300,  274,  301,  302,  303,  304,  277,  278,  305,
+      292,  307,  309,  310,  311,  279,  280,  312,  313,  314,
+      281,  282,  283,  286,  288,  289,  290,  291,  292,  298,
+      300,  315,  301,  302,  303,  304,  317,  319,  305,  292,
+      307,  309,  310,  311,  320,  321,  312,  313,  314,  322,
+      323,  324,  326,  328,  332,  333,  334,  336,  335,  337,
+      315,  335,  339,  340,  341,  317,  319,  342,  343,  344,
+      345,  346,  347,  320,  321,  348,  349,  350,  322,  323,
+      324,  326,  328,  332,  333,  334,  336,  335,  337,  351,
 
-      351,  352,  357,  358,  359,  361,  362,  364,  337,  338,
-      365,  339,  340,  366,  368,  341,  369,  370,  371,  373,
-      374,  376,  377,  378,  345,  347,  350,  380,  381,  351,
-      352,  357,  358,  359,  361,  362,  364,  382,  383,  365,
-      385,  387,  366,  368,  388,  369,  370,  371,  373,  374,
-      376,  377,  378,  389,  390,  392,  380,  381,  393,  394,
-      398,  399,  402,  403,  404,  405,  382,  383,  406,  385,
-      387,  407,  409,  388,  411,  412,  413,  417,  418,  419,
-      421,  422,  389,  390,  392,  423,  424,  393,  394,  398,
-      399,  402,  403,  404,  405,  425,  427,  406,  430,  431,
+      335,  339,  340,  341,  352,  353,  342,  343,  344,  345,
+      346,  347,  357,  359,  348,  349,  350,  362,  363,  364,
+      369,  370,  371,  373,  374,  376,  377,  378,  351,  380,
+      381,  382,  383,  352,  353,  385,  386,  388,  389,  390,
+      392,  357,  359,  393,  394,  395,  362,  363,  364,  369,
+      370,  371,  373,  374,  376,  377,  378,  397,  380,  381,
+      382,  383,  399,  400,  385,  386,  388,  389,  390,  392,
+      401,  402,  393,  394,  395,  404,  405,  406,  410,  411,
+      414,  415,  416,  417,  418,  419,  397,  421,  423,  424,
+      425,  399,  400,  429,  430,  431,  433,  434,  435,  401,
 
-      407,  409,  432,  411,  412,  413,  417,  418,  419,  421,
-      422,  433,  437,  438,  423,  424,  441,  442,  443,  444,
-      445,  447,  448,  449,  425,  427,  450,  430,  431,  451,
-      452,  432,  453,  455,  456,  458,  460,  461,  462,  464,
-      433,  437,  438,  465,  466,  441,  442,  443,  444,  445,
-      447,  448,  449,  468,  469,  450,  470,  472,  451,  452,
-      474,  453,  455,  456,  458,  460,  461,  462,  464,  475,
-      476,  477,  465,  466,  478,  480,  482,  483,  484,  487,
-      490,  491,  468,  469,  492,  470,  472,  495,  496,  474,
-      498,  499,  500,  501,  502,  504,    0,    0,  475,  476,
+      402,  436,  437,  439,  404,  405,  406,  410,  411,  414,
+      415,  416,  417,  418,  419,  442,  421,  423,  424,  425,
+      443,  444,  429,  430,  431,  433,  434,  435,  445,  449,
+      436,  437,  439,  450,  453,  454,  455,  456,  457,  459,
+      460,  461,  462,  463,  442,  464,  465,  467,  468,  443,
+      444,  470,  472,  473,  474,  476,  477,  445,  449,  478,
+      480,  481,  450,  453,  454,  455,  456,  457,  459,  460,
+      461,  462,  463,  482,  464,  465,  467,  468,  484,  486,
+      470,  472,  473,  474,  476,  477,  487,  488,  478,  480,
+      481,  489,  490,  492,  494,  495,  496,  499,  502,  503,
 
-      477,    0,    0,  478,  480,  482,  483,  484,  487,  490,
-      491,    0,    0,  492,    0,    0,  495,  496,    0,  498,
-      499,  500,  501,  502,  504,  508,  508,  508,  508,  508,
-      508,  508,  508,  508,  508,  509,  509,  509,  509,  509,
-      509,  509,  509,  509,  509,  510,  510,  510,  510,  510,
-      510,  510,  510,  510,  510,  511,  511,  511,  511,  511,
-      511,  511,  511,  511,  511,  512,  512,  512,  512,  512,
-      512,  512,  512,  512,  512,  513,  513,  514,  514,  514,
-        0,  514,  515,  515,  515,  515,  516,  516,  516,    0,
-      516,  516,  516,  516,  516,  516,  517,  517,  517,    0,
+      504,  507,  482,  508,  510,  511,  512,  484,  486,  513,
+      514,  516,    0,    0,    0,  487,  488,    0,    0,    0,
+      489,  490,  492,  494,  495,  496,  499,  502,  503,  504,
+      507,    0,  508,  510,  511,  512,    0,    0,  513,  514,
+      516,  520,  520,  520,  520,  520,  520,  520,  520,  520,
+      520,  521,  521,  521,  521,  521,  521,  521,  521,  521,
+      521,  522,  522,  522,  522,  522,  522,  522,  522,  522,
+      522,  523,  523,  523,  523,  523,  523,  523,  523,  523,
+      523,  524,  524,  524,  524,  524,  524,  524,  524,  524,
+      524,  525,  525,  526,  526,  526,    0,  526,  527,  527,
 
-      517,  517,  517,  517,    0,  517,  518,  518,  518,  518,
-      518,  518,  518,  518,  518,  518,  519,  519,    0,  519,
-      519,  519,  519,  519,  519,  519,  520,    0,  520,  520,
-      520,  520,  520,  520,  520,  520,  521,  521,  522,  522,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
+      527,  527,  528,  528,  528,    0,  528,  528,  528,  528,
+      528,  528,  529,  529,  529,    0,  529,  529,  529,  529,
+        0,  529,  530,  530,  530,  530,  530,  530,  530,  530,
+      530,  530,  531,  531,    0,  531,  531,  531,  531,  531,
+      531,  531,  532,    0,  532,  532,  532,  532,  532,  532,
+      532,  532,  533,  533,  534,  534,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
 
-      507,  507,  507,  507,  507,  507,  507,  507,  507,  507,
-      507,  507
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,
+      519,  519,  519,  519,  519,  519,  519,  519
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[137] =
+static yyconst flex_int32_t yy_rule_can_match_eol[142] =
     {   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, 
@@ -903,7 +908,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, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 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.
@@ -969,12 +975,14 @@
 class ParsePredicate;
 class ParseSample;
 class ParseScalarLiteral;
+class ParseSearchedWhenClause;
 class ParseSelect;
 class ParseSelectionClause;
 class ParseSelectionItem;
 class ParseSelectionItemScalar;
 class ParseSelectionList;
 class ParseSimpleTableReference;
+class ParseSimpleWhenClause;
 class ParseStringKeyLiteralValues;
 class ParseStatement;
 class ParseStatementCopyFrom;
@@ -1017,7 +1025,7 @@
 
 
 
-#line 1021 "SqlLexer_gen.cpp"
+#line 1029 "SqlLexer_gen.cpp"
 
 #define INITIAL 0
 #define CONDITION_SQL 1
@@ -1305,10 +1313,10 @@
 		}
 
 	{
-#line 125 "../SqlLexer.lpp"
+#line 127 "../SqlLexer.lpp"
 
 
-#line 1312 "SqlLexer_gen.cpp"
+#line 1320 "SqlLexer_gen.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1335,13 +1343,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 >= 508 )
+				if ( yy_current_state >= 520 )
 					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 != 507 );
+		while ( yy_current_state != 519 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1375,7 +1383,7 @@
 
 case 1:
 YY_RULE_SETUP
-#line 128 "../SqlLexer.lpp"
+#line 130 "../SqlLexer.lpp"
 {
     /* A forward slash character represents a system command. */
     BEGIN(CONDITION_COMMAND);
@@ -1387,7 +1395,7 @@
 case 2:
 /* rule 2 can match eol */
 YY_RULE_SETUP
-#line 136 "../SqlLexer.lpp"
+#line 138 "../SqlLexer.lpp"
 {
     /* This is a SQL command. Place the char back and process normally. */
     yyless(0);
@@ -1399,7 +1407,7 @@
 
 case 3:
 YY_RULE_SETUP
-#line 145 "../SqlLexer.lpp"
+#line 147 "../SqlLexer.lpp"
 {
     /* This is a command argument. */
     yylval->string_value_ = new quickstep::ParseString(
@@ -1409,7 +1417,7 @@
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 152 "../SqlLexer.lpp"
+#line 154 "../SqlLexer.lpp"
 {
     /* Ignore whitespace. */
   }
@@ -1417,7 +1425,7 @@
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 156 "../SqlLexer.lpp"
+#line 158 "../SqlLexer.lpp"
 {
     /* Newline reverts the lexer to the initial state. */
     yycolumn = 0;
@@ -1429,547 +1437,572 @@
 
 case 6:
 YY_RULE_SETUP
-#line 165 "../SqlLexer.lpp"
+#line 167 "../SqlLexer.lpp"
 return TOKEN_ADD;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 166 "../SqlLexer.lpp"
+#line 168 "../SqlLexer.lpp"
 return TOKEN_ALL;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 167 "../SqlLexer.lpp"
+#line 169 "../SqlLexer.lpp"
 return TOKEN_ALTER;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 168 "../SqlLexer.lpp"
+#line 170 "../SqlLexer.lpp"
 return TOKEN_AND;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 169 "../SqlLexer.lpp"
+#line 171 "../SqlLexer.lpp"
 return TOKEN_AS;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 170 "../SqlLexer.lpp"
+#line 172 "../SqlLexer.lpp"
 return TOKEN_ASC;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 171 "../SqlLexer.lpp"
+#line 173 "../SqlLexer.lpp"
 return TOKEN_ASC;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 172 "../SqlLexer.lpp"
+#line 174 "../SqlLexer.lpp"
 return TOKEN_BETWEEN;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 173 "../SqlLexer.lpp"
+#line 175 "../SqlLexer.lpp"
 return TOKEN_BIGINT;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 174 "../SqlLexer.lpp"
+#line 176 "../SqlLexer.lpp"
 return TOKEN_BIT;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 175 "../SqlLexer.lpp"
+#line 177 "../SqlLexer.lpp"
 return TOKEN_BLOCKPROPERTIES;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 176 "../SqlLexer.lpp"
+#line 178 "../SqlLexer.lpp"
 return TOKEN_BLOCKSAMPLE;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 177 "../SqlLexer.lpp"
+#line 179 "../SqlLexer.lpp"
 return TOKEN_BLOOM_FILTER;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 178 "../SqlLexer.lpp"
-return TOKEN_CSB_TREE;
+#line 180 "../SqlLexer.lpp"
+return TOKEN_CASE;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 179 "../SqlLexer.lpp"
-return TOKEN_BY;
+#line 181 "../SqlLexer.lpp"
+return TOKEN_CSB_TREE;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 180 "../SqlLexer.lpp"
-return TOKEN_CHARACTER;
+#line 182 "../SqlLexer.lpp"
+return TOKEN_BY;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 181 "../SqlLexer.lpp"
+#line 183 "../SqlLexer.lpp"
 return TOKEN_CHARACTER;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 182 "../SqlLexer.lpp"
-return TOKEN_CHECK;
+#line 184 "../SqlLexer.lpp"
+return TOKEN_CHARACTER;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 183 "../SqlLexer.lpp"
-return TOKEN_COLUMN;
+#line 185 "../SqlLexer.lpp"
+return TOKEN_CHECK;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 184 "../SqlLexer.lpp"
-return TOKEN_CONSTRAINT;
+#line 186 "../SqlLexer.lpp"
+return TOKEN_COLUMN;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 185 "../SqlLexer.lpp"
-return TOKEN_COPY;
+#line 187 "../SqlLexer.lpp"
+return TOKEN_CONSTRAINT;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 186 "../SqlLexer.lpp"
-return TOKEN_CREATE;
+#line 188 "../SqlLexer.lpp"
+return TOKEN_COPY;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 187 "../SqlLexer.lpp"
-return TOKEN_DATE;
+#line 189 "../SqlLexer.lpp"
+return TOKEN_CREATE;
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 188 "../SqlLexer.lpp"
-return TOKEN_DATETIME;
+#line 190 "../SqlLexer.lpp"
+return TOKEN_DATE;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 189 "../SqlLexer.lpp"
-return TOKEN_DECIMAL;
+#line 191 "../SqlLexer.lpp"
+return TOKEN_DATETIME;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 190 "../SqlLexer.lpp"
-return TOKEN_DEFAULT;
+#line 192 "../SqlLexer.lpp"
+return TOKEN_DECIMAL;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 191 "../SqlLexer.lpp"
-return TOKEN_DELETE;
+#line 193 "../SqlLexer.lpp"
+return TOKEN_DEFAULT;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 192 "../SqlLexer.lpp"
-return TOKEN_DELIMITER;
+#line 194 "../SqlLexer.lpp"
+return TOKEN_DELETE;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 193 "../SqlLexer.lpp"
-return TOKEN_DESC;
+#line 195 "../SqlLexer.lpp"
+return TOKEN_DELIMITER;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 194 "../SqlLexer.lpp"
+#line 196 "../SqlLexer.lpp"
 return TOKEN_DESC;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 195 "../SqlLexer.lpp"
-return TOKEN_DISTINCT;
+#line 197 "../SqlLexer.lpp"
+return TOKEN_DESC;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 196 "../SqlLexer.lpp"
-return TOKEN_DOUBLE;
+#line 198 "../SqlLexer.lpp"
+return TOKEN_DISTINCT;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 197 "../SqlLexer.lpp"
-return TOKEN_DROP;
+#line 199 "../SqlLexer.lpp"
+return TOKEN_DOUBLE;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 198 "../SqlLexer.lpp"
-return TOKEN_ESCAPE_STRINGS;
+#line 200 "../SqlLexer.lpp"
+return TOKEN_DROP;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 199 "../SqlLexer.lpp"
-return TOKEN_EXISTS;
+#line 201 "../SqlLexer.lpp"
+return TOKEN_ELSE;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 200 "../SqlLexer.lpp"
-return TOKEN_EXTRACT;
+#line 202 "../SqlLexer.lpp"
+return TOKEN_END;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 201 "../SqlLexer.lpp"
-return TOKEN_FALSE;
+#line 203 "../SqlLexer.lpp"
+return TOKEN_ESCAPE_STRINGS;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 202 "../SqlLexer.lpp"
-return TOKEN_FIRST;
+#line 204 "../SqlLexer.lpp"
+return TOKEN_EXISTS;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 203 "../SqlLexer.lpp"
-return TOKEN_FLOAT;
+#line 205 "../SqlLexer.lpp"
+return TOKEN_EXTRACT;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 204 "../SqlLexer.lpp"
-return TOKEN_FOREIGN;
+#line 206 "../SqlLexer.lpp"
+return TOKEN_FALSE;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 205 "../SqlLexer.lpp"
-return TOKEN_FROM;
+#line 207 "../SqlLexer.lpp"
+return TOKEN_FIRST;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 206 "../SqlLexer.lpp"
-return TOKEN_FULL;
+#line 208 "../SqlLexer.lpp"
+return TOKEN_FLOAT;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 207 "../SqlLexer.lpp"
-return TOKEN_GROUP;
+#line 209 "../SqlLexer.lpp"
+return TOKEN_FOREIGN;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 208 "../SqlLexer.lpp"
-return TOKEN_HASH;
+#line 210 "../SqlLexer.lpp"
+return TOKEN_FROM;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 209 "../SqlLexer.lpp"
-return TOKEN_HAVING;
+#line 211 "../SqlLexer.lpp"
+return TOKEN_FULL;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 210 "../SqlLexer.lpp"
-return TOKEN_INDEX;
+#line 212 "../SqlLexer.lpp"
+return TOKEN_GROUP;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 211 "../SqlLexer.lpp"
-return TOKEN_INNER;
+#line 213 "../SqlLexer.lpp"
+return TOKEN_HASH;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 212 "../SqlLexer.lpp"
-return TOKEN_INSERT;
+#line 214 "../SqlLexer.lpp"
+return TOKEN_HAVING;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 213 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+#line 215 "../SqlLexer.lpp"
+return TOKEN_INDEX;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 214 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+#line 216 "../SqlLexer.lpp"
+return TOKEN_INNER;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 215 "../SqlLexer.lpp"
-return TOKEN_INTERVAL;
+#line 217 "../SqlLexer.lpp"
+return TOKEN_INSERT;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 216 "../SqlLexer.lpp"
-return TOKEN_INTO;
+#line 218 "../SqlLexer.lpp"
+return TOKEN_INTEGER;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 217 "../SqlLexer.lpp"
-return TOKEN_IS;
+#line 219 "../SqlLexer.lpp"
+return TOKEN_INTEGER;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 218 "../SqlLexer.lpp"
-return TOKEN_JOIN;
+#line 220 "../SqlLexer.lpp"
+return TOKEN_INTERVAL;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 219 "../SqlLexer.lpp"
-return TOKEN_KEY;
+#line 221 "../SqlLexer.lpp"
+return TOKEN_INTO;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 220 "../SqlLexer.lpp"
-return TOKEN_LAST;
+#line 222 "../SqlLexer.lpp"
+return TOKEN_IS;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 221 "../SqlLexer.lpp"
-return TOKEN_LEFT;
+#line 223 "../SqlLexer.lpp"
+return TOKEN_JOIN;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 222 "../SqlLexer.lpp"
-return TOKEN_LIKE;
+#line 224 "../SqlLexer.lpp"
+return TOKEN_KEY;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 223 "../SqlLexer.lpp"
-return TOKEN_LIMIT;
+#line 225 "../SqlLexer.lpp"
+return TOKEN_LAST;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 224 "../SqlLexer.lpp"
-return TOKEN_LONG;
+#line 226 "../SqlLexer.lpp"
+return TOKEN_LEFT;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 225 "../SqlLexer.lpp"
-return TOKEN_NOT;
+#line 227 "../SqlLexer.lpp"
+return TOKEN_LIKE;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 226 "../SqlLexer.lpp"
-return TOKEN_NULL;
+#line 228 "../SqlLexer.lpp"
+return TOKEN_LIMIT;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 227 "../SqlLexer.lpp"
-return TOKEN_NULLS;
+#line 229 "../SqlLexer.lpp"
+return TOKEN_LONG;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 228 "../SqlLexer.lpp"
-return TOKEN_OFF;
+#line 230 "../SqlLexer.lpp"
+return TOKEN_NOT;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 229 "../SqlLexer.lpp"
-return TOKEN_ON;
+#line 231 "../SqlLexer.lpp"
+return TOKEN_NULL;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 230 "../SqlLexer.lpp"
-return TOKEN_OR;
+#line 232 "../SqlLexer.lpp"
+return TOKEN_NULLS;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 231 "../SqlLexer.lpp"
-return TOKEN_ORDER;
+#line 233 "../SqlLexer.lpp"
+return TOKEN_OFF;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 232 "../SqlLexer.lpp"
-return TOKEN_OUTER;
+#line 234 "../SqlLexer.lpp"
+return TOKEN_ON;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 233 "../SqlLexer.lpp"
-return TOKEN_PARTITION;
+#line 235 "../SqlLexer.lpp"
+return TOKEN_OR;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 234 "../SqlLexer.lpp"
-return TOKEN_PARTITIONS;
+#line 236 "../SqlLexer.lpp"
+return TOKEN_ORDER;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 235 "../SqlLexer.lpp"
-return TOKEN_PERCENT;
+#line 237 "../SqlLexer.lpp"
+return TOKEN_OUTER;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 236 "../SqlLexer.lpp"
-return TOKEN_PRIMARY;
+#line 238 "../SqlLexer.lpp"
+return TOKEN_PARTITION;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 237 "../SqlLexer.lpp"
-return TOKEN_QUIT;
+#line 239 "../SqlLexer.lpp"
+return TOKEN_PARTITIONS;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 238 "../SqlLexer.lpp"
-return TOKEN_RANGE;
+#line 240 "../SqlLexer.lpp"
+return TOKEN_PERCENT;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 239 "../SqlLexer.lpp"
-return TOKEN_REAL;
+#line 241 "../SqlLexer.lpp"
+return TOKEN_PRIMARY;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 240 "../SqlLexer.lpp"
-return TOKEN_REFERENCES;
+#line 242 "../SqlLexer.lpp"
+return TOKEN_QUIT;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 241 "../SqlLexer.lpp"
-return TOKEN_REGEXP;
+#line 243 "../SqlLexer.lpp"
+return TOKEN_RANGE;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 242 "../SqlLexer.lpp"
-return TOKEN_RIGHT;
+#line 244 "../SqlLexer.lpp"
+return TOKEN_REAL;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 243 "../SqlLexer.lpp"
-return TOKEN_ROW_DELIMITER;
+#line 245 "../SqlLexer.lpp"
+return TOKEN_REFERENCES;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 244 "../SqlLexer.lpp"
-return TOKEN_SELECT;
+#line 246 "../SqlLexer.lpp"
+return TOKEN_REGEXP;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 245 "../SqlLexer.lpp"
-return TOKEN_SET;
+#line 247 "../SqlLexer.lpp"
+return TOKEN_RIGHT;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 246 "../SqlLexer.lpp"
-return TOKEN_SMALLINT;
+#line 248 "../SqlLexer.lpp"
+return TOKEN_ROW_DELIMITER;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 247 "../SqlLexer.lpp"
-return TOKEN_TABLE;
+#line 249 "../SqlLexer.lpp"
+return TOKEN_SELECT;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 248 "../SqlLexer.lpp"
-return TOKEN_TIME;
+#line 250 "../SqlLexer.lpp"
+return TOKEN_SET;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 249 "../SqlLexer.lpp"
-return TOKEN_TIMESTAMP;
+#line 251 "../SqlLexer.lpp"
+return TOKEN_SMALLINT;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 250 "../SqlLexer.lpp"
-return TOKEN_TRUE;
+#line 252 "../SqlLexer.lpp"
+return TOKEN_TABLE;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 251 "../SqlLexer.lpp"
-return TOKEN_TUPLESAMPLE;
+#line 253 "../SqlLexer.lpp"
+return TOKEN_THEN;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 252 "../SqlLexer.lpp"
-return TOKEN_UNIQUE;
+#line 254 "../SqlLexer.lpp"
+return TOKEN_TIME;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 253 "../SqlLexer.lpp"
-return TOKEN_UPDATE;
+#line 255 "../SqlLexer.lpp"
+return TOKEN_TIMESTAMP;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 254 "../SqlLexer.lpp"
-return TOKEN_USING;
+#line 256 "../SqlLexer.lpp"
+return TOKEN_TRUE;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 255 "../SqlLexer.lpp"
-return TOKEN_VALUES;
+#line 257 "../SqlLexer.lpp"
+return TOKEN_TUPLESAMPLE;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 256 "../SqlLexer.lpp"
-return TOKEN_VARCHAR;
+#line 258 "../SqlLexer.lpp"
+return TOKEN_UNIQUE;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 257 "../SqlLexer.lpp"
-return TOKEN_WHERE;
+#line 259 "../SqlLexer.lpp"
+return TOKEN_UPDATE;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 258 "../SqlLexer.lpp"
-return TOKEN_WITH;
+#line 260 "../SqlLexer.lpp"
+return TOKEN_USING;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 259 "../SqlLexer.lpp"
-return TOKEN_YEARMONTH;
+#line 261 "../SqlLexer.lpp"
+return TOKEN_VALUES;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 261 "../SqlLexer.lpp"
-return TOKEN_EQ;
+#line 262 "../SqlLexer.lpp"
+return TOKEN_VARCHAR;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 262 "../SqlLexer.lpp"
-return TOKEN_NEQ;
+#line 263 "../SqlLexer.lpp"
+return TOKEN_WHEN;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 263 "../SqlLexer.lpp"
-return TOKEN_NEQ;
+#line 264 "../SqlLexer.lpp"
+return TOKEN_WHERE;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 264 "../SqlLexer.lpp"
-return TOKEN_LT;
+#line 265 "../SqlLexer.lpp"
+return TOKEN_WITH;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 265 "../SqlLexer.lpp"
-return TOKEN_GT;
+#line 266 "../SqlLexer.lpp"
+return TOKEN_YEARMONTH;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 266 "../SqlLexer.lpp"
-return TOKEN_LEQ;
+#line 268 "../SqlLexer.lpp"
+return TOKEN_EQ;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 267 "../SqlLexer.lpp"
-return TOKEN_GEQ;
+#line 269 "../SqlLexer.lpp"
+return TOKEN_NEQ;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 269 "../SqlLexer.lpp"
-return yytext[0];
+#line 270 "../SqlLexer.lpp"
+return TOKEN_NEQ;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 270 "../SqlLexer.lpp"
+#line 271 "../SqlLexer.lpp"
+return TOKEN_LT;
+	YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 272 "../SqlLexer.lpp"
+return TOKEN_GT;
+	YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 273 "../SqlLexer.lpp"
+return TOKEN_LEQ;
+	YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 274 "../SqlLexer.lpp"
+return TOKEN_GEQ;
+	YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 276 "../SqlLexer.lpp"
+return yytext[0];
+	YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 277 "../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 110:
+case 115:
 YY_RULE_SETUP
-#line 276 "../SqlLexer.lpp"
+#line 283 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED_ESCAPED);
   }
 	YY_BREAK
-case 111:
+case 116:
 YY_RULE_SETUP
-#line 281 "../SqlLexer.lpp"
+#line 288 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED);
   }
 	YY_BREAK
-case 112:
+case 117:
 YY_RULE_SETUP
-#line 286 "../SqlLexer.lpp"
+#line 293 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_DOUBLE_QUOTED);
@@ -1981,7 +2014,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 295 "../SqlLexer.lpp"
+#line 302 "../SqlLexer.lpp"
 {
     delete yylval->string_value_;
     BEGIN(INITIAL);
@@ -1992,9 +2025,9 @@
 
 /* Process escape sequences. */
 
-case 113:
+case 118:
 YY_RULE_SETUP
-#line 305 "../SqlLexer.lpp"
+#line 312 "../SqlLexer.lpp"
 {
     /* Octal code */
     unsigned int code;
@@ -2008,9 +2041,9 @@
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 114:
+case 119:
 YY_RULE_SETUP
-#line 317 "../SqlLexer.lpp"
+#line 324 "../SqlLexer.lpp"
 {
     /* Hexadecimal code */
     unsigned int code;
@@ -2018,9 +2051,9 @@
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 115:
+case 120:
 YY_RULE_SETUP
-#line 323 "../SqlLexer.lpp"
+#line 330 "../SqlLexer.lpp"
 {
     /* A numeric escape sequence that isn't correctly specified. */
     delete yylval->string_value_;
@@ -2029,58 +2062,58 @@
     return TOKEN_LEX_ERROR;
   }
 	YY_BREAK
-case 116:
+case 121:
 YY_RULE_SETUP
-#line 330 "../SqlLexer.lpp"
+#line 337 "../SqlLexer.lpp"
 {
     /* Backspace */
     yylval->string_value_->push_back('\b');
   }
 	YY_BREAK
-case 117:
+case 122:
 YY_RULE_SETUP
-#line 334 "../SqlLexer.lpp"
+#line 341 "../SqlLexer.lpp"
 {
     /* Form-feed */
     yylval->string_value_->push_back('\f');
   }
 	YY_BREAK
-case 118:
+case 123:
 YY_RULE_SETUP
-#line 338 "../SqlLexer.lpp"
+#line 345 "../SqlLexer.lpp"
 {
     /* Newline */
     yylval->string_value_->push_back('\n');
   }
 	YY_BREAK
-case 119:
+case 124:
 YY_RULE_SETUP
-#line 342 "../SqlLexer.lpp"
+#line 349 "../SqlLexer.lpp"
 {
     /* Carriage-return */
     yylval->string_value_->push_back('\r');
   }
 	YY_BREAK
-case 120:
+case 125:
 YY_RULE_SETUP
-#line 346 "../SqlLexer.lpp"
+#line 353 "../SqlLexer.lpp"
 {
     /* Horizontal Tab */
     yylval->string_value_->push_back('\t');
   }
 	YY_BREAK
-case 121:
-/* rule 121 can match eol */
+case 126:
+/* rule 126 can match eol */
 YY_RULE_SETUP
-#line 350 "../SqlLexer.lpp"
+#line 357 "../SqlLexer.lpp"
 {
     /* Any other character (including actual newline or carriage return) */
     yylval->string_value_->push_back(yytext[1]);
   }
 	YY_BREAK
-case 122:
+case 127:
 YY_RULE_SETUP
-#line 354 "../SqlLexer.lpp"
+#line 361 "../SqlLexer.lpp"
 {
     /* This should only be encountered right before an EOF. */
     delete yylval->string_value_;
@@ -2091,17 +2124,17 @@
 	YY_BREAK
 
 
-case 123:
+case 128:
 YY_RULE_SETUP
-#line 364 "../SqlLexer.lpp"
+#line 371 "../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 124:
+case 129:
 YY_RULE_SETUP
-#line 368 "../SqlLexer.lpp"
+#line 375 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2110,17 +2143,17 @@
 	YY_BREAK
 
 
-case 125:
+case 130:
 YY_RULE_SETUP
-#line 376 "../SqlLexer.lpp"
+#line 383 "../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 126:
+case 131:
 YY_RULE_SETUP
-#line 380 "../SqlLexer.lpp"
+#line 387 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2128,94 +2161,94 @@
   }
 	YY_BREAK
 
-case 127:
-/* rule 127 can match eol */
+case 132:
+/* rule 132 can match eol */
 YY_RULE_SETUP
-#line 387 "../SqlLexer.lpp"
+#line 394 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 128:
-/* rule 128 can match eol */
+case 133:
+/* rule 133 can match eol */
 YY_RULE_SETUP
-#line 392 "../SqlLexer.lpp"
+#line 399 "../SqlLexer.lpp"
 {
   /* Scan up to a quote or escape sequence. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 129:
-/* rule 129 can match eol */
+case 134:
+/* rule 134 can match eol */
 YY_RULE_SETUP
-#line 397 "../SqlLexer.lpp"
+#line 404 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
 
-case 130:
+case 135:
 YY_RULE_SETUP
-#line 403 "../SqlLexer.lpp"
+#line 410 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(
         yylloc->first_line, yylloc->first_column, std::string(yytext, yyleng));
     return TOKEN_NAME;
   }
 	YY_BREAK
-case 131:
+case 136:
 YY_RULE_SETUP
-#line 409 "../SqlLexer.lpp"
+#line 416 "../SqlLexer.lpp"
 {
     yylval->numeric_literal_value_ = new quickstep::NumericParseLiteralValue(
         yylloc->first_line, yylloc->first_column, yytext);
     return TOKEN_UNSIGNED_NUMVAL;
   }
 	YY_BREAK
-case 132:
+case 137:
 YY_RULE_SETUP
-#line 415 "../SqlLexer.lpp"
+#line 422 "../SqlLexer.lpp"
 /* comment */
 	YY_BREAK
-case 133:
-/* rule 133 can match eol */
+case 138:
+/* rule 138 can match eol */
 YY_RULE_SETUP
-#line 417 "../SqlLexer.lpp"
+#line 424 "../SqlLexer.lpp"
 { yycolumn = 0; }
 	YY_BREAK
-case 134:
+case 139:
 YY_RULE_SETUP
-#line 419 "../SqlLexer.lpp"
+#line 426 "../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 423 "../SqlLexer.lpp"
+#line 430 "../SqlLexer.lpp"
 {
   /* All conditions except for mutli-state string extracting conditions. */
   BEGIN(INITIAL);
   return TOKEN_EOF;
 }
 	YY_BREAK
-case 135:
+case 140:
 YY_RULE_SETUP
-#line 429 "../SqlLexer.lpp"
+#line 436 "../SqlLexer.lpp"
 {
   BEGIN(INITIAL);
   quickstep_yyerror(NULL, yyscanner, NULL, "illegal character");
   return TOKEN_LEX_ERROR;
 }
 	YY_BREAK
-case 136:
+case 141:
 YY_RULE_SETUP
-#line 435 "../SqlLexer.lpp"
+#line 442 "../SqlLexer.lpp"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2219 "SqlLexer_gen.cpp"
+#line 2252 "SqlLexer_gen.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2509,7 +2542,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 >= 508 )
+			if ( yy_current_state >= 520 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2538,11 +2571,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 >= 508 )
+		if ( yy_current_state >= 520 )
 			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 == 507);
+	yy_is_jam = (yy_current_state == 519);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -3376,7 +3409,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 435 "../SqlLexer.lpp"
+#line 442 "../SqlLexer.lpp"
 
 
 
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index 1b1823b..f454e7b 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -360,7 +360,7 @@
 #undef YY_DECL
 #endif
 
-#line 435 "../SqlLexer.lpp"
+#line 442 "../SqlLexer.lpp"
 
 
 #line 367 "SqlLexer_gen.hpp"
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index 324a066..0a3ccba 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -107,6 +107,7 @@
 #include "parser/ParseAttributeDefinition.hpp"
 #include "parser/ParseBasicExpressions.hpp"
 #include "parser/ParseBlockProperties.hpp"
+#include "parser/ParseCaseExpressions.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseGeneratorTableReference.hpp"
 #include "parser/ParseGroupBy.hpp"
@@ -147,7 +148,7 @@
 // Needed for Bison 2.6 and higher, which do not automatically provide this typedef.
 typedef void* yyscan_t;
 
-#line 151 "SqlParser_gen.cpp" /* yacc.c:339  */
+#line 152 "SqlParser_gen.cpp" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -214,80 +215,85 @@
     TOKEN_BLOOM_FILTER = 287,
     TOKEN_CSB_TREE = 288,
     TOKEN_BY = 289,
-    TOKEN_CHARACTER = 290,
-    TOKEN_CHECK = 291,
-    TOKEN_COLUMN = 292,
-    TOKEN_CONSTRAINT = 293,
-    TOKEN_COPY = 294,
-    TOKEN_CREATE = 295,
-    TOKEN_DATE = 296,
-    TOKEN_DATETIME = 297,
-    TOKEN_DECIMAL = 298,
-    TOKEN_DEFAULT = 299,
-    TOKEN_DELETE = 300,
-    TOKEN_DELIMITER = 301,
-    TOKEN_DESC = 302,
-    TOKEN_DISTINCT = 303,
-    TOKEN_DOUBLE = 304,
-    TOKEN_DROP = 305,
-    TOKEN_ESCAPE_STRINGS = 306,
-    TOKEN_EXISTS = 307,
-    TOKEN_EXTRACT = 308,
-    TOKEN_FALSE = 309,
-    TOKEN_FIRST = 310,
-    TOKEN_FLOAT = 311,
-    TOKEN_FOREIGN = 312,
-    TOKEN_FROM = 313,
-    TOKEN_FULL = 314,
-    TOKEN_GROUP = 315,
-    TOKEN_HASH = 316,
-    TOKEN_HAVING = 317,
-    TOKEN_INDEX = 318,
-    TOKEN_INNER = 319,
-    TOKEN_INSERT = 320,
-    TOKEN_INTEGER = 321,
-    TOKEN_INTERVAL = 322,
-    TOKEN_INTO = 323,
-    TOKEN_JOIN = 324,
-    TOKEN_KEY = 325,
-    TOKEN_LAST = 326,
-    TOKEN_LEFT = 327,
-    TOKEN_LIMIT = 328,
-    TOKEN_LONG = 329,
-    TOKEN_NULL = 330,
-    TOKEN_NULLS = 331,
-    TOKEN_OFF = 332,
-    TOKEN_ON = 333,
-    TOKEN_ORDER = 334,
-    TOKEN_OUTER = 335,
-    TOKEN_PARTITION = 336,
-    TOKEN_PARTITIONS = 337,
-    TOKEN_PERCENT = 338,
-    TOKEN_PRIMARY = 339,
-    TOKEN_QUIT = 340,
-    TOKEN_RANGE = 341,
-    TOKEN_REAL = 342,
-    TOKEN_REFERENCES = 343,
-    TOKEN_RIGHT = 344,
-    TOKEN_ROW_DELIMITER = 345,
-    TOKEN_SELECT = 346,
-    TOKEN_SET = 347,
-    TOKEN_SMALLINT = 348,
-    TOKEN_TABLE = 349,
-    TOKEN_TIME = 350,
-    TOKEN_TIMESTAMP = 351,
-    TOKEN_TRUE = 352,
-    TOKEN_TUPLESAMPLE = 353,
-    TOKEN_UNIQUE = 354,
-    TOKEN_UPDATE = 355,
-    TOKEN_USING = 356,
-    TOKEN_VALUES = 357,
-    TOKEN_VARCHAR = 358,
-    TOKEN_WHERE = 359,
-    TOKEN_WITH = 360,
-    TOKEN_YEARMONTH = 361,
-    TOKEN_EOF = 362,
-    TOKEN_LEX_ERROR = 363
+    TOKEN_CASE = 290,
+    TOKEN_CHARACTER = 291,
+    TOKEN_CHECK = 292,
+    TOKEN_COLUMN = 293,
+    TOKEN_CONSTRAINT = 294,
+    TOKEN_COPY = 295,
+    TOKEN_CREATE = 296,
+    TOKEN_DATE = 297,
+    TOKEN_DATETIME = 298,
+    TOKEN_DECIMAL = 299,
+    TOKEN_DEFAULT = 300,
+    TOKEN_DELETE = 301,
+    TOKEN_DELIMITER = 302,
+    TOKEN_DESC = 303,
+    TOKEN_DISTINCT = 304,
+    TOKEN_DOUBLE = 305,
+    TOKEN_DROP = 306,
+    TOKEN_ELSE = 307,
+    TOKEN_END = 308,
+    TOKEN_ESCAPE_STRINGS = 309,
+    TOKEN_EXISTS = 310,
+    TOKEN_EXTRACT = 311,
+    TOKEN_FALSE = 312,
+    TOKEN_FIRST = 313,
+    TOKEN_FLOAT = 314,
+    TOKEN_FOREIGN = 315,
+    TOKEN_FROM = 316,
+    TOKEN_FULL = 317,
+    TOKEN_GROUP = 318,
+    TOKEN_HASH = 319,
+    TOKEN_HAVING = 320,
+    TOKEN_INDEX = 321,
+    TOKEN_INNER = 322,
+    TOKEN_INSERT = 323,
+    TOKEN_INTEGER = 324,
+    TOKEN_INTERVAL = 325,
+    TOKEN_INTO = 326,
+    TOKEN_JOIN = 327,
+    TOKEN_KEY = 328,
+    TOKEN_LAST = 329,
+    TOKEN_LEFT = 330,
+    TOKEN_LIMIT = 331,
+    TOKEN_LONG = 332,
+    TOKEN_NULL = 333,
+    TOKEN_NULLS = 334,
+    TOKEN_OFF = 335,
+    TOKEN_ON = 336,
+    TOKEN_ORDER = 337,
+    TOKEN_OUTER = 338,
+    TOKEN_PARTITION = 339,
+    TOKEN_PARTITIONS = 340,
+    TOKEN_PERCENT = 341,
+    TOKEN_PRIMARY = 342,
+    TOKEN_QUIT = 343,
+    TOKEN_RANGE = 344,
+    TOKEN_REAL = 345,
+    TOKEN_REFERENCES = 346,
+    TOKEN_RIGHT = 347,
+    TOKEN_ROW_DELIMITER = 348,
+    TOKEN_SELECT = 349,
+    TOKEN_SET = 350,
+    TOKEN_SMALLINT = 351,
+    TOKEN_TABLE = 352,
+    TOKEN_THEN = 353,
+    TOKEN_TIME = 354,
+    TOKEN_TIMESTAMP = 355,
+    TOKEN_TRUE = 356,
+    TOKEN_TUPLESAMPLE = 357,
+    TOKEN_UNIQUE = 358,
+    TOKEN_UPDATE = 359,
+    TOKEN_USING = 360,
+    TOKEN_VALUES = 361,
+    TOKEN_VARCHAR = 362,
+    TOKEN_WHEN = 363,
+    TOKEN_WHERE = 364,
+    TOKEN_WITH = 365,
+    TOKEN_YEARMONTH = 366,
+    TOKEN_EOF = 367,
+    TOKEN_LEX_ERROR = 368
   };
 #endif
 
@@ -296,7 +302,7 @@
 
 union YYSTYPE
 {
-#line 115 "../SqlParser.ypp" /* yacc.c:355  */
+#line 116 "../SqlParser.ypp" /* yacc.c:355  */
 
   quickstep::ParseString *string_value_;
 
@@ -318,6 +324,12 @@
 
   quickstep::ParseSubqueryExpression *subquery_expression_;
 
+  quickstep::PtrVector<quickstep::ParseSimpleWhenClause> *simple_when_clause_list_;
+  quickstep::ParseSimpleWhenClause *simple_when_clause_;
+
+  quickstep::PtrVector<quickstep::ParseSearchedWhenClause> *searched_when_clause_list_;
+  quickstep::ParseSearchedWhenClause *searched_when_clause_;
+
   quickstep::ParseSelectionClause *selection_;
   quickstep::ParseSelectionItem *selection_item_;
   quickstep::ParseSelectionList *selection_list_;
@@ -380,7 +392,7 @@
   quickstep::PtrVector<quickstep::ParseSubqueryTableReference> *with_list_;
   quickstep::ParseSubqueryTableReference *with_list_element_;
 
-#line 384 "SqlParser_gen.cpp" /* yacc.c:355  */
+#line 396 "SqlParser_gen.cpp" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -409,13 +421,13 @@
 #endif /* !YY_QUICKSTEP_YY_SQLPARSER_GEN_HPP_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
-#line 199 "../SqlParser.ypp" /* yacc.c:358  */
+#line 206 "../SqlParser.ypp" /* yacc.c:358  */
 
 /* This header needs YYSTYPE, which is defined by the %union directive above */
 #include "SqlLexer_gen.hpp"
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature);
 
-#line 419 "SqlParser_gen.cpp" /* yacc.c:358  */
+#line 431 "SqlParser_gen.cpp" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -659,21 +671,21 @@
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  47
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   943
+#define YYLAST   1117
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  120
+#define YYNTOKENS  125
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  89
+#define YYNNTS  95
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  238
+#define YYNRULES  249
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  462
+#define YYNSTATES  485
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   363
+#define YYMAXUTOK   368
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -683,11 +695,11 @@
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     115,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     120,     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,   119,     2,     2,
-     116,   117,    23,    21,   118,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   114,
+       2,     2,     2,     2,     2,     2,     2,   124,     2,     2,
+     121,   122,    23,    21,   123,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   119,
        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,
@@ -718,37 +730,38 @@
       80,    81,    82,    83,    84,    85,    86,    87,    88,    89,
       90,    91,    92,    93,    94,    95,    96,    97,    98,    99,
      100,   101,   102,   103,   104,   105,   106,   107,   108,   109,
-     110,   111,   112,   113
+     110,   111,   112,   113,   114,   115,   116,   117,   118
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   540,   540,   544,   548,   552,   556,   559,   566,   569,
-     572,   575,   578,   581,   584,   587,   590,   593,   599,   605,
-     612,   618,   625,   634,   639,   648,   653,   658,   662,   668,
-     673,   676,   679,   684,   687,   690,   693,   696,   699,   702,
-     705,   708,   711,   723,   726,   729,   747,   767,   770,   773,
-     778,   783,   789,   795,   804,   808,   814,   817,   822,   827,
-     832,   839,   846,   850,   856,   859,   864,   867,   872,   875,
-     880,   883,   902,   906,   912,   916,   922,   925,   928,   933,
-     936,   943,   948,   959,   963,   969,   972,   978,   986,   989,
-     992,   998,  1003,  1006,  1011,  1015,  1019,  1023,  1029,  1034,
-    1039,  1043,  1049,  1055,  1058,  1063,  1068,  1072,  1078,  1084,
-    1090,  1093,  1097,  1103,  1106,  1111,  1115,  1121,  1124,  1127,
-    1132,  1137,  1140,  1146,  1150,  1156,  1162,  1168,  1174,  1180,
-    1186,  1192,  1198,  1206,  1211,  1214,  1217,  1222,  1226,  1230,
-    1233,  1237,  1242,  1245,  1250,  1253,  1258,  1262,  1268,  1271,
-    1276,  1279,  1284,  1287,  1292,  1295,  1314,  1318,  1324,  1331,
-    1334,  1337,  1342,  1345,  1348,  1354,  1357,  1362,  1367,  1376,
-    1381,  1390,  1395,  1398,  1403,  1406,  1411,  1417,  1423,  1426,
-    1429,  1437,  1440,  1445,  1448,  1453,  1456,  1461,  1464,  1467,
-    1470,  1473,  1478,  1482,  1486,  1489,  1494,  1499,  1503,  1509,
-    1512,  1515,  1518,  1530,  1534,  1553,  1568,  1572,  1578,  1581,
-    1586,  1590,  1597,  1600,  1603,  1606,  1609,  1612,  1615,  1618,
-    1621,  1624,  1629,  1640,  1643,  1648,  1651,  1654,  1660,  1664,
-    1670,  1673,  1681,  1684,  1687,  1690,  1696,  1701,  1706
+       0,   566,   566,   570,   574,   578,   582,   585,   592,   595,
+     598,   601,   604,   607,   610,   613,   616,   619,   625,   631,
+     638,   644,   651,   660,   665,   674,   679,   684,   688,   694,
+     699,   702,   705,   710,   713,   716,   719,   722,   725,   728,
+     731,   734,   737,   749,   752,   755,   773,   793,   796,   799,
+     804,   809,   815,   821,   830,   834,   840,   843,   848,   853,
+     858,   865,   872,   876,   882,   885,   890,   893,   898,   901,
+     906,   909,   928,   932,   938,   942,   948,   951,   954,   959,
+     962,   969,   974,   985,   989,   995,   998,  1004,  1012,  1015,
+    1018,  1024,  1029,  1032,  1037,  1041,  1045,  1049,  1055,  1060,
+    1065,  1069,  1075,  1081,  1084,  1089,  1094,  1098,  1104,  1110,
+    1116,  1119,  1123,  1129,  1132,  1137,  1141,  1147,  1150,  1153,
+    1158,  1163,  1166,  1172,  1176,  1182,  1188,  1194,  1200,  1206,
+    1212,  1218,  1224,  1232,  1237,  1240,  1243,  1248,  1252,  1256,
+    1259,  1263,  1268,  1271,  1276,  1279,  1284,  1288,  1294,  1297,
+    1302,  1305,  1310,  1313,  1318,  1321,  1340,  1344,  1350,  1357,
+    1360,  1363,  1368,  1371,  1374,  1380,  1383,  1388,  1393,  1402,
+    1407,  1416,  1421,  1424,  1429,  1432,  1437,  1443,  1449,  1452,
+    1455,  1463,  1466,  1471,  1474,  1479,  1482,  1487,  1490,  1493,
+    1496,  1499,  1502,  1507,  1511,  1515,  1518,  1523,  1528,  1531,
+    1536,  1540,  1546,  1551,  1555,  1561,  1566,  1569,  1574,  1578,
+    1584,  1587,  1590,  1593,  1605,  1609,  1628,  1643,  1647,  1653,
+    1656,  1661,  1665,  1672,  1675,  1678,  1681,  1684,  1687,  1690,
+    1693,  1696,  1699,  1704,  1715,  1718,  1723,  1726,  1729,  1735,
+    1739,  1745,  1748,  1756,  1759,  1762,  1765,  1771,  1776,  1781
 };
 #endif
 
@@ -766,13 +779,14 @@
   "TOKEN_ADD", "TOKEN_ALL", "TOKEN_ALTER", "TOKEN_AS", "TOKEN_ASC",
   "TOKEN_BIGINT", "TOKEN_BIT", "TOKEN_BLOCKPROPERTIES",
   "TOKEN_BLOCKSAMPLE", "TOKEN_BLOOM_FILTER", "TOKEN_CSB_TREE", "TOKEN_BY",
-  "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_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_INDEX",
+  "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_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",
@@ -780,25 +794,26 @@
   "TOKEN_PARTITIONS", "TOKEN_PERCENT", "TOKEN_PRIMARY", "TOKEN_QUIT",
   "TOKEN_RANGE", "TOKEN_REAL", "TOKEN_REFERENCES", "TOKEN_RIGHT",
   "TOKEN_ROW_DELIMITER", "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMALLINT",
-  "TOKEN_TABLE", "TOKEN_TIME", "TOKEN_TIMESTAMP", "TOKEN_TRUE",
-  "TOKEN_TUPLESAMPLE", "TOKEN_UNIQUE", "TOKEN_UPDATE", "TOKEN_USING",
-  "TOKEN_VALUES", "TOKEN_VARCHAR", "TOKEN_WHERE", "TOKEN_WITH",
-  "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",
-  "table_constraint_def", "table_constraint_def_commalist",
-  "opt_table_constraint_def_commalist", "opt_column_list",
-  "opt_block_properties", "opt_partition_clause", "partition_type",
-  "key_value_list", "key_value", "key_string_value", "key_string_list",
-  "key_integer_value", "index_type", "opt_index_properties",
-  "insert_statement", "copy_from_statement", "opt_copy_from_params",
-  "copy_from_params", "update_statement", "delete_statement",
-  "assignment_list", "assignment_item", "select_statement", "with_clause",
-  "with_list", "with_list_element", "select_query", "opt_all_distinct",
-  "selection", "selection_item_commalist", "selection_item", "from_clause",
+  "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", "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", "table_constraint_def",
+  "table_constraint_def_commalist", "opt_table_constraint_def_commalist",
+  "opt_column_list", "opt_block_properties", "opt_partition_clause",
+  "partition_type", "key_value_list", "key_value", "key_string_value",
+  "key_string_list", "key_integer_value", "index_type",
+  "opt_index_properties", "insert_statement", "copy_from_statement",
+  "opt_copy_from_params", "copy_from_params", "update_statement",
+  "delete_statement", "assignment_list", "assignment_item",
+  "select_statement", "with_clause", "with_list", "with_list_element",
+  "select_query", "opt_all_distinct", "selection",
+  "selection_item_commalist", "selection_item", "from_clause",
   "opt_join_chain", "join_chain", "join", "subquery_expression",
   "opt_sample_clause", "table_reference", "table_reference_signature",
   "table_reference_signature_primary", "table_reference_commalist",
@@ -808,11 +823,13 @@
   "where_clause", "or_expression", "and_expression", "not_expression",
   "predicate_expression_base", "add_expression", "multiply_expression",
   "unary_expression", "expression_base", "function_call",
-  "extract_function", "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
+  "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
 };
 #endif
 
@@ -832,14 +849,15 @@
      330,   331,   332,   333,   334,   335,   336,   337,   338,   339,
      340,   341,   342,   343,   344,   345,   346,   347,   348,   349,
      350,   351,   352,   353,   354,   355,   356,   357,   358,   359,
-     360,   361,   362,   363,    59,    10,    40,    41,    44,    37
+     360,   361,   362,   363,   364,   365,   366,   367,   368,    59,
+      10,    40,    41,    44,    37
 };
 # endif
 
-#define YYPACT_NINF -206
+#define YYPACT_NINF -222
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-206)))
+  (!!((Yystate) == (-222)))
 
 #define YYTABLE_NINF -1
 
@@ -850,53 +868,55 @@
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     535,  -206,  -206,   -32,   139,    11,    21,   -25,    47,  -206,
-      54,   139,   139,  -206,   164,   112,  -206,  -206,  -206,  -206,
-    -206,  -206,  -206,  -206,  -206,  -206,   -28,  -206,   127,   182,
-     139,  -206,  -206,   130,   139,   139,   139,   139,   139,  -206,
-    -206,   541,   114,    96,  -206,   197,   106,  -206,  -206,  -206,
-     168,  -206,  -206,  -206,  -206,    57,   243,   169,   145,   154,
-    -206,   102,  -206,  -206,   247,   260,  -206,  -206,  -206,   157,
-    -206,   262,  -206,  -206,   161,  -206,  -206,   287,  -206,  -206,
-    -206,  -206,  -206,  -206,   183,   269,   703,   314,   280,   228,
-    -206,   138,    -3,  -206,  -206,  -206,  -206,  -206,  -206,   784,
-      -2,   139,   139,   229,   139,   139,   217,   223,   237,   139,
-     139,   460,  -206,  -206,   232,   139,  -206,  -206,  -206,   342,
-    -206,   139,  -206,   343,  -206,     1,  -206,    13,   154,   703,
-    -206,  -206,   139,   703,  -206,  -206,  -206,  -206,   703,   260,
-    -206,   139,   361,   -48,  -206,   340,  -206,   257,  -206,    84,
-    -206,   257,   139,    99,   139,   139,   238,  -206,   241,  -206,
-     116,   827,   622,   229,   460,   351,   352,  -206,  -206,   272,
-     349,   832,   152,   245,   300,   253,  -206,    60,  -206,    98,
-      60,   -22,   306,  -206,  -206,    -3,  -206,  -206,   256,   703,
-    -206,   254,   162,   139,  -206,   703,   258,  -206,   139,  -206,
-    -206,   261,   299,   301,   264,  -206,  -206,  -206,    90,   139,
-     275,    99,   139,  -206,   158,  -206,  -206,     2,    37,   460,
-     460,   227,  -206,  -206,  -206,  -206,  -206,  -206,  -206,  -206,
-     703,   703,    19,  -206,   178,   278,  -206,   703,  -206,   139,
-    -206,  -206,    62,   304,   139,    92,   121,    13,  -206,   110,
-    -206,  -206,   379,   380,    60,   350,   321,  -206,   180,  -206,
-     703,  -206,   254,  -206,  -206,   460,   274,   276,   139,   386,
-     -20,   194,  -206,   196,   366,   271,  -206,   279,   286,  -206,
-     318,   283,   832,  -206,   327,   139,  -206,  -206,   158,  -206,
-    -206,   352,  -206,  -206,  -206,   703,   149,   254,   325,  -206,
-    -206,   832,   290,    22,  -206,   139,   336,   139,   -46,   139,
-     337,   139,   338,  -206,  -206,   328,   329,  -206,   703,   460,
-     334,  -206,   254,     4,   139,   139,   198,  -206,  -206,  -206,
-    -206,  -206,  -206,  -206,   159,  -206,   139,  -206,  -206,   297,
-      99,   385,   339,  -206,   460,  -206,  -206,   308,  -206,   191,
-     703,  -206,  -206,   832,  -206,   -42,   139,   -38,   460,   -26,
-     139,   -23,   139,  -206,  -206,   309,   351,   389,   353,  -206,
-     200,   205,  -206,   424,   -20,  -206,   139,  -206,  -206,   319,
-     391,  -206,    10,   139,   703,   254,   207,   460,   -14,   460,
-     351,   460,   -10,   460,    -5,   703,   427,  -206,   344,  -206,
-    -206,  -206,   209,  -206,  -206,  -206,  -206,     9,   139,    -1,
-    -206,   322,   254,  -206,   351,   460,   351,   351,   460,   351,
-     460,   320,  -206,   131,  -206,   139,  -206,   139,  -206,  -206,
-     139,  -206,   212,  -206,  -206,   326,  -206,   351,   351,   351,
-     703,  -206,  -206,   355,   330,  -206,   218,  -206,   139,  -206,
-     105,  -206,   139,  -206,   220,  -206,  -206,   222,   356,  -206,
-     438,  -206
+     164,  -222,  -222,    51,   165,    18,    45,   104,    55,  -222,
+      43,   165,   165,  -222,   121,    74,  -222,  -222,  -222,  -222,
+    -222,  -222,  -222,  -222,  -222,  -222,    13,  -222,    91,   210,
+     165,  -222,  -222,   159,   165,   165,   165,   165,   165,  -222,
+    -222,   585,   141,   123,  -222,   218,   132,  -222,  -222,  -222,
+     192,  -222,  -222,  -222,  -222,    19,   266,   196,   168,   180,
+    -222,    67,  -222,  -222,   294,   306,  -222,  -222,  -222,   670,
+     200,  -222,   273,  -222,  -222,   220,  -222,  -222,   312,  -222,
+    -222,  -222,  -222,  -222,  -222,   229,   278,   840,   351,   295,
+     251,  -222,   239,    16,  -222,  -222,  -222,  -222,  -222,  -222,
+    -222,   925,    -6,   165,   165,   261,   165,   165,   222,   234,
+     268,   165,   165,   500,  -222,  -222,   263,   165,  -222,  -222,
+    -222,   500,     3,   -28,  -222,   378,  -222,   165,  -222,   380,
+    -222,    24,  -222,     5,   180,   840,  -222,  -222,   165,   840,
+    -222,  -222,  -222,  -222,   840,   306,  -222,   165,   414,    89,
+    -222,   377,  -222,   290,  -222,   -40,  -222,   290,   165,    93,
+     165,   165,   269,  -222,   270,  -222,   163,  1001,   755,   261,
+     500,   384,   385,  -222,  -222,   293,   373,   957,   169,     6,
+     840,   -15,  -222,   840,  -222,   338,   276,   333,   279,  -222,
+     173,  -222,   103,   173,    29,   332,  -222,  -222,    16,  -222,
+    -222,   281,   840,  -222,   275,   176,   165,  -222,   840,   282,
+    -222,   165,  -222,  -222,   284,   328,   329,   287,  -222,  -222,
+    -222,    96,   165,   299,    93,   165,  -222,    68,  -222,  -222,
+      -3,    39,   500,   500,   257,  -222,  -222,  -222,  -222,  -222,
+    -222,  -222,  -222,   840,   840,     7,  -222,   209,   300,   840,
+      49,  -222,   352,   275,  -222,  -222,   840,  -222,   165,  -222,
+    -222,   154,   335,   165,   162,   179,     5,  -222,   147,  -222,
+    -222,   406,   407,   173,   376,   346,  -222,   211,  -222,   840,
+    -222,   275,  -222,  -222,   500,   296,   301,   165,   418,   110,
+     213,  -222,   215,   397,   302,  -222,   305,   310,  -222,   347,
+     308,   957,  -222,   353,   165,  -222,  -222,    68,  -222,  -222,
+     385,  -222,  -222,  -222,   840,    70,   275,   349,  -222,  -222,
+     957,   313,   275,   840,  -222,    41,  -222,   165,   356,   165,
+     -50,   165,   361,   165,   362,  -222,  -222,   350,   354,  -222,
+     840,   500,   363,  -222,   275,     2,   165,   165,   223,  -222,
+    -222,  -222,  -222,  -222,  -222,  -222,   181,  -222,   165,  -222,
+    -222,   319,    93,   408,   364,  -222,   500,  -222,  -222,   330,
+    -222,   208,   840,  -222,  -222,   957,   275,  -222,   -43,   165,
+     -42,   500,   -27,   165,   -22,   165,  -222,  -222,   334,   384,
+     413,   375,  -222,   237,   240,  -222,   453,   110,  -222,   165,
+    -222,  -222,   339,   420,  -222,    10,   165,   840,   275,   242,
+     500,   -19,   500,   384,   500,   -18,   500,   -17,   840,   457,
+    -222,   369,  -222,  -222,  -222,   244,  -222,  -222,  -222,  -222,
+       9,   165,    53,  -222,   344,   275,  -222,   384,   500,   384,
+     384,   500,   384,   500,   357,  -222,   152,  -222,   165,  -222,
+     165,  -222,  -222,   165,  -222,   246,  -222,  -222,   355,  -222,
+     384,   384,   384,   840,  -222,  -222,   386,   358,  -222,   248,
+    -222,   165,  -222,    14,  -222,   165,  -222,   250,  -222,  -222,
+     255,   382,  -222,   466,  -222
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -904,81 +924,85 @@
      means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       0,     6,   238,     0,     0,     0,     0,     0,     0,    18,
+       0,     6,   249,     0,     0,     0,     0,     0,     0,    18,
      110,     0,     0,     7,     0,     0,    15,     8,    10,    11,
-      13,    14,     9,    17,    12,    16,     0,   103,     0,   236,
-       0,   230,   231,     0,     0,     0,     0,     0,     0,   111,
+      13,    14,     9,    17,    12,    16,     0,   103,     0,   247,
+       0,   241,   242,     0,     0,     0,     0,     0,     0,   111,
      112,     0,     0,   105,   106,     0,   144,     1,     3,     2,
-       0,   104,     5,     4,   237,     0,     0,     0,     0,   165,
-      25,     0,   203,   200,     0,   222,   113,    40,    29,     0,
-      30,    31,    34,    36,     0,    37,    39,     0,    41,   199,
-      35,    38,    32,    33,     0,     0,     0,     0,     0,   114,
-     115,   119,   182,   184,   186,   189,   190,   188,   187,     0,
-     208,     0,     0,     0,     0,     0,     0,     0,    92,     0,
-       0,     0,    99,   166,     0,     0,    89,   201,   202,     0,
-      43,     0,   204,     0,    44,     0,   205,     0,   165,     0,
-     223,   224,     0,     0,   118,   226,   227,   225,     0,     0,
-     185,     0,     0,   165,   101,     0,   107,     0,   108,     0,
-     228,     0,     0,     0,     0,     0,     0,    91,    66,    27,
-       0,     0,     0,     0,     0,   167,   169,   171,   173,     0,
-     187,     0,     0,     0,     0,     0,   191,     0,   146,   121,
-     141,   134,   148,   116,   117,   181,   183,   209,     0,     0,
-     192,   197,     0,     0,    98,     0,     0,   145,     0,    90,
-      19,     0,     0,     0,     0,    20,    21,    22,     0,     0,
-       0,    64,     0,    42,    56,   172,   180,     0,     0,     0,
-       0,     0,   212,   214,   215,   216,   217,   213,   218,   220,
-       0,     0,     0,   206,     0,     0,    45,     0,    46,     0,
-     137,   142,     0,     0,     0,     0,     0,     0,   120,   122,
-     124,   140,     0,     0,   139,     0,   150,   193,     0,   194,
-       0,   100,   102,   133,   229,     0,     0,     0,     0,     0,
-       0,     0,   210,     0,   208,     0,    63,    65,    68,    28,
-       0,     0,     0,    47,     0,     0,    49,    55,    57,    26,
-     179,   168,   170,   219,   221,     0,     0,   178,     0,   177,
-      88,     0,     0,     0,   143,     0,     0,     0,     0,     0,
-       0,     0,     0,   147,   123,     0,     0,   138,     0,     0,
-     152,   195,   198,     0,     0,     0,     0,    94,   234,   235,
-     233,   232,    95,    93,     0,    67,     0,    83,    84,    85,
-       0,     0,    70,    48,     0,    51,    50,     0,    54,     0,
-       0,   176,   207,     0,   196,     0,     0,     0,     0,     0,
-       0,     0,     0,   135,   136,   149,   151,     0,   154,    61,
-       0,     0,    58,     0,     0,   211,     0,    24,    62,     0,
-       0,    23,     0,     0,     0,   174,     0,     0,     0,     0,
-     126,     0,     0,     0,     0,     0,     0,   109,     0,    59,
-      96,    97,     0,    74,    76,    77,    78,     0,     0,     0,
-      52,     0,   175,    87,   132,     0,   125,   128,     0,   130,
-       0,   153,   156,   159,   155,     0,    86,     0,    82,    80,
-       0,    79,     0,    72,    73,     0,    53,   131,   127,   129,
-       0,   160,   161,   162,     0,    75,     0,    69,     0,   157,
-       0,   158,     0,    81,     0,   163,   164,     0,     0,    60,
-       0,    71
+       0,   104,     5,     4,   248,     0,     0,     0,     0,   165,
+      25,     0,   214,   211,     0,   233,   113,    40,    29,     0,
+       0,    30,    31,    34,    36,     0,    37,    39,     0,    41,
+     210,    35,    38,    32,    33,     0,     0,     0,     0,     0,
+     114,   115,   119,   182,   184,   186,   189,   190,   191,   188,
+     187,     0,   219,     0,     0,     0,     0,     0,     0,     0,
+      92,     0,     0,     0,    99,   166,     0,     0,    89,   212,
+     213,     0,     0,   206,   203,     0,    43,     0,   215,     0,
+      44,     0,   216,     0,   165,     0,   234,   235,     0,     0,
+     118,   237,   238,   236,     0,     0,   185,     0,     0,   165,
+     101,     0,   107,     0,   108,     0,   239,     0,     0,     0,
+       0,     0,     0,    91,    66,    27,     0,     0,     0,     0,
+       0,   167,   169,   171,   173,     0,   187,     0,     0,     0,
+       0,   206,   200,     0,   204,     0,     0,     0,     0,   192,
+       0,   146,   121,   141,   134,   148,   116,   117,   181,   183,
+     220,     0,     0,   193,   208,     0,     0,    98,     0,     0,
+     145,     0,    90,    19,     0,     0,     0,     0,    20,    21,
+      22,     0,     0,     0,    64,     0,    42,    56,   172,   180,
+       0,     0,     0,     0,     0,   223,   225,   226,   227,   228,
+     224,   229,   231,     0,     0,     0,   217,     0,     0,     0,
+       0,   201,     0,   207,   199,    45,     0,    46,     0,   137,
+     142,     0,     0,     0,     0,     0,     0,   120,   122,   124,
+     140,     0,     0,   139,     0,   150,   194,     0,   195,     0,
+     100,   102,   133,   240,     0,     0,     0,     0,     0,     0,
+       0,   221,     0,   219,     0,    63,    65,    68,    28,     0,
+       0,     0,    47,     0,     0,    49,    55,    57,    26,   179,
+     168,   170,   230,   232,     0,     0,   178,     0,   177,    88,
+       0,     0,   205,     0,   198,     0,   143,     0,     0,     0,
+       0,     0,     0,     0,     0,   147,   123,     0,     0,   138,
+       0,     0,   152,   196,   209,     0,     0,     0,     0,    94,
+     245,   246,   244,   243,    95,    93,     0,    67,     0,    83,
+      84,    85,     0,     0,    70,    48,     0,    51,    50,     0,
+      54,     0,     0,   176,   218,     0,   202,   197,     0,     0,
+       0,     0,     0,     0,     0,     0,   135,   136,   149,   151,
+       0,   154,    61,     0,     0,    58,     0,     0,   222,     0,
+      24,    62,     0,     0,    23,     0,     0,     0,   174,     0,
+       0,     0,     0,   126,     0,     0,     0,     0,     0,     0,
+     109,     0,    59,    96,    97,     0,    74,    76,    77,    78,
+       0,     0,     0,    52,     0,   175,    87,   132,     0,   125,
+     128,     0,   130,     0,   153,   156,   159,   155,     0,    86,
+       0,    82,    80,     0,    79,     0,    72,    73,     0,    53,
+     131,   127,   129,     0,   160,   161,   162,     0,    75,     0,
+      69,     0,   157,     0,   158,     0,    81,     0,   163,   164,
+       0,     0,    60,     0,    71
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -206,  -206,  -206,  -206,  -206,  -206,  -206,  -206,  -124,  -206,
-     288,   163,  -206,  -206,  -205,  -206,  -206,  -206,  -206,  -206,
-    -206,    39,    23,  -206,  -206,  -206,  -206,  -206,  -206,  -206,
-    -206,  -206,  -206,  -206,  -206,   259,  -206,  -206,  -206,   354,
-     -21,  -206,  -206,  -206,   331,  -206,  -206,  -206,   206,   -67,
-    -206,   210,  -145,    -9,  -206,  -206,  -206,  -206,  -206,  -206,
-      14,  -206,  -206,   -57,  -206,  -162,   239,   248,   311,   -40,
-     341,   333,   364,  -116,  -206,  -180,  -167,   122,   -87,  -206,
-    -206,  -206,  -206,  -206,   -88,    -4,   109,  -206,  -206
+    -222,  -222,  -222,  -222,  -222,  -222,  -222,  -222,  -130,  -222,
+     307,   170,  -222,  -222,  -221,  -222,  -222,  -222,  -222,  -222,
+    -222,    50,    32,  -222,  -222,  -222,  -222,  -222,  -222,  -222,
+    -222,  -222,  -222,  -222,  -222,   277,  -222,  -222,  -222,   381,
+     -20,  -222,  -222,  -222,   359,  -222,  -222,  -222,   216,   -82,
+    -222,   221,  -156,   -10,  -222,  -222,  -222,  -222,  -222,  -222,
+      23,  -222,  -222,    48,  -222,   -86,   258,   259,   323,   -21,
+     360,   367,   392,  -121,  -222,  -222,  -222,   314,  -222,   379,
+     317,  -198,  -176,   125,   -94,  -222,  -222,  -222,  -222,  -222,
+     -95,    -4,   106,  -222,  -222
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   159,   160,
-      87,   287,   288,   289,   205,   277,   278,   210,   342,   381,
-     435,   402,   403,   404,   405,   406,   339,   377,    21,    22,
-     157,   271,    23,    24,   143,   144,    25,    26,    43,    44,
-      27,    41,    88,    89,    90,   128,   248,   249,   250,   177,
-     254,   178,   240,   241,   179,   256,   320,   368,   397,   421,
-     422,   443,   451,   112,   113,   165,   166,   167,   168,   169,
-      92,    93,    94,    95,    96,   192,    97,   234,    98,   273,
-     231,    99,   133,   138,   149,   100,   332,    28,    29
+      -1,    14,    15,    16,    17,    18,    19,    20,   165,   166,
+      88,   306,   307,   308,   218,   296,   297,   223,   364,   404,
+     458,   425,   426,   427,   428,   429,   361,   400,    21,    22,
+     163,   290,    23,    24,   149,   150,    25,    26,    43,    44,
+      27,    41,    89,    90,    91,   134,   267,   268,   269,   190,
+     273,   191,   259,   260,   192,   275,   342,   391,   420,   444,
+     445,   466,   474,   114,   115,   171,   172,   173,   174,   175,
+      93,    94,    95,    96,    97,    98,   181,   182,   123,   124,
+     185,   205,    99,   247,   100,   292,   244,   101,   139,   144,
+     155,   102,   354,    28,    29
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -986,282 +1010,319 @@
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint16 yytable[] =
 {
-      33,    91,   217,    45,   233,    51,   276,    42,    46,   258,
-     219,   180,   219,    31,   252,    32,   428,    31,   219,    32,
-     135,   136,   130,   131,   170,   141,    55,   172,   200,   298,
-      57,    58,    59,    60,    61,   251,   148,   358,   429,   328,
-     116,   387,    50,   130,   131,   389,   125,   221,   222,   223,
-     224,   225,   226,   227,   228,   229,   230,   391,   130,   131,
-     393,   111,   329,   330,    31,   433,    32,    30,    10,   415,
-     193,   182,   198,   418,    37,   170,   198,   170,   420,    34,
-     198,   253,   331,    39,    36,   106,   194,   134,   279,    91,
-     434,   239,   198,    45,   142,   198,   216,   145,    46,   299,
-     150,   151,   191,   323,   198,   158,   161,    40,   198,   317,
-      35,   150,   107,   198,   142,   345,   137,   174,   176,   290,
-      38,   369,   272,   181,   218,   430,   196,   410,   184,   147,
-     199,   180,   170,   170,   352,   378,   305,   187,   365,   354,
-     201,   269,    31,    31,    32,    32,   270,   306,   161,   191,
-     206,   207,   130,   131,   176,   262,   308,   366,   350,   130,
-     131,   202,   242,   441,    47,   455,   309,   243,   280,   132,
-     130,   131,   244,    46,   242,   245,    46,   310,   170,   243,
-     326,   456,   382,   442,   244,    54,   233,   245,   203,   145,
-     296,   297,   246,    56,   264,   311,   390,   303,    10,   281,
-     384,   197,   198,   204,   246,   274,   312,   282,   161,   114,
-     373,   101,   130,   131,   102,   374,   247,   355,   115,   357,
-     322,   359,   104,   361,    48,   414,    49,   416,   103,   417,
-     304,   419,   170,   211,   212,    46,   370,   371,   283,    52,
-     150,   105,    53,   181,   293,   294,   295,   284,   108,   375,
-      46,   285,   109,   437,   117,   349,   438,   170,   439,   152,
-     153,   110,   286,   111,   150,   154,   155,   118,   388,   235,
-     198,   170,   392,   119,   394,   130,   131,   121,   191,   259,
-     260,   347,   221,   222,   223,   224,   225,   226,   227,   228,
-     229,   230,   122,   130,   131,   300,   301,   321,   260,   123,
-     170,   150,   170,   150,   170,   150,   170,   150,   337,   338,
-     385,   333,   334,   335,   336,   372,   198,   398,   198,   126,
-     150,   150,   399,   198,   413,   301,   426,   427,   170,   447,
-     427,   170,   274,   170,   120,   453,   198,   458,   198,   459,
-     198,   124,   446,   127,   412,   147,   129,   156,   171,   173,
-     175,   195,   150,    10,   208,   423,   150,   209,   150,   219,
-     454,   220,   236,   237,   457,    31,    62,    32,    63,   232,
-     238,   255,   407,   257,   266,   263,   267,   265,   307,   411,
-     268,   275,    64,    65,   188,   302,   315,   316,   319,   318,
-     324,   327,   325,   141,    67,    68,   341,   340,   343,   344,
-     423,    69,   346,   431,   407,   351,   353,    70,    71,    72,
-     356,   360,   362,   376,   189,    73,   363,   364,   367,    74,
-     379,   444,    75,   407,   383,   380,   150,   260,   395,   400,
-     409,   396,    76,    77,   424,   408,   450,   425,   440,   436,
-      78,    79,   448,   460,   150,   461,   452,   432,   150,   214,
-     445,   348,   261,    80,   449,   314,   146,   313,   291,    81,
-     183,    82,    83,   140,    31,    62,    32,    63,   292,    84,
-     162,   186,    85,   215,   185,   386,     0,    86,   190,     0,
-       0,    64,    65,   401,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    67,    68,     0,     0,     0,     0,     0,
-      69,     0,     0,     0,     0,     0,    70,    71,    72,     0,
-       0,     0,     0,     0,    73,     0,     0,   163,    74,     0,
-       0,    75,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    76,    77,     0,     0,     0,     1,     0,     2,    78,
-      79,     0,     0,     0,     0,    31,    62,    32,    63,     0,
-       0,     0,    80,     0,     0,     0,     0,     0,    81,     0,
-      82,    83,    64,    65,    66,     3,     0,     0,    84,     0,
-       0,    85,     0,     0,    67,    68,   164,     0,     0,     4,
-       5,    69,     0,     0,     0,     6,     0,    70,    71,    72,
-       7,     0,     0,     0,     0,    73,     0,     0,     0,    74,
-       0,     0,    75,     0,     0,     8,     0,     0,     0,     0,
-       0,     0,    76,    77,     0,     0,     0,     0,     0,     0,
-      78,    79,     0,     0,     0,     9,    31,    62,    32,    63,
-       0,    10,     0,    80,     0,     0,     0,     0,     0,    81,
-      11,    82,    83,    64,    65,    12,     0,    13,     0,    84,
-       0,     0,    85,     0,     0,    67,    68,    86,     0,     0,
-       0,     0,    69,     0,     0,     0,     0,     0,    70,    71,
-      72,     0,     0,     0,     0,     0,    73,     0,     0,   163,
-      74,     0,     0,    75,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    76,    77,     0,     0,     0,     0,     0,
-       0,    78,    79,     0,     0,     0,     0,    31,    62,    32,
-      63,     0,     0,     0,    80,     0,     0,     0,     0,     0,
-      81,     0,    82,    83,    64,    65,     0,     0,     0,     0,
-      84,     0,     0,    85,     0,     0,    67,    68,   164,     0,
-       0,     0,     0,    69,     0,     0,     0,     0,     0,    70,
-      71,    72,     0,     0,     0,     0,     0,    73,     0,     0,
-       0,    74,     0,     0,    75,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    76,    77,     0,     0,     0,     0,
-       0,     0,    78,    79,     0,     0,     0,     0,    31,    62,
-      32,    63,     0,     0,     0,    80,     0,     0,     0,     0,
-       0,    81,     0,    82,    83,    64,   139,     0,     0,     0,
-       0,    84,     0,     0,    85,     0,     0,    67,    68,    86,
-       0,     0,     0,     0,    69,     0,     0,     0,     0,     0,
-      70,    71,    72,     0,     0,     0,     0,    62,    73,    63,
-       0,     0,    74,     0,     0,    75,     0,     0,     0,     0,
-       0,     0,     0,    64,   139,    76,    77,     0,     0,     0,
-      67,    68,     0,    78,    79,    67,    68,    69,     0,     0,
-       0,     0,    69,    70,    71,    72,    80,     0,    70,    71,
-      72,    73,    81,     0,    82,    83,    73,     0,    75,     0,
-       0,     0,    84,    75,     0,    85,     0,     0,    76,   213,
-      86,     0,     0,    76,    77,     0,    78,     0,     0,     0,
-       0,    78,    79,     0,     0,     0,     0,     0,     0,    80,
-       0,     0,     0,     0,    80,    81,     0,    82,    83,     0,
-      81,     0,    82,    83,     0,    84,     0,     0,    85,     0,
-      84,     0,     0,    85
+      33,   246,    45,   295,   277,   232,    51,    42,    46,    31,
+     232,    32,   193,    31,   232,    32,   451,   317,   232,   176,
+      92,   147,   178,   154,   136,   137,    55,   176,   213,   183,
+      57,    58,    59,    60,    61,   179,   381,   270,   452,   141,
+     142,   118,   183,   410,   412,   136,   137,   108,   122,   234,
+     235,   236,   237,   238,   239,   240,   241,   242,   243,   414,
+     136,   137,   136,   137,   416,   271,   131,   438,   441,   443,
+     136,   137,    39,   211,   176,   109,   176,   478,   299,   372,
+     211,   211,   210,   211,   230,   121,    50,   229,   140,    34,
+     318,   136,   137,   479,    45,   298,   211,    40,   180,   151,
+      46,   211,   156,   157,   211,   211,   211,   164,   167,   249,
+     300,    36,    10,   156,    92,   148,   180,   339,   301,   309,
+      35,    47,   456,   187,   392,   367,   153,   204,   291,   194,
+     453,    38,   433,   209,   197,   214,   272,   212,   176,   176,
+     143,   401,   388,   200,   374,   193,   189,   457,   288,   231,
+     148,   302,   323,    30,   167,   289,   219,   220,   215,   250,
+     303,   189,   253,   377,   304,     1,    10,     2,   330,    31,
+     261,    32,   350,   136,   137,   262,   305,    31,   116,    32,
+     263,   204,   195,   264,   464,   216,    46,   281,   117,    46,
+     176,    48,   348,    49,     3,   351,   352,   207,   345,   246,
+     265,   217,   151,   113,   258,   465,    37,   283,    52,     4,
+       5,    53,   206,    54,   261,     6,   353,   407,   293,   262,
+       7,   167,   315,   316,   263,    56,   266,   264,   322,   136,
+     137,   327,   378,   396,   380,   325,   382,     8,   384,   331,
+     397,   103,   328,    31,   265,    32,   104,   176,   326,   105,
+     332,   393,   394,   106,    46,   389,   333,     9,   344,   156,
+     136,   137,   194,    10,   398,   158,   159,   334,   107,    46,
+     138,   110,   176,    11,   312,   313,   314,   160,   161,    12,
+     405,    13,   111,   156,   411,   224,   225,   176,   415,   112,
+     417,   248,   211,   371,   113,   413,   136,   137,   278,   279,
+     369,   119,   376,   234,   235,   236,   237,   238,   239,   240,
+     241,   242,   243,   120,   136,   137,   176,   128,   176,   204,
+     176,   125,   176,   156,   437,   156,   439,   156,   440,   156,
+     442,   319,   320,   343,   279,   355,   356,   357,   358,   359,
+     360,   127,   156,   156,   176,   395,   211,   176,   126,   176,
+     129,   408,   460,   130,   293,   461,   132,   462,   469,   421,
+     211,   133,   422,   211,   436,   320,   449,   450,   470,   450,
+     476,   211,   481,   211,   135,   156,   477,   482,   211,   156,
+     480,   156,   153,   162,   177,   186,   435,   188,   208,    10,
+     221,   222,   232,   245,   233,   430,   254,   446,   255,   256,
+     274,   257,   434,   276,   282,   284,   285,   286,   287,   294,
+     324,   321,   329,   337,   338,   340,   341,   346,    31,    62,
+      32,    63,   347,   349,   147,   363,   454,   430,   362,   366,
+     365,   368,   373,   379,   375,    64,    65,   201,   383,   385,
+     399,   386,   446,   402,   467,   387,   430,    67,    68,   156,
+     390,   406,   418,   403,    69,    70,   419,   279,   423,   432,
+     431,    71,    72,    73,   447,   448,   459,   156,   202,    74,
+     473,   156,   483,   484,   227,    75,   471,   370,    76,   475,
+     463,   455,   468,   280,   336,   152,   472,   335,    77,    78,
+     310,   228,   311,   146,   196,   251,    79,    80,   252,   198,
+     409,     0,   184,   424,    31,    62,    32,    63,     0,    81,
+     168,   199,     0,     0,     0,    82,     0,     0,    83,    84,
+       0,    64,    65,     0,     0,     0,    85,     0,     0,     0,
+      86,     0,     0,    67,    68,    87,   203,     0,     0,     0,
+      69,    70,     0,     0,     0,     0,     0,    71,    72,    73,
+       0,     0,     0,     0,     0,    74,     0,     0,     0,     0,
+     169,    75,     0,     0,    76,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    77,    78,     0,     0,     0,     0,
+       0,     0,    79,    80,     0,     0,     0,     0,     0,    31,
+      62,    32,    63,     0,     0,    81,     0,     0,     0,     0,
+       0,    82,     0,     0,    83,    84,    64,    65,    66,     0,
+       0,     0,    85,     0,     0,     0,    86,     0,    67,    68,
+       0,   170,     0,     0,     0,    69,    70,     0,     0,     0,
+       0,     0,    71,    72,    73,     0,     0,     0,     0,     0,
+      74,     0,     0,     0,     0,     0,    75,     0,     0,    76,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    77,
+      78,     0,     0,     0,     0,     0,     0,    79,    80,     0,
+       0,     0,     0,     0,    31,    62,    32,    63,     0,     0,
+      81,     0,     0,     0,     0,     0,    82,     0,     0,    83,
+      84,    64,    65,     0,     0,     0,     0,    85,     0,     0,
+       0,    86,     0,    67,    68,     0,    87,     0,     0,     0,
+      69,    70,     0,     0,     0,     0,     0,    71,    72,    73,
+       0,     0,     0,     0,     0,    74,     0,     0,     0,     0,
+       0,    75,     0,     0,    76,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    77,    78,     0,     0,     0,     0,
+       0,     0,    79,    80,     0,     0,     0,     0,     0,    31,
+      62,    32,    63,     0,     0,    81,     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,     0,     0,     0,    69,    70,     0,     0,     0,
+       0,     0,    71,    72,    73,     0,     0,     0,     0,     0,
+      74,     0,     0,     0,     0,   169,    75,     0,     0,    76,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    77,
+      78,     0,     0,     0,     0,     0,     0,    79,    80,     0,
+       0,     0,     0,     0,    31,    62,    32,    63,     0,     0,
+      81,     0,     0,     0,     0,     0,    82,     0,     0,    83,
+      84,    64,    65,     0,     0,     0,     0,    85,     0,     0,
+       0,    86,     0,    67,    68,     0,   170,     0,     0,     0,
+      69,    70,     0,     0,     0,     0,     0,    71,    72,    73,
+       0,     0,     0,     0,     0,    74,     0,     0,     0,     0,
+       0,    75,     0,     0,    76,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    77,    78,     0,     0,     0,     0,
+       0,     0,    79,    80,     0,     0,     0,     0,     0,    31,
+      62,    32,    63,     0,     0,    81,     0,     0,     0,     0,
+       0,    82,     0,     0,    83,    84,    64,   145,     0,     0,
+       0,     0,    85,     0,     0,     0,    86,     0,    67,    68,
+       0,    87,    62,     0,    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,    70,    77,
+      78,     0,     0,     0,    71,    72,    73,    79,    80,     0,
+       0,     0,    74,     0,     0,     0,     0,     0,     0,     0,
+      81,    76,     0,     0,     0,     0,    82,     0,     0,    83,
+      84,    77,    78,     0,    67,    68,     0,    85,     0,    79,
+      80,    86,    70,     0,     0,     0,    87,     0,    71,    72,
+      73,     0,    81,     0,     0,     0,    74,     0,    82,     0,
+       0,    83,    84,     0,     0,    76,     0,     0,     0,    85,
+       0,     0,     0,    86,     0,    77,   226,     0,     0,     0,
+       0,     0,     0,    79,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    81,     0,     0,     0,
+       0,     0,    82,     0,     0,    83,    84,     0,     0,     0,
+       0,     0,     0,    85,     0,     0,     0,    86
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,    41,   164,    12,   171,    26,   211,    11,    12,   189,
-       8,   127,     8,     4,    36,     6,     7,     4,     8,     6,
-      23,    24,    21,    22,   111,    27,    30,   115,   152,    10,
-      34,    35,    36,    37,    38,   180,   103,    83,    29,    59,
-      61,    83,    70,    21,    22,    83,    86,    10,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    83,    21,    22,
-      83,   109,    82,    83,     4,    66,     6,    99,    96,    83,
-     118,   128,   118,    83,    99,   162,   118,   164,    83,    68,
-     118,   103,   102,    29,    63,    28,   143,    91,   212,   129,
-      91,    31,   118,   102,   116,   118,   163,   101,   102,    80,
-     104,   105,   142,   265,   118,   109,   110,    53,   118,   254,
-      99,   115,    55,   118,   116,   282,   119,   121,   117,   117,
-      73,   117,   209,   127,   164,   116,   147,   117,   132,   116,
-     151,   247,   219,   220,   301,   340,    74,   141,   318,   117,
-      41,    51,     4,     4,     6,     6,    56,    85,   152,   189,
-     154,   155,    21,    22,   117,   195,   244,   319,     9,    21,
-      22,    62,    64,    32,     0,    60,    74,    69,    10,    31,
-      21,    22,    74,   177,    64,    77,   180,    85,   265,    69,
-     268,    76,   344,    52,    74,     3,   353,    77,    89,   193,
-     230,   231,    94,    63,   198,    74,   358,   237,    96,    41,
-       9,   117,   118,   104,    94,   209,    85,    49,   212,   107,
-      51,    97,    21,    22,   118,    56,   118,   305,   116,   307,
-     260,   309,   116,   311,   112,   387,   114,   389,    31,   391,
-     239,   393,   319,   117,   118,   239,   324,   325,    80,   112,
-     244,    73,   115,   247,    17,    18,    19,    89,     5,   336,
-     254,    93,    83,   415,     7,   295,   418,   344,   420,    42,
-      43,   116,   104,   109,   268,    42,    43,     7,   356,   117,
-     118,   358,   360,   116,   362,    21,    22,   116,   318,   117,
-     118,   285,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,     5,    21,    22,   117,   118,   117,   118,   116,
-     387,   305,   389,   307,   391,   309,   393,   311,    37,    38,
-     350,   117,   118,   117,   118,   117,   118,   117,   118,     5,
-     324,   325,   117,   118,   117,   118,   117,   118,   415,   117,
-     118,   418,   336,   420,    72,   117,   118,   117,   118,   117,
-     118,    72,   430,    63,   384,   116,   118,   110,   116,     7,
-       7,    11,   356,    96,   116,   395,   360,   116,   362,     8,
-     448,     9,   117,    63,   452,     4,     5,     6,     7,    20,
-     117,    65,   376,   117,    75,   117,    75,   116,    74,   383,
-     116,   106,    21,    22,    23,   107,     7,     7,    67,    39,
-     116,     5,   116,    27,    33,    34,   110,   118,    80,   116,
-     440,    40,    75,   407,   408,    80,   116,    46,    47,    48,
-      74,    74,    74,   116,    53,    54,    88,    88,    84,    58,
-      35,   425,    61,   427,   116,    86,   430,   118,    39,     5,
-      39,    78,    71,    72,     7,   116,    81,    93,   118,   117,
-      79,    80,   116,    87,   448,     7,   116,   408,   452,   161,
-     427,   288,   193,    92,   440,   249,   102,   247,   219,    98,
-     129,   100,   101,    99,     4,     5,     6,     7,   220,   108,
-      10,   138,   111,   162,   133,   353,    -1,   116,   117,    -1,
-      -1,    21,    22,   374,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    33,    34,    -1,    -1,    -1,    -1,    -1,
-      40,    -1,    -1,    -1,    -1,    -1,    46,    47,    48,    -1,
-      -1,    -1,    -1,    -1,    54,    -1,    -1,    57,    58,    -1,
-      -1,    61,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    71,    72,    -1,    -1,    -1,     1,    -1,     3,    79,
-      80,    -1,    -1,    -1,    -1,     4,     5,     6,     7,    -1,
-      -1,    -1,    92,    -1,    -1,    -1,    -1,    -1,    98,    -1,
-     100,   101,    21,    22,    23,    30,    -1,    -1,   108,    -1,
-      -1,   111,    -1,    -1,    33,    34,   116,    -1,    -1,    44,
-      45,    40,    -1,    -1,    -1,    50,    -1,    46,    47,    48,
-      55,    -1,    -1,    -1,    -1,    54,    -1,    -1,    -1,    58,
-      -1,    -1,    61,    -1,    -1,    70,    -1,    -1,    -1,    -1,
-      -1,    -1,    71,    72,    -1,    -1,    -1,    -1,    -1,    -1,
-      79,    80,    -1,    -1,    -1,    90,     4,     5,     6,     7,
-      -1,    96,    -1,    92,    -1,    -1,    -1,    -1,    -1,    98,
-     105,   100,   101,    21,    22,   110,    -1,   112,    -1,   108,
-      -1,    -1,   111,    -1,    -1,    33,    34,   116,    -1,    -1,
-      -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    46,    47,
-      48,    -1,    -1,    -1,    -1,    -1,    54,    -1,    -1,    57,
-      58,    -1,    -1,    61,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    71,    72,    -1,    -1,    -1,    -1,    -1,
-      -1,    79,    80,    -1,    -1,    -1,    -1,     4,     5,     6,
-       7,    -1,    -1,    -1,    92,    -1,    -1,    -1,    -1,    -1,
-      98,    -1,   100,   101,    21,    22,    -1,    -1,    -1,    -1,
-     108,    -1,    -1,   111,    -1,    -1,    33,    34,   116,    -1,
-      -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    46,
-      47,    48,    -1,    -1,    -1,    -1,    -1,    54,    -1,    -1,
-      -1,    58,    -1,    -1,    61,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    71,    72,    -1,    -1,    -1,    -1,
-      -1,    -1,    79,    80,    -1,    -1,    -1,    -1,     4,     5,
-       6,     7,    -1,    -1,    -1,    92,    -1,    -1,    -1,    -1,
-      -1,    98,    -1,   100,   101,    21,    22,    -1,    -1,    -1,
-      -1,   108,    -1,    -1,   111,    -1,    -1,    33,    34,   116,
-      -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,
-      46,    47,    48,    -1,    -1,    -1,    -1,     5,    54,     7,
-      -1,    -1,    58,    -1,    -1,    61,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    21,    22,    71,    72,    -1,    -1,    -1,
-      33,    34,    -1,    79,    80,    33,    34,    40,    -1,    -1,
-      -1,    -1,    40,    46,    47,    48,    92,    -1,    46,    47,
-      48,    54,    98,    -1,   100,   101,    54,    -1,    61,    -1,
-      -1,    -1,   108,    61,    -1,   111,    -1,    -1,    71,    72,
-     116,    -1,    -1,    71,    72,    -1,    79,    -1,    -1,    -1,
-      -1,    79,    80,    -1,    -1,    -1,    -1,    -1,    -1,    92,
-      -1,    -1,    -1,    -1,    92,    98,    -1,   100,   101,    -1,
-      98,    -1,   100,   101,    -1,   108,    -1,    -1,   111,    -1,
-     108,    -1,    -1,   111
+       4,   177,    12,   224,   202,     8,    26,    11,    12,     4,
+       8,     6,   133,     4,     8,     6,     7,    10,     8,   113,
+      41,    27,   117,   105,    21,    22,    30,   121,   158,    57,
+      34,    35,    36,    37,    38,   121,    86,   193,    29,    23,
+      24,    61,    57,    86,    86,    21,    22,    28,    69,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    86,
+      21,    22,    21,    22,    86,    36,    87,    86,    86,    86,
+      21,    22,    29,   123,   168,    56,   170,    63,    10,     9,
+     123,   123,   122,   123,   170,   113,    73,   169,    92,    71,
+      83,    21,    22,    79,   104,   225,   123,    54,   113,   103,
+     104,   123,   106,   107,   123,   123,   123,   111,   112,   103,
+      42,    66,    99,   117,   135,   121,   113,   273,    50,   122,
+     102,     0,    69,   127,   122,   301,   121,   148,   222,   133,
+     121,    76,   122,   153,   138,    42,   107,   157,   232,   233,
+     124,   362,   340,   147,   320,   266,   122,    94,    52,   170,
+     121,    83,   103,   102,   158,    59,   160,   161,    65,   180,
+      92,   122,   183,   122,    96,     1,    99,     3,   263,     4,
+      67,     6,    62,    21,    22,    72,   108,     4,   111,     6,
+      77,   202,   134,    80,    32,    92,   190,   208,   121,   193,
+     284,   117,   287,   119,    30,    85,    86,   149,   284,   375,
+      97,   108,   206,   114,    31,    53,   102,   211,   117,    45,
+      46,   120,   123,     3,    67,    51,   106,     9,   222,    72,
+      56,   225,   243,   244,    77,    66,   123,    80,   249,    21,
+      22,    77,   327,    52,   329,   256,   331,    73,   333,    77,
+      59,   100,    88,     4,    97,     6,   123,   341,   258,    31,
+      88,   346,   347,   121,   258,   341,    77,    93,   279,   263,
+      21,    22,   266,    99,   358,    43,    44,    88,    76,   273,
+      31,     5,   366,   109,    17,    18,    19,    43,    44,   115,
+     366,   117,    86,   287,   379,   122,   123,   381,   383,   121,
+     385,   122,   123,   314,   114,   381,    21,    22,   122,   123,
+     304,     7,   323,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,     7,    21,    22,   410,     5,   412,   340,
+     414,   121,   416,   327,   410,   329,   412,   331,   414,   333,
+     416,   122,   123,   122,   123,   122,   123,   122,   123,    37,
+      38,   121,   346,   347,   438,   122,   123,   441,    75,   443,
+     121,   372,   438,    75,   358,   441,     5,   443,   453,   122,
+     123,    66,   122,   123,   122,   123,   122,   123,   122,   123,
+     122,   123,   122,   123,   123,   379,   471,   122,   123,   383,
+     475,   385,   121,   115,   121,     7,   407,     7,    11,    99,
+     121,   121,     8,    20,     9,   399,    58,   418,   122,    66,
+      68,   122,   406,   122,   122,   121,    78,    78,   121,   110,
+      58,   111,    77,     7,     7,    39,    70,   121,     4,     5,
+       6,     7,   121,     5,    27,   115,   430,   431,   123,   121,
+      83,    78,    83,    77,   121,    21,    22,    23,    77,    77,
+     121,    91,   463,    35,   448,    91,   450,    33,    34,   453,
+      87,   121,    39,    89,    40,    41,    81,   123,     5,    39,
+     121,    47,    48,    49,     7,    96,   122,   471,    54,    55,
+      84,   475,    90,     7,   167,    61,   121,   307,    64,   121,
+     123,   431,   450,   206,   268,   104,   463,   266,    74,    75,
+     232,   168,   233,   101,   135,   181,    82,    83,   181,   139,
+     375,    -1,   123,   397,     4,     5,     6,     7,    -1,    95,
+      10,   144,    -1,    -1,    -1,   101,    -1,    -1,   104,   105,
+      -1,    21,    22,    -1,    -1,    -1,   112,    -1,    -1,    -1,
+     116,    -1,    -1,    33,    34,   121,   122,    -1,    -1,    -1,
+      40,    41,    -1,    -1,    -1,    -1,    -1,    47,    48,    49,
+      -1,    -1,    -1,    -1,    -1,    55,    -1,    -1,    -1,    -1,
+      60,    61,    -1,    -1,    64,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    74,    75,    -1,    -1,    -1,    -1,
+      -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    95,    -1,    -1,    -1,    -1,
+      -1,   101,    -1,    -1,   104,   105,    21,    22,    23,    -1,
+      -1,    -1,   112,    -1,    -1,    -1,   116,    -1,    33,    34,
+      -1,   121,    -1,    -1,    -1,    40,    41,    -1,    -1,    -1,
+      -1,    -1,    47,    48,    49,    -1,    -1,    -1,    -1,    -1,
+      55,    -1,    -1,    -1,    -1,    -1,    61,    -1,    -1,    64,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    74,
+      75,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,    -1,
+      -1,    -1,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
+      95,    -1,    -1,    -1,    -1,    -1,   101,    -1,    -1,   104,
+     105,    21,    22,    -1,    -1,    -1,    -1,   112,    -1,    -1,
+      -1,   116,    -1,    33,    34,    -1,   121,    -1,    -1,    -1,
+      40,    41,    -1,    -1,    -1,    -1,    -1,    47,    48,    49,
+      -1,    -1,    -1,    -1,    -1,    55,    -1,    -1,    -1,    -1,
+      -1,    61,    -1,    -1,    64,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    74,    75,    -1,    -1,    -1,    -1,
+      -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    95,    -1,    -1,    -1,    -1,
+      -1,   101,    -1,    -1,   104,   105,    21,    22,    -1,    -1,
+      -1,    -1,   112,   113,    -1,    -1,   116,    -1,    33,    34,
+      -1,   121,    -1,    -1,    -1,    40,    41,    -1,    -1,    -1,
+      -1,    -1,    47,    48,    49,    -1,    -1,    -1,    -1,    -1,
+      55,    -1,    -1,    -1,    -1,    60,    61,    -1,    -1,    64,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    74,
+      75,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,    -1,
+      -1,    -1,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
+      95,    -1,    -1,    -1,    -1,    -1,   101,    -1,    -1,   104,
+     105,    21,    22,    -1,    -1,    -1,    -1,   112,    -1,    -1,
+      -1,   116,    -1,    33,    34,    -1,   121,    -1,    -1,    -1,
+      40,    41,    -1,    -1,    -1,    -1,    -1,    47,    48,    49,
+      -1,    -1,    -1,    -1,    -1,    55,    -1,    -1,    -1,    -1,
+      -1,    61,    -1,    -1,    64,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    74,    75,    -1,    -1,    -1,    -1,
+      -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    95,    -1,    -1,    -1,    -1,
+      -1,   101,    -1,    -1,   104,   105,    21,    22,    -1,    -1,
+      -1,    -1,   112,    -1,    -1,    -1,   116,    -1,    33,    34,
+      -1,   121,     5,    -1,     7,    40,    41,    -1,    -1,    -1,
+      -1,    -1,    47,    48,    49,    -1,    -1,    -1,    21,    22,
+      55,    -1,    -1,    -1,    -1,    -1,    61,    -1,    -1,    64,
+      33,    34,    -1,    -1,    -1,    -1,    -1,    -1,    41,    74,
+      75,    -1,    -1,    -1,    47,    48,    49,    82,    83,    -1,
+      -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      95,    64,    -1,    -1,    -1,    -1,   101,    -1,    -1,   104,
+     105,    74,    75,    -1,    33,    34,    -1,   112,    -1,    82,
+      83,   116,    41,    -1,    -1,    -1,   121,    -1,    47,    48,
+      49,    -1,    95,    -1,    -1,    -1,    55,    -1,   101,    -1,
+      -1,   104,   105,    -1,    -1,    64,    -1,    -1,    -1,   112,
+      -1,    -1,    -1,   116,    -1,    74,    75,    -1,    -1,    -1,
+      -1,    -1,    -1,    82,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    95,    -1,    -1,    -1,
+      -1,    -1,   101,    -1,    -1,   104,   105,    -1,    -1,    -1,
+      -1,    -1,    -1,   112,    -1,    -1,    -1,   116
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     1,     3,    30,    44,    45,    50,    55,    70,    90,
-      96,   105,   110,   112,   121,   122,   123,   124,   125,   126,
-     127,   148,   149,   152,   153,   156,   157,   160,   207,   208,
-      99,     4,     6,   205,    68,    99,    63,    99,    73,    29,
-      53,   161,   205,   158,   159,   173,   205,     0,   112,   114,
-      70,   160,   112,   115,     3,   205,    63,   205,   205,   205,
-     205,   205,     5,     7,    21,    22,    23,    33,    34,    40,
-      46,    47,    48,    54,    58,    61,    71,    72,    79,    80,
-      92,    98,   100,   101,   108,   111,   116,   130,   162,   163,
-     164,   189,   190,   191,   192,   193,   194,   196,   198,   201,
-     205,    97,   118,    31,   116,    73,    28,    55,     5,    83,
-     116,   109,   183,   184,   107,   116,   160,     7,     7,   116,
-      72,   116,     5,   116,    72,   189,     5,    63,   165,   118,
-      21,    22,    31,   202,   205,    23,    24,   119,   203,    22,
-     192,    27,   116,   154,   155,   205,   159,   116,   169,   204,
-     205,   205,    42,    43,    42,    43,   110,   150,   205,   128,
-     129,   205,    10,    57,   116,   185,   186,   187,   188,   189,
-     198,   116,   204,     7,   205,     7,   117,   169,   171,   174,
-     193,   205,   183,   164,   205,   190,   191,   205,    23,    53,
-     117,   189,   195,   118,   183,    11,   160,   117,   118,   160,
-     128,    41,    62,    89,   104,   134,   205,   205,   116,   116,
-     137,   117,   118,    72,   130,   188,   169,   185,   189,     8,
-       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,   200,    20,   196,   197,   117,   117,    63,   117,    31,
-     172,   173,    64,    69,    74,    77,    94,   118,   166,   167,
-     168,   172,    36,   103,   170,    65,   175,   117,   195,   117,
-     118,   155,   189,   117,   205,   116,    75,    75,   116,    51,
-      56,   151,   198,   199,   205,   106,   134,   135,   136,   128,
-      10,    41,    49,    80,    89,    93,   104,   131,   132,   133,
-     117,   186,   187,    17,    18,    19,   189,   189,    10,    80,
-     117,   118,   107,   189,   173,    74,    85,    74,   204,    74,
-      85,    74,    85,   171,   168,     7,     7,   172,    39,    67,
-     176,   117,   189,   185,   116,   116,   204,     5,    59,    82,
-      83,   102,   206,   117,   118,   117,   118,    37,    38,   146,
-     118,   110,   138,    80,   116,   196,    75,   205,   131,   189,
-       9,    80,   196,   116,   117,   204,    74,   204,    83,   204,
-      74,   204,    74,    88,    88,   195,   185,    84,   177,   117,
-     204,   204,   117,    51,    56,   198,   116,   147,   134,    35,
-      86,   139,   185,   116,     9,   189,   197,    83,   204,    83,
-     185,    83,   204,    83,   204,    39,    78,   178,   117,   117,
-       5,   206,   141,   142,   143,   144,   145,   205,   116,    39,
-     117,   205,   189,   117,   185,    83,   185,   185,    83,   185,
-      83,   179,   180,   189,     7,    93,   117,   118,     7,    29,
-     116,   205,   141,    66,    91,   140,   117,   185,   185,   185,
-     118,    32,    52,   181,   205,   142,   204,   117,   116,   180,
-      81,   182,   116,   117,   204,    60,    76,   204,   117,   117,
-      87,     7
+       0,     1,     3,    30,    45,    46,    51,    56,    73,    93,
+      99,   109,   115,   117,   126,   127,   128,   129,   130,   131,
+     132,   153,   154,   157,   158,   161,   162,   165,   218,   219,
+     102,     4,     6,   216,    71,   102,    66,   102,    76,    29,
+      54,   166,   216,   163,   164,   178,   216,     0,   117,   119,
+      73,   165,   117,   120,     3,   216,    66,   216,   216,   216,
+     216,   216,     5,     7,    21,    22,    23,    33,    34,    40,
+      41,    47,    48,    49,    55,    61,    64,    74,    75,    82,
+      83,    95,   101,   104,   105,   112,   116,   121,   135,   167,
+     168,   169,   194,   195,   196,   197,   198,   199,   200,   207,
+     209,   212,   216,   100,   123,    31,   121,    76,    28,    56,
+       5,    86,   121,   114,   188,   189,   111,   121,   165,     7,
+       7,   113,   194,   203,   204,   121,    75,   121,     5,   121,
+      75,   194,     5,    66,   170,   123,    21,    22,    31,   213,
+     216,    23,    24,   124,   214,    22,   197,    27,   121,   159,
+     160,   216,   164,   121,   174,   215,   216,   216,    43,    44,
+      43,    44,   115,   155,   216,   133,   134,   216,    10,    60,
+     121,   190,   191,   192,   193,   194,   209,   121,   215,   190,
+     113,   201,   202,    57,   204,   205,     7,   216,     7,   122,
+     174,   176,   179,   198,   216,   188,   169,   216,   195,   196,
+     216,    23,    54,   122,   194,   206,   123,   188,    11,   165,
+     122,   123,   165,   133,    42,    65,    92,   108,   139,   216,
+     216,   121,   121,   142,   122,   123,    75,   135,   193,   174,
+     190,   194,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,   211,    20,   207,   208,   122,   103,
+     194,   202,   205,   194,    58,   122,    66,   122,    31,   177,
+     178,    67,    72,    77,    80,    97,   123,   171,   172,   173,
+     177,    36,   107,   175,    68,   180,   122,   206,   122,   123,
+     160,   194,   122,   216,   121,    78,    78,   121,    52,    59,
+     156,   209,   210,   216,   110,   139,   140,   141,   133,    10,
+      42,    50,    83,    92,    96,   108,   136,   137,   138,   122,
+     191,   192,    17,    18,    19,   194,   194,    10,    83,   122,
+     123,   111,   194,   103,    58,   194,   178,    77,    88,    77,
+     215,    77,    88,    77,    88,   176,   173,     7,     7,   177,
+      39,    70,   181,   122,   194,   190,   121,   121,   215,     5,
+      62,    85,    86,   106,   217,   122,   123,   122,   123,    37,
+      38,   151,   123,   115,   143,    83,   121,   207,    78,   216,
+     136,   194,     9,    83,   207,   121,   194,   122,   215,    77,
+     215,    86,   215,    77,   215,    77,    91,    91,   206,   190,
+      87,   182,   122,   215,   215,   122,    52,    59,   209,   121,
+     152,   139,    35,    89,   144,   190,   121,     9,   194,   208,
+      86,   215,    86,   190,    86,   215,    86,   215,    39,    81,
+     183,   122,   122,     5,   217,   146,   147,   148,   149,   150,
+     216,   121,    39,   122,   216,   194,   122,   190,    86,   190,
+     190,    86,   190,    86,   184,   185,   194,     7,    96,   122,
+     123,     7,    29,   121,   216,   146,    69,    94,   145,   122,
+     190,   190,   190,   123,    32,    53,   186,   216,   147,   215,
+     122,   121,   185,    84,   187,   121,   122,   215,    63,    79,
+     215,   122,   122,    90,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,   120,   121,   121,   121,   121,   121,   121,   122,   122,
-     122,   122,   122,   122,   122,   122,   122,   122,   123,   124,
-     124,   124,   124,   125,   126,   127,   128,   129,   129,   130,
-     130,   130,   130,   130,   130,   130,   130,   130,   130,   130,
-     130,   130,   130,   130,   130,   130,   130,   131,   131,   131,
-     131,   131,   131,   131,   132,   132,   133,   133,   134,   134,
-     134,   134,   135,   135,   136,   136,   137,   137,   138,   138,
-     139,   139,   140,   140,   141,   141,   142,   142,   142,   143,
-     143,   144,   145,   146,   146,   147,   147,   148,   148,   148,
-     148,   149,   150,   150,   151,   151,   151,   151,   152,   153,
-     154,   154,   155,   156,   156,   157,   158,   158,   159,   160,
-     161,   161,   161,   162,   162,   163,   163,   164,   164,   164,
-     165,   166,   166,   167,   167,   168,   168,   168,   168,   168,
-     168,   168,   168,   169,   170,   170,   170,   171,   171,   171,
-     171,   171,   172,   172,   173,   173,   174,   174,   175,   175,
-     176,   176,   177,   177,   178,   178,   179,   179,   180,   181,
-     181,   181,   182,   182,   182,   183,   183,   184,   185,   185,
-     186,   186,   187,   187,   188,   188,   188,   188,   188,   188,
-     188,   189,   189,   190,   190,   191,   191,   192,   192,   192,
-     192,   192,   193,   193,   193,   193,   194,   195,   195,   196,
-     196,   196,   196,   196,   196,   196,   197,   197,   198,   198,
-     199,   199,   200,   200,   200,   200,   200,   200,   200,   200,
-     200,   200,   201,   202,   202,   203,   203,   203,   204,   204,
-     205,   205,   206,   206,   206,   206,   207,   208,   208
+       0,   125,   126,   126,   126,   126,   126,   126,   127,   127,
+     127,   127,   127,   127,   127,   127,   127,   127,   128,   129,
+     129,   129,   129,   130,   131,   132,   133,   134,   134,   135,
+     135,   135,   135,   135,   135,   135,   135,   135,   135,   135,
+     135,   135,   135,   135,   135,   135,   135,   136,   136,   136,
+     136,   136,   136,   136,   137,   137,   138,   138,   139,   139,
+     139,   139,   140,   140,   141,   141,   142,   142,   143,   143,
+     144,   144,   145,   145,   146,   146,   147,   147,   147,   148,
+     148,   149,   150,   151,   151,   152,   152,   153,   153,   153,
+     153,   154,   155,   155,   156,   156,   156,   156,   157,   158,
+     159,   159,   160,   161,   161,   162,   163,   163,   164,   165,
+     166,   166,   166,   167,   167,   168,   168,   169,   169,   169,
+     170,   171,   171,   172,   172,   173,   173,   173,   173,   173,
+     173,   173,   173,   174,   175,   175,   175,   176,   176,   176,
+     176,   176,   177,   177,   178,   178,   179,   179,   180,   180,
+     181,   181,   182,   182,   183,   183,   184,   184,   185,   186,
+     186,   186,   187,   187,   187,   188,   188,   189,   190,   190,
+     191,   191,   192,   192,   193,   193,   193,   193,   193,   193,
+     193,   194,   194,   195,   195,   196,   196,   197,   197,   197,
+     197,   197,   197,   198,   198,   198,   198,   199,   200,   200,
+     201,   201,   202,   203,   203,   204,   205,   205,   206,   206,
+     207,   207,   207,   207,   207,   207,   207,   208,   208,   209,
+     209,   210,   210,   211,   211,   211,   211,   211,   211,   211,
+     211,   211,   211,   212,   213,   213,   214,   214,   214,   215,
+     215,   216,   216,   217,   217,   217,   217,   218,   219,   219
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -1286,11 +1347,12 @@
        1,     1,     0,     2,     2,     0,     1,     2,     3,     1,
        3,     1,     2,     1,     5,     6,     4,     3,     3,     3,
        2,     3,     1,     3,     1,     2,     1,     1,     1,     1,
-       1,     3,     3,     4,     4,     5,     6,     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
+       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
 };
 
 
@@ -1787,833 +1849,893 @@
   switch (yytype)
     {
           case 3: /* TOKEN_COMMAND  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1797 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1859 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 4: /* TOKEN_NAME  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1807 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1869 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 5: /* TOKEN_STRING_SINGLE_QUOTED  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1817 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1879 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 6: /* TOKEN_STRING_DOUBLE_QUOTED  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1827 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1889 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 7: /* TOKEN_UNSIGNED_NUMVAL  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).numeric_literal_value_) != nullptr) {
     delete ((*yyvaluep).numeric_literal_value_);
   }
 }
-#line 1837 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1899 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 122: /* sql_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 127: /* sql_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).statement_) != nullptr) {
     delete ((*yyvaluep).statement_);
   }
 }
-#line 1847 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1909 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 123: /* quit_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 128: /* quit_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).quit_statement_) != nullptr) {
     delete ((*yyvaluep).quit_statement_);
   }
 }
-#line 1857 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1919 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 124: /* alter_table_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 129: /* alter_table_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).statement_) != nullptr) {
     delete ((*yyvaluep).statement_);
   }
 }
-#line 1867 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1929 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 125: /* create_table_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 130: /* create_table_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).create_table_statement_) != nullptr) {
     delete ((*yyvaluep).create_table_statement_);
   }
 }
-#line 1877 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1939 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 126: /* create_index_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 131: /* create_index_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).statement_) != nullptr) {
     delete ((*yyvaluep).statement_);
   }
 }
-#line 1887 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1949 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 127: /* drop_table_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 132: /* drop_table_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).drop_table_statement_) != nullptr) {
     delete ((*yyvaluep).drop_table_statement_);
   }
 }
-#line 1897 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1959 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 128: /* column_def  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 133: /* column_def  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_definition_) != nullptr) {
     delete ((*yyvaluep).attribute_definition_);
   }
 }
-#line 1907 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1969 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 129: /* column_def_commalist  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 134: /* column_def_commalist  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_definition_list_) != nullptr) {
     delete ((*yyvaluep).attribute_definition_list_);
   }
 }
-#line 1917 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1979 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 130: /* data_type  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 135: /* data_type  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).data_type_) != nullptr) {
     delete ((*yyvaluep).data_type_);
   }
 }
-#line 1927 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1989 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 131: /* column_constraint_def  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 136: /* column_constraint_def  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).column_constraint_) != nullptr) {
     delete ((*yyvaluep).column_constraint_);
   }
 }
-#line 1937 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1999 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 132: /* column_constraint_def_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 137: /* column_constraint_def_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).column_constraint_list_) != nullptr) {
     delete ((*yyvaluep).column_constraint_list_);
   }
 }
-#line 1947 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2009 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 133: /* opt_column_constraint_def_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 138: /* opt_column_constraint_def_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).column_constraint_list_) != nullptr) {
     delete ((*yyvaluep).column_constraint_list_);
   }
 }
-#line 1957 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2019 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 137: /* opt_column_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 142: /* opt_column_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_list_) != nullptr) {
     delete ((*yyvaluep).attribute_list_);
   }
 }
-#line 1967 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2029 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 138: /* opt_block_properties  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 143: /* opt_block_properties  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).block_properties_) != nullptr) {
     delete ((*yyvaluep).block_properties_);
   }
 }
-#line 1977 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2039 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 139: /* opt_partition_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 144: /* opt_partition_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).partition_clause_) != nullptr) {
     delete ((*yyvaluep).partition_clause_);
   }
 }
-#line 1987 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2049 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 140: /* partition_type  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 145: /* partition_type  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 1997 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2059 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 141: /* key_value_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 146: /* key_value_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_value_list_) != nullptr) {
     delete ((*yyvaluep).key_value_list_);
   }
 }
-#line 2007 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2069 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 142: /* key_value  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 147: /* key_value  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_value_) != nullptr) {
     delete ((*yyvaluep).key_value_);
   }
 }
-#line 2017 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2079 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 143: /* key_string_value  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 148: /* key_string_value  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_string_value_) != nullptr) {
     delete ((*yyvaluep).key_string_value_);
   }
 }
-#line 2027 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2089 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 144: /* key_string_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 149: /* key_string_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_string_list_) != nullptr) {
     delete ((*yyvaluep).key_string_list_);
   }
 }
-#line 2037 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2099 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 145: /* key_integer_value  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 150: /* key_integer_value  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_integer_value_) != nullptr) {
     delete ((*yyvaluep).key_integer_value_);
   }
 }
-#line 2047 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2109 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 146: /* index_type  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 151: /* index_type  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2057 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2119 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 147: /* opt_index_properties  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 152: /* opt_index_properties  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).key_value_list_) != nullptr) {
     delete ((*yyvaluep).key_value_list_);
   }
 }
-#line 2067 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2129 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 148: /* insert_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 153: /* insert_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).insert_statement_) != nullptr) {
     delete ((*yyvaluep).insert_statement_);
   }
 }
-#line 2077 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2139 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 149: /* copy_from_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 154: /* copy_from_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).copy_from_statement_) != nullptr) {
     delete ((*yyvaluep).copy_from_statement_);
   }
 }
-#line 2087 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2149 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 150: /* opt_copy_from_params  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 155: /* opt_copy_from_params  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).copy_from_params_) != nullptr) {
     delete ((*yyvaluep).copy_from_params_);
   }
 }
-#line 2097 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2159 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 151: /* copy_from_params  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 156: /* copy_from_params  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).copy_from_params_) != nullptr) {
     delete ((*yyvaluep).copy_from_params_);
   }
 }
-#line 2107 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2169 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 152: /* update_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 157: /* update_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).update_statement_) != nullptr) {
     delete ((*yyvaluep).update_statement_);
   }
 }
-#line 2117 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2179 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 153: /* delete_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 158: /* delete_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).delete_statement_) != nullptr) {
     delete ((*yyvaluep).delete_statement_);
   }
 }
-#line 2127 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2189 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 154: /* assignment_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 159: /* assignment_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).assignment_list_) != nullptr) {
     delete ((*yyvaluep).assignment_list_);
   }
 }
-#line 2137 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2199 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 155: /* assignment_item  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 160: /* assignment_item  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).assignment_) != nullptr) {
     delete ((*yyvaluep).assignment_);
   }
 }
-#line 2147 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2209 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 156: /* select_statement  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 161: /* select_statement  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).select_statement_) != nullptr) {
     delete ((*yyvaluep).select_statement_);
   }
 }
-#line 2157 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2219 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 157: /* with_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 162: /* with_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).with_list_) != nullptr) {
     delete ((*yyvaluep).with_list_);
   }
 }
-#line 2167 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2229 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 158: /* with_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 163: /* with_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).with_list_) != nullptr) {
     delete ((*yyvaluep).with_list_);
   }
 }
-#line 2177 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2239 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 159: /* with_list_element  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 164: /* with_list_element  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).with_list_element_) != nullptr) {
     delete ((*yyvaluep).with_list_element_);
   }
 }
-#line 2187 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2249 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 160: /* select_query  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 165: /* select_query  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).select_query_) != nullptr) {
     delete ((*yyvaluep).select_query_);
   }
 }
-#line 2197 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2259 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 162: /* selection  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 167: /* selection  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).selection_) != nullptr) {
     delete ((*yyvaluep).selection_);
   }
 }
-#line 2207 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2269 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 163: /* selection_item_commalist  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 168: /* selection_item_commalist  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).selection_list_) != nullptr) {
     delete ((*yyvaluep).selection_list_);
   }
 }
-#line 2217 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2279 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 164: /* selection_item  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 169: /* selection_item  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).selection_item_) != nullptr) {
     delete ((*yyvaluep).selection_item_);
   }
 }
-#line 2227 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2289 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 165: /* from_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 170: /* from_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_list_) != nullptr) {
     delete ((*yyvaluep).table_reference_list_);
   }
 }
-#line 2237 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2299 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 169: /* subquery_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 174: /* subquery_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).subquery_expression_) != nullptr) {
     delete ((*yyvaluep).subquery_expression_);
   }
 }
-#line 2247 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2309 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 170: /* opt_sample_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 175: /* opt_sample_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_sample_clause_) != nullptr) {
     delete ((*yyvaluep).opt_sample_clause_);
   }
 }
-#line 2257 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2319 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 171: /* table_reference  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 176: /* table_reference  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_) != nullptr) {
     delete ((*yyvaluep).table_reference_);
   }
 }
-#line 2267 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2329 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 172: /* table_reference_signature  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 177: /* table_reference_signature  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_signature_) != nullptr) {
     delete ((*yyvaluep).table_reference_signature_);
   }
 }
-#line 2277 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2339 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 173: /* table_reference_signature_primary  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 178: /* table_reference_signature_primary  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_signature_) != nullptr) {
     delete ((*yyvaluep).table_reference_signature_);
   }
 }
-#line 2287 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2349 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 174: /* table_reference_commalist  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 179: /* table_reference_commalist  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).table_reference_list_) != nullptr) {
     delete ((*yyvaluep).table_reference_list_);
   }
 }
-#line 2297 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2359 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 175: /* opt_group_by_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 180: /* opt_group_by_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_group_by_clause_) != nullptr) {
     delete ((*yyvaluep).opt_group_by_clause_);
   }
 }
-#line 2307 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2369 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 176: /* opt_having_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 181: /* opt_having_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_having_clause_) != nullptr) {
     delete ((*yyvaluep).opt_having_clause_);
   }
 }
-#line 2317 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2379 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 177: /* opt_order_by_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 182: /* opt_order_by_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_order_by_clause_) != nullptr) {
     delete ((*yyvaluep).opt_order_by_clause_);
   }
 }
-#line 2327 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2389 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 178: /* opt_limit_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 183: /* opt_limit_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).opt_limit_clause_) != nullptr) {
     delete ((*yyvaluep).opt_limit_clause_);
   }
 }
-#line 2337 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2399 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 179: /* order_commalist  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 184: /* order_commalist  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_commalist_) != nullptr) {
     delete ((*yyvaluep).order_commalist_);
   }
 }
-#line 2347 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2409 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 180: /* order_item  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 185: /* order_item  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_item_) != nullptr) {
     delete ((*yyvaluep).order_item_);
   }
 }
-#line 2357 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2419 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 181: /* opt_order_direction  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 186: /* opt_order_direction  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_direction_) != nullptr) {
     delete ((*yyvaluep).order_direction_);
   }
 }
-#line 2367 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2429 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 182: /* opt_nulls_first  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 187: /* opt_nulls_first  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).order_direction_) != nullptr) {
     delete ((*yyvaluep).order_direction_);
   }
 }
-#line 2377 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2439 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 183: /* opt_where_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 188: /* opt_where_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2387 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2449 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 184: /* where_clause  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 189: /* where_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2397 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2459 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 185: /* or_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 190: /* or_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2407 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2469 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 186: /* and_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 191: /* and_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2417 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2479 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 187: /* not_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 192: /* not_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2427 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2489 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 188: /* predicate_expression_base  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 193: /* predicate_expression_base  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).predicate_) != nullptr) {
     delete ((*yyvaluep).predicate_);
   }
 }
-#line 2437 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2499 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 189: /* add_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 194: /* add_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2447 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2509 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 190: /* multiply_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 195: /* multiply_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2457 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2519 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 191: /* unary_expression  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 196: /* unary_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2467 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2529 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 192: /* expression_base  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 197: /* expression_base  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2477 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2539 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 193: /* function_call  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 198: /* function_call  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).function_call_) != nullptr) {
     delete ((*yyvaluep).function_call_);
   }
 }
-#line 2487 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2549 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 194: /* extract_function  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 199: /* extract_function  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_) != nullptr) {
     delete ((*yyvaluep).expression_);
   }
 }
-#line 2497 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2559 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 195: /* expression_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 200: /* case_expression  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).expression_) != nullptr) {
+    delete ((*yyvaluep).expression_);
+  }
+}
+#line 2569 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 201: /* simple_when_clause_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).simple_when_clause_list_) != nullptr) {
+    delete ((*yyvaluep).simple_when_clause_list_);
+  }
+}
+#line 2579 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 202: /* simple_when_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).simple_when_clause_) != nullptr) {
+    delete ((*yyvaluep).simple_when_clause_);
+  }
+}
+#line 2589 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 203: /* searched_when_clause_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).searched_when_clause_list_) != nullptr) {
+    delete ((*yyvaluep).searched_when_clause_list_);
+  }
+}
+#line 2599 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 204: /* searched_when_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).searched_when_clause_) != nullptr) {
+    delete ((*yyvaluep).searched_when_clause_);
+  }
+}
+#line 2609 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 205: /* opt_else_clause  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
+      {
+  if (((*yyvaluep).expression_) != nullptr) {
+    delete ((*yyvaluep).expression_);
+  }
+}
+#line 2619 "SqlParser_gen.cpp" /* yacc.c:1257  */
+        break;
+
+    case 206: /* expression_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).expression_list_) != nullptr) {
     delete ((*yyvaluep).expression_list_);
   }
 }
-#line 2507 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2629 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 196: /* literal_value  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 207: /* literal_value  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).literal_value_) != nullptr) {
     delete ((*yyvaluep).literal_value_);
   }
 }
-#line 2517 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2639 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 197: /* literal_value_commalist  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 208: /* literal_value_commalist  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).literal_value_list_) != nullptr) {
     delete ((*yyvaluep).literal_value_list_);
   }
 }
-#line 2527 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2649 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 198: /* attribute_ref  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 209: /* attribute_ref  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_) != nullptr) {
     delete ((*yyvaluep).attribute_);
   }
 }
-#line 2537 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2659 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 199: /* attribute_ref_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 210: /* attribute_ref_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).attribute_list_) != nullptr) {
     delete ((*yyvaluep).attribute_list_);
   }
 }
-#line 2547 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2669 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 200: /* comparison_operation  */
-#line 527 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 211: /* comparison_operation  */
+#line 553 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2553 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2675 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 201: /* unary_operation  */
-#line 528 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 212: /* unary_operation  */
+#line 554 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2559 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2681 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 202: /* add_operation  */
-#line 529 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 213: /* add_operation  */
+#line 555 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2565 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2687 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 203: /* multiply_operation  */
-#line 529 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 214: /* multiply_operation  */
+#line 555 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2571 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2693 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 204: /* name_commalist  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 215: /* name_commalist  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_list_) != nullptr) {
     delete ((*yyvaluep).string_list_);
   }
 }
-#line 2581 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2703 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 205: /* any_name  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 216: /* any_name  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2591 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2713 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 206: /* boolean_value  */
-#line 526 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 217: /* boolean_value  */
+#line 552 "../SqlParser.ypp" /* yacc.c:1257  */
       { }
-#line 2597 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2719 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 207: /* command  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 218: /* command  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).command_) != nullptr) {
     delete ((*yyvaluep).command_);
   }
 }
-#line 2607 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2729 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
-    case 208: /* command_argument_list  */
-#line 531 "../SqlParser.ypp" /* yacc.c:1257  */
+    case 219: /* command_argument_list  */
+#line 557 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).command_argument_list_) != nullptr) {
     delete ((*yyvaluep).command_argument_list_);
   }
 }
-#line 2617 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2739 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
 
@@ -2905,148 +3027,148 @@
   switch (yyn)
     {
         case 2:
-#line 540 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 566 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].statement_);
     YYACCEPT;
   }
-#line 2914 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3036 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 3:
-#line 544 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 570 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].statement_);
     YYACCEPT;
   }
-#line 2923 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3045 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 4:
-#line 548 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 574 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].command_);
     YYACCEPT;
   }
-#line 2932 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3054 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 5:
-#line 552 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 578 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     *parsedStatement = (yyvsp[-1].command_);
     YYACCEPT;
   }
-#line 2941 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3063 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 6:
-#line 556 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 582 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     YYABORT;
   }
-#line 2949 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3071 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 7:
-#line 559 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 585 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     // Regular yyparse() return codes are non-negative, so use a negative one here.
     return -1;
   }
-#line 2958 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3080 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 8:
-#line 566 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 592 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].statement_);
   }
-#line 2966 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3088 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 9:
-#line 569 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 595 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].copy_from_statement_);
   }
-#line 2974 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3096 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 10:
-#line 572 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 598 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].create_table_statement_);
   }
-#line 2982 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3104 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 11:
-#line 575 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 601 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].statement_);
   }
-#line 2990 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3112 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 12:
-#line 578 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 604 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].delete_statement_);
   }
-#line 2998 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3120 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 13:
-#line 581 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 607 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].drop_table_statement_);
   }
-#line 3006 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3128 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 14:
-#line 584 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 610 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].insert_statement_);
   }
-#line 3014 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3136 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 15:
-#line 587 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 613 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].quit_statement_);
   }
-#line 3022 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3144 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 16:
-#line 590 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 616 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].select_statement_);
   }
-#line 3030 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3152 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 17:
-#line 593 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 619 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.statement_) = (yyvsp[0].update_statement_);
   }
-#line 3038 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3160 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 18:
-#line 599 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 625 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.quit_statement_) = new quickstep::ParseStatementQuit((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 3046 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3168 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 19:
-#line 605 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 631 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
     delete (yyvsp[0].attribute_definition_);
@@ -3054,22 +3176,22 @@
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3058 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3180 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 20:
-#line 612 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 638 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
     (yyval.statement_) = nullptr;
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3069 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3191 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 21:
-#line 618 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 644 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
     delete (yyvsp[0].string_value_);
@@ -3077,11 +3199,11 @@
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3081 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3203 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 22:
-#line 625 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 651 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].string_value_);
     delete (yyvsp[0].string_value_);
@@ -3089,19 +3211,19 @@
     NotSupported(&(yylsp[-5]), yyscanner, "ALTER statements");
     YYERROR;
   }
-#line 3093 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3215 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 23:
-#line 634 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 660 "../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 3101 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3223 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 24:
-#line 639 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 665 "../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_));
@@ -3109,153 +3231,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 3113 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3235 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 25:
-#line 648 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 674 "../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 3121 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3243 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 26:
-#line 653 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 679 "../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 3129 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3251 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 27:
-#line 658 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 684 "../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 3138 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3260 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 28:
-#line 662 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 688 "../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 3147 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3269 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 29:
-#line 668 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 694 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = nullptr;
     NotSupported(&(yylsp[0]), yyscanner, "BIT data type");
     YYERROR;
   }
-#line 3157 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3279 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 30:
-#line 673 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 699 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
   }
-#line 3165 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3287 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 31:
-#line 676 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 702 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
   }
-#line 3173 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3295 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 32:
-#line 679 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 705 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = nullptr;
     NotSupported(&(yylsp[0]), yyscanner, "TIME data type");
     YYERROR;
   }
-#line 3183 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3305 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 33:
-#line 684 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 710 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
   }
-#line 3191 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3313 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 34:
-#line 687 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 713 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
   }
-#line 3199 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3321 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 35:
-#line 690 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 716 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
   }
-#line 3207 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3329 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 36:
-#line 693 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 719 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
   }
-#line 3215 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3337 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 37:
-#line 696 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 722 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kFloat));
   }
-#line 3223 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3345 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 38:
-#line 699 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 725 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt));
   }
-#line 3231 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3353 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 39:
-#line 702 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 728 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt));
   }
-#line 3239 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3361 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 40:
-#line 705 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 731 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong));
   }
-#line 3247 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3369 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 41:
-#line 708 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 734 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong));
   }
-#line 3255 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3377 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 42:
-#line 711 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 737 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This pattern exhibits a shift/reduce conflict with the
@@ -3268,27 +3390,27 @@
         "or YEARMONTH INTERVAL");
     YYERROR;
   }
-#line 3272 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3394 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 43:
-#line 723 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 749 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetimeInterval));
   }
-#line 3280 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3402 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 44:
-#line 726 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 752 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.data_type_) = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kYearMonthInterval));
   }
-#line 3288 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3410 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 45:
-#line 729 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 755 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-1].numeric_literal_value_)->float_like()) {
       delete (yyvsp[-1].numeric_literal_value_);
@@ -3307,11 +3429,11 @@
       }
     }
   }
-#line 3311 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3433 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 46:
-#line 747 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 773 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-1].numeric_literal_value_)->float_like()) {
       delete (yyvsp[-1].numeric_literal_value_);
@@ -3330,69 +3452,69 @@
       }
     }
   }
-#line 3334 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3456 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 47:
-#line 767 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 793 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = new quickstep::ParseColumnConstraintNull((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 3342 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3464 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 48:
-#line 770 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 796 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = new quickstep::ParseColumnConstraintNotNull((yylsp[-1]).first_line, (yylsp[-1]).first_column);
   }
-#line 3350 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3472 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 49:
-#line 773 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 799 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     NotSupported(&(yylsp[0]), yyscanner, "Column Constraints (UNIQUE)");
     YYERROR;
   }
-#line 3360 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3482 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 50:
-#line 778 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 804 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     NotSupported(&(yylsp[-1]), yyscanner, "Column Constraints (PRIMARY KEY)");
     YYERROR;
   }
-#line 3370 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3492 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 51:
-#line 783 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 809 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     delete (yyvsp[0].literal_value_);
     NotSupported(&(yylsp[-1]), yyscanner, "Column Constraints (DEFAULT)");
     YYERROR;
   }
-#line 3381 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3503 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 52:
-#line 789 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 815 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     delete (yyvsp[-1].predicate_);
     NotSupported(&(yylsp[-3]), yyscanner, "Column Constraints (CHECK)");
     YYERROR;
   }
-#line 3392 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3514 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 53:
-#line 795 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 821 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_) = nullptr;
     delete (yyvsp[-3].string_value_);
@@ -3400,65 +3522,65 @@
     NotSupported(&(yylsp[-4]), yyscanner, "Foreign Keys");
     YYERROR;
   }
-#line 3404 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3526 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 54:
-#line 804 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 830 "../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 3413 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3535 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 55:
-#line 808 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 834 "../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 3422 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3544 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 56:
-#line 814 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 840 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_list_) = nullptr;
   }
-#line 3430 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3552 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 57:
-#line 817 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 843 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.column_constraint_list_) = (yyvsp[0].column_constraint_list_);
   }
-#line 3438 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3560 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 58:
-#line 822 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 848 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-1].string_list_);
     NotSupported(&(yylsp[-3]), yyscanner, "Table Constraints (UNIQUE)");
     YYERROR;
   }
-#line 3448 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3570 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 59:
-#line 827 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 853 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-1].string_list_);
     NotSupported(&(yylsp[-4]), yyscanner, "Table Constraints (PRIMARY KEY)");
     YYERROR;
   }
-#line 3458 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3580 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 60:
-#line 832 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 858 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-6].string_list_);
     delete (yyvsp[-3].string_value_);
@@ -3466,95 +3588,95 @@
     NotSupported(&(yylsp[-9]), yyscanner, "Table Constraints (FOREIGN KEY)");
     YYERROR;
   }
-#line 3470 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3592 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 61:
-#line 839 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 865 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-1].predicate_);
     NotSupported(&(yylsp[-3]), yyscanner, "Table Constraints (CHECK)");
     YYERROR;
   }
-#line 3480 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3602 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 62:
-#line 846 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 872 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[-2]), yyscanner, "Table Constraints");
     YYERROR;
   }
-#line 3489 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3611 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 63:
-#line 850 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 876 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[0]), yyscanner, "Table Constraints");
     YYERROR;
   }
-#line 3498 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3620 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 64:
-#line 856 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 882 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /* $$ = nullptr; */
   }
-#line 3506 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3628 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 65:
-#line 859 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 885 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /* $$ = $1; */
   }
-#line 3514 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3636 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 66:
-#line 864 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 890 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = nullptr;
   }
-#line 3522 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3644 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 67:
-#line 867 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 893 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = (yyvsp[-1].attribute_list_);
   }
-#line 3530 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3652 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 68:
-#line 872 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 898 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.block_properties_) = nullptr;
   }
-#line 3538 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3660 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 69:
-#line 875 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 901 "../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 3546 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3668 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 70:
-#line 880 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 906 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.partition_clause_) = nullptr;
   }
-#line 3554 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3676 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 71:
-#line 883 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 909 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].numeric_literal_value_)->float_like()) {
       delete (yyvsp[0].numeric_literal_value_);
@@ -3572,97 +3694,97 @@
       }
     }
   }
-#line 3576 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3698 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 72:
-#line 902 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 928 "../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 3585 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3707 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 73:
-#line 906 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 932 "../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 3594 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3716 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 74:
-#line 912 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 938 "../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 3603 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3725 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 75:
-#line 916 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 942 "../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 3612 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3734 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 76:
-#line 922 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 948 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_) = (yyvsp[0].key_string_value_);
   }
-#line 3620 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3742 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 77:
-#line 925 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 951 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_) = (yyvsp[0].key_string_list_);
   }
-#line 3628 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3750 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 78:
-#line 928 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 954 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_) = (yyvsp[0].key_integer_value_);
   }
-#line 3636 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3758 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 79:
-#line 933 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 959 "../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 3644 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3766 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 80:
-#line 936 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 962 "../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 3654 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3776 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 81:
-#line 943 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 969 "../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 3662 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3784 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 82:
-#line 948 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 974 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].numeric_literal_value_)->float_like()) {
       delete (yyvsp[0].numeric_literal_value_);
@@ -3672,45 +3794,45 @@
     }
     (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 3676 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3798 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 83:
-#line 959 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 985 "../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 3685 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3807 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 84:
-#line 963 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 989 "../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 3694 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3816 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 85:
-#line 969 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 995 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_list_) = nullptr;
   }
-#line 3702 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3824 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 86:
-#line 972 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 998 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.key_value_list_) = (yyvsp[-1].key_value_list_);
   }
-#line 3710 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3832 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 87:
-#line 978 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1004 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-7].string_value_);
     delete (yyvsp[-5].string_list_);
@@ -3719,592 +3841,592 @@
     NotSupported(&(yylsp[-6]), yyscanner, "list of column names in INSERT statement");
     YYERROR;
   }
-#line 3723 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3845 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 88:
-#line 986 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1012 "../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 3731 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3853 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 89:
-#line 989 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1015 "../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 3739 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3861 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 90:
-#line 992 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1018 "../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 3747 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3869 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 91:
-#line 998 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1024 "../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 3755 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3877 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 92:
-#line 1003 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1029 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.copy_from_params_) = nullptr;
   }
-#line 3763 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3885 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 93:
-#line 1006 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1032 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.copy_from_params_) = (yyvsp[-1].copy_from_params_);
   }
-#line 3771 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3893 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 94:
-#line 1011 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1037 "../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 3780 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3902 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 95:
-#line 1015 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1041 "../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 3789 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3911 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 96:
-#line 1019 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1045 "../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 3798 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3920 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 97:
-#line 1023 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1049 "../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 3807 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3929 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 98:
-#line 1029 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1055 "../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 3815 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3937 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 99:
-#line 1034 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1060 "../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 3823 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3945 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 100:
-#line 1039 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1065 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.assignment_list_) = (yyvsp[-2].assignment_list_);
     (yyval.assignment_list_)->push_back((yyvsp[0].assignment_));
   }
-#line 3832 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3954 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 101:
-#line 1043 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1069 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.assignment_list_) = new quickstep::PtrList<quickstep::ParseAssignment>();
     (yyval.assignment_list_)->push_back((yyvsp[0].assignment_));
   }
-#line 3841 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3963 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 102:
-#line 1049 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1075 "../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 3849 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3971 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 103:
-#line 1055 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1081 "../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 3857 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3979 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 104:
-#line 1058 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1084 "../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 3865 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3987 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 105:
-#line 1063 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1089 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.with_list_) = (yyvsp[0].with_list_);
   }
-#line 3873 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 3995 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 106:
-#line 1068 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1094 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.with_list_) = new quickstep::PtrVector<quickstep::ParseSubqueryTableReference>();
     (yyval.with_list_)->push_back((yyvsp[0].with_list_element_));
   }
-#line 3882 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4004 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 107:
-#line 1072 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1098 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.with_list_) = (yyvsp[-2].with_list_);
     (yyval.with_list_)->push_back((yyvsp[0].with_list_element_));
   }
-#line 3891 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4013 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 108:
-#line 1078 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1104 "../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 3900 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4022 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 109:
-#line 1085 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1111 "../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 3908 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4030 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 110:
-#line 1090 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1116 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /* $$ = nullptr; */
   }
-#line 3916 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4038 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 111:
-#line 1093 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1119 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[0]), yyscanner, "ALL in selection");
     YYERROR;
   }
-#line 3925 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4047 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 112:
-#line 1097 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1123 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[0]), yyscanner, "DISTINCT in selection");
     YYERROR;
   }
-#line 3934 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4056 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 113:
-#line 1103 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1129 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_) = new quickstep::ParseSelectionStar((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 3942 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4064 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 114:
-#line 1106 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1132 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_) = (yyvsp[0].selection_list_);
   }
-#line 3950 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4072 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 115:
-#line 1111 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1137 "../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 3959 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4081 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 116:
-#line 1115 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1141 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_list_) = (yyvsp[-2].selection_list_);
     (yyval.selection_list_)->add((yyvsp[0].selection_item_));
   }
-#line 3968 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4090 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 117:
-#line 1121 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1147 "../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 3976 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4098 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 118:
-#line 1124 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1150 "../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 3984 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4106 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 119:
-#line 1127 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1153 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.selection_item_) = new quickstep::ParseSelectionItem((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].expression_));
   }
-#line 3992 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4114 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 120:
-#line 1132 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1158 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_list_) = (yyvsp[-1].table_reference_list_);
   }
-#line 4000 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4122 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 121:
-#line 1137 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1163 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /* $$ = nullptr; */
   }
-#line 4008 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4130 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 122:
-#line 1140 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1166 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[0]), yyscanner, "alternate JOIN syntax (specify in WHERE clause instead)");
     YYERROR;
   }
-#line 4017 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4139 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 123:
-#line 1146 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1172 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[-1]), yyscanner, "alternate JOIN syntax (specify in WHERE clause instead)");
     YYERROR;
   }
-#line 4026 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4148 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 124:
-#line 1150 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1176 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     NotSupported(&(yylsp[0]), yyscanner, "alternate JOIN syntax (specify in WHERE clause instead)");
     YYERROR;
   }
-#line 4035 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4157 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 125:
-#line 1156 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1182 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-2].string_list_);
     delete (yyvsp[0].predicate_);
     NotSupported(&(yylsp[-4]), yyscanner, "alternate JOIN syntax (specify in WHERE clause instead)");
     YYERROR;
   }
-#line 4046 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4168 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 126:
-#line 1162 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1188 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-2].string_list_);
     delete (yyvsp[0].predicate_);
     NotSupported(&(yylsp[-3]), yyscanner, "alternate JOIN syntax (specify in WHERE clause instead)");
     YYERROR;
   }
-#line 4057 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4179 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 127:
-#line 1168 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1194 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-2].string_list_);
     delete (yyvsp[0].predicate_);
     NotSupported(&(yylsp[-5]), yyscanner, "OUTER JOIN");
     YYERROR;
   }
-#line 4068 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 128:
-#line 1174 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    delete (yyvsp[-2].string_list_);
-    delete (yyvsp[0].predicate_);
-    NotSupported(&(yylsp[-4]), yyscanner, "OUTER JOIN");
-    YYERROR;
-  }
-#line 4079 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 129:
-#line 1180 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    delete (yyvsp[-2].string_list_);
-    delete (yyvsp[0].predicate_);
-    NotSupported(&(yylsp[-5]), yyscanner, "OUTER JOIN");
-    YYERROR;
-  }
-#line 4090 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 130:
-#line 1186 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    delete (yyvsp[-2].string_list_);
-    delete (yyvsp[0].predicate_);
-    NotSupported(&(yylsp[-4]), yyscanner, "OUTER JOIN");
-    YYERROR;
-  }
-#line 4101 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 131:
-#line 1192 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    delete (yyvsp[-2].string_list_);
-    delete (yyvsp[0].predicate_);
-    NotSupported(&(yylsp[-5]), yyscanner, "OUTER JOIN");
-    YYERROR;
-  }
-#line 4112 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 132:
-#line 1198 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    delete (yyvsp[-2].string_list_);
-    delete (yyvsp[0].predicate_);
-    NotSupported(&(yylsp[-4]), yyscanner, "OUTER JOIN");
-    YYERROR;
-  }
-#line 4123 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 133:
-#line 1206 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.subquery_expression_) = new quickstep::ParseSubqueryExpression((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-1].select_query_));
-  }
-#line 4131 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 134:
-#line 1211 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.opt_sample_clause_) = NULL;
-  }
-#line 4139 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 135:
-#line 1214 "../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 4147 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 136:
-#line 1217 "../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 4155 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 137:
-#line 1222 "../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 4164 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 138:
-#line 1226 "../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 4173 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 139:
-#line 1230 "../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 4181 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 140:
-#line 1233 "../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 4190 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 141:
+  case 128:
+#line 1200 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    delete (yyvsp[-2].string_list_);
+    delete (yyvsp[0].predicate_);
+    NotSupported(&(yylsp[-4]), yyscanner, "OUTER JOIN");
+    YYERROR;
+  }
+#line 4201 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 129:
+#line 1206 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    delete (yyvsp[-2].string_list_);
+    delete (yyvsp[0].predicate_);
+    NotSupported(&(yylsp[-5]), yyscanner, "OUTER JOIN");
+    YYERROR;
+  }
+#line 4212 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 130:
+#line 1212 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    delete (yyvsp[-2].string_list_);
+    delete (yyvsp[0].predicate_);
+    NotSupported(&(yylsp[-4]), yyscanner, "OUTER JOIN");
+    YYERROR;
+  }
+#line 4223 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 131:
+#line 1218 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    delete (yyvsp[-2].string_list_);
+    delete (yyvsp[0].predicate_);
+    NotSupported(&(yylsp[-5]), yyscanner, "OUTER JOIN");
+    YYERROR;
+  }
+#line 4234 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 132:
+#line 1224 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    delete (yyvsp[-2].string_list_);
+    delete (yyvsp[0].predicate_);
+    NotSupported(&(yylsp[-4]), yyscanner, "OUTER JOIN");
+    YYERROR;
+  }
+#line 4245 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 133:
+#line 1232 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.subquery_expression_) = new quickstep::ParseSubqueryExpression((yylsp[-2]).first_line, (yylsp[-2]).first_column, (yyvsp[-1].select_query_));
+  }
+#line 4253 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 134:
 #line 1237 "../SqlParser.ypp" /* yacc.c:1661  */
     {
+    (yyval.opt_sample_clause_) = NULL;
+  }
+#line 4261 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 135:
+#line 1240 "../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 4269 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 136:
+#line 1243 "../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 4277 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 137:
+#line 1248 "../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 4286 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 138:
+#line 1252 "../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 4295 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 139:
+#line 1256 "../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 4303 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 140:
+#line 1259 "../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 4312 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 141:
+#line 1263 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
     (yyval.table_reference_) = new quickstep::ParseGeneratorTableReference((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].function_call_));
   }
-#line 4198 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4320 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 142:
-#line 1242 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1268 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_signature_) = (yyvsp[0].table_reference_signature_);
   }
-#line 4206 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4328 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 143:
-#line 1245 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1271 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.table_reference_signature_) = (yyvsp[0].table_reference_signature_);
   }
-#line 4214 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4336 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 144:
-#line 1250 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1276 "../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 4222 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4344 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 145:
-#line 1253 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1279 "../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 4230 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4352 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 146:
-#line 1258 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1284 "../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 4239 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4361 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 147:
-#line 1262 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1288 "../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 4248 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4370 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 148:
-#line 1268 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1294 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_group_by_clause_) = nullptr;
   }
-#line 4256 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4378 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 149:
-#line 1271 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1297 "../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 4264 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4386 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 150:
-#line 1276 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1302 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_having_clause_) = nullptr;
   }
-#line 4272 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4394 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 151:
-#line 1279 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1305 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_having_clause_) = new quickstep::ParseHaving((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[0].predicate_));
   }
-#line 4280 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4402 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 152:
-#line 1284 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1310 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_order_by_clause_) = nullptr;
   }
-#line 4288 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4410 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 153:
-#line 1287 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1313 "../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 4296 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4418 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 154:
-#line 1292 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1318 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.opt_limit_clause_) = nullptr;
   }
-#line 4304 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4426 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 155:
-#line 1295 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1321 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[0].numeric_literal_value_)->float_like()) {
       delete (yyvsp[0].numeric_literal_value_);
@@ -4322,111 +4444,111 @@
       }
     }
   }
-#line 4326 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4448 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 156:
-#line 1314 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1340 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_commalist_) = new quickstep::PtrList<quickstep::ParseOrderByItem>();
     (yyval.order_commalist_)->push_back((yyvsp[0].order_item_));
   }
-#line 4335 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4457 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 157:
-#line 1318 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1344 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_commalist_) = (yyvsp[-2].order_commalist_);
     (yyval.order_commalist_)->push_back((yyvsp[0].order_item_));
   }
-#line 4344 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4466 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 158:
-#line 1324 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1350 "../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 4354 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4476 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 159:
-#line 1331 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1357 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = nullptr;
   }
-#line 4362 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4484 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 160:
-#line 1334 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1360 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(true);
   }
-#line 4370 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4492 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 161:
-#line 1337 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1363 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(false);
   }
-#line 4378 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4500 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 162:
-#line 1342 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1368 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = nullptr;
   }
-#line 4386 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4508 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 163:
-#line 1345 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1371 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(true);
   }
-#line 4394 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4516 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 164:
-#line 1348 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1374 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.order_direction_) = new bool(false);
   }
-#line 4402 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4524 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 165:
-#line 1354 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1380 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = nullptr;
   }
-#line 4410 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4532 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 166:
-#line 1357 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1383 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4418 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4540 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 167:
-#line 1362 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1388 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4426 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4548 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 168:
-#line 1367 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1393 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-2].predicate_)->getParsePredicateType() == quickstep::ParsePredicate::kDisjunction) {
       (yyval.predicate_) = (yyvsp[-2].predicate_);
@@ -4436,19 +4558,19 @@
     }
     static_cast<quickstep::ParsePredicateDisjunction *>((yyval.predicate_))->addPredicate((yyvsp[0].predicate_));
   }
-#line 4440 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4562 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 169:
-#line 1376 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1402 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4448 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4570 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 170:
-#line 1381 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1407 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     if ((yyvsp[-2].predicate_)->getParsePredicateType() == quickstep::ParsePredicate::kConjunction) {
       (yyval.predicate_) = (yyvsp[-2].predicate_);
@@ -4458,273 +4580,365 @@
     }
     static_cast<quickstep::ParsePredicateConjunction *>((yyval.predicate_))->addPredicate((yyvsp[0].predicate_));
   }
-#line 4462 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4584 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 171:
-#line 1390 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1416 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4470 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4592 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 172:
-#line 1395 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1421 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateNegation((yylsp[-1]).first_line, (yylsp[-1]).first_column, (yyvsp[0].predicate_));
   }
-#line 4478 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4600 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 173:
-#line 1398 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1424 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[0].predicate_);
   }
-#line 4486 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4608 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 174:
-#line 1403 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1429 "../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 4494 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4616 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 175:
-#line 1406 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1432 "../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 4504 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4626 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 176:
-#line 1411 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1437 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-3].attribute_);
     (yyval.predicate_) = nullptr;
     NotSupported(&(yylsp[-2]), yyscanner, "NULL comparison predicates");
     YYERROR;
   }
-#line 4515 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4637 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 177:
-#line 1417 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1443 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     delete (yyvsp[-2].attribute_);
     (yyval.predicate_) = nullptr;
     NotSupported(&(yylsp[-1]), yyscanner, "NULL comparison predicates");
     YYERROR;
   }
-#line 4526 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4648 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 178:
-#line 1423 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1449 "../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 4534 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4656 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 179:
-#line 1426 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1452 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = (yyvsp[-1].predicate_);
   }
-#line 4542 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4664 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
   case 180:
-#line 1429 "../SqlParser.ypp" /* yacc.c:1661  */
+#line 1455 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.predicate_) = new quickstep::ParsePredicateExists((yylsp[-1]).first_line,
                                              (yylsp[-1]).first_column,
                                              (yyvsp[0].subquery_expression_));
   }
-#line 4552 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 181:
-#line 1437 "../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 4560 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 182:
-#line 1440 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].expression_);
-  }
-#line 4568 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 183:
-#line 1445 "../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 4576 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 184:
-#line 1448 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].expression_);
-  }
-#line 4584 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 185:
-#line 1453 "../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 4592 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 186:
-#line 1456 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].expression_);
-  }
-#line 4600 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 187:
-#line 1461 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].attribute_);
-  }
-#line 4608 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 188:
-#line 1464 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = new quickstep::ParseScalarLiteral((yyvsp[0].literal_value_));
-  }
-#line 4616 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 189:
-#line 1467 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].function_call_);
-  }
-#line 4624 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 190:
-#line 1470 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[0].expression_);
-  }
-#line 4632 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 191:
-#line 1473 "../SqlParser.ypp" /* yacc.c:1661  */
-    {
-    (yyval.expression_) = (yyvsp[-1].expression_);
-  }
-#line 4640 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 192:
-#line 1478 "../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 4649 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 193:
-#line 1482 "../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 4658 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 194:
-#line 1486 "../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 4666 "SqlParser_gen.cpp" /* yacc.c:1661  */
-    break;
-
-  case 195:
-#line 1489 "../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_));
-  }
 #line 4674 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 196:
-#line 1494 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 181:
+#line 1463 "../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.expression_) = new quickstep::ParseBinaryExpression((yylsp[-1]).first_line, (yylsp[-1]).first_column, *(yyvsp[-1].binary_operation_), (yyvsp[-2].expression_), (yyvsp[0].expression_));
   }
 #line 4682 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 197:
+  case 182:
+#line 1466 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4690 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 183:
+#line 1471 "../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 4698 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 184:
+#line 1474 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4706 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 185:
+#line 1479 "../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 4714 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 186:
+#line 1482 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4722 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 187:
+#line 1487 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].attribute_);
+  }
+#line 4730 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 188:
+#line 1490 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = new quickstep::ParseScalarLiteral((yyvsp[0].literal_value_));
+  }
+#line 4738 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 189:
+#line 1493 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].function_call_);
+  }
+#line 4746 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 190:
+#line 1496 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4754 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 191:
 #line 1499 "../SqlParser.ypp" /* yacc.c:1661  */
     {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4762 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 192:
+#line 1502 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[-1].expression_);
+  }
+#line 4770 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 193:
+#line 1507 "../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 4779 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 194:
+#line 1511 "../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 4788 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 195:
+#line 1515 "../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 4796 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 196:
+#line 1518 "../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_));
+  }
+#line 4804 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 197:
+#line 1523 "../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_));
+  }
+#line 4812 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 198:
+#line 1528 "../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_));
+  }
+#line 4820 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 199:
+#line 1531 "../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_));
+  }
+#line 4828 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 200:
+#line 1536 "../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 4837 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 201:
+#line 1540 "../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 4846 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 202:
+#line 1546 "../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 4854 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 203:
+#line 1551 "../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 4863 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 204:
+#line 1555 "../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 4872 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 205:
+#line 1561 "../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 4880 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 206:
+#line 1566 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = NULL;
+  }
+#line 4888 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 207:
+#line 1569 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
+    (yyval.expression_) = (yyvsp[0].expression_);
+  }
+#line 4896 "SqlParser_gen.cpp" /* yacc.c:1661  */
+    break;
+
+  case 208:
+#line 1574 "../SqlParser.ypp" /* yacc.c:1661  */
+    {
     (yyval.expression_list_) = new quickstep::PtrList<quickstep::ParseExpression>();
     (yyval.expression_list_)->push_back((yyvsp[0].expression_));
   }
-#line 4691 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4905 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 198:
-#line 1503 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 209:
+#line 1578 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.expression_list_) = (yyvsp[-2].expression_list_);
     (yyval.expression_list_)->push_back((yyvsp[0].expression_));
   }
-#line 4700 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4914 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 199:
-#line 1509 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 210:
+#line 1584 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_) = new quickstep::NullParseLiteralValue((yylsp[0]).first_line, (yylsp[0]).first_column);
   }
-#line 4708 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4922 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 200:
-#line 1512 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 211:
+#line 1587 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
   }
-#line 4716 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4930 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 201:
-#line 1515 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 212:
+#line 1590 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
   }
-#line 4724 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4938 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 202:
-#line 1518 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 213:
+#line 1593 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This case exhibits a shift/reduce conflict with the
@@ -4737,20 +4951,20 @@
     (yyvsp[0].numeric_literal_value_)->prependMinus();
     (yyval.literal_value_) = (yyvsp[0].numeric_literal_value_);
   }
-#line 4741 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4955 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 203:
-#line 1530 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 214:
+#line 1605 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.literal_value_) = new quickstep::StringParseLiteralValue((yyvsp[0].string_value_),
                                                 nullptr);  // No explicit type.
   }
-#line 4750 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4964 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 204:
-#line 1534 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 215:
+#line 1609 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This case exhibits a shift/reduce conflict with the
@@ -4770,11 +4984,11 @@
       YYERROR;
     }
   }
-#line 4774 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 4988 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 205:
-#line 1553 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 216:
+#line 1628 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     quickstep::StringParseLiteralValue *parse_value
         = new quickstep::StringParseLiteralValue((yyvsp[0].string_value_), &((yyvsp[-1].data_type_)->getType()));
@@ -4788,143 +5002,143 @@
       (yyval.literal_value_) = parse_value;
     }
   }
-#line 4792 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5006 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 206:
-#line 1568 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 217:
+#line 1643 "../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 4801 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5015 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 207:
-#line 1572 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 218:
+#line 1647 "../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 4810 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5024 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 208:
-#line 1578 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 219:
+#line 1653 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_) = new quickstep::ParseAttribute((yylsp[0]).first_line, (yylsp[0]).first_column, (yyvsp[0].string_value_));
   }
-#line 4818 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5032 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 209:
-#line 1581 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 220:
+#line 1656 "../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 4826 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5040 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 210:
-#line 1586 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 221:
+#line 1661 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = new quickstep::PtrList<quickstep::ParseAttribute>();
     (yyval.attribute_list_)->push_back((yyvsp[0].attribute_));
   }
-#line 4835 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5049 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 211:
-#line 1590 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 222:
+#line 1665 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.attribute_list_) = (yyvsp[-2].attribute_list_);
     (yyval.attribute_list_)->push_back((yyvsp[0].attribute_));
   }
-#line 4844 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5058 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 212:
-#line 1597 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 223:
+#line 1672 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kEqual);
   }
-#line 4852 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5066 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 213:
-#line 1600 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 224:
+#line 1675 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotEqual);
   }
-#line 4860 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5074 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 214:
-#line 1603 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 225:
+#line 1678 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLess);
   }
-#line 4868 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5082 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 215:
-#line 1606 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 226:
+#line 1681 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLessOrEqual);
   }
-#line 4876 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5090 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 216:
-#line 1609 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 227:
+#line 1684 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreater);
   }
-#line 4884 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5098 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 217:
-#line 1612 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 228:
+#line 1687 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreaterOrEqual);
   }
-#line 4892 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5106 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 218:
-#line 1615 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 229:
+#line 1690 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLike);
   }
-#line 4900 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5114 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 219:
-#line 1618 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 230:
+#line 1693 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotLike);
   }
-#line 4908 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5122 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 220:
-#line 1621 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 231:
+#line 1696 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kRegexMatch);
   }
-#line 4916 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5130 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 221:
-#line 1624 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 232:
+#line 1699 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.comparison_) =  &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotRegexMatch);
   }
-#line 4924 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5138 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 222:
-#line 1629 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 233:
+#line 1704 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     /**
      * NOTE(chasseur): This case exhibits a shift/reduce conflict with the
@@ -4934,146 +5148,146 @@
      **/
     (yyval.unary_operation_) = &quickstep::UnaryOperationFactory::GetUnaryOperation(quickstep::UnaryOperationID::kNegate);
   }
-#line 4938 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5152 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 223:
-#line 1640 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 234:
+#line 1715 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kAdd);
   }
-#line 4946 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5160 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 224:
-#line 1643 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 235:
+#line 1718 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kSubtract);
   }
-#line 4954 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5168 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 225:
-#line 1648 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 236:
+#line 1723 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kModulo);
   }
-#line 4962 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5176 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 226:
-#line 1651 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 237:
+#line 1726 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kMultiply);
   }
-#line 4970 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5184 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 227:
-#line 1654 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 238:
+#line 1729 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.binary_operation_) = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kDivide);
   }
-#line 4978 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5192 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 228:
-#line 1660 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 239:
+#line 1735 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_list_) = new quickstep::PtrList<quickstep::ParseString>();
     (yyval.string_list_)->push_back((yyvsp[0].string_value_));
   }
-#line 4987 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5201 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 229:
-#line 1664 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 240:
+#line 1739 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_list_) = (yyvsp[-2].string_list_);
     (yyval.string_list_)->push_back((yyvsp[0].string_value_));
   }
-#line 4996 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5210 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 230:
-#line 1670 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 241:
+#line 1745 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.string_value_) = (yyvsp[0].string_value_);
   }
-#line 5004 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5218 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 231:
-#line 1673 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 242:
+#line 1748 "../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 5015 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5229 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 232:
-#line 1681 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 243:
+#line 1756 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = true;
   }
-#line 5023 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5237 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 233:
-#line 1684 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 244:
+#line 1759 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = true;
   }
-#line 5031 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5245 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 234:
-#line 1687 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 245:
+#line 1762 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = false;
   }
-#line 5039 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5253 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 235:
-#line 1690 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 246:
+#line 1765 "../SqlParser.ypp" /* yacc.c:1661  */
     {
     (yyval.boolean_value_) = false;
   }
-#line 5047 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5261 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 236:
-#line 1696 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 247:
+#line 1771 "../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 5055 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5269 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 237:
-#line 1701 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 248:
+#line 1776 "../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 5065 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5279 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
-  case 238:
-#line 1706 "../SqlParser.ypp" /* yacc.c:1661  */
+  case 249:
+#line 1781 "../SqlParser.ypp" /* yacc.c:1661  */
     { /* Epsilon, an empy match. */
     (yyval.command_argument_list_) = new quickstep::PtrVector<quickstep::ParseString>();
   }
-#line 5073 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5287 "SqlParser_gen.cpp" /* yacc.c:1661  */
     break;
 
 
-#line 5077 "SqlParser_gen.cpp" /* yacc.c:1661  */
+#line 5291 "SqlParser_gen.cpp" /* yacc.c:1661  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -5308,7 +5522,7 @@
 #endif
   return yyresult;
 }
-#line 1710 "../SqlParser.ypp" /* yacc.c:1906  */
+#line 1785 "../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 fe1cce6..26adf87 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -77,80 +77,85 @@
     TOKEN_BLOOM_FILTER = 287,
     TOKEN_CSB_TREE = 288,
     TOKEN_BY = 289,
-    TOKEN_CHARACTER = 290,
-    TOKEN_CHECK = 291,
-    TOKEN_COLUMN = 292,
-    TOKEN_CONSTRAINT = 293,
-    TOKEN_COPY = 294,
-    TOKEN_CREATE = 295,
-    TOKEN_DATE = 296,
-    TOKEN_DATETIME = 297,
-    TOKEN_DECIMAL = 298,
-    TOKEN_DEFAULT = 299,
-    TOKEN_DELETE = 300,
-    TOKEN_DELIMITER = 301,
-    TOKEN_DESC = 302,
-    TOKEN_DISTINCT = 303,
-    TOKEN_DOUBLE = 304,
-    TOKEN_DROP = 305,
-    TOKEN_ESCAPE_STRINGS = 306,
-    TOKEN_EXISTS = 307,
-    TOKEN_EXTRACT = 308,
-    TOKEN_FALSE = 309,
-    TOKEN_FIRST = 310,
-    TOKEN_FLOAT = 311,
-    TOKEN_FOREIGN = 312,
-    TOKEN_FROM = 313,
-    TOKEN_FULL = 314,
-    TOKEN_GROUP = 315,
-    TOKEN_HASH = 316,
-    TOKEN_HAVING = 317,
-    TOKEN_INDEX = 318,
-    TOKEN_INNER = 319,
-    TOKEN_INSERT = 320,
-    TOKEN_INTEGER = 321,
-    TOKEN_INTERVAL = 322,
-    TOKEN_INTO = 323,
-    TOKEN_JOIN = 324,
-    TOKEN_KEY = 325,
-    TOKEN_LAST = 326,
-    TOKEN_LEFT = 327,
-    TOKEN_LIMIT = 328,
-    TOKEN_LONG = 329,
-    TOKEN_NULL = 330,
-    TOKEN_NULLS = 331,
-    TOKEN_OFF = 332,
-    TOKEN_ON = 333,
-    TOKEN_ORDER = 334,
-    TOKEN_OUTER = 335,
-    TOKEN_PARTITION = 336,
-    TOKEN_PARTITIONS = 337,
-    TOKEN_PERCENT = 338,
-    TOKEN_PRIMARY = 339,
-    TOKEN_QUIT = 340,
-    TOKEN_RANGE = 341,
-    TOKEN_REAL = 342,
-    TOKEN_REFERENCES = 343,
-    TOKEN_RIGHT = 344,
-    TOKEN_ROW_DELIMITER = 345,
-    TOKEN_SELECT = 346,
-    TOKEN_SET = 347,
-    TOKEN_SMALLINT = 348,
-    TOKEN_TABLE = 349,
-    TOKEN_TIME = 350,
-    TOKEN_TIMESTAMP = 351,
-    TOKEN_TRUE = 352,
-    TOKEN_TUPLESAMPLE = 353,
-    TOKEN_UNIQUE = 354,
-    TOKEN_UPDATE = 355,
-    TOKEN_USING = 356,
-    TOKEN_VALUES = 357,
-    TOKEN_VARCHAR = 358,
-    TOKEN_WHERE = 359,
-    TOKEN_WITH = 360,
-    TOKEN_YEARMONTH = 361,
-    TOKEN_EOF = 362,
-    TOKEN_LEX_ERROR = 363
+    TOKEN_CASE = 290,
+    TOKEN_CHARACTER = 291,
+    TOKEN_CHECK = 292,
+    TOKEN_COLUMN = 293,
+    TOKEN_CONSTRAINT = 294,
+    TOKEN_COPY = 295,
+    TOKEN_CREATE = 296,
+    TOKEN_DATE = 297,
+    TOKEN_DATETIME = 298,
+    TOKEN_DECIMAL = 299,
+    TOKEN_DEFAULT = 300,
+    TOKEN_DELETE = 301,
+    TOKEN_DELIMITER = 302,
+    TOKEN_DESC = 303,
+    TOKEN_DISTINCT = 304,
+    TOKEN_DOUBLE = 305,
+    TOKEN_DROP = 306,
+    TOKEN_ELSE = 307,
+    TOKEN_END = 308,
+    TOKEN_ESCAPE_STRINGS = 309,
+    TOKEN_EXISTS = 310,
+    TOKEN_EXTRACT = 311,
+    TOKEN_FALSE = 312,
+    TOKEN_FIRST = 313,
+    TOKEN_FLOAT = 314,
+    TOKEN_FOREIGN = 315,
+    TOKEN_FROM = 316,
+    TOKEN_FULL = 317,
+    TOKEN_GROUP = 318,
+    TOKEN_HASH = 319,
+    TOKEN_HAVING = 320,
+    TOKEN_INDEX = 321,
+    TOKEN_INNER = 322,
+    TOKEN_INSERT = 323,
+    TOKEN_INTEGER = 324,
+    TOKEN_INTERVAL = 325,
+    TOKEN_INTO = 326,
+    TOKEN_JOIN = 327,
+    TOKEN_KEY = 328,
+    TOKEN_LAST = 329,
+    TOKEN_LEFT = 330,
+    TOKEN_LIMIT = 331,
+    TOKEN_LONG = 332,
+    TOKEN_NULL = 333,
+    TOKEN_NULLS = 334,
+    TOKEN_OFF = 335,
+    TOKEN_ON = 336,
+    TOKEN_ORDER = 337,
+    TOKEN_OUTER = 338,
+    TOKEN_PARTITION = 339,
+    TOKEN_PARTITIONS = 340,
+    TOKEN_PERCENT = 341,
+    TOKEN_PRIMARY = 342,
+    TOKEN_QUIT = 343,
+    TOKEN_RANGE = 344,
+    TOKEN_REAL = 345,
+    TOKEN_REFERENCES = 346,
+    TOKEN_RIGHT = 347,
+    TOKEN_ROW_DELIMITER = 348,
+    TOKEN_SELECT = 349,
+    TOKEN_SET = 350,
+    TOKEN_SMALLINT = 351,
+    TOKEN_TABLE = 352,
+    TOKEN_THEN = 353,
+    TOKEN_TIME = 354,
+    TOKEN_TIMESTAMP = 355,
+    TOKEN_TRUE = 356,
+    TOKEN_TUPLESAMPLE = 357,
+    TOKEN_UNIQUE = 358,
+    TOKEN_UPDATE = 359,
+    TOKEN_USING = 360,
+    TOKEN_VALUES = 361,
+    TOKEN_VARCHAR = 362,
+    TOKEN_WHEN = 363,
+    TOKEN_WHERE = 364,
+    TOKEN_WITH = 365,
+    TOKEN_YEARMONTH = 366,
+    TOKEN_EOF = 367,
+    TOKEN_LEX_ERROR = 368
   };
 #endif
 
@@ -159,7 +164,7 @@
 
 union YYSTYPE
 {
-#line 115 "../SqlParser.ypp" /* yacc.c:1915  */
+#line 116 "../SqlParser.ypp" /* yacc.c:1915  */
 
   quickstep::ParseString *string_value_;
 
@@ -181,6 +186,12 @@
 
   quickstep::ParseSubqueryExpression *subquery_expression_;
 
+  quickstep::PtrVector<quickstep::ParseSimpleWhenClause> *simple_when_clause_list_;
+  quickstep::ParseSimpleWhenClause *simple_when_clause_;
+
+  quickstep::PtrVector<quickstep::ParseSearchedWhenClause> *searched_when_clause_list_;
+  quickstep::ParseSearchedWhenClause *searched_when_clause_;
+
   quickstep::ParseSelectionClause *selection_;
   quickstep::ParseSelectionItem *selection_item_;
   quickstep::ParseSelectionList *selection_list_;
@@ -243,7 +254,7 @@
   quickstep::PtrVector<quickstep::ParseSubqueryTableReference> *with_list_;
   quickstep::ParseSubqueryTableReference *with_list_element_;
 
-#line 247 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 258 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;
diff --git a/parser/tests/Select.test b/parser/tests/Select.test
index 8147c53..18c3f0d 100644
--- a/parser/tests/Select.test
+++ b/parser/tests/Select.test
@@ -1437,3 +1437,121 @@
         | +-NumericLiteral[numeric_string=100,float_like=false]
         +-Literal
           +-NumericLiteral[numeric_string=3,float_like=false]
+==
+
+# CASE expressions.
+SELECT CASE col1%2
+           WHEN 1 THEN 'odd'
+           ELSE 'even'
+       END
+FROM test;
+--
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  |   +-SimpleCaseExpression
+  |     +-case_operand=Modulo
+  |     | +-left_operand=AttributeReference[attribute_name=col1]
+  |     | +-right_operand=Literal
+  |     |   +-NumericLiteral[numeric_string=2,float_like=false]
+  |     +-else_result_expression=Literal
+  |     | +-StringLiteral[value=even]
+  |     +-when_clauses=
+  |       +-SimpleWhenClause
+  |         +-condition_operand=Literal
+  |         | +-NumericLiteral[numeric_string=1,float_like=false]
+  |         +-result_expression=Literal
+  |           +-StringLiteral[value=odd]
+  +-from_clause=
+    +-TableReference[table=test]
+==
+
+SELECT *
+FROM test
+WHERE CASE WHEN col1 > col2 THEN col3
+           ELSE col4
+      END > 0;
+--
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectStar
+  +-where_clause=Greater
+  | +-left_operand=SearchedCaseExpression
+  | | +-else_result_expression=AttributeReference[attribute_name=col4]
+  | | +-when_clauses=
+  | |   +-SearchedWhenClause
+  | |     +-condition_predicate=Greater
+  | |     | +-left_operand=AttributeReference[attribute_name=col1]
+  | |     | +-right_operand=AttributeReference[attribute_name=col2]
+  | |     +-result_expression=AttributeReference[attribute_name=col3]
+  | +-right_operand=Literal
+  |   +-NumericLiteral[numeric_string=0,float_like=false]
+  +-from_clause=
+    +-TableReference[table=test]
+==
+
+SELECT
+  FUN(CASE col1
+        WHEN col2 + FUN(
+               CASE WHEN col1 < col2 THEN 0
+                    ELSE 1
+               END +
+               CASE WHEN col1 < col3 THEN 0
+                    ELSE 1
+               END
+             ) THEN 1
+        WHEN col3 THEN 2
+        ELSE 0
+      END + col4)
+FROM test;
+--
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  |   +-FunctionCall[name=FUN]
+  |     +-Add
+  |       +-left_operand=SimpleCaseExpression
+  |       | +-case_operand=AttributeReference[attribute_name=col1]
+  |       | +-else_result_expression=Literal
+  |       | | +-NumericLiteral[numeric_string=0,float_like=false]
+  |       | +-when_clauses=
+  |       |   +-SimpleWhenClause
+  |       |   | +-condition_operand=Add
+  |       |   | | +-left_operand=AttributeReference[attribute_name=col2]
+  |       |   | | +-right_operand=FunctionCall[name=FUN]
+  |       |   | |   +-Add
+  |       |   | |     +-left_operand=SearchedCaseExpression
+  |       |   | |     | +-else_result_expression=Literal
+  |       |   | |     | | +-NumericLiteral[numeric_string=1,float_like=false]
+  |       |   | |     | +-when_clauses=
+  |       |   | |     |   +-SearchedWhenClause
+  |       |   | |     |     +-condition_predicate=Less
+  |       |   | |     |     | +-left_operand=AttributeReference[
+  |       |   | |     |     | | attribute_name=col1]
+  |       |   | |     |     | +-right_operand=AttributeReference[
+  |       |   | |     |     |   attribute_name=col2]
+  |       |   | |     |     +-result_expression=Literal
+  |       |   | |     |       +-NumericLiteral[numeric_string=0,float_like=false]
+  |       |   | |     +-right_operand=SearchedCaseExpression
+  |       |   | |       +-else_result_expression=Literal
+  |       |   | |       | +-NumericLiteral[numeric_string=1,float_like=false]
+  |       |   | |       +-when_clauses=
+  |       |   | |         +-SearchedWhenClause
+  |       |   | |           +-condition_predicate=Less
+  |       |   | |           | +-left_operand=AttributeReference[
+  |       |   | |           | | attribute_name=col1]
+  |       |   | |           | +-right_operand=AttributeReference[
+  |       |   | |           |   attribute_name=col3]
+  |       |   | |           +-result_expression=Literal
+  |       |   | |             +-NumericLiteral[numeric_string=0,float_like=false]
+  |       |   | +-result_expression=Literal
+  |       |   |   +-NumericLiteral[numeric_string=1,float_like=false]
+  |       |   +-SimpleWhenClause
+  |       |     +-condition_operand=AttributeReference[attribute_name=col3]
+  |       |     +-result_expression=Literal
+  |       |       +-NumericLiteral[numeric_string=2,float_like=false]
+  |       +-right_operand=AttributeReference[attribute_name=col4]
+  +-from_clause=
+    +-TableReference[table=test]
diff --git a/parser/tests/TPCH.test b/parser/tests/TPCH.test
index 3b9fd37..af300a4 100644
--- a/parser/tests/TPCH.test
+++ b/parser/tests/TPCH.test
@@ -578,10 +578,10 @@
 # Query 8
 SELECT
   o_year,
-  SUM(case
-    when nation = 'UNITED STATES' then volume
-    else 0
-  end) / SUM(volume) AS mkt_share
+  SUM(CASE
+    WHEN nation = 'UNITED STATES' THEN volume
+    ELSE 0
+  END) / SUM(volume) AS mkt_share
 FROM
   (
     SELECT
@@ -614,9 +614,99 @@
 ORDER BY
   o_year
 --
-ERROR: syntax error (4 : 5)
-    when nation = 'UNITED STATES' the...
-    ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem
+  | | +-AttributeReference[attribute_name=o_year]
+  | +-SelectListItem[alias=mkt_share]
+  |   +-Divide
+  |     +-left_operand=FunctionCall[name=SUM]
+  |     | +-SearchedCaseExpression
+  |     |   +-else_result_expression=Literal
+  |     |   | +-NumericLiteral[numeric_string=0,float_like=false]
+  |     |   +-when_clauses=
+  |     |     +-SearchedWhenClause
+  |     |       +-condition_predicate=Equal
+  |     |       | +-left_operand=AttributeReference[attribute_name=nation]
+  |     |       | +-right_operand=Literal
+  |     |       |   +-StringLiteral[value=UNITED STATES]
+  |     |       +-result_expression=AttributeReference[attribute_name=volume]
+  |     +-right_operand=FunctionCall[name=SUM]
+  |       +-AttributeReference[attribute_name=volume]
+  +-group_by=GroupBy
+  | +-AttributeReference[attribute_name=o_year]
+  +-order_by=OrderBy
+  | +-OrderByItem[is_asc=true,nulls_first=false]
+  |   +-AttributeReference[attribute_name=o_year]
+  +-from_clause=
+    +-SubqueryTable
+      +-table_signature=TableSignature[table_alias=all_nations]
+      +-SubqueryExpression
+        +-Select
+          +-select_clause=SelectList
+          | +-SelectListItem[alias=o_year]
+          | | +-Extract[unit=year]
+          | |   +-date_expression=AttributeReference[attribute_name=o_orderdate]
+          | +-SelectListItem[alias=volume]
+          | | +-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]
+          | +-SelectListItem[alias=nation]
+          |   +-AttributeReference[attribute_name=n_name,relation_name=n2]
+          +-where_clause=And
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=p_partkey]
+          | | +-right_operand=AttributeReference[attribute_name=l_partkey]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=s_suppkey]
+          | | +-right_operand=AttributeReference[attribute_name=l_suppkey]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=l_orderkey]
+          | | +-right_operand=AttributeReference[attribute_name=o_orderkey]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=o_custkey]
+          | | +-right_operand=AttributeReference[attribute_name=c_custkey]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=c_nationkey]
+          | | +-right_operand=AttributeReference[attribute_name=n_nationkey,
+          | |   relation_name=n1]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=n_regionkey,
+          | | | relation_name=n1]
+          | | +-right_operand=AttributeReference[attribute_name=r_regionkey]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=r_name]
+          | | +-right_operand=Literal
+          | |   +-StringLiteral[value=AMERICA]
+          | +-Equal
+          | | +-left_operand=AttributeReference[attribute_name=s_nationkey]
+          | | +-right_operand=AttributeReference[attribute_name=n_nationkey,
+          | |   relation_name=n2]
+          | +-Between
+          | | +-check_operand=AttributeReference[attribute_name=o_orderdate]
+          | | +-lower_bound_operand=Literal
+          | | | +-StringLiteral[value=1995-01-01,explicit_type=Datetime]
+          | | +-upper_bound_operand=Literal
+          | |   +-StringLiteral[value=1996-12-31,explicit_type=Datetime]
+          | +-Equal
+          |   +-left_operand=AttributeReference[attribute_name=p_type]
+          |   +-right_operand=Literal
+          |     +-StringLiteral[value=MEDIUM ANODIZED NICKEL]
+          +-from_clause=
+            +-TableReference[table=part]
+            +-TableReference[table=supplier]
+            +-TableReference[table=lineitem]
+            +-TableReference[table=orders]
+            +-TableReference[table=customer]
+            +-TableReference[table=nation]
+            | +-table_signature=TableSignature[table_alias=n1]
+            +-TableReference[table=nation]
+            | +-table_signature=TableSignature[table_alias=n2]
+            +-TableReference[table=region]
 ==
 
 # Query 9
@@ -867,18 +957,18 @@
 # Query 12
 SELECT
   l_shipmode,
-  SUM(case
-    when o_orderpriority = '1-URGENT'
+  SUM(CASE
+    WHEN o_orderpriority = '1-URGENT'
       OR o_orderpriority = '2-HIGH'
-      then 1
-    else 0
-  end) AS high_line_count,
-  SUM(case
-    when o_orderpriority <> '1-URGENT'
+      THEN 1
+    ELSE 0
+  END) AS high_line_count,
+  SUM(CASE
+    WHEN o_orderpriority <> '1-URGENT'
       AND o_orderpriority <> '2-HIGH'
-      then 1
-    else 0
-  end) AS low_line_count
+      THEN 1
+    ELSE 0
+  END) AS low_line_count
 FROM
   orders,
   lineitem
@@ -894,9 +984,9 @@
 ORDER BY
   l_shipmode
 --
-ERROR: syntax error (4 : 5)
-    when o_orderpriority = '1-URGEN...
-    ^
+ERROR: syntax error (20 : 18)
+  AND l_shipmode in ('REG AIR', 'RAIL')
+                 ^
 ==
 
 # Query 13
@@ -928,11 +1018,11 @@
 
 # Query 14
 SELECT
-  100.00 * sum(case
-    when p_type LIKE 'PROMO%'
-      then l_extendedprice * (1 - l_discount)
-    else 0
-  end) / SUM(l_extendedprice * (1 - l_discount)) AS promo_revenue
+  100.00 * SUM(CASE
+    WHEN p_type LIKE 'PROMO%'
+      THEN l_extendedprice * (1 - l_discount)
+    ELSE 0
+  END) / SUM(l_extendedprice * (1 - l_discount)) AS promo_revenue
 FROM
   lineitem,
   part
@@ -941,9 +1031,57 @@
   AND l_shipdate >= DATE '1994-11-01'
   AND l_shipdate < DATE '1994-11-01' + INTERVAL '1 month'
 --
-ERROR: syntax error (3 : 5)
-    when p_type LIKE 'PROMO%'
-    ^
+SelectStatement
++-select_query=Select
+  +-select_clause=SelectList
+  | +-SelectListItem[alias=promo_revenue]
+  |   +-Divide
+  |     +-left_operand=Multiply
+  |     | +-left_operand=Literal
+  |     | | +-NumericLiteral[numeric_string=100.00,float_like=true]
+  |     | +-right_operand=FunctionCall[name=SUM]
+  |     |   +-SearchedCaseExpression
+  |     |     +-else_result_expression=Literal
+  |     |     | +-NumericLiteral[numeric_string=0,float_like=false]
+  |     |     +-when_clauses=
+  |     |       +-SearchedWhenClause
+  |     |         +-condition_predicate=kLike
+  |     |         | +-left_operand=AttributeReference[attribute_name=p_type]
+  |     |         | +-right_operand=Literal
+  |     |         |   +-StringLiteral[value=PROMO%]
+  |     |         +-result_expression=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]
+  |     +-right_operand=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
+  | +-Equal
+  | | +-left_operand=AttributeReference[attribute_name=l_partkey]
+  | | +-right_operand=AttributeReference[attribute_name=p_partkey]
+  | +-GreaterOrEqual
+  | | +-left_operand=AttributeReference[attribute_name=l_shipdate]
+  | | +-right_operand=Literal
+  | |   +-StringLiteral[value=1994-11-01,explicit_type=Datetime]
+  | +-Less
+  |   +-left_operand=AttributeReference[attribute_name=l_shipdate]
+  |   +-right_operand=Add
+  |     +-left_operand=Literal
+  |     | +-StringLiteral[value=1994-11-01,explicit_type=Datetime]
+  |     +-right_operand=Literal
+  |       +-StringLiteral[value=1 month,explicit_type=YearMonthInterval]
+  +-from_clause=
+    +-TableReference[table=lineitem]
+    +-TableReference[table=part]
 ==
 
 # Query 15
diff --git a/query_optimizer/OptimizerContext.hpp b/query_optimizer/OptimizerContext.hpp
index 0ae3386..abdc7f4 100644
--- a/query_optimizer/OptimizerContext.hpp
+++ b/query_optimizer/OptimizerContext.hpp
@@ -61,6 +61,7 @@
         current_expr_id_(-1),
         catalog_database_(catalog_database),
         storage_manager_(storage_manager),
+        has_nested_queries_(false),
         is_catalog_changed_(false) {}
 
   /**
@@ -107,6 +108,20 @@
   }
 
   /**
+   * @brief Indicate that the query has a nested subquery.
+   */
+  void set_has_nested_queries() {
+    has_nested_queries_ = true;
+  }
+
+  /**
+   * @return True if the query has a nested subquery.
+   */
+  bool has_nested_queries() const {
+    return has_nested_queries_;
+  }
+
+  /**
    * @brief Sets <is_catalog_changed_> to be true to indicate the query will
    *        modify the catalog permanently.
    */
@@ -125,6 +140,8 @@
   CatalogDatabase *catalog_database_;
   StorageManager *storage_manager_;
 
+  bool has_nested_queries_;
+
   bool is_catalog_changed_;
 
   DISALLOW_COPY_AND_ASSIGN(OptimizerContext);
diff --git a/query_optimizer/expressions/AttributeReference.cpp b/query_optimizer/expressions/AttributeReference.cpp
index f6831d9..b15d482 100644
--- a/query_optimizer/expressions/AttributeReference.cpp
+++ b/query_optimizer/expressions/AttributeReference.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.
@@ -38,12 +40,13 @@
                                     attribute_name(),
                                     attribute_alias(),
                                     relation_name(),
-                                    getValueType());
+                                    getValueType(),
+                                    scope());
 }
 
 std::vector<AttributeReferencePtr> AttributeReference::getReferencedAttributes()
     const {
-  return { Create(id(), attribute_name(), attribute_alias(), relation_name(), type_) };
+  return { Create(id(), attribute_name(), attribute_alias(), relation_name(), getValueType(), scope()) };
 }
 
 ::quickstep::Scalar *AttributeReference::concretize(
@@ -54,6 +57,27 @@
   return new ::quickstep::ScalarAttribute(*found_it->second);
 }
 
+void AttributeReference::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  NamedExpression::getFieldStringItems(
+      inline_field_names,
+      inline_field_values,
+      non_container_child_field_names,
+      non_container_child_fields,
+      container_child_field_names,
+      container_child_fields);
+
+  if (scope_ == AttributeReferenceScope::kOuter) {
+    inline_field_names->push_back("is_outer_reference");
+    inline_field_values->push_back("true");
+  }
+}
+
 }  // namespace expressions
 }  // namespace optimizer
 }  // namespace quickstep
diff --git a/query_optimizer/expressions/AttributeReference.hpp b/query_optimizer/expressions/AttributeReference.hpp
index b9f670a..f299bbc 100644
--- a/query_optimizer/expressions/AttributeReference.hpp
+++ b/query_optimizer/expressions/AttributeReference.hpp
@@ -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.
@@ -42,6 +44,16 @@
  *  @{
  */
 
+/**
+ * @brief The scope of the referenced attribute. I.e. whether the referenced
+ *        attribute belongs to a local TableReference or comes from an outside
+ *        TableReference. The outside case implies a correlated subquery.
+ */
+enum class AttributeReferenceScope {
+  kLocal = 0,
+  kOuter
+};
+
 class AttributeReference;
 typedef std::shared_ptr<const AttributeReference> AttributeReferencePtr;
 
@@ -61,6 +73,13 @@
 
   bool isConstant() const override { return false; }
 
+  /**
+   * @return The scope of the referenced attribute.
+   */
+  const AttributeReferenceScope scope() const {
+    return scope_;
+  }
+
   ExpressionPtr copyWithNewChildren(
       const std::vector<ExpressionPtr> &new_children) const override;
 
@@ -81,30 +100,44 @@
    *                      expression comes from. This is only for
    *                      printing purpose.
    * @param type The type of the value of the referenced expression.
+   * @param scope The scope of the referenced attribute.
    * @return An immutable AttributeReference.
    */
   static AttributeReferencePtr Create(ExprId attribute_id,
                                       const std::string &attribute_name,
                                       const std::string &attribute_alias,
                                       const std::string &relation_name,
-                                      const Type &type) {
+                                      const Type &type,
+                                      const AttributeReferenceScope scope) {
     return AttributeReferencePtr(new AttributeReference(
-        attribute_id, attribute_name, attribute_alias, relation_name, type));
+        attribute_id, attribute_name, attribute_alias, relation_name, type, scope));
   }
 
+ protected:
+  void getFieldStringItems(
+     std::vector<std::string> *inline_field_names,
+     std::vector<std::string> *inline_field_values,
+     std::vector<std::string> *non_container_child_field_names,
+     std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+     std::vector<std::string> *container_child_field_names,
+     std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
  private:
   AttributeReference(attribute_id attribute_id,
                      const std::string &attribute_name,
                      const std::string &attribute_alias,
                      const std::string &relation_name,
-                     const Type &type)
+                     const Type &type,
+                     const AttributeReferenceScope scope)
       : NamedExpression(attribute_id,
                         attribute_name,
                         attribute_alias,
                         relation_name),
-        type_(type) {}
+        type_(type),
+        scope_(scope) {}
 
   const Type &type_;
+  const AttributeReferenceScope scope_;
 
   DISALLOW_COPY_AND_ASSIGN(AttributeReference);
 };
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index c7e8115..470bfb9 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -1,5 +1,7 @@
 #   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.
@@ -21,6 +23,7 @@
 add_library(quickstep_queryoptimizer_expressions_Cast Cast.cpp Cast.hpp)
 add_library(quickstep_queryoptimizer_expressions_ComparisonExpression ComparisonExpression.cpp
             ComparisonExpression.hpp)
+add_library(quickstep_queryoptimizer_expressions_Exists Exists.cpp Exists.hpp)
 add_library(quickstep_queryoptimizer_expressions_Expression ../../empty_src.cpp Expression.hpp)
 add_library(quickstep_queryoptimizer_expressions_ExpressionType ../../empty_src.cpp ExpressionType.hpp)
 add_library(quickstep_queryoptimizer_expressions_ExprId ../../empty_src.cpp ExprId.hpp)
@@ -34,6 +37,9 @@
 add_library(quickstep_queryoptimizer_expressions_PredicateLiteral PredicateLiteral.cpp PredicateLiteral.hpp)
 add_library(quickstep_queryoptimizer_expressions_Scalar ../../empty_src.cpp Scalar.hpp)
 add_library(quickstep_queryoptimizer_expressions_ScalarLiteral ScalarLiteral.cpp ScalarLiteral.hpp)
+add_library(quickstep_queryoptimizer_expressions_SearchedCase SearchedCase.cpp SearchedCase.hpp)
+add_library(quickstep_queryoptimizer_expressions_SimpleCase SimpleCase.cpp SimpleCase.hpp)
+add_library(quickstep_queryoptimizer_expressions_SubqueryExpression SubqueryExpression.cpp SubqueryExpression.hpp)
 add_library(quickstep_queryoptimizer_expressions_UnaryExpression UnaryExpression.cpp UnaryExpression.hpp)
 
 # Link dependencies:
@@ -111,6 +117,15 @@
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonID
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_queryoptimizer_expressions_Exists
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_Expression
+                      quickstep_queryoptimizer_expressions_ExpressionType
+                      quickstep_queryoptimizer_expressions_Predicate
+                      quickstep_queryoptimizer_expressions_SubqueryExpression
+                      quickstep_utility_Macros
+                      glog)
 target_link_libraries(quickstep_queryoptimizer_expressions_Expression
                       quickstep_queryoptimizer_OptimizerTree
                       quickstep_queryoptimizer_expressions_ExpressionType
@@ -202,6 +217,48 @@
                       quickstep_types_Type
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_queryoptimizer_expressions_SearchedCase
+                      quickstep_expressions_predicate_Predicate
+                      quickstep_expressions_scalar_Scalar
+                      quickstep_expressions_scalar_ScalarCaseExpression
+                      quickstep_expressions_scalar_ScalarLiteral
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_ExprId
+                      quickstep_queryoptimizer_expressions_Expression
+                      quickstep_queryoptimizer_expressions_ExpressionType
+                      quickstep_queryoptimizer_expressions_Predicate
+                      quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_Type
+                      quickstep_utility_Cast
+                      quickstep_utility_Macros)
+target_link_libraries(quickstep_queryoptimizer_expressions_SimpleCase
+                      quickstep_expressions_predicate_Predicate
+                      quickstep_expressions_scalar_Scalar
+                      quickstep_expressions_scalar_ScalarCaseExpression
+                      quickstep_expressions_scalar_ScalarLiteral
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_ComparisonExpression
+                      quickstep_queryoptimizer_expressions_ExprId
+                      quickstep_queryoptimizer_expressions_Expression
+                      quickstep_queryoptimizer_expressions_ExpressionType
+                      quickstep_queryoptimizer_expressions_Predicate
+                      quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_Type
+                      quickstep_types_operations_comparisons_ComparisonFactory
+                      quickstep_types_operations_comparisons_ComparisonID
+                      quickstep_utility_Cast
+                      quickstep_utility_Macros)
+target_link_libraries(quickstep_queryoptimizer_expressions_SubqueryExpression
+                      glog
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_Expression
+                      quickstep_queryoptimizer_expressions_ExpressionType
+                      quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_queryoptimizer_logical_Logical
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_UnaryExpression
                       glog
                       quickstep_expressions_scalar_ScalarUnaryExpression
@@ -225,6 +282,7 @@
                       quickstep_queryoptimizer_expressions_BinaryExpression
                       quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_ComparisonExpression
+                      quickstep_queryoptimizer_expressions_Exists
                       quickstep_queryoptimizer_expressions_Expression
                       quickstep_queryoptimizer_expressions_ExpressionType
                       quickstep_queryoptimizer_expressions_ExprId
@@ -238,4 +296,7 @@
                       quickstep_queryoptimizer_expressions_PredicateLiteral
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_queryoptimizer_expressions_SearchedCase
+                      quickstep_queryoptimizer_expressions_SimpleCase
+                      quickstep_queryoptimizer_expressions_SubqueryExpression
                       quickstep_queryoptimizer_expressions_UnaryExpression)
diff --git a/query_optimizer/expressions/Exists.cpp b/query_optimizer/expressions/Exists.cpp
new file mode 100644
index 0000000..12d3a8b
--- /dev/null
+++ b/query_optimizer/expressions/Exists.cpp
@@ -0,0 +1,52 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "query_optimizer/expressions/Exists.hpp"
+
+#include <vector>
+#include <string>
+
+#include "query_optimizer/OptimizerTree.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace expressions {
+
+::quickstep::Predicate* Exists::concretize(
+    const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
+  LOG(FATAL) << "Exists predicate should not be concretized";
+  return nullptr;
+}
+
+
+void Exists::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  non_container_child_field_names->push_back("exists_subquery");
+  non_container_child_fields->push_back(exists_subquery_);
+}
+
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
diff --git a/query_optimizer/expressions/Exists.hpp b/query_optimizer/expressions/Exists.hpp
new file mode 100644
index 0000000..dd951c5
--- /dev/null
+++ b/query_optimizer/expressions/Exists.hpp
@@ -0,0 +1,118 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_EXISTS_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_EXISTS_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/ExpressionType.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
+#include "query_optimizer/expressions/SubqueryExpression.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+namespace optimizer {
+namespace expressions {
+
+/** \addtogroup OptimizerExpressions
+ *  @{
+ */
+
+class Exists;
+typedef std::shared_ptr<const Exists> ExistsPtr;
+
+/**
+ * @brief EXISTS predicate expression.
+ */
+class Exists : public Predicate {
+ public:
+  ExpressionType getExpressionType() const override {
+    return ExpressionType::kExists;
+  }
+
+  std::string getName() const override {
+    return "Exists";
+  }
+
+  bool isConstant() const override {
+    return false;
+  }
+
+  /**
+   * @return The subquery expression for this EXISTS predicate.
+   */
+  const SubqueryExpressionPtr& exists_subquery() const {
+    return exists_subquery_;
+  }
+
+  ExpressionPtr copyWithNewChildren(
+      const std::vector<ExpressionPtr> &new_children) const override {
+    DCHECK_EQ(new_children.size(), 1u);
+    return Create(std::static_pointer_cast<const SubqueryExpression>(new_children[0]));
+  }
+
+  std::vector<AttributeReferencePtr> getReferencedAttributes() const override {
+    return {};
+  }
+
+  ::quickstep::Predicate* concretize(
+      const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const override;
+
+  /**
+   * @brief Create an Exists predicate expression.
+   *
+   * @param exists_subquery The subquery expression for this EXISTS predicate.
+   * @return An immutable Exists expression node.
+   */
+  static ExistsPtr Create(const SubqueryExpressionPtr &exists_subquery) {
+    return ExistsPtr(new Exists(exists_subquery));
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  explicit Exists(const SubqueryExpressionPtr &exists_subquery)
+      : exists_subquery_(exists_subquery) {
+    addChild(exists_subquery_);
+  }
+
+  SubqueryExpressionPtr exists_subquery_;
+
+  DISALLOW_COPY_AND_ASSIGN(Exists);
+};
+
+/** @} */
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
+
+
+#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_EXISTS_HPP_ */
diff --git a/query_optimizer/expressions/ExpressionType.hpp b/query_optimizer/expressions/ExpressionType.hpp
index d1b5c23..afd6f81 100644
--- a/query_optimizer/expressions/ExpressionType.hpp
+++ b/query_optimizer/expressions/ExpressionType.hpp
@@ -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.
@@ -36,11 +38,15 @@
   kBinaryExpression,
   kCast,
   kComparisonExpression,
+  kExists,
   kLogicalAnd,
   kLogicalOr,
   kLogicalNot,
   kPredicateLiteral,
   kScalarLiteral,
+  kSearchedCase,
+  kSimpleCase,
+  kSubqueryExpression,
   kUnaryExpression
 };
 
diff --git a/query_optimizer/expressions/ExpressionUtil.cpp b/query_optimizer/expressions/ExpressionUtil.cpp
index 4395a43..3481d6c 100644
--- a/query_optimizer/expressions/ExpressionUtil.cpp
+++ b/query_optimizer/expressions/ExpressionUtil.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,6 +19,8 @@
 
 #include "query_optimizer/expressions/ExpressionUtil.hpp"
 
+#include <vector>
+
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/NamedExpression.hpp"
 
@@ -29,7 +33,20 @@
                                     expression->attribute_name(),
                                     expression->attribute_alias(),
                                     expression->relation_name(),
-                                    expression->getValueType());
+                                    expression->getValueType(),
+                                    AttributeReferenceScope::kLocal);
+}
+
+std::vector<AttributeReferencePtr> GetAttributeReferencesWithinScope(
+    const std::vector<AttributeReferencePtr> &attributes,
+    const AttributeReferenceScope scope) {
+  std::vector<AttributeReferencePtr> filtered_attributes;
+  for (const auto& attr_it : attributes) {
+    if (attr_it->scope() == scope) {
+      filtered_attributes.emplace_back(attr_it);
+    }
+  }
+  return filtered_attributes;
 }
 
 }  // namespace expressions
diff --git a/query_optimizer/expressions/ExpressionUtil.hpp b/query_optimizer/expressions/ExpressionUtil.hpp
index 6038957..cc9fbbe 100644
--- a/query_optimizer/expressions/ExpressionUtil.hpp
+++ b/query_optimizer/expressions/ExpressionUtil.hpp
@@ -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.
@@ -69,6 +71,7 @@
 };
 
 typedef std::unordered_set<NamedExpressionPtr, NamedExpressionHash, NamedExpressionEqual> UnorderedNamedExpressionSet;
+typedef std::unordered_set<AttributeReferencePtr, NamedExpressionHash, NamedExpressionEqual> UnorderedAttributeSet;
 
 /**
  * @brief Checks whether \p expression_to_check is contained by \p expressions.
@@ -121,6 +124,19 @@
 AttributeReferencePtr ToRef(const NamedExpressionPtr &expression);
 
 /**
+ * @brief Filter a vector of AttributeReferencePtr to get those which are in
+ *        the specified scope.
+ *
+ * @param attributes The vector of AttributeReferencePtr to be filtered.
+ * @param scope The specified reference scope.
+ *
+ * @return A vector of AttributeReferencePtr within the specified scope.
+ */
+std::vector<AttributeReferencePtr> GetAttributeReferencesWithinScope(
+    const std::vector<AttributeReferencePtr> &attributes,
+    const AttributeReferenceScope scope);
+
+/**
  * @brief Creates a list of AttributeReferences from a list of NamedExpressions
  *        with each AttributeReference referencing a distinct NamedExpression.
  *        The input and the output have 1:1 matching.
diff --git a/query_optimizer/expressions/PatternMatcher.hpp b/query_optimizer/expressions/PatternMatcher.hpp
index 2aab671..4c5432d 100644
--- a/query_optimizer/expressions/PatternMatcher.hpp
+++ b/query_optimizer/expressions/PatternMatcher.hpp
@@ -139,6 +139,8 @@
                                       ExpressionType::kLogicalOr,
                                       ExpressionType::kPredicateLiteral,
                                       ExpressionType::kScalarLiteral,
+                                      ExpressionType::kSearchedCase,
+                                      ExpressionType::kSimpleCase,
                                       ExpressionType::kUnaryExpression>;
 using SomeScalarLiteral = SomeExpressionNode<ScalarLiteral, ExpressionType::kScalarLiteral>;
 using SomeUnaryExpression = SomeExpressionNode<UnaryExpression, ExpressionType::kUnaryExpression>;
diff --git a/query_optimizer/expressions/SearchedCase.cpp b/query_optimizer/expressions/SearchedCase.cpp
new file mode 100644
index 0000000..57da7a1
--- /dev/null
+++ b/query_optimizer/expressions/SearchedCase.cpp
@@ -0,0 +1,164 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "query_optimizer/expressions/SearchedCase.hpp"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "expressions/predicate/Predicate.hpp"
+#include "expressions/scalar/ScalarCaseExpression.hpp"
+#include "expressions/scalar/ScalarLiteral.hpp"
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "types/Type.hpp"
+#include "utility/Cast.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace expressions {
+
+bool SearchedCase::isConstant() const {
+  // We treat a SearchedCase as constant only if all operands are constant.
+  for (const PredicatePtr &condition_predicate : condition_predicates_) {
+    if (!condition_predicate->isConstant()) {
+      return false;
+    }
+  }
+  for (const ScalarPtr &conditional_result_expression : conditional_result_expressions_) {
+    if (!conditional_result_expression->isConstant()) {
+      return false;
+    }
+  }
+  return (else_result_expression_ == nullptr || else_result_expression_->isConstant());
+}
+
+std::vector<AttributeReferencePtr> SearchedCase::getReferencedAttributes() const {
+  std::vector<AttributeReferencePtr> referenced_attributes;
+  for (const PredicatePtr &condition_predicate : condition_predicates_) {
+    const std::vector<AttributeReferencePtr> referenced_attributes_in_condition_predicate =
+        condition_predicate->getReferencedAttributes();
+    referenced_attributes.insert(referenced_attributes.end(),
+                                 referenced_attributes_in_condition_predicate.begin(),
+                                 referenced_attributes_in_condition_predicate.end());
+  }
+  for (const ScalarPtr &conditional_result_expression : conditional_result_expressions_) {
+    const std::vector<AttributeReferencePtr> referenced_attributes_in_conditional_result_expression =
+        conditional_result_expression->getReferencedAttributes();
+    referenced_attributes.insert(referenced_attributes.end(),
+                                 referenced_attributes_in_conditional_result_expression.begin(),
+                                 referenced_attributes_in_conditional_result_expression.end());
+  }
+  if (else_result_expression_ != nullptr) {
+    const std::vector<AttributeReferencePtr> referenced_attributes_in_else_result_expression =
+        else_result_expression_->getReferencedAttributes();
+    referenced_attributes.insert(referenced_attributes.end(),
+                                 referenced_attributes_in_else_result_expression.begin(),
+                                 referenced_attributes_in_else_result_expression.end());
+  }
+  return referenced_attributes;
+}
+
+ExpressionPtr SearchedCase::copyWithNewChildren(
+    const std::vector<ExpressionPtr> &new_children) const {
+  DCHECK_EQ(getNumChildren(), new_children.size());
+
+  std::vector<PredicatePtr> new_condition_predicates;
+  std::vector<ScalarPtr> new_conditional_result_expressions;
+  ScalarPtr new_else_result_expression;
+
+  new_condition_predicates.reserve(condition_predicates_.size());
+  new_conditional_result_expressions.reserve(condition_predicates_.size());
+
+  std::size_t num_when_clauses = condition_predicates_.size();
+  for (std::size_t index = 0; index < num_when_clauses; ++index) {
+    new_condition_predicates.push_back(
+        std::static_pointer_cast<const Predicate>(new_children[index]));
+
+    new_conditional_result_expressions.push_back(
+        std::static_pointer_cast<const Scalar>(new_children[index + num_when_clauses]));
+  }
+  if (else_result_expression_ != nullptr) {
+    new_else_result_expression =
+        std::static_pointer_cast<const Scalar>(new_children.back());
+  }
+
+  return Create(new_condition_predicates,
+                new_conditional_result_expressions,
+                new_else_result_expression, value_type_);
+}
+
+::quickstep::Scalar* SearchedCase::concretize(
+    const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
+  std::vector<std::unique_ptr<quickstep::Predicate>> when_predicates;
+  for (const PredicatePtr &predicate : condition_predicates_) {
+    when_predicates.emplace_back(predicate->concretize(substitution_map));
+  }
+
+  std::vector<std::unique_ptr<quickstep::Scalar>> result_expressions;
+  for (const ScalarPtr &expression : conditional_result_expressions_) {
+    result_expressions.emplace_back(expression->concretize(substitution_map));
+  }
+
+  std::unique_ptr<quickstep::Scalar> else_result_expression;
+  if (else_result_expression_ == nullptr) {
+    else_result_expression.reset(
+        new quickstep::ScalarLiteral(value_type_.makeNullValue(), value_type_));
+  } else {
+    else_result_expression.reset(
+        else_result_expression_->concretize(substitution_map));
+  }
+
+  return new quickstep::ScalarCaseExpression(
+      value_type_,
+      std::move(when_predicates),
+      std::move(result_expressions),
+      else_result_expression_->concretize(substitution_map));
+}
+
+void SearchedCase::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  container_child_field_names->push_back("condition_perdicates");
+  container_child_fields->push_back(
+      CastSharedPtrVector<OptimizerTreeBase>(condition_predicates_));
+
+  container_child_field_names->push_back("conditional_result_expressions");
+  container_child_fields->push_back(
+      CastSharedPtrVector<OptimizerTreeBase>(conditional_result_expressions_));
+
+  if (else_result_expression_ != nullptr) {
+    non_container_child_field_names->push_back("else_result_expression");
+    non_container_child_fields->push_back(else_result_expression_);
+  }
+}
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
diff --git a/query_optimizer/expressions/SearchedCase.hpp b/query_optimizer/expressions/SearchedCase.hpp
new file mode 100644
index 0000000..8bea0c4
--- /dev/null
+++ b/query_optimizer/expressions/SearchedCase.hpp
@@ -0,0 +1,170 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SEARCHED_CASE_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SEARCHED_CASE_HPP_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "expressions/scalar/Scalar.hpp"
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ExprId.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/ExpressionType.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class CatalogAttribute;
+class Type;
+
+namespace optimizer {
+namespace expressions {
+
+/** \addtogroup OptimizerExpressions
+ *  @{
+ */
+
+class SearchedCase;
+typedef std::shared_ptr<const SearchedCase> SearchedCasePtr;
+
+/**
+ * @brief A searched CASE expression. It searches the first predicate in
+ *        <condition_predicates_> that evaluates to true and returns the value
+ *        of the expression in <conditional_result_expressions_> at the same
+ *        position; if none of <condition_predicates_> evaluate to true, returns
+ *        the value of <else_result_expression_> when <else_result_expression_>
+ *        is not NULL, otherwise returns NULL.
+ */
+class SearchedCase : public Scalar {
+ public:
+  ExpressionType getExpressionType() const override {
+    return ExpressionType::kSearchedCase;
+  }
+
+  std::string getName() const override {
+    return "SearchedCase";
+  }
+
+  const Type& getValueType() const override {
+    return value_type_;
+  }
+
+  /**
+   * @return The vector of condition predicates.
+   */
+  const std::vector<PredicatePtr>& condition_predicates() const {
+    return condition_predicates_;
+  }
+
+  /**
+   * @return The vector of conditional result expressions.
+   */
+  const std::vector<ScalarPtr>& conditional_result_expressions() const {
+    return conditional_result_expressions_;
+  }
+
+  /**
+   * @return The ELSE result expression.
+   */
+  const ScalarPtr& else_result_expression() const {
+    return else_result_expression_;
+  }
+
+  bool isConstant() const override;
+
+  std::vector<AttributeReferencePtr> getReferencedAttributes() const override;
+
+  ExpressionPtr copyWithNewChildren(
+      const std::vector<ExpressionPtr> &new_children) const override;
+
+  ::quickstep::Scalar* concretize(
+      const std::unordered_map<ExprId, const CatalogAttribute*>& substitution_map) const override;
+
+  /**
+   * @brief Creates an immutable SearchedCase.
+   *
+   * @param condition_predicates A vector of condition predicates.
+   * @param conditional_result_expressions A vector of result expressions, one
+   *        for each condition predicate.
+   * @param else_result_expression The optional ELSE expression.
+   * @param value_type The data type of this expression which should be the
+   *        unified type of all result expressions.
+   * @return An immutable SimpleCase.
+   */
+  static SearchedCasePtr Create(const std::vector<PredicatePtr> &condition_predicates,
+                                const std::vector<ScalarPtr> &conditional_result_expressions,
+                                const ScalarPtr &else_result_expression,
+                                const Type &value_type) {
+    return SearchedCasePtr(new SearchedCase(condition_predicates,
+                                            conditional_result_expressions,
+                                            else_result_expression,
+                                            value_type));
+  }
+
+ protected:
+  void getFieldStringItems(std::vector<std::string> *inline_field_names,
+                           std::vector<std::string> *inline_field_values,
+                           std::vector<std::string> *non_container_child_field_names,
+                           std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+                           std::vector<std::string> *container_child_field_names,
+                           std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  SearchedCase(const std::vector<PredicatePtr> &condition_predicates,
+               const std::vector<ScalarPtr> &conditional_result_expressions,
+               const ScalarPtr &else_result_expression,
+               const Type &value_type)
+      : condition_predicates_(condition_predicates),
+        conditional_result_expressions_(conditional_result_expressions),
+        else_result_expression_(else_result_expression),
+        value_type_(value_type) {
+    for (const PredicatePtr &condition_predicate : condition_predicates_) {
+      addChild(condition_predicate);
+    }
+    for (const ScalarPtr &conditional_result_expression : conditional_result_expressions_) {
+      addChild(conditional_result_expression);
+    }
+    if (else_result_expression_ != nullptr) {
+      addChild(else_result_expression_);
+    }
+  }
+
+  std::vector<PredicatePtr> condition_predicates_;
+  std::vector<ScalarPtr> conditional_result_expressions_;
+
+  // May be NULL.
+  ScalarPtr else_result_expression_;
+
+  const Type &value_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(SearchedCase);
+};
+
+/** @} */
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
+
+#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SEARCHED_CASE_HPP_ */
diff --git a/query_optimizer/expressions/SimpleCase.cpp b/query_optimizer/expressions/SimpleCase.cpp
new file mode 100644
index 0000000..8c6227f
--- /dev/null
+++ b/query_optimizer/expressions/SimpleCase.cpp
@@ -0,0 +1,186 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "query_optimizer/expressions/SimpleCase.hpp"
+
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "expressions/predicate/Predicate.hpp"
+#include "expressions/scalar/ScalarCaseExpression.hpp"
+#include "expressions/scalar/ScalarLiteral.hpp"
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ComparisonExpression.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "types/Type.hpp"
+#include "types/operations/comparisons/ComparisonID.hpp"
+#include "types/operations/comparisons/ComparisonFactory.hpp"
+#include "utility/Cast.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace expressions {
+
+// We treat a SimpleCase as constant only if all operands are constant.
+bool SimpleCase::isConstant() const {
+  if (!case_operand_->isConstant()) {
+    return false;
+  }
+  for (const ScalarPtr &condition_operand : condition_operands_) {
+    if (!condition_operand->isConstant()) {
+      return false;
+    }
+  }
+  for (const ScalarPtr &conditional_result_expression : conditional_result_expressions_) {
+    if (!conditional_result_expression->isConstant()) {
+      return false;
+    }
+  }
+  return (else_result_expression_ == nullptr || else_result_expression_->isConstant());
+}
+
+std::vector<AttributeReferencePtr> SimpleCase::getReferencedAttributes() const {
+  std::vector<AttributeReferencePtr> referenced_attributes;
+
+  const std::vector<AttributeReferencePtr> referenced_attributes_in_case_operand =
+      case_operand_->getReferencedAttributes();
+  referenced_attributes.insert(referenced_attributes.end(),
+                               referenced_attributes_in_case_operand.begin(),
+                               referenced_attributes_in_case_operand.end());
+
+  for (const ScalarPtr &condition_operand : condition_operands_) {
+    const std::vector<AttributeReferencePtr> referenced_attributes_in_condition_operand =
+        condition_operand->getReferencedAttributes();
+    referenced_attributes.insert(referenced_attributes.end(),
+                                 referenced_attributes_in_condition_operand.begin(),
+                                 referenced_attributes_in_condition_operand.end());
+  }
+  for (const ScalarPtr &conditional_result_expression : conditional_result_expressions_) {
+    const std::vector<AttributeReferencePtr> referenced_attributes_in_conditional_result_expression =
+        conditional_result_expression->getReferencedAttributes();
+    referenced_attributes.insert(referenced_attributes.end(),
+                                 referenced_attributes_in_conditional_result_expression.begin(),
+                                 referenced_attributes_in_conditional_result_expression.end());
+  }
+  if (else_result_expression_ != nullptr) {
+    const std::vector<AttributeReferencePtr> referenced_attributes_in_else_result_expression =
+        else_result_expression_->getReferencedAttributes();
+    referenced_attributes.insert(referenced_attributes.end(),
+                                 referenced_attributes_in_else_result_expression.begin(),
+                                 referenced_attributes_in_else_result_expression.end());
+  }
+
+  return referenced_attributes;
+}
+
+ExpressionPtr SimpleCase::copyWithNewChildren(const std::vector<ExpressionPtr> &new_children) const {
+  DCHECK_EQ(getNumChildren(), new_children.size());
+
+  ScalarPtr new_case_operand;
+  std::vector<ScalarPtr> new_condition_operands;
+  std::vector<ScalarPtr> new_conditional_result_expressions;
+  ScalarPtr new_else_result_expression;
+
+  new_condition_operands.reserve(condition_operands_.size());
+  new_conditional_result_expressions.reserve(condition_operands_.size());
+
+  new_case_operand = std::static_pointer_cast<const Scalar>(new_children[0]);
+  std::size_t num_when_clauses = condition_operands_.size();
+  for (std::size_t index = 1; index <= num_when_clauses; ++index) {
+    new_condition_operands.push_back(
+        std::static_pointer_cast<const Scalar>(new_children[index]));
+
+    new_conditional_result_expressions.push_back(
+        std::static_pointer_cast<const Scalar>(new_children[index + num_when_clauses]));
+  }
+  if (else_result_expression_ != nullptr) {
+    new_else_result_expression =
+        std::static_pointer_cast<const Scalar>(new_children.back());
+  }
+
+  return Create(new_case_operand,
+                new_condition_operands,
+                new_conditional_result_expressions,
+                new_else_result_expression,
+                value_type_);
+}
+
+::quickstep::Scalar* SimpleCase::concretize(
+    const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
+  std::vector<std::unique_ptr<quickstep::Predicate>> when_predicates;
+  for (const ScalarPtr &condition_operand : condition_operands_) {
+    const PredicatePtr predicate =
+        ComparisonExpression::Create(
+            quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kEqual),
+            case_operand_,
+            condition_operand);
+    when_predicates.emplace_back(predicate->concretize(substitution_map));
+  }
+
+  std::vector<std::unique_ptr<quickstep::Scalar>> result_expressions;
+  for (const ScalarPtr &expression : conditional_result_expressions_) {
+    result_expressions.emplace_back(expression->concretize(substitution_map));
+  }
+
+  std::unique_ptr<quickstep::Scalar> else_result_expression;
+  if (else_result_expression_ == nullptr) {
+    else_result_expression.reset(
+        new quickstep::ScalarLiteral(value_type_.makeNullValue(), value_type_));
+  } else {
+    else_result_expression.reset(
+        else_result_expression_->concretize(substitution_map));
+  }
+
+  return new quickstep::ScalarCaseExpression(
+      value_type_,
+      std::move(when_predicates),
+      std::move(result_expressions),
+      else_result_expression.release());
+}
+
+void SimpleCase::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  non_container_child_field_names->push_back("case_operand");
+  non_container_child_fields->push_back(case_operand_);
+
+  container_child_field_names->push_back("condition_operands");
+  container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(condition_operands_));
+
+  container_child_field_names->push_back("result_expressions");
+  container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(conditional_result_expressions_));
+
+  if (else_result_expression_ != nullptr) {
+    non_container_child_field_names->push_back("else_result_expression");
+    non_container_child_fields->push_back(else_result_expression_);
+  }
+}
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
diff --git a/query_optimizer/expressions/SimpleCase.hpp b/query_optimizer/expressions/SimpleCase.hpp
new file mode 100644
index 0000000..a037a0e
--- /dev/null
+++ b/query_optimizer/expressions/SimpleCase.hpp
@@ -0,0 +1,185 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SIMPLE_CASE_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SIMPLE_CASE_HPP_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "expressions/scalar/Scalar.hpp"
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ExprId.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/ExpressionType.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class CatalogAttribute;
+class Type;
+
+namespace optimizer {
+namespace expressions {
+
+/** \addtogroup OptimizerExpressions
+ *  @{
+ */
+
+class SimpleCase;
+typedef std::shared_ptr<const SimpleCase> SimpleCasePtr;
+
+/**
+ * @brief A simple CASE expression. It searches the first expression in
+ *        <condition_operands_> with a value equal to <case_operand_>, and
+ *        returns the value of the expression in <conditional_result_expressions_>
+ *        at the same position; if none of <condition_operands_> meet the
+ *        condition, returns the value of <else_result_expression_> when
+ *        <else_result_expression_> is not NULL, otherwise returns NULL.
+ */
+class SimpleCase : public Scalar {
+ public:
+  ExpressionType getExpressionType() const override {
+    return ExpressionType::kSimpleCase;
+  }
+
+  std::string getName() const override {
+    return "SimpleCase";
+  }
+
+  const Type& getValueType() const override {
+    return value_type_;
+  }
+
+  /**
+   * @return The CASE operand.
+   */
+  const ScalarPtr& case_operand() const {
+    return case_operand_;
+  }
+
+  /**
+   * @return The vector of condition operands.
+   */
+  const std::vector<ScalarPtr>& condition_operands() const {
+    return condition_operands_;
+  }
+
+  /**
+   * @return The vector of conditional result expressions, one for each
+   *         condition operand.
+   */
+  const std::vector<ScalarPtr>& conditional_result_expressions() const {
+    return conditional_result_expressions_;
+  }
+
+  /**
+   * @return The ELSE result expression.
+   */
+  const ScalarPtr& else_result_expression() const {
+    return else_result_expression_;
+  }
+
+  bool isConstant() const override;
+
+  std::vector<AttributeReferencePtr> getReferencedAttributes() const override;
+
+  ExpressionPtr copyWithNewChildren(
+      const std::vector<ExpressionPtr> &new_children) const override;
+
+  ::quickstep::Scalar* concretize(
+      const std::unordered_map<ExprId, const CatalogAttribute*>& substitution_map) const override;
+
+  /**
+   * @brief Creates an immutable SimpleCase.
+   *
+   * @param case_operand The CASE operand.
+   * @param condition_operands A vector of expressions to be compared with
+   *        the \p case_operand.
+   * @param conditional_result_expressions A vector of result expressions, one
+   *        per expression of \p condition_operands.
+   * @param else_result_expression The optional ELSE expression.
+   * @param value_type The data type of this expression which should be the
+   *        unified type of all result expressions.
+   * @return An immutable SimpleCase.
+   */
+  static SimpleCasePtr Create(const ScalarPtr &case_operand,
+                              const std::vector<ScalarPtr> &condition_operands,
+                              const std::vector<ScalarPtr> &conditional_result_expressions,
+                              const ScalarPtr &else_result_expression,
+                              const Type &value_type) {
+    return SimpleCasePtr(new SimpleCase(case_operand,
+                                        condition_operands,
+                                        conditional_result_expressions,
+                                        else_result_expression,
+                                        value_type));
+  }
+
+ protected:
+  void getFieldStringItems(std::vector<std::string> *inline_field_names,
+                           std::vector<std::string> *inline_field_values,
+                           std::vector<std::string> *non_container_child_field_names,
+                           std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+                           std::vector<std::string> *container_child_field_names,
+                           std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  SimpleCase(const ScalarPtr &case_operand,
+             const std::vector<ScalarPtr> &condition_operands,
+             const std::vector<ScalarPtr> &conditional_result_expressions,
+             const ScalarPtr &else_result_expression,
+             const Type &value_type)
+      : case_operand_(case_operand),
+        condition_operands_(condition_operands),
+        conditional_result_expressions_(conditional_result_expressions),
+        else_result_expression_(else_result_expression),
+        value_type_(value_type) {
+    addChild(case_operand_);
+    for (const ScalarPtr &condition_operand : condition_operands_) {
+      addChild(condition_operand);
+    }
+    for (const ScalarPtr &conditional_result_expression : conditional_result_expressions_) {
+      addChild(conditional_result_expression);
+    }
+    if (else_result_expression_ != nullptr) {
+      addChild(else_result_expression);
+    }
+  }
+
+  ScalarPtr case_operand_;
+  std::vector<ScalarPtr> condition_operands_;
+  std::vector<ScalarPtr> conditional_result_expressions_;
+
+  // May be NULL.
+  ScalarPtr else_result_expression_;
+
+  const Type &value_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(SimpleCase);
+};
+
+/** @} */
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
+
+#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SIMPLE_CASE_HPP_ */
diff --git a/query_optimizer/expressions/SubqueryExpression.cpp b/query_optimizer/expressions/SubqueryExpression.cpp
new file mode 100644
index 0000000..f1a97ca
--- /dev/null
+++ b/query_optimizer/expressions/SubqueryExpression.cpp
@@ -0,0 +1,58 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#include "query_optimizer/expressions/SubqueryExpression.hpp"
+
+#include <string>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace expressions {
+
+::quickstep::Scalar* SubqueryExpression::concretize(
+    const std::unordered_map<ExprId, const CatalogAttribute*>& substitution_map) const {
+  LOG(FATAL) << "SubqueryExpression should not be concretized";
+  return nullptr;
+}
+
+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";
+  return {};
+}
+
+void SubqueryExpression::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  non_container_child_field_names->push_back("subquery");
+  non_container_child_fields->push_back(subquery_);
+}
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
diff --git a/query_optimizer/expressions/SubqueryExpression.hpp b/query_optimizer/expressions/SubqueryExpression.hpp
new file mode 100644
index 0000000..e0e2733
--- /dev/null
+++ b/query_optimizer/expressions/SubqueryExpression.hpp
@@ -0,0 +1,126 @@
+/**
+ *   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.
+ *   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.
+ **/
+
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SUBQUERY_EXPRESSION_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SUBQUERY_EXPRESSION_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/ExpressionType.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "query_optimizer/logical/Logical.hpp"
+#include "query_optimizer/OptimizerTree.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class Type;
+
+namespace optimizer {
+namespace expressions {
+
+/** \addtogroup OptimizerExpressions
+ *  @{
+ */
+
+class SubqueryExpression;
+typedef std::shared_ptr<const SubqueryExpression> SubqueryExpressionPtr;
+
+/**
+ * @brief A subquery used in an expression.
+ */
+class SubqueryExpression : public Scalar {
+ public:
+  ExpressionType getExpressionType() const override {
+    return ExpressionType::kSubqueryExpression;
+  }
+
+  std::string getName() const override { return "SubqueryExpression"; }
+
+  const Type& getValueType() const override {
+    return output_attribute_->getValueType();
+  }
+
+  bool isConstant() const override {
+    return output_attribute_->isConstant();
+  }
+
+  /**
+   * @return The referenced logical subquery node.
+   */
+  const logical::LogicalPtr& subquery() const {
+    return subquery_;
+  }
+
+  std::vector<AttributeReferencePtr> getReferencedAttributes() const override;
+
+  ExpressionPtr copyWithNewChildren(
+      const std::vector<ExpressionPtr> &new_children) const override {
+    DCHECK(new_children.empty());
+    return Create(subquery_);
+  }
+
+  ::quickstep::Scalar* concretize(
+      const std::unordered_map<ExprId, const CatalogAttribute*>& substitution_map) const override;
+
+  /**
+   * @brief Creates a subquery expression.
+   * @note This expression can only be used in a logical plan.
+   *
+   * @param subquery The logical subquery node.
+   * @return An immutable SubqueryExpression.
+   */
+  static SubqueryExpressionPtr Create(const logical::LogicalPtr& subquery) {
+    return SubqueryExpressionPtr(new SubqueryExpression(subquery));
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  explicit SubqueryExpression(const logical::LogicalPtr& subquery)
+      : subquery_(subquery),
+        output_attribute_(subquery->getOutputAttributes()[0]) {
+    DCHECK(!subquery->getOutputAttributes().empty());
+  }
+
+  logical::LogicalPtr subquery_;
+  // Set to the first output attribute if the subquery is a multi-column table query.
+  const AttributeReferencePtr output_attribute_;
+
+  DISALLOW_COPY_AND_ASSIGN(SubqueryExpression);
+};
+
+/** @} */
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
+
+#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_SUBQUERY_EXPRESSION_HPP_ */
diff --git a/query_optimizer/logical/TableGenerator.hpp b/query_optimizer/logical/TableGenerator.hpp
index d57872e..ea8826a 100644
--- a/query_optimizer/logical/TableGenerator.hpp
+++ b/query_optimizer/logical/TableGenerator.hpp
@@ -1,6 +1,6 @@
 /**
  *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
- *   University of Wisconsin—Madison.
+ *     University of Wisconsin—Madison.
  *   Copyright 2016 Pivotal Software, Inc.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -153,7 +153,8 @@
             generator_function_handle->getOutputColumnName(i),
             table_alias,
             table_name,
-            generator_function_handle->getOutputColumnType(i)));
+            generator_function_handle->getOutputColumnType(i),
+            E::AttributeReferenceScope::kLocal));
     }
   }
 
diff --git a/query_optimizer/logical/TableReference.cpp b/query_optimizer/logical/TableReference.cpp
index b4d80ee..8f0362a 100644
--- a/query_optimizer/logical/TableReference.cpp
+++ b/query_optimizer/logical/TableReference.cpp
@@ -48,7 +48,8 @@
             attribute_it->getName(),
             attribute_it->getDisplayName(),
             relation_alias,
-            attribute_it->getType()));
+            attribute_it->getType(),
+            E::AttributeReferenceScope::kLocal));
   }
 }
 
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index 22cf397..72f5bd7 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -39,6 +39,7 @@
                       quickstep_parser_ParseAssignment
                       quickstep_parser_ParseBasicExpressions
                       quickstep_parser_ParseBlockProperties
+                      quickstep_parser_ParseCaseExpressions
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseGeneratorTableReference
                       quickstep_parser_ParseGroupBy
@@ -47,6 +48,7 @@
                       quickstep_parser_ParseLiteralValue
                       quickstep_parser_ParseOrderBy
                       quickstep_parser_ParsePredicate
+                      quickstep_parser_ParsePredicateExists
                       quickstep_parser_ParseSelect
                       quickstep_parser_ParseSelectionClause
                       quickstep_parser_ParseSimpleTableReference
@@ -63,6 +65,7 @@
                       quickstep_queryoptimizer_expressions_BinaryExpression
                       quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_ComparisonExpression
+                      quickstep_queryoptimizer_expressions_Exists
                       quickstep_queryoptimizer_expressions_ExprId
                       quickstep_queryoptimizer_expressions_ExpressionUtil
                       quickstep_queryoptimizer_expressions_LogicalAnd
@@ -74,6 +77,9 @@
                       quickstep_queryoptimizer_expressions_PredicateLiteral
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_queryoptimizer_expressions_SearchedCase
+                      quickstep_queryoptimizer_expressions_SimpleCase
+                      quickstep_queryoptimizer_expressions_SubqueryExpression
                       quickstep_queryoptimizer_expressions_UnaryExpression
                       quickstep_queryoptimizer_logical_Aggregate
                       quickstep_queryoptimizer_logical_CopyFrom
diff --git a/query_optimizer/resolver/NameResolver.cpp b/query_optimizer/resolver/NameResolver.cpp
index 0db12fc..35745f3 100644
--- a/query_optimizer/resolver/NameResolver.cpp
+++ b/query_optimizer/resolver/NameResolver.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.
@@ -58,7 +60,7 @@
     const ParseString *parse_rel_name,
     const L::LogicalPtr &logical) {
   DCHECK(parse_rel_name != nullptr);
-  relations_.emplace_back(new RelationInfo(logical));
+  relations_.emplace_back(new RelationInfo(*parse_rel_name, logical));
   const std::string lower_rel_name = ToLower(parse_rel_name->value());
   if (rel_name_to_rel_info_map_.find(lower_rel_name) !=
       rel_name_to_rel_info_map_.end()) {
@@ -72,6 +74,7 @@
     const ParseString *parse_attr_node,
     const ParseString *parse_rel_node) const {
   E::AttributeReferencePtr attribute;
+  // Look up the attribute from local scope.
   if (parse_rel_node == nullptr) {
     // If the relation name is not given, search all visible relations.
     for (const std::unique_ptr<RelationInfo> &item : relations_) {
@@ -91,15 +94,30 @@
         rel_name_to_rel_info_map_.find(ToLower(parse_rel_node->value()));
     if (found_it != rel_name_to_rel_info_map_.end()) {
       attribute = found_it->second->findAttributeByName(parse_attr_node);
-    } else {
-      THROW_SQL_ERROR_AT(parse_rel_node) << "Unrecognized relation "
-                                         << parse_rel_node->value();
     }
   }
+
+  // If cannot find the attribute in local scope, look into parent scopes.
+  if (attribute == nullptr) {
+    if (parent_resolver_ != nullptr) {
+      const E::AttributeReferencePtr outer_attribute =
+          parent_resolver_->lookup(parse_attr_node, parse_rel_node);
+      if (outer_attribute != nullptr) {
+        attribute = E::AttributeReference::Create(outer_attribute->id(),
+                                                  outer_attribute->attribute_name(),
+                                                  outer_attribute->attribute_alias(),
+                                                  outer_attribute->relation_name(),
+                                                  outer_attribute->getValueType(),
+                                                  E::AttributeReferenceScope::kOuter);
+      }
+    }
+  }
+
   if (attribute == nullptr) {
     THROW_SQL_ERROR_AT(parse_attr_node) << "Unrecognized attribute "
                                         << parse_attr_node->value();
   }
+
   return attribute;
 }
 
diff --git a/query_optimizer/resolver/NameResolver.hpp b/query_optimizer/resolver/NameResolver.hpp
index 733ffb8..4809fe8 100644
--- a/query_optimizer/resolver/NameResolver.hpp
+++ b/query_optimizer/resolver/NameResolver.hpp
@@ -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.
@@ -47,8 +49,12 @@
  public:
   /**
    * @brief Constructor.
+   *
+   * @param parent_resolver The NameResolver inherited from the outer query.
+   *                        NULL if there is no outer query.
    */
-  NameResolver() {}
+  explicit NameResolver(const NameResolver *parent_resolver = nullptr)
+      : parent_resolver_(parent_resolver) {}
 
   /**
    * @brief Adds the attributes of the relation produced by \p logical
@@ -108,8 +114,10 @@
    * @brief Info of a relation and its visible attributes in the name scope.
    */
   struct RelationInfo {
-    explicit RelationInfo(const logical::LogicalPtr &logical_in)
-        : logical(logical_in),
+    explicit RelationInfo(const ParseString &parse_relation_name_in,
+                          const logical::LogicalPtr &logical_in)
+        : parse_relation_name(parse_relation_name_in),
+          logical(logical_in),
           attributes(logical->getOutputAttributes()) {
       int current_attribute_index = 0;
       for (const expressions::AttributeReferencePtr &attribute : attributes) {
@@ -133,6 +141,7 @@
     // relation. Returns NULL if no attribute with the given name is found.
     expressions::AttributeReferencePtr findAttributeByName(const ParseString *parse_attr_node) const;
 
+    const ParseString &parse_relation_name;
     logical::LogicalPtr logical;
 
     std::vector<expressions::AttributeReferencePtr> attributes;
@@ -142,6 +151,8 @@
     std::map<std::string, int> name_to_attribute_index_map;
   };
 
+  const NameResolver *parent_resolver_;
+
   /**
    * @brief Relation info in the name scope.
    */
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 7fb5a90..f44aae8 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -37,6 +37,7 @@
 #include "parser/ParseAssignment.hpp"
 #include "parser/ParseBasicExpressions.hpp"
 #include "parser/ParseBlockProperties.hpp"
+#include "parser/ParseCaseExpressions.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseGeneratorTableReference.hpp"
 #include "parser/ParseGroupBy.hpp"
@@ -45,6 +46,7 @@
 #include "parser/ParseLiteralValue.hpp"
 #include "parser/ParseOrderBy.hpp"
 #include "parser/ParsePredicate.hpp"
+#include "parser/ParsePredicateExists.hpp"
 #include "parser/ParseSelect.hpp"
 #include "parser/ParseSelectionClause.hpp"
 #include "parser/ParseSimpleTableReference.hpp"
@@ -61,6 +63,7 @@
 #include "query_optimizer/expressions/BinaryExpression.hpp"
 #include "query_optimizer/expressions/Cast.hpp"
 #include "query_optimizer/expressions/ComparisonExpression.hpp"
+#include "query_optimizer/expressions/Exists.hpp"
 #include "query_optimizer/expressions/ExprId.hpp"
 #include "query_optimizer/expressions/ExpressionUtil.hpp"
 #include "query_optimizer/expressions/LogicalAnd.hpp"
@@ -72,6 +75,9 @@
 #include "query_optimizer/expressions/PredicateLiteral.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
 #include "query_optimizer/expressions/ScalarLiteral.hpp"
+#include "query_optimizer/expressions/SearchedCase.hpp"
+#include "query_optimizer/expressions/SimpleCase.hpp"
+#include "query_optimizer/expressions/SubqueryExpression.hpp"
 #include "query_optimizer/expressions/UnaryExpression.hpp"
 #include "query_optimizer/logical/Aggregate.hpp"
 #include "query_optimizer/logical/CopyFrom.hpp"
@@ -319,7 +325,8 @@
       logical_plan_ =
           resolveSelect(*select_statement.select_query(),
                         "" /* select_name */,
-                        nullptr /* No Type hints */);
+                        nullptr /* No Type hints */,
+                        nullptr /* parent_resolver */);
       if (select_statement.with_clause() != nullptr) {
         // Report an error if there is a WITH query that is not actually used.
         if (!with_queries_info_.unreferenced_query_indexes.empty()) {
@@ -413,7 +420,8 @@
                                       attribute_definition.name()->value(),
                                       attribute_definition.name()->value(),
                                       relation_name,
-                                      attribute_definition.data_type().getType()));
+                                      attribute_definition.data_type().getType(),
+                                      E::AttributeReferenceScope::kLocal));
     attribute_name_set.insert(lower_attribute_name);
   }
 
@@ -720,7 +728,10 @@
 
   // Resolve the selection query.
   const L::LogicalPtr selection_logical =
-      resolveSelect(*insert_statement.select_query(), "", &type_hints);
+      resolveSelect(*insert_statement.select_query(),
+                    "" /* select_name */,
+                    &type_hints,
+                    nullptr /* parent_resolver */);
   const std::vector<E::AttributeReferencePtr> selection_attributes =
       selection_logical->getOutputAttributes();
 
@@ -926,9 +937,9 @@
 L::LogicalPtr Resolver::resolveSelect(
     const ParseSelect &select_query,
     const std::string &select_name,
-    const std::vector<const Type*> *type_hints) {
-  // Create a new name scope. We currently do not support correlated query.
-  std::unique_ptr<NameResolver> name_resolver(new NameResolver());
+    const std::vector<const Type*> *type_hints,
+    const NameResolver *parent_resolver) {
+  std::unique_ptr<NameResolver> name_resolver(new NameResolver(parent_resolver));
 
   // Resolve FROM clause.
   L::LogicalPtr logical_plan;
@@ -1174,6 +1185,23 @@
   return logical_plan;
 }
 
+E::SubqueryExpressionPtr Resolver::resolveSubqueryExpression(
+    const ParseSubqueryExpression &parse_subquery_expression,
+    const std::vector<const Type*> *type_hints,
+    ExpressionResolutionInfo *expression_resolution_info) {
+  L::LogicalPtr logical_subquery =
+      resolveSelect(*parse_subquery_expression.query(),
+                    "" /* select_name */,
+                    type_hints,
+                    &expression_resolution_info->name_resolver);
+
+  if (!context_->has_nested_queries()) {
+    context_->set_has_nested_queries();
+  }
+
+  return E::SubqueryExpression::Create(logical_subquery);
+}
+
 void Resolver::appendProjectIfNeedPrecomputationBeforeAggregation(
     const SelectListInfo &select_list_info,
     std::vector<E::NamedExpressionPtr> *select_list_expressions,
@@ -1416,7 +1444,8 @@
       logical_plan = resolveSelect(
           *static_cast<const ParseSubqueryTableReference&>(table_reference).subquery_expr()->query(),
           reference_alias->value(),
-          nullptr /* No Type hints */);
+          nullptr /* No Type hints */,
+          nullptr /* parent_resolver */);
 
       if (reference_signature->column_aliases() != nullptr) {
         logical_plan = RenameOutputColumns(logical_plan, *reference_signature);
@@ -1818,6 +1847,22 @@
           ->concretize(type_hint, &concrete_type);
       return E::ScalarLiteral::Create(std::move(concrete), *concrete_type);
     }
+    case ParseExpression::kSearchedCaseExpression: {
+      const ParseSearchedCaseExpression &parse_searched_case_expression =
+          static_cast<const ParseSearchedCaseExpression&>(parse_expression);
+      return resolveSearchedCaseExpression(
+          parse_searched_case_expression,
+          type_hint,
+          expression_resolution_info);
+    }
+    case ParseExpression::kSimpleCaseExpression: {
+      const ParseSimpleCaseExpression &parse_simple_case_expression =
+          static_cast<const ParseSimpleCaseExpression&>(parse_expression);
+      return resolveSimpleCaseExpression(
+          parse_simple_case_expression,
+          type_hint,
+          expression_resolution_info);
+    }
     case ParseExpression::kUnaryExpression: {
       const ParseUnaryExpression &parse_unary_expr =
           static_cast<const ParseUnaryExpression&>(parse_expression);
@@ -1922,6 +1967,259 @@
   }
 }
 
+E::ScalarPtr Resolver::resolveSearchedCaseExpression(
+    const ParseSearchedCaseExpression &parse_searched_case_expression,
+    const Type *type_hint,
+    ExpressionResolutionInfo *expression_resolution_info) {
+  // Resolve the condition and result expression pairs.
+  std::vector<E::PredicatePtr> condition_predicates;
+  std::vector<E::ScalarPtr> conditional_result_expressions;
+  const Type *result_data_type = nullptr;
+
+  for (const ParseSearchedWhenClause &when_clause : *parse_searched_case_expression.when_clauses()) {
+    ExpressionResolutionInfo condition_predicate_resolution_info(*expression_resolution_info);
+    condition_predicates.emplace_back(
+        resolvePredicate(*when_clause.condition_predicate(),
+                         &condition_predicate_resolution_info));
+
+    ExpressionResolutionInfo result_expression_resolution_info(*expression_resolution_info);
+    const E::ScalarPtr result_expression =
+        resolveExpression(*when_clause.result_expression(),
+                          type_hint,
+                          &result_expression_resolution_info);
+
+    // Check that the type of this result expression can be cast to or cast from
+    // the unified type of the previous expression.
+    if (result_data_type == nullptr) {
+      result_data_type = &result_expression->getValueType();
+    } else if (!result_expression->getValueType().equals(*result_data_type)) {
+      const Type *temp_result_data_type =
+          TypeFactory::GetUnifyingType(*result_data_type,
+                                       result_expression->getValueType());
+
+      if (temp_result_data_type == nullptr) {
+        THROW_SQL_ERROR_AT(when_clause.result_expression())
+            << "The result expression in the WHEN clause has an incompatible "
+            << "type with preceding result expressions ("
+            << result_expression->getValueType().getName()
+            << " vs. " << result_data_type->getName() << ")";
+      }
+      result_data_type = temp_result_data_type;
+    }
+    conditional_result_expressions.emplace_back(result_expression);
+
+    // Propagate the aggregation info.
+    if (!expression_resolution_info->hasAggregate()) {
+      if (condition_predicate_resolution_info.hasAggregate()) {
+        expression_resolution_info->parse_aggregate_expression =
+            condition_predicate_resolution_info.parse_aggregate_expression;
+      } else if (result_expression_resolution_info.hasAggregate()) {
+        expression_resolution_info->parse_aggregate_expression =
+            result_expression_resolution_info.parse_aggregate_expression;
+      }
+    }
+  }
+
+  // Resolve the ELSE result expression.
+  E::ScalarPtr else_result_expression;
+  if (parse_searched_case_expression.else_result_expression() != nullptr) {
+    ExpressionResolutionInfo else_expression_resolution_info(*expression_resolution_info);
+    else_result_expression =
+        resolveExpression(*parse_searched_case_expression.else_result_expression(),
+                          result_data_type,
+                          &else_expression_resolution_info);
+
+    if (!else_result_expression->getValueType().equals(*result_data_type)) {
+      const Type *temp_result_data_type =
+          TypeFactory::GetUnifyingType(*result_data_type,
+                                       else_result_expression->getValueType());
+      if (temp_result_data_type == nullptr) {
+        THROW_SQL_ERROR_AT(parse_searched_case_expression.else_result_expression())
+            << "The result expression in the ELSE clause has an incompatible "
+               "type with result expressions in the WHEN clauses ("
+            << else_result_expression->getValueType().getName()
+            << " vs. " << result_data_type->getName() << ")";
+      }
+      result_data_type = temp_result_data_type;
+    }
+
+    // Propagate the aggregation info.
+    if (!expression_resolution_info->hasAggregate()
+        && else_expression_resolution_info.hasAggregate()) {
+      expression_resolution_info->parse_aggregate_expression =
+          else_expression_resolution_info.parse_aggregate_expression;
+    }
+  }
+
+  // Cast all the result expressions to the same type.
+  for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
+    if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
+      conditional_result_expression =
+          E::Cast::Create(conditional_result_expression, *result_data_type);
+    }
+  }
+  if (else_result_expression != nullptr
+      && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
+    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
+  }
+
+  if (else_result_expression == nullptr) {
+    // If there is no ELSE clause, the data type must be nullable.
+    // Note that the unifying result expression type may be non-nullable.
+    result_data_type = &result_data_type->getNullableVersion();
+  }
+
+  return E::SearchedCase::Create(condition_predicates,
+                                 conditional_result_expressions,
+                                 else_result_expression,
+                                 *result_data_type);
+}
+
+E::ScalarPtr Resolver::resolveSimpleCaseExpression(
+    const ParseSimpleCaseExpression &parse_simple_case_expression,
+    const Type *type_hint,
+    ExpressionResolutionInfo *expression_resolution_info) {
+  // Resolve the CASE operand.
+  ExpressionResolutionInfo case_expression_resolution_info(*expression_resolution_info);
+  E::ScalarPtr case_operand =
+      resolveExpression(
+          *parse_simple_case_expression.case_operand(),
+          nullptr /* type_hint */,
+          &case_expression_resolution_info);
+
+  // Propagate the aggregation info.
+  expression_resolution_info->parse_aggregate_expression =
+      case_expression_resolution_info.parse_aggregate_expression;
+
+  // Resolve the condition and result expression pairs.
+  std::vector<E::ScalarPtr> condition_operands;
+  std::vector<E::ScalarPtr> conditional_result_expressions;
+  const Type *result_data_type = nullptr;
+  const Type *condition_operand_data_type = &case_operand->getValueType();
+
+  for (const ParseSimpleWhenClause &when_clause : *parse_simple_case_expression.when_clauses()) {
+    ExpressionResolutionInfo condition_operand_resolution_info(*expression_resolution_info);
+    const E::ScalarPtr condition_operand =
+        resolveExpression(*when_clause.condition_operand(),
+                          condition_operand_data_type,
+                          &condition_operand_resolution_info);
+    if (!condition_operand->getValueType().equals(*condition_operand_data_type)) {
+      const Type *temp_condition_operand_data_type =
+          TypeFactory::GetUnifyingType(*condition_operand_data_type,
+                                       condition_operand->getValueType());
+      if (temp_condition_operand_data_type == nullptr) {
+        THROW_SQL_ERROR_AT(when_clause.condition_operand())
+            << "The comparison expression in the WHEN clause has an incompatible "
+            << "type with preceding comparison expressions"
+            << condition_operand->getValueType().getName()
+            << " vs. " << condition_operand_data_type->getName() << ")";
+      }
+      condition_operand_data_type = temp_condition_operand_data_type;
+    }
+    condition_operands.emplace_back(condition_operand);
+
+    ExpressionResolutionInfo result_expression_resolution_info(*expression_resolution_info);
+    const E::ScalarPtr result_expression =
+        resolveExpression(*when_clause.result_expression(),
+                          type_hint,
+                          &result_expression_resolution_info);
+
+    // Check that the type of this result expression can be cast to or cast from
+    // the unified type of the previous expression.
+    if (result_data_type == nullptr) {
+      result_data_type = &result_expression->getValueType();
+    } else if (!result_expression->getValueType().equals(*result_data_type)) {
+      const Type *temp_result_data_type =
+          TypeFactory::GetUnifyingType(*result_data_type,
+                                       result_expression->getValueType());
+      if (temp_result_data_type == nullptr) {
+        THROW_SQL_ERROR_AT(when_clause.result_expression())
+            << "The result expression in the WHEN clause has an incompatible "
+            << "type with preceding result expressions ("
+            << result_expression->getValueType().getName()
+            << " vs. " << result_data_type->getName() << ")";
+      }
+      result_data_type = temp_result_data_type;
+    }
+    conditional_result_expressions.emplace_back(result_expression);
+
+    // Propagate the aggregation info.
+    if (!expression_resolution_info->hasAggregate()) {
+      if (condition_operand_resolution_info.hasAggregate()) {
+        expression_resolution_info->parse_aggregate_expression =
+            condition_operand_resolution_info.parse_aggregate_expression;
+      } else if (result_expression_resolution_info.hasAggregate()) {
+        expression_resolution_info->parse_aggregate_expression =
+            result_expression_resolution_info.parse_aggregate_expression;
+      }
+    }
+  }
+
+  // Resolve the ELSE result expression.
+  E::ScalarPtr else_result_expression;
+  if (parse_simple_case_expression.else_result_expression() != nullptr) {
+    ExpressionResolutionInfo else_expression_resolution_info(*expression_resolution_info);
+    else_result_expression =
+        resolveExpression(*parse_simple_case_expression.else_result_expression(),
+                          result_data_type,
+                          &else_expression_resolution_info);
+    if (!else_result_expression->getValueType().equals(*result_data_type)) {
+      const Type *temp_result_data_type =
+          TypeFactory::GetUnifyingType(*result_data_type,
+                                       else_result_expression->getValueType());
+      if (temp_result_data_type == nullptr) {
+        THROW_SQL_ERROR_AT(parse_simple_case_expression.else_result_expression())
+            << "The result expression in the ELSE clause has an incompatible type "
+               "with result expressions in the WHEN clauses ("
+            << else_result_expression->getValueType().getName()
+            << " vs. " << result_data_type->getName() << ")";
+      }
+      result_data_type = temp_result_data_type;
+    }
+
+    // Propagate the aggregation info.
+    if (!expression_resolution_info->hasAggregate() &&
+        else_expression_resolution_info.hasAggregate()) {
+      expression_resolution_info->parse_aggregate_expression =
+          else_expression_resolution_info.parse_aggregate_expression;
+    }
+  }
+
+  const Comparison &equal_comp = ComparisonFactory::GetComparison(ComparisonID::kEqual);
+  if (!equal_comp.canCompareTypes(case_operand->getValueType(),
+                                  *condition_operand_data_type)) {
+    THROW_SQL_ERROR_AT(parse_simple_case_expression.case_operand())
+        << "The CASE operand type cannot be compared with the type of "
+        << "comparison expressions ("
+        << case_operand->getValueType().getName()
+        << " vs. " << condition_operand_data_type->getName() << ")";
+  }
+
+  // Cast all the result expressions to the same type.
+  for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
+    if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
+      conditional_result_expression =
+          E::Cast::Create(conditional_result_expression, *result_data_type);
+    }
+  }
+  if (else_result_expression != nullptr
+      && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
+    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
+  }
+
+  if (else_result_expression == nullptr) {
+    // If there is no ELSE clause, the data type must be nullable.
+    // Note that the unifying result expression type may be non-nullable.
+    result_data_type = &result_data_type->getNullableVersion();
+  }
+
+  return E::SimpleCase::Create(case_operand,
+                               condition_operands,
+                               conditional_result_expressions,
+                               else_result_expression,
+                               *result_data_type);
+}
+
 // TODO(chasseur): For now this only handles resolving aggregate functions. In
 // the future it should be extended to resolve scalar functions as well.
 E::ScalarPtr Resolver::resolveFunctionCall(
@@ -2219,6 +2517,14 @@
           resolvePredicates(static_cast<const ParsePredicateWithList&>(parse_predicate).operands(),
                             expression_resolution_info));
     }
+    case ParsePredicate::kExists: {
+      const ParsePredicateExists &exists =
+          static_cast<const ParsePredicateExists&>(parse_predicate);
+      return E::Exists::Create(
+          resolveSubqueryExpression(*exists.subquery(),
+                                    nullptr /* type_hints */,
+                                    expression_resolution_info));
+    }
     default:
       LOG(FATAL) << "Unknown predicate: " << parse_predicate.toString();
   }
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index 3b75114..39b5388 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -27,6 +27,7 @@
 #include "query_optimizer/expressions/ExprId.hpp"
 #include "query_optimizer/expressions/NamedExpression.hpp"
 #include "query_optimizer/expressions/Predicate.hpp"
+#include "query_optimizer/expressions/SubqueryExpression.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
 #include "query_optimizer/logical/Logical.hpp"
 #include "utility/Macros.hpp"
@@ -42,8 +43,10 @@
 class ParseGeneratorTableReference;
 class ParseOrderBy;
 class ParsePredicate;
+class ParseSearchedCaseExpression;
 class ParseSelect;
 class ParseSelectionClause;
+class ParseSimpleCaseExpression;
 class ParseSimpleTableReference;
 class ParseSubqueryTableReference;
 class ParseStatement;
@@ -57,6 +60,7 @@
 class ParseStatementSelect;
 class ParseStatementUpdate;
 class ParseString;
+class ParseSubqueryExpression;
 class ParseTableReference;
 class ParseTableReferenceSignature;
 class ParseTreeNode;
@@ -152,12 +156,14 @@
    * @param select_name The name for the SELECT query.
    * @param type_hints Type hints for the expressions in the SELECT clause. Can
    *                   be NULL if there is no expectation.
+   * @param parent_resolver The name resolver of the outer query if exists.
    * @return A logical plan for the SELECT query.
    */
   logical::LogicalPtr resolveSelect(
       const ParseSelect &select_statement,
       const std::string &select_name,
-      const std::vector<const Type*> *type_hints);
+      const std::vector<const Type*> *type_hints,
+      const NameResolver *parent_resolver);
 
   /**
    * @brief Resolves a CREATE TABLE query and returns a logical plan.
@@ -359,6 +365,36 @@
       ExpressionResolutionInfo *expression_resolution_info);
 
   /**
+   * @brief Resolves a searched CASE expression.
+   *
+   * @param type_hint The expected result type of this expression.
+   * @param parse_searched_case_expression The parsed searched CASE expression
+   *        to be resolved.
+   * @param expresssion_resolution_info Resolution info that contains the name
+   *        resolver and info to be updated after resolution.
+   * @return An optimizer expression for the CASE expression.
+   */
+  expressions::ScalarPtr resolveSearchedCaseExpression(
+      const ParseSearchedCaseExpression &parse_searched_case_expression,
+      const Type *type_hint,
+      ExpressionResolutionInfo *expression_resolution_info);
+
+  /**
+   * @brief Resolves a simple CASE expression.
+   *
+   * @param type_hint The expected result type of this expression.
+   * @param parse_simple_case_expression The parsed simple CASE expression
+   *        to be resolved.
+   * @param expresssion_resolution_info Resolution info that contains the name
+   *        resolver and info to be updated after resolution.
+   * @return An optimizer expression for the CASE expression.
+   */
+  expressions::ScalarPtr resolveSimpleCaseExpression(
+      const ParseSimpleCaseExpression &parse_simple_case_expression,
+      const Type *type_hint,
+      ExpressionResolutionInfo *expression_resolution_info);
+
+  /**
    * @brief Resolves a function call. For a non-scalar function, the returned
    *        expression is an AttributeReference to the actual resolved expression.
    *
@@ -403,6 +439,19 @@
       ExpressionResolutionInfo *expression_resolution_info);
 
   /**
+   * @brief Resolves a table/scalar subquery expression.
+   * 
+   * @param parse_subquery_expression The parsed subquery expression.
+   * @param type_hints The type hints for output columns by the subquery.
+   * @param expression_resolution_info Resolution info that contains the name
+   *        resolver and info to be updated after resolution.
+   */
+  expressions::SubqueryExpressionPtr resolveSubqueryExpression(
+      const ParseSubqueryExpression &parse_subquery_expression,
+      const std::vector<const Type*> *type_hints,
+      ExpressionResolutionInfo *expression_resolution_info);
+
+  /**
    * @brief Resolves a relation name to a pointer to the corresponding
    *        CatalogRelation with the name.
    *
diff --git a/query_optimizer/tests/execution_generator/Select.test b/query_optimizer/tests/execution_generator/Select.test
index 82f7816..e1614cb 100644
--- a/query_optimizer/tests/execution_generator/Select.test
+++ b/query_optimizer/tests/execution_generator/Select.test
@@ -674,6 +674,53 @@
 +-----------------------------------------------------+
 ==
 
+SELECT i,
+       CASE i%2
+         WHEN 1 THEN 'odd'
+         ELSE 'even'
+       END
+FROM generate_series(1, 5) AS gs(i);
+--
++-----------+--------------------------------------------+
+|i          |CASE (i%2) WHEN 1 THEN 'odd' ELSE 'even' END|
++-----------+--------------------------------------------+
+|          1|                                         odd|
+|          2|                                        even|
+|          3|                                         odd|
+|          4|                                        even|
+|          5|                                         odd|
++-----------+--------------------------------------------+
+==
+
+SELECT SUM(CASE WHEN i < 4 THEN i
+                ELSE i * i
+           END) AS result
+FROM generate_series(1, 5) AS gs(i);
+--
++--------------------+
+|result              |
++--------------------+
+|                  47|
++--------------------+
+==
+
+SELECT *
+FROM generate_series(1, 3) AS gs1(i),
+     generate_series(1, 3) AS gs2(j)
+WHERE CASE WHEN i < j THEN i
+           ELSE j
+       END > 1;
+--
++-----------+-----------+
+|i          |j          |
++-----------+-----------+
+|          2|          2|
+|          2|          3|
+|          3|          2|
+|          3|          3|
++-----------+-----------+
+==
+
 # TODO(team): Support uncorrelated queries.
 # SELECT COUNT(*)
 # FROM test
diff --git a/query_optimizer/tests/resolver/Select.test b/query_optimizer/tests/resolver/Select.test
index 1290d5e..2276de3 100644
--- a/query_optimizer/tests/resolver/Select.test
+++ b/query_optimizer/tests/resolver/Select.test
@@ -1,5 +1,7 @@
 #   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.
@@ -2327,6 +2329,85 @@
     type=Double NULL]
 ==
 
+SELECT i
+FROM generate_series(0, 100, 3) AS gs1(i)
+WHERE
+  EXISTS (
+    SELECT *
+    FROM generate_series(0, 100, 5) AS gs2(i)
+    WHERE gs1.i = gs2.i
+  )
+  AND NOT EXISTS (
+    SELECT *
+    FROM generate_series(0, 100, 10) AS gs3(i)
+    WHERE gs1.i = gs3.i
+  )
+  AND (i < 40 OR i > 60);
+--
+TopLevelPlan
++-plan=Project
+| +-input=Filter
+| | +-input=Project
+| | | +-input=TableGenerator[function_name=generate_series,table_alias=gs1]
+| | | | +-AttributeReference[id=0,name=generate_series,alias=gs1,
+| | | |   relation=generate_series,type=Int]
+| | | +-project_list=
+| | |   +-Alias[id=1,name=i,relation=,type=Int]
+| | |     +-AttributeReference[id=0,name=generate_series,alias=gs1,
+| | |       relation=generate_series,type=Int]
+| | +-filter_predicate=And
+| |   +-Exists
+| |   | +-exists_subquery=SubqueryExpression
+| |   |   +-subquery=Project
+| |   |     +-input=Filter
+| |   |     | +-input=Project
+| |   |     | | +-input=TableGenerator[function_name=generate_series,
+| |   |     | | | table_alias=gs2]
+| |   |     | | | +-AttributeReference[id=2,name=generate_series,alias=gs2,
+| |   |     | | |   relation=generate_series,type=Int]
+| |   |     | | +-project_list=
+| |   |     | |   +-Alias[id=3,name=i,relation=,type=Int]
+| |   |     | |     +-AttributeReference[id=2,name=generate_series,alias=gs2,
+| |   |     | |       relation=generate_series,type=Int]
+| |   |     | +-filter_predicate=Equal
+| |   |     |   +-AttributeReference[id=1,name=i,relation=,type=Int,
+| |   |     |   | is_outer_reference=true]
+| |   |     |   +-AttributeReference[id=3,name=i,relation=,type=Int]
+| |   |     +-project_list=
+| |   |       +-AttributeReference[id=3,name=i,relation=,type=Int]
+| |   +-NOT
+| |   | +-Exists
+| |   |   +-exists_subquery=SubqueryExpression
+| |   |     +-subquery=Project
+| |   |       +-input=Filter
+| |   |       | +-input=Project
+| |   |       | | +-input=TableGenerator[function_name=generate_series,
+| |   |       | | | table_alias=gs3]
+| |   |       | | | +-AttributeReference[id=4,name=generate_series,alias=gs3,
+| |   |       | | |   relation=generate_series,type=Int]
+| |   |       | | +-project_list=
+| |   |       | |   +-Alias[id=5,name=i,relation=,type=Int]
+| |   |       | |     +-AttributeReference[id=4,name=generate_series,alias=gs3,
+| |   |       | |       relation=generate_series,type=Int]
+| |   |       | +-filter_predicate=Equal
+| |   |       |   +-AttributeReference[id=1,name=i,relation=,type=Int,
+| |   |       |   | is_outer_reference=true]
+| |   |       |   +-AttributeReference[id=5,name=i,relation=,type=Int]
+| |   |       +-project_list=
+| |   |         +-AttributeReference[id=5,name=i,relation=,type=Int]
+| |   +-Or
+| |     +-Less
+| |     | +-AttributeReference[id=1,name=i,relation=,type=Int]
+| |     | +-Literal[value=40,type=Int]
+| |     +-Greater
+| |       +-AttributeReference[id=1,name=i,relation=,type=Int]
+| |       +-Literal[value=60,type=Int]
+| +-project_list=
+|   +-AttributeReference[id=1,name=i,relation=,type=Int]
++-output_attributes=
+  +-AttributeReference[id=1,name=i,relation=,type=Int]
+==
+
 select interval '4 day' + interval '5 year'
 from test
 --
@@ -2373,3 +2454,148 @@
 ERROR: Can not apply binary operation "Divide" to arguments of types Int and Datetime (1 : 10)
 select 5 / (date '1999-10-12' + yearmont...
          ^
+==
+
+# CASE expressions.
+SELECT CASE int_col%2
+           WHEN 1 THEN 'odd'
+           ELSE 'even'
+       END
+FROM test;
+--
+TopLevelPlan
++-plan=Project
+| +-input=TableReference[relation_name=Test,relation_alias=test]
+| | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+| | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+| | +-AttributeReference[id=2,name=float_col,relation=test,type=Float]
+| | +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
+| | +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+| | +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
+| +-project_list=
+|   +-Alias[id=6,name=,alias=CASE (int_col%2) WHEN 1 THEN 'odd' ELSE 'even' END,
+|     relation=,type=VarChar(4)]
+|     +-SimpleCase
+|       +-case_operand=Modulo
+|       | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+|       | +-Literal[value=2,type=Int]
+|       +-else_result_expression=Literal[value=even,type=VarChar(4)]
+|       +-condition_operands=
+|       | +-Literal[value=1,type=Int]
+|       +-result_expressions=
+|         +-Literal[value=odd,type=VarChar(3)]
++-output_attributes=
+  +-AttributeReference[id=6,name=,
+    alias=CASE (int_col%2) WHEN 1 THEN 'odd' ELSE 'even' END,relation=,
+    type=VarChar(4)]
+==
+
+SELECT char_col, vchar_col
+FROM test
+WHERE CASE WHEN int_col > long_col THEN float_col
+           ELSE double_col
+      END > 0;
+--
+TopLevelPlan
++-plan=Project
+| +-input=Filter
+| | +-input=TableReference[relation_name=Test,relation_alias=test]
+| | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+| | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+| | | +-AttributeReference[id=2,name=float_col,relation=test,type=Float]
+| | | +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
+| | | +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+| | | +-AttributeReference[id=5,name=vchar_col,relation=test,
+| | |   type=VarChar(20) NULL]
+| | +-filter_predicate=Greater
+| |   +-SearchedCase
+| |   | +-else_result_expression=AttributeReference[id=3,name=double_col,
+| |   | | relation=test,type=Double NULL]
+| |   | +-condition_perdicates=
+| |   | | +-Greater
+| |   | |   +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+| |   | |   +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+| |   | +-conditional_result_expressions=
+| |   |   +-Cast[target_type=Double NULL]
+| |   |     +-operand=AttributeReference[id=2,name=float_col,relation=test,
+| |   |       type=Float]
+| |   +-Literal[value=0,type=Int]
+| +-project_list=
+|   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+|   +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
++-output_attributes=
+  +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+  +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
+==
+
+SELECT
+  SUM(CASE double_col
+        WHEN long_col +
+             CASE WHEN int_col < float_col THEN 0
+                  ELSE 1
+             END +
+             CASE WHEN char_col <> vchar_col THEN 0
+                  ELSE 1
+             END
+             THEN 1
+        WHEN float_col THEN 2
+      END + int_col) AS result
+FROM test;
+--
+TopLevelPlan
++-plan=Project
+| +-input=Aggregate
+| | +-input=TableReference[relation_name=Test,relation_alias=test]
+| | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+| | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+| | | +-AttributeReference[id=2,name=float_col,relation=test,type=Float]
+| | | +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
+| | | +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+| | | +-AttributeReference[id=5,name=vchar_col,relation=test,
+| | |   type=VarChar(20) NULL]
+| | +-grouping_expressions=
+| | | +-[]
+| | +-aggregate_expressions=
+| |   +-Alias[id=6,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
+| |     +-AggregateFunction[function=SUM]
+| |       +-Add
+| |         +-SimpleCase
+| |         | +-case_operand=AttributeReference[id=3,name=double_col,
+| |         | | relation=test,type=Double NULL]
+| |         | +-condition_operands=
+| |         | | +-Add
+| |         | | | +-Add
+| |         | | | | +-AttributeReference[id=1,name=long_col,relation=test,
+| |         | | | | | type=Long]
+| |         | | | | +-SearchedCase
+| |         | | | |   +-else_result_expression=Literal[value=1,type=Double]
+| |         | | | |   +-condition_perdicates=
+| |         | | | |   | +-Less
+| |         | | | |   |   +-AttributeReference[id=0,name=int_col,relation=test,
+| |         | | | |   |   | type=Int NULL]
+| |         | | | |   |   +-AttributeReference[id=2,name=float_col,
+| |         | | | |   |     relation=test,type=Float]
+| |         | | | |   +-conditional_result_expressions=
+| |         | | | |     +-Literal[value=0,type=Double]
+| |         | | | +-SearchedCase
+| |         | | |   +-else_result_expression=Literal[value=1,type=Double]
+| |         | | |   +-condition_perdicates=
+| |         | | |   | +-NotEqual
+| |         | | |   |   +-AttributeReference[id=4,name=char_col,relation=test,
+| |         | | |   |   | type=Char(20)]
+| |         | | |   |   +-AttributeReference[id=5,name=vchar_col,relation=test,
+| |         | | |   |     type=VarChar(20) NULL]
+| |         | | |   +-conditional_result_expressions=
+| |         | | |     +-Literal[value=0,type=Double]
+| |         | | +-AttributeReference[id=2,name=float_col,relation=test,
+| |         | |   type=Float]
+| |         | +-result_expressions=
+| |         |   +-Literal[value=1,type=Int]
+| |         |   +-Literal[value=2,type=Int]
+| |         +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+| +-project_list=
+|   +-Alias[id=6,name=result,relation=,type=Long NULL]
+|     +-AttributeReference[id=6,name=,alias=$aggregate0,relation=$aggregate,
+|       type=Long NULL]
++-output_attributes=
+  +-AttributeReference[id=6,name=result,relation=,type=Long NULL]