quickstep-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jianq...@apache.org
Subject [27/27] incubator-quickstep git commit: Quickstep for GRAIL.
Date Fri, 17 Nov 2017 19:41:07 GMT
Quickstep for GRAIL.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/aec7623a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/aec7623a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/aec7623a

Branch: refs/heads/trace
Commit: aec7623aa7782c7dc9aa0633b53c9da85634a4a0
Parents: 0fe838d
Author: Jianqiao Zhu <jianqiao@cs.wisc.edu>
Authored: Sat Sep 2 23:06:37 2017 -0500
Committer: Jianqiao Zhu <jianqiao@cs.wisc.edu>
Committed: Fri Nov 17 13:24:22 2017 -0600

----------------------------------------------------------------------
 CMakeLists.txt                                  |    4 +-
 catalog/CatalogRelationStatistics.hpp           |    9 +
 cli/CommandExecutor.cpp                         |  249 +-
 cli/Constants.hpp                               |    2 +
 cli/IOInterface.hpp                             |    9 +-
 cli/LocalIO.hpp                                 |    4 +
 cli/NetworkCli.proto                            |    1 +
 cli/NetworkCliClient.hpp                        |    7 +-
 cli/NetworkCliClientMain.cpp                    |   30 +-
 cli/NetworkIO.cpp                               |    5 +
 cli/NetworkIO.hpp                               |   33 +-
 cli/QuickstepCli.cpp                            |    3 +-
 cli/quickstep/NetworkCliOuterClass.java         | 1388 +++++++
 cli/tests/NetworkIO_unittest.cpp                |    2 +-
 .../aggregation/AggregateFunctionMax.cpp        |    4 +-
 .../aggregation/AggregateFunctionMin.cpp        |    4 +-
 parser/SqlLexer.lpp                             |    1 +
 parser/SqlParser.ypp                            |   15 +-
 parser/preprocessed/SqlLexer_gen.cpp            |  861 ++---
 parser/preprocessed/SqlLexer_gen.hpp            |    2 +-
 parser/preprocessed/SqlParser_gen.cpp           | 3436 +++++++++---------
 parser/preprocessed/SqlParser_gen.hpp           |   49 +-
 query_optimizer/ExecutionGenerator.cpp          |   12 +-
 .../cost_model/StarSchemaSimpleCostModel.cpp    |    4 +-
 query_optimizer/resolver/Resolver.cpp           |    9 +-
 relational_operators/TableExportOperator.cpp    |    2 +
 relational_operators/TextScanOperator.cpp       |  104 +-
 relational_operators/TextScanOperator.hpp       |    2 +
 storage/AggregationOperationState.cpp           |    3 +-
 utility/ExecutionDAGVisualizer.cpp              |    6 +-
 30 files changed, 4009 insertions(+), 2251 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 071f8fc..cb8e9f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -291,7 +291,7 @@ else()
   # Treat warnings as errors, 'cause we hardcore.
   CHECK_CXX_COMPILER_FLAG("-Werror" COMPILER_HAS_WERROR)
   if (COMPILER_HAS_WERROR)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
+    # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
   endif()
 
   # Clang reports such warning when using Protoc 3.0 beta.
@@ -585,7 +585,7 @@ if(USE_TCMALLOC)
   CHECK_CXX_COMPILER_FLAG("-Wno-return-type-c-linkage"
                           COMPILER_HAS_WNO_RETURN_TYPE_C_LINKAGE)
   if (COMPILER_HAS_WNO_RETURN_TYPE_C_LINKAGE)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage")
+    # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage")
   endif()
 endif()
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/catalog/CatalogRelationStatistics.hpp
----------------------------------------------------------------------
diff --git a/catalog/CatalogRelationStatistics.hpp b/catalog/CatalogRelationStatistics.hpp
index df95231..55fc747 100644
--- a/catalog/CatalogRelationStatistics.hpp
+++ b/catalog/CatalogRelationStatistics.hpp
@@ -68,6 +68,15 @@ class CatalogRelationStatistics {
   serialization::CatalogRelationStatistics getProto() const;
 
   /**
+   * @brief Clear all statistics.
+   */
+  void clear() {
+    num_tuples_ = kNullValue;
+    column_stats_.clear();
+    is_exact_ = true;
+  }
+
+  /**
    * @brief Check whether the statistics are exact for the relation.
    *
    * return True if the statistics are exact for the relation, false otherwise.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/CommandExecutor.cpp
----------------------------------------------------------------------
diff --git a/cli/CommandExecutor.cpp b/cli/CommandExecutor.cpp
index 6a84672..7976d7d 100644
--- a/cli/CommandExecutor.cpp
+++ b/cli/CommandExecutor.cpp
@@ -201,9 +201,28 @@ void ExecuteAnalyze(const PtrVector<ParseString> &arguments,
     CatalogRelationStatistics *mutable_stat =
         mutable_relation->getStatisticsMutable();
 
+    mutable_stat->clear();
+
     const std::string rel_name = EscapeQuotes(relation.getName(), '"');
 
-    // Get the number of distinct values for each column.
+    // Get the number of tuples for the relation.
+    std::string query_string = "SELECT COUNT(*) FROM \"";
+    query_string.append(rel_name);
+    query_string.append("\";");
+
+    TypedValue num_tuples =
+        ExecuteQueryForSingleResult(main_thread_client_id,
+                                    foreman_client_id,
+                                    query_string,
+                                    bus,
+                                    storage_manager,
+                                    query_processor,
+                                    parser_wrapper.get());
+
+    DCHECK_EQ(TypeID::kLong, num_tuples.getTypeID());
+    mutable_stat->setNumTuples(num_tuples.getLiteral<std::int64_t>());
+
+    // Get the min/max values for each column.
     for (const CatalogAttribute &attribute : relation) {
       const std::string attr_name = EscapeQuotes(attribute.getName(), '"');
       const Type &attr_type = attribute.getType();
@@ -211,24 +230,15 @@ void ExecuteAnalyze(const PtrVector<ParseString> &arguments,
           AggregateFunctionMin::Instance().canApplyToTypes({&attr_type});
       bool is_max_applicable =
           AggregateFunctionMax::Instance().canApplyToTypes({&attr_type});
+      if (!is_min_applicable || !is_max_applicable) {
+        continue;
+      }
 
-      // NOTE(jianqiao): Note that the relation name and the attribute names may
-      // contain non-letter characters, e.g. CREATE TABLE "with space"("1" int).
-      // So here we need to format the names with double quotes (").
-      std::string query_string = "SELECT COUNT(DISTINCT \"";
+      std::string query_string = "SELECT MIN(\"";
       query_string.append(attr_name);
-      query_string.append("\")");
-      if (is_min_applicable) {
-        query_string.append(", MIN(\"");
-        query_string.append(attr_name);
-        query_string.append("\")");
-      }
-      if (is_max_applicable) {
-        query_string.append(", MAX(\"");
-        query_string.append(attr_name);
-        query_string.append("\")");
-      }
-      query_string.append(" FROM \"");
+      query_string.append("\"), MAX(\"");
+      query_string.append(attr_name);
+      query_string.append("\") FROM \"");
       query_string.append(rel_name);
       query_string.append("\";");
 
@@ -240,42 +250,181 @@ void ExecuteAnalyze(const PtrVector<ParseString> &arguments,
                                    storage_manager,
                                    query_processor,
                                    parser_wrapper.get());
-
-      auto results_it = results.begin();
-      DCHECK_EQ(TypeID::kLong, results_it->getTypeID());
+      DCHECK_EQ(2u, results.size());
 
       const attribute_id attr_id = attribute.getID();
-      mutable_stat->setNumDistinctValues(attr_id,
-                                         results_it->getLiteral<std::int64_t>());
-      if (is_min_applicable) {
-        ++results_it;
-        mutable_stat->setMinValue(attr_id, *results_it);
+      mutable_stat->setMinValue(attr_id, results[0]);
+      mutable_stat->setMaxValue(attr_id, results[1]);
+    }
+
+    // Get the number of distinct values for each column.
+    for (const CatalogAttribute &attribute : relation) {
+      const std::string attr_name = EscapeQuotes(attribute.getName(), '"');
+
+      std::string query_string = "SELECT COUNT(*) FROM (SELECT \"";
+      query_string.append(attr_name);
+      query_string.append("\" FROM \"");
+      query_string.append(rel_name);
+      query_string.append("\" GROUP BY \"");
+      query_string.append(attr_name);
+      query_string.append("\") t;");
+
+      TypedValue num_distinct_values =
+          ExecuteQueryForSingleResult(main_thread_client_id,
+                                      foreman_client_id,
+                                      query_string,
+                                      bus,
+                                      storage_manager,
+                                      query_processor,
+                                      parser_wrapper.get());
+
+      DCHECK_EQ(TypeID::kLong, num_distinct_values.getTypeID());
+      mutable_stat->setNumDistinctValues(
+          attribute.getID(), num_distinct_values.getLiteral<std::int64_t>());
+    }
+
+    fprintf(out, "done\n");
+    fflush(out);
+  }
+  query_processor->markCatalogAltered();
+  query_processor->saveCatalog();
+}
+
+void ExecuteAnalyzeRange(const PtrVector<ParseString> &arguments,
+                         const tmb::client_id main_thread_client_id,
+                         const tmb::client_id foreman_client_id,
+                         MessageBus *bus,
+                         StorageManager *storage_manager,
+                         QueryProcessor *query_processor,
+                         FILE *out) {
+  const CatalogDatabase &database = *query_processor->getDefaultDatabase();
+
+  std::unique_ptr<SqlParserWrapper> parser_wrapper(new SqlParserWrapper());
+  std::vector<std::reference_wrapper<const CatalogRelation>> relations;
+  if (arguments.empty()) {
+    relations.insert(relations.begin(), database.begin(), database.end());
+  } else {
+    for (const auto &rel_name : arguments) {
+      const CatalogRelation *rel = database.getRelationByName(rel_name.value());
+      if (rel == nullptr) {
+        THROW_SQL_ERROR_AT(&rel_name) << "Table does not exist";
+      } else {
+        relations.emplace_back(*rel);
+      }
+    }
+  }
+
+  // Analyze each relation in the database.
+  for (const CatalogRelation &relation : relations) {
+    fprintf(out, "Analyzing %s ... ", relation.getName().c_str());
+    fflush(out);
+
+    CatalogRelation *mutable_relation =
+        query_processor->getDefaultDatabase()->getRelationByIdMutable(relation.getID());
+    CatalogRelationStatistics *mutable_stat =
+        mutable_relation->getStatisticsMutable();
+
+    if (!mutable_stat->isExact()) {
+      mutable_stat->clear();
+
+      const std::string rel_name = EscapeQuotes(relation.getName(), '"');
+
+      for (const CatalogAttribute &attribute : relation) {
+        const std::string attr_name = EscapeQuotes(attribute.getName(), '"');
+        const Type &attr_type = attribute.getType();
+        bool is_min_applicable =
+            AggregateFunctionMin::Instance().canApplyToTypes({&attr_type});
+        bool is_max_applicable =
+            AggregateFunctionMax::Instance().canApplyToTypes({&attr_type});
+        if (!is_min_applicable || !is_max_applicable) {
+          continue;
+        }
+
+        std::string query_string = "SELECT MIN(\"";
+        query_string.append(attr_name);
+        query_string.append("\"), MAX(\"");
+        query_string.append(attr_name);
+        query_string.append("\") FROM \"");
+        query_string.append(rel_name);
+        query_string.append("\";");
+
+        std::vector<TypedValue> results =
+            ExecuteQueryForSingleRow(main_thread_client_id,
+                                     foreman_client_id,
+                                     query_string,
+                                     bus,
+                                     storage_manager,
+                                     query_processor,
+                                     parser_wrapper.get());
+        DCHECK_EQ(2u, results.size());
+
+        const attribute_id attr_id = attribute.getID();
+        mutable_stat->setMinValue(attr_id, results[0]);
+        mutable_stat->setMaxValue(attr_id, results[1]);
       }
-      if (is_max_applicable) {
-        ++results_it;
-        mutable_stat->setMaxValue(attr_id, *results_it);
+    }
+    fprintf(out, "done\n");
+    fflush(out);
+  }
+  query_processor->markCatalogAltered();
+  query_processor->saveCatalog();
+}
+
+void ExecuteAnalyzeCount(const PtrVector<ParseString> &arguments,
+                         const tmb::client_id main_thread_client_id,
+                         const tmb::client_id foreman_client_id,
+                         MessageBus *bus,
+                         StorageManager *storage_manager,
+                         QueryProcessor *query_processor,
+                         FILE *out) {
+  const CatalogDatabase &database = *query_processor->getDefaultDatabase();
+
+  std::unique_ptr<SqlParserWrapper> parser_wrapper(new SqlParserWrapper());
+  std::vector<std::reference_wrapper<const CatalogRelation>> relations;
+  if (arguments.empty()) {
+    relations.insert(relations.begin(), database.begin(), database.end());
+  } else {
+    for (const auto &rel_name : arguments) {
+      const CatalogRelation *rel = database.getRelationByName(rel_name.value());
+      if (rel == nullptr) {
+        THROW_SQL_ERROR_AT(&rel_name) << "Table does not exist";
+      } else {
+        relations.emplace_back(*rel);
       }
     }
+  }
 
-    // Get the number of tuples for the relation.
-    std::string query_string = "SELECT COUNT(*) FROM \"";
-    query_string.append(rel_name);
-    query_string.append("\";");
+  // Analyze each relation in the database.
+  for (const CatalogRelation &relation : relations) {
+    fprintf(out, "Analyzing %s ... ", relation.getName().c_str());
+    fflush(out);
 
-    TypedValue num_tuples =
-        ExecuteQueryForSingleResult(main_thread_client_id,
-                                    foreman_client_id,
-                                    query_string,
-                                    bus,
-                                    storage_manager,
-                                    query_processor,
-                                    parser_wrapper.get());
+    CatalogRelation *mutable_relation =
+        query_processor->getDefaultDatabase()->getRelationByIdMutable(relation.getID());
+    CatalogRelationStatistics *mutable_stat =
+        mutable_relation->getStatisticsMutable();
 
-    DCHECK_EQ(TypeID::kLong, num_tuples.getTypeID());
-    mutable_stat->setNumTuples(num_tuples.getLiteral<std::int64_t>());
+    if (!mutable_stat->isExact()) {
+      mutable_stat->clear();
 
-    mutable_stat->setExactness(true);
+      // Get the number of tuples for the relation.
+      std::string query_string = "SELECT COUNT(*) FROM \"";
+      query_string.append(EscapeQuotes(relation.getName(), '"'));
+      query_string.append("\";");
 
+      TypedValue num_tuples =
+          ExecuteQueryForSingleResult(main_thread_client_id,
+                                      foreman_client_id,
+                                      query_string,
+                                      bus,
+                                      storage_manager,
+                                      query_processor,
+                                      parser_wrapper.get());
+
+      DCHECK_EQ(TypeID::kLong, num_tuples.getTypeID());
+      mutable_stat->setNumTuples(num_tuples.getLiteral<std::int64_t>());
+
+    }
     fprintf(out, "done\n");
     fflush(out);
   }
@@ -314,6 +463,20 @@ void executeCommand(const ParseStatement &statement,
                    bus,
                    storage_manager,
                    query_processor, out);
+  } else if (command_str == kAnalyzeRangeCommand) {
+    ExecuteAnalyzeRange(arguments,
+                        main_thread_client_id,
+                        foreman_client_id,
+                        bus,
+                        storage_manager,
+                        query_processor, out);
+  } else if (command_str == kAnalyzeCountCommand) {
+    ExecuteAnalyzeCount(arguments,
+                        main_thread_client_id,
+                        foreman_client_id,
+                        bus,
+                        storage_manager,
+                        query_processor, out);
   } else {
     THROW_SQL_ERROR_AT(command.command()) << "Invalid Command";
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/Constants.hpp
----------------------------------------------------------------------
diff --git a/cli/Constants.hpp b/cli/Constants.hpp
index 0b4a37b..8934b03 100644
--- a/cli/Constants.hpp
+++ b/cli/Constants.hpp
@@ -30,6 +30,8 @@ namespace cli {
 constexpr char kDescribeDatabaseCommand[] = "\\dt";
 constexpr char kDescribeTableCommand[] = "\\d";
 constexpr char kAnalyzeCommand[] = "\\analyze";
+constexpr char kAnalyzeRangeCommand[] = "\\analyzerange";
+constexpr char kAnalyzeCountCommand[] = "\\analyzecount";
 
 /** @} */
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/IOInterface.hpp
----------------------------------------------------------------------
diff --git a/cli/IOInterface.hpp b/cli/IOInterface.hpp
index dc0d5b2..ec125f9 100644
--- a/cli/IOInterface.hpp
+++ b/cli/IOInterface.hpp
@@ -40,14 +40,19 @@ class IOHandle {
   virtual ~IOHandle() {}
 
   /**
+   * @return A file handle for standard input.
+   */
+  virtual FILE* in() = 0;
+
+  /**
    * @return A file handle for standard output.
    */
-  virtual FILE *out() = 0;
+  virtual FILE* out() = 0;
 
   /**
    * @return A file handle for error output.
    */
-  virtual FILE *err() = 0;
+  virtual FILE* err() = 0;
 
   virtual std::string getCommand() const = 0;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/LocalIO.hpp
----------------------------------------------------------------------
diff --git a/cli/LocalIO.hpp b/cli/LocalIO.hpp
index 4dc3b3f..42501d2 100644
--- a/cli/LocalIO.hpp
+++ b/cli/LocalIO.hpp
@@ -46,6 +46,10 @@ class LocalIOHandle final : public IOHandle {
 
   ~LocalIOHandle() override {}
 
+  FILE *in() override {
+    return stdin;
+  }
+
   FILE *out() override {
     return stdout;
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/NetworkCli.proto
----------------------------------------------------------------------
diff --git a/cli/NetworkCli.proto b/cli/NetworkCli.proto
index e065c7c..1558d01 100644
--- a/cli/NetworkCli.proto
+++ b/cli/NetworkCli.proto
@@ -25,6 +25,7 @@ service NetworkCli {
 
 message QueryRequest {
   string query = 1;
+  string data = 2;
 }
 
 message QueryResponse {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/NetworkCliClient.hpp
----------------------------------------------------------------------
diff --git a/cli/NetworkCliClient.hpp b/cli/NetworkCliClient.hpp
index 7affeff..5c11cb2 100644
--- a/cli/NetworkCliClient.hpp
+++ b/cli/NetworkCliClient.hpp
@@ -53,9 +53,10 @@ class NetworkCliClient {
    * @param user_query A SQL statement or command to be executed on the server.
    * @return The text of the server's response.
    */
-  std::string Query(const std::string &user_query) {
+  std::string Query(const std::string &user_query, const std::string &data) {
     QueryRequest request;
     request.set_query(user_query);
+    request.set_data(data);
     QueryResponse response;
 
     Status status = SendQuery(request, &response);
@@ -63,8 +64,8 @@ class NetworkCliClient {
     if (status.ok()) {
       return HandleQueryResponse(response);
     } else {
-      LOG(WARNING) << "RPC call failed with code " << status.error_code()
-                   << " and message: " << status.error_message();
+      std::cout << "RPC call failed with code " << status.error_code()
+                << " and message: " << status.error_message() << "\n";
       return "RPC failed";
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/NetworkCliClientMain.cpp
----------------------------------------------------------------------
diff --git a/cli/NetworkCliClientMain.cpp b/cli/NetworkCliClientMain.cpp
index c55819b..164d81e 100644
--- a/cli/NetworkCliClientMain.cpp
+++ b/cli/NetworkCliClientMain.cpp
@@ -38,22 +38,42 @@ int main(int argc, char **argv) {
   gflags::ParseCommandLineFlags(&argc, &argv, true);
   grpc_init();
 
+  grpc::ChannelArguments grpc_args;
+  grpc_args.SetMaxSendMessageSize(quickstep::FLAGS_cli_network_max_message_length);
+  grpc_args.SetMaxReceiveMessageSize(quickstep::FLAGS_cli_network_max_message_length);
+
   // Attempts to send a single query retrieved from stdin to the Quickstep Server.
   NetworkCliClient qs_client(
-    grpc::CreateChannel(quickstep::NetworkIO::GetAddress(),
-                        grpc::InsecureChannelCredentials()));
+    grpc::CreateCustomChannel(quickstep::NetworkIO::GetAddress(),
+                              grpc::InsecureChannelCredentials(),
+                              grpc_args));
 
   // Read stdin until EOF, then we use a Line reader to divide query into parts.
   std::cin >> std::noskipws;
   std::istream_iterator<char> it(std::cin), end;
-  std::string user_queries(it, end);
+  std::string input(it, end);
+
+  if (input.empty()) {
+    return 0;
+  }
+
+  // Temporary hack for transmitting data in a separate channel ...
+  std::string queries;
+  std::string data;
+  if (input.front() == 0) {
+    const std::size_t r = input.find(static_cast<char>(0), 1);
+    queries = input.substr(1, r - 1);
+    data = input.substr(r + 1);
+  } else {
+    queries = std::move(input);
+  }
 
   LineReaderBuffered linereader;
-  linereader.setBuffer(user_queries);
+  linereader.setBuffer(queries);
   while (!linereader.bufferEmpty()) {
     std::string query = linereader.getNextCommand();
     if (!query.empty()) {
-      std::cout << qs_client.Query(query) << std::endl;
+      std::cout << qs_client.Query(query, data) << std::endl;
     }
   }
   return 0;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/NetworkIO.cpp
----------------------------------------------------------------------
diff --git a/cli/NetworkIO.cpp b/cli/NetworkIO.cpp
index f0acc65..cbc815e 100644
--- a/cli/NetworkIO.cpp
+++ b/cli/NetworkIO.cpp
@@ -47,10 +47,15 @@ DEFINE_string(cli_network_ip, "0.0.0.0",
                 "if the cli is set to use the network mode (--mode=network). Defaults to "
                 "the address of localhost.");
 
+DEFINE_int32(cli_network_max_message_length, 1073741824,
+             "The maximum message length transferred through grpc");
+
 NetworkIO::NetworkIO() {
   grpc::ServerBuilder builder;
   builder.AddListeningPort(GetAddress(), grpc::InsecureServerCredentials());
   builder.RegisterService(&service_);
+  builder.SetMaxReceiveMessageSize(FLAGS_cli_network_max_message_length);
+  builder.SetMaxSendMessageSize(FLAGS_cli_network_max_message_length);
   server_ = builder.BuildAndStart();
   LOG(INFO) << "Listening on " << GetAddress();
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/NetworkIO.hpp
----------------------------------------------------------------------
diff --git a/cli/NetworkIO.hpp b/cli/NetworkIO.hpp
index 3693f88..e55c206 100644
--- a/cli/NetworkIO.hpp
+++ b/cli/NetworkIO.hpp
@@ -47,6 +47,7 @@ using grpc::Status;
 namespace quickstep {
 DECLARE_int32(cli_network_port);
 DECLARE_string(cli_network_ip);
+DECLARE_int32(cli_network_max_message_length);
 namespace networkio_internal {
 
 /**
@@ -80,8 +81,9 @@ class RequestState {
    * @note Quickstep may either produce a query response or cancel. Both these actions must notify the condition.
    */
   void waitForResponse() {
-    while (!response_ready_)
+    while (!response_ready_) {
       condition_->await();
+    }
   }
 
   /**
@@ -95,16 +97,16 @@ class RequestState {
   }
 
   /**
-   * @return The producer's query for Quickstep to process.
+   * @return The producer's request for Quickstep to process.
    */
-  std::string getRequest() const {
-    return request_.query();
+  const QueryRequest& getRequest() const {
+    return request_;
   }
 
   /**
    * @return The response message from Quickstep.
    */
-  QueryResponse getResponse() const {
+  const QueryResponse& getResponse() const {
     DCHECK(response_ready_);
     return response_message_;
   }
@@ -212,12 +214,21 @@ class NetworkCliServiceImpl final : public NetworkCli::Service {
 class NetworkIOHandle final : public IOHandle {
  public:
   explicit NetworkIOHandle(RequestState* state)
-      : request_state_(state) {}
+      : request_state_(state) {
+    const std::string &data = request_state_->getRequest().data();
+    if (!data.empty()) {
+      std::fwrite(data.c_str(), 1, data.length(), in_stream_.file());
+    }
+  }
 
   ~NetworkIOHandle() override {
-      // All the commands from the last network interaction have completed, return our response.
-      // This signals to the producer thread that the interaction is complete.
-      request_state_->responseReady(out_stream_.str(), err_stream_.str());
+    // All the commands from the last network interaction have completed, return our response.
+    // This signals to the producer thread that the interaction is complete.
+    request_state_->responseReady(out_stream_.str(), err_stream_.str());
+  }
+
+  FILE* in() override {
+    return in_stream_.file();
   }
 
   FILE* out() override {
@@ -229,11 +240,11 @@ class NetworkIOHandle final : public IOHandle {
   }
 
   std::string getCommand() const override {
-    return request_state_->getRequest();
+    return request_state_->getRequest().query();
   }
 
  private:
-  MemStream out_stream_, err_stream_;
+  MemStream in_stream_, out_stream_, err_stream_;
   RequestState *request_state_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkIOHandle);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/QuickstepCli.cpp
----------------------------------------------------------------------
diff --git a/cli/QuickstepCli.cpp b/cli/QuickstepCli.cpp
index e8ca56c..5db5dfc 100644
--- a/cli/QuickstepCli.cpp
+++ b/cli/QuickstepCli.cpp
@@ -305,8 +305,9 @@ int main(int argc, char* argv[]) {
   for (;;) {
     string *command_string = new string();
     std::unique_ptr<quickstep::IOHandle> io_handle(io->getNextIOHandle());
+    ScopedReassignment<FILE*> reassign_stdin(&stdin, io_handle->in());
     ScopedReassignment<FILE*> reassign_stdout(&stdout, io_handle->out());
-    ScopedReassignment<FILE*> reassign_stderr(&stderr, io_handle->err());
+//    ScopedReassignment<FILE*> reassign_stderr(&stderr, io_handle->err());
 
     *command_string = io_handle->getCommand();
     LOG(INFO) << "Command received: " << *command_string;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/quickstep/NetworkCliOuterClass.java
----------------------------------------------------------------------
diff --git a/cli/quickstep/NetworkCliOuterClass.java b/cli/quickstep/NetworkCliOuterClass.java
new file mode 100644
index 0000000..6f4e833
--- /dev/null
+++ b/cli/quickstep/NetworkCliOuterClass.java
@@ -0,0 +1,1388 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: NetworkCli.proto
+
+package quickstep;
+
+public final class NetworkCliOuterClass {
+  private NetworkCliOuterClass() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface QueryRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:quickstep.QueryRequest)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>string query = 1;</code>
+     */
+    java.lang.String getQuery();
+    /**
+     * <code>string query = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getQueryBytes();
+
+    /**
+     * <code>string data = 2;</code>
+     */
+    java.lang.String getData();
+    /**
+     * <code>string data = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getDataBytes();
+  }
+  /**
+   * Protobuf type {@code quickstep.QueryRequest}
+   */
+  public  static final class QueryRequest extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:quickstep.QueryRequest)
+      QueryRequestOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use QueryRequest.newBuilder() to construct.
+    private QueryRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private QueryRequest() {
+      query_ = "";
+      data_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private QueryRequest(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              query_ = s;
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              data_ = s;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              quickstep.NetworkCliOuterClass.QueryRequest.class, quickstep.NetworkCliOuterClass.QueryRequest.Builder.class);
+    }
+
+    public static final int QUERY_FIELD_NUMBER = 1;
+    private volatile java.lang.Object query_;
+    /**
+     * <code>string query = 1;</code>
+     */
+    public java.lang.String getQuery() {
+      java.lang.Object ref = query_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        query_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string query = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getQueryBytes() {
+      java.lang.Object ref = query_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        query_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int DATA_FIELD_NUMBER = 2;
+    private volatile java.lang.Object data_;
+    /**
+     * <code>string data = 2;</code>
+     */
+    public java.lang.String getData() {
+      java.lang.Object ref = data_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        data_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string data = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getDataBytes() {
+      java.lang.Object ref = data_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        data_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getQueryBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, query_);
+      }
+      if (!getDataBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, data_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getQueryBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, query_);
+      }
+      if (!getDataBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, data_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof quickstep.NetworkCliOuterClass.QueryRequest)) {
+        return super.equals(obj);
+      }
+      quickstep.NetworkCliOuterClass.QueryRequest other = (quickstep.NetworkCliOuterClass.QueryRequest) obj;
+
+      boolean result = true;
+      result = result && getQuery()
+          .equals(other.getQuery());
+      result = result && getData()
+          .equals(other.getData());
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + QUERY_FIELD_NUMBER;
+      hash = (53 * hash) + getQuery().hashCode();
+      hash = (37 * hash) + DATA_FIELD_NUMBER;
+      hash = (53 * hash) + getData().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(quickstep.NetworkCliOuterClass.QueryRequest prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code quickstep.QueryRequest}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:quickstep.QueryRequest)
+        quickstep.NetworkCliOuterClass.QueryRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                quickstep.NetworkCliOuterClass.QueryRequest.class, quickstep.NetworkCliOuterClass.QueryRequest.Builder.class);
+      }
+
+      // Construct using quickstep.NetworkCliOuterClass.QueryRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        query_ = "";
+
+        data_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_descriptor;
+      }
+
+      public quickstep.NetworkCliOuterClass.QueryRequest getDefaultInstanceForType() {
+        return quickstep.NetworkCliOuterClass.QueryRequest.getDefaultInstance();
+      }
+
+      public quickstep.NetworkCliOuterClass.QueryRequest build() {
+        quickstep.NetworkCliOuterClass.QueryRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public quickstep.NetworkCliOuterClass.QueryRequest buildPartial() {
+        quickstep.NetworkCliOuterClass.QueryRequest result = new quickstep.NetworkCliOuterClass.QueryRequest(this);
+        result.query_ = query_;
+        result.data_ = data_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof quickstep.NetworkCliOuterClass.QueryRequest) {
+          return mergeFrom((quickstep.NetworkCliOuterClass.QueryRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(quickstep.NetworkCliOuterClass.QueryRequest other) {
+        if (other == quickstep.NetworkCliOuterClass.QueryRequest.getDefaultInstance()) return this;
+        if (!other.getQuery().isEmpty()) {
+          query_ = other.query_;
+          onChanged();
+        }
+        if (!other.getData().isEmpty()) {
+          data_ = other.data_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        quickstep.NetworkCliOuterClass.QueryRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (quickstep.NetworkCliOuterClass.QueryRequest) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object query_ = "";
+      /**
+       * <code>string query = 1;</code>
+       */
+      public java.lang.String getQuery() {
+        java.lang.Object ref = query_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          query_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string query = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getQueryBytes() {
+        java.lang.Object ref = query_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          query_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string query = 1;</code>
+       */
+      public Builder setQuery(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        query_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string query = 1;</code>
+       */
+      public Builder clearQuery() {
+        
+        query_ = getDefaultInstance().getQuery();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string query = 1;</code>
+       */
+      public Builder setQueryBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        query_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object data_ = "";
+      /**
+       * <code>string data = 2;</code>
+       */
+      public java.lang.String getData() {
+        java.lang.Object ref = data_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          data_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string data = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getDataBytes() {
+        java.lang.Object ref = data_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          data_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string data = 2;</code>
+       */
+      public Builder setData(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        data_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string data = 2;</code>
+       */
+      public Builder clearData() {
+        
+        data_ = getDefaultInstance().getData();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string data = 2;</code>
+       */
+      public Builder setDataBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        data_ = value;
+        onChanged();
+        return this;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:quickstep.QueryRequest)
+    }
+
+    // @@protoc_insertion_point(class_scope:quickstep.QueryRequest)
+    private static final quickstep.NetworkCliOuterClass.QueryRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new quickstep.NetworkCliOuterClass.QueryRequest();
+    }
+
+    public static quickstep.NetworkCliOuterClass.QueryRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<QueryRequest>
+        PARSER = new com.google.protobuf.AbstractParser<QueryRequest>() {
+      public QueryRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new QueryRequest(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<QueryRequest> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<QueryRequest> getParserForType() {
+      return PARSER;
+    }
+
+    public quickstep.NetworkCliOuterClass.QueryRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface QueryResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:quickstep.QueryResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>string query_result = 1;</code>
+     */
+    java.lang.String getQueryResult();
+    /**
+     * <code>string query_result = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getQueryResultBytes();
+
+    /**
+     * <code>string error_result = 2;</code>
+     */
+    java.lang.String getErrorResult();
+    /**
+     * <code>string error_result = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getErrorResultBytes();
+  }
+  /**
+   * Protobuf type {@code quickstep.QueryResponse}
+   */
+  public  static final class QueryResponse extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:quickstep.QueryResponse)
+      QueryResponseOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use QueryResponse.newBuilder() to construct.
+    private QueryResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private QueryResponse() {
+      queryResult_ = "";
+      errorResult_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private QueryResponse(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              queryResult_ = s;
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              errorResult_ = s;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              quickstep.NetworkCliOuterClass.QueryResponse.class, quickstep.NetworkCliOuterClass.QueryResponse.Builder.class);
+    }
+
+    public static final int QUERY_RESULT_FIELD_NUMBER = 1;
+    private volatile java.lang.Object queryResult_;
+    /**
+     * <code>string query_result = 1;</code>
+     */
+    public java.lang.String getQueryResult() {
+      java.lang.Object ref = queryResult_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        queryResult_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string query_result = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getQueryResultBytes() {
+      java.lang.Object ref = queryResult_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        queryResult_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int ERROR_RESULT_FIELD_NUMBER = 2;
+    private volatile java.lang.Object errorResult_;
+    /**
+     * <code>string error_result = 2;</code>
+     */
+    public java.lang.String getErrorResult() {
+      java.lang.Object ref = errorResult_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        errorResult_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string error_result = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getErrorResultBytes() {
+      java.lang.Object ref = errorResult_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        errorResult_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getQueryResultBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, queryResult_);
+      }
+      if (!getErrorResultBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, errorResult_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getQueryResultBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, queryResult_);
+      }
+      if (!getErrorResultBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, errorResult_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof quickstep.NetworkCliOuterClass.QueryResponse)) {
+        return super.equals(obj);
+      }
+      quickstep.NetworkCliOuterClass.QueryResponse other = (quickstep.NetworkCliOuterClass.QueryResponse) obj;
+
+      boolean result = true;
+      result = result && getQueryResult()
+          .equals(other.getQueryResult());
+      result = result && getErrorResult()
+          .equals(other.getErrorResult());
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + QUERY_RESULT_FIELD_NUMBER;
+      hash = (53 * hash) + getQueryResult().hashCode();
+      hash = (37 * hash) + ERROR_RESULT_FIELD_NUMBER;
+      hash = (53 * hash) + getErrorResult().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(quickstep.NetworkCliOuterClass.QueryResponse prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code quickstep.QueryResponse}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:quickstep.QueryResponse)
+        quickstep.NetworkCliOuterClass.QueryResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                quickstep.NetworkCliOuterClass.QueryResponse.class, quickstep.NetworkCliOuterClass.QueryResponse.Builder.class);
+      }
+
+      // Construct using quickstep.NetworkCliOuterClass.QueryResponse.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        queryResult_ = "";
+
+        errorResult_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_descriptor;
+      }
+
+      public quickstep.NetworkCliOuterClass.QueryResponse getDefaultInstanceForType() {
+        return quickstep.NetworkCliOuterClass.QueryResponse.getDefaultInstance();
+      }
+
+      public quickstep.NetworkCliOuterClass.QueryResponse build() {
+        quickstep.NetworkCliOuterClass.QueryResponse result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public quickstep.NetworkCliOuterClass.QueryResponse buildPartial() {
+        quickstep.NetworkCliOuterClass.QueryResponse result = new quickstep.NetworkCliOuterClass.QueryResponse(this);
+        result.queryResult_ = queryResult_;
+        result.errorResult_ = errorResult_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof quickstep.NetworkCliOuterClass.QueryResponse) {
+          return mergeFrom((quickstep.NetworkCliOuterClass.QueryResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(quickstep.NetworkCliOuterClass.QueryResponse other) {
+        if (other == quickstep.NetworkCliOuterClass.QueryResponse.getDefaultInstance()) return this;
+        if (!other.getQueryResult().isEmpty()) {
+          queryResult_ = other.queryResult_;
+          onChanged();
+        }
+        if (!other.getErrorResult().isEmpty()) {
+          errorResult_ = other.errorResult_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        quickstep.NetworkCliOuterClass.QueryResponse parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (quickstep.NetworkCliOuterClass.QueryResponse) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object queryResult_ = "";
+      /**
+       * <code>string query_result = 1;</code>
+       */
+      public java.lang.String getQueryResult() {
+        java.lang.Object ref = queryResult_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          queryResult_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string query_result = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getQueryResultBytes() {
+        java.lang.Object ref = queryResult_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          queryResult_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string query_result = 1;</code>
+       */
+      public Builder setQueryResult(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        queryResult_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string query_result = 1;</code>
+       */
+      public Builder clearQueryResult() {
+        
+        queryResult_ = getDefaultInstance().getQueryResult();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string query_result = 1;</code>
+       */
+      public Builder setQueryResultBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        queryResult_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object errorResult_ = "";
+      /**
+       * <code>string error_result = 2;</code>
+       */
+      public java.lang.String getErrorResult() {
+        java.lang.Object ref = errorResult_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          errorResult_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string error_result = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getErrorResultBytes() {
+        java.lang.Object ref = errorResult_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          errorResult_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string error_result = 2;</code>
+       */
+      public Builder setErrorResult(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        errorResult_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string error_result = 2;</code>
+       */
+      public Builder clearErrorResult() {
+        
+        errorResult_ = getDefaultInstance().getErrorResult();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string error_result = 2;</code>
+       */
+      public Builder setErrorResultBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        errorResult_ = value;
+        onChanged();
+        return this;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:quickstep.QueryResponse)
+    }
+
+    // @@protoc_insertion_point(class_scope:quickstep.QueryResponse)
+    private static final quickstep.NetworkCliOuterClass.QueryResponse DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new quickstep.NetworkCliOuterClass.QueryResponse();
+    }
+
+    public static quickstep.NetworkCliOuterClass.QueryResponse getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<QueryResponse>
+        PARSER = new com.google.protobuf.AbstractParser<QueryResponse>() {
+      public QueryResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new QueryResponse(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<QueryResponse> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<QueryResponse> getParserForType() {
+      return PARSER;
+    }
+
+    public quickstep.NetworkCliOuterClass.QueryResponse getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_quickstep_QueryRequest_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_quickstep_QueryRequest_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_quickstep_QueryResponse_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_quickstep_QueryResponse_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020NetworkCli.proto\022\tquickstep\"+\n\014QueryRe" +
+      "quest\022\r\n\005query\030\001 \001(\t\022\014\n\004data\030\002 \001(\t\";\n\rQu" +
+      "eryResponse\022\024\n\014query_result\030\001 \001(\t\022\024\n\014err" +
+      "or_result\030\002 \001(\t2N\n\nNetworkCli\022@\n\tSendQue" +
+      "ry\022\027.quickstep.QueryRequest\032\030.quickstep." +
+      "QueryResponse\"\000b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+    internal_static_quickstep_QueryRequest_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_quickstep_QueryRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_quickstep_QueryRequest_descriptor,
+        new java.lang.String[] { "Query", "Data", });
+    internal_static_quickstep_QueryResponse_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_quickstep_QueryResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_quickstep_QueryResponse_descriptor,
+        new java.lang.String[] { "QueryResult", "ErrorResult", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/cli/tests/NetworkIO_unittest.cpp
----------------------------------------------------------------------
diff --git a/cli/tests/NetworkIO_unittest.cpp b/cli/tests/NetworkIO_unittest.cpp
index 9dbd63e..9c4bfc4 100644
--- a/cli/tests/NetworkIO_unittest.cpp
+++ b/cli/tests/NetworkIO_unittest.cpp
@@ -68,7 +68,7 @@ class TestNetworkIO {
     CHECK(current_request_ == nullptr);
     current_request_ = service_.waitForRequest();
     EXPECT_EQ(current_request_->getCanceled(), false);
-    return current_request_->getRequest();
+    return current_request_->getRequest().query();
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/expressions/aggregation/AggregateFunctionMax.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionMax.cpp b/expressions/aggregation/AggregateFunctionMax.cpp
index cc04bf4..6ceacc9 100644
--- a/expressions/aggregation/AggregateFunctionMax.cpp
+++ b/expressions/aggregation/AggregateFunctionMax.cpp
@@ -50,7 +50,9 @@ const Type* AggregateFunctionMax::resultTypeForArgumentTypes(
     return nullptr;
   }
 
-  return &(argument_types.front()->getNullableVersion());
+  // FIXME(jianqiao): The result type can be nullable when it is NOT a group-by
+  // aggregation.
+  return argument_types.front();
 }
 
 AggregationHandle* AggregateFunctionMax::createHandle(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/expressions/aggregation/AggregateFunctionMin.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionMin.cpp b/expressions/aggregation/AggregateFunctionMin.cpp
index 9fa93de..d88169f 100644
--- a/expressions/aggregation/AggregateFunctionMin.cpp
+++ b/expressions/aggregation/AggregateFunctionMin.cpp
@@ -50,7 +50,9 @@ const Type* AggregateFunctionMin::resultTypeForArgumentTypes(
     return nullptr;
   }
 
-  return &(argument_types.front()->getNullableVersion());
+  // FIXME(jianqiao): The result type can be nullable when it is NOT a group-by
+  // aggregation.
+  return argument_types.front();
 }
 
 AggregationHandle* AggregateFunctionMin::createHandle(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index d818d0b..d6b57bf 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -270,6 +270,7 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "sma"              return TOKEN_SMA;
   "smallint"         return TOKEN_SMALLINT;
   "stderr"           return TOKEN_STDERR;
+  "stdin"            return TOKEN_STDIN;
   "stdout"           return TOKEN_STDOUT;
   "substring"        return TOKEN_SUBSTRING;
   "table"            return TOKEN_TABLE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/aec7623a/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index ba69b3d..1a12512 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -341,6 +341,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_SMA;
 %token TOKEN_SMALLINT;
 %token TOKEN_STDERR;
+%token TOKEN_STDIN;
 %token TOKEN_STDOUT;
 %token TOKEN_SUBSTRING;
 %token TOKEN_TABLE;
@@ -371,6 +372,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
   datetime_unit
   index_type
   partition_type
+  copy_from_target
   copy_to_target
 
 %type <boolean_value_>
@@ -1117,10 +1119,10 @@ insert_statement:
   ;
 
 copy_statement:
-  TOKEN_COPY any_name TOKEN_FROM TOKEN_STRING_SINGLE_QUOTED opt_copy_params {
+  TOKEN_COPY any_name copy_from_target opt_copy_params {
     $$ = new quickstep::ParseStatementCopy(@1.first_line, @1.first_column,
                                            quickstep::ParseStatementCopy::kFrom,
-                                           $2, $4, $5);
+                                           $2, $3, $4);
   }
   | TOKEN_COPY any_name copy_to_target opt_copy_params {
     $$ = new quickstep::ParseStatementCopy(@1.first_line, @1.first_column,
@@ -1136,6 +1138,15 @@ copy_statement:
                                            $3, $1, $4, $5);
   };
 
+copy_from_target:
+  TOKEN_FROM TOKEN_STRING_SINGLE_QUOTED {
+    $$ = new quickstep::ParseString($2->line_number(), $2->column_number(), "@" + $2->value());
+    delete $2;
+  }
+  | TOKEN_FROM TOKEN_STDIN {
+    $$ = new quickstep::ParseString(@2.first_line, @2.first_column, "$stdin");
+  };
+
 copy_to_target:
   TOKEN_TO TOKEN_STRING_SINGLE_QUOTED {
     $$ = new quickstep::ParseString($2->line_number(), $2->column_number(), "@" + $2->value());


Mime
View raw message