You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/09/01 17:07:29 UTC

incubator-quickstep git commit: Python API example

Repository: incubator-quickstep
Updated Branches:
  refs/heads/python-api-example [created] 78c3541f6


Python API example


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

Branch: refs/heads/python-api-example
Commit: 78c3541f691334648b5f8e90c740e6f77907a969
Parents: 2981651
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Fri Sep 1 12:07:13 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Fri Sep 1 12:07:13 2017 -0500

----------------------------------------------------------------------
 api/python/ancestor.txt                       |  16 ++
 api/python/example.py                         |  11 ++
 api/python/quickstep.py                       |  25 +++
 api/python/quickstep.pyc                      | Bin 0 -> 1514 bytes
 cli/Flags.cpp                                 |   2 +
 cli/Flags.hpp                                 |   2 +
 cli/IOInterface.hpp                           |  11 +-
 cli/NetworkCliClientMain.cpp                  |   1 -
 cli/QuickstepCli.cpp                          |  16 +-
 utility/CMakeLists.txt                        |  11 ++
 utility/ScopedReassignment.hpp                |  81 +++++++++
 utility/tests/ScopedReassignment_unittest.cpp | 184 +++++++++++++++++++++
 12 files changed, 351 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/api/python/ancestor.txt
----------------------------------------------------------------------
diff --git a/api/python/ancestor.txt b/api/python/ancestor.txt
new file mode 100644
index 0000000..8d15955
--- /dev/null
+++ b/api/python/ancestor.txt
@@ -0,0 +1,16 @@
+CREATE TABLE r(parent VARCHAR(64), child VARCHAR(64));
+
+INSERT INTO r VALUES('bill', 'mary');
+INSERT INTO r VALUES('mary', 'john');
+...
+...
+...
+
+
+CREATE TABLE s(ancestor VARCHAR(64), offspring VARCHAR(64));
+
+=> ancestor
+
+ancestor('biil', 'mary')
+ancestor('mary', 'john')
+ancestor('bill', 'john')

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/api/python/example.py
----------------------------------------------------------------------
diff --git a/api/python/example.py b/api/python/example.py
new file mode 100644
index 0000000..a9be4fd
--- /dev/null
+++ b/api/python/example.py
@@ -0,0 +1,11 @@
+from quickstep import Quickstep
+
+qs = Quickstep('/Users/jianqiao/Desktop/incubator-quickstep/build/Debug/quickstep_client')
+
+print 'Executing "SELECT * FROM r" ...'
+print '--'
+print qs.execute('SELECT * FROM r')
+
+print 'Executing "COPY SELECT * FROM r TO stdout WITH (FORMAT CSV, HEADER FALSE)" ...'
+print '--'
+print qs.execute('COPY SELECT * FROM r TO stdout WITH (FORMAT CSV, HEADER FALSE)')

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/api/python/quickstep.py
----------------------------------------------------------------------
diff --git a/api/python/quickstep.py b/api/python/quickstep.py
new file mode 100644
index 0000000..720efd8
--- /dev/null
+++ b/api/python/quickstep.py
@@ -0,0 +1,25 @@
+from subprocess import Popen, PIPE, STDOUT
+
+class Quickstep(object):
+  def __init__(self, client_path, server_ip = None, server_port = None):
+    self.client_path = client_path
+    self.server_ip = server_ip
+    self.server_port = server_port
+
+  def __addSemicolon__(self, query):
+    return query + ('' if query.endswith(';') else ';')
+
+  def execute(self, query):
+    query = self.__addSemicolon__(query)
+
+    cmd = self.client_path
+    if self.server_ip is not None:
+      cmd += ' -cli_network_ip=' + self.server_ip
+    if self.server_port is not None:
+      cmd += ' -cli_network_port=' + self.server_port
+
+    client_process = Popen([cmd], stdout=PIPE, stdin=PIPE, stderr=PIPE)
+    out, err = client_process.communicate(input = query)
+
+    # Currently we ignore the stderr stream and just return stdout's data.
+    return out

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/api/python/quickstep.pyc
----------------------------------------------------------------------
diff --git a/api/python/quickstep.pyc b/api/python/quickstep.pyc
new file mode 100644
index 0000000..665f555
Binary files /dev/null and b/api/python/quickstep.pyc differ

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/cli/Flags.cpp
----------------------------------------------------------------------
diff --git a/cli/Flags.cpp b/cli/Flags.cpp
index 362eac3..78e72aa 100644
--- a/cli/Flags.cpp
+++ b/cli/Flags.cpp
@@ -36,6 +36,8 @@ DEFINE_bool(print_query, false,
             "Print each input query statement. This is useful when running a "
             "large number of queries in a batch.");
 
+DEFINE_bool(timing, true, "Whether to show execution time of each statement.");
+
 DEFINE_bool(initialize_db, false, "If true, initialize a database.");
 
 static bool ValidateNumWorkers(const char *flagname, int value) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/cli/Flags.hpp
----------------------------------------------------------------------
diff --git a/cli/Flags.hpp b/cli/Flags.hpp
index 1ae37c4..4d3fd75 100644
--- a/cli/Flags.hpp
+++ b/cli/Flags.hpp
@@ -45,6 +45,8 @@ DECLARE_string(storage_path);
 
 DECLARE_bool(preload_buffer_pool);
 
+DECLARE_bool(timing);
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/cli/IOInterface.hpp
----------------------------------------------------------------------
diff --git a/cli/IOInterface.hpp b/cli/IOInterface.hpp
index 815596e..dc0d5b2 100644
--- a/cli/IOInterface.hpp
+++ b/cli/IOInterface.hpp
@@ -28,7 +28,7 @@
 namespace quickstep {
 
 /**
- * An individual IO interaction with Quickstep.
+ * @brief An individual IO interaction with Quickstep.
  */
 class IOHandle {
  public:
@@ -56,18 +56,21 @@ class IOHandle {
 };
 
 /**
- * Virtual base defines a generic, file-based interface around IO. One IO interaction (eg a SQL query) will be assigned
- * an IOHandle. On destruction of the IOHandle, the IO interaction has finished.
+ * @brief Virtual base defines a generic, file-based interface around IO.
+ *        One IO interaction (eg a SQL query) will be assigned an IOHandle.
+ *        On destruction of the IOHandle, the IO interaction has finished.
  */
 class IOInterface {
  public:
   /**
-   * @note Destructing the IOInterface should close any outstanding IO state (eg an open port).
+   * @note Destructing the IOInterface should close any outstanding IO state
+   *       (e.g. an open port).
    */
   virtual ~IOInterface() {}
 
   /**
    * @brief Retrieves the next IOHandle. Blocks if no IO ready.
+   *
    * @return An IOHandle.
    */
   virtual IOHandle* getNextIOHandle() = 0;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/cli/NetworkCliClientMain.cpp
----------------------------------------------------------------------
diff --git a/cli/NetworkCliClientMain.cpp b/cli/NetworkCliClientMain.cpp
index 862941c..c55819b 100644
--- a/cli/NetworkCliClientMain.cpp
+++ b/cli/NetworkCliClientMain.cpp
@@ -53,7 +53,6 @@ int main(int argc, char **argv) {
   while (!linereader.bufferEmpty()) {
     std::string query = linereader.getNextCommand();
     if (!query.empty()) {
-      std::cout << query << std::endl;
       std::cout << qs_client.Query(query) << std::endl;
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/cli/QuickstepCli.cpp
----------------------------------------------------------------------
diff --git a/cli/QuickstepCli.cpp b/cli/QuickstepCli.cpp
index c55bdd7..51a2ca1 100644
--- a/cli/QuickstepCli.cpp
+++ b/cli/QuickstepCli.cpp
@@ -69,6 +69,7 @@
 #include "utility/ExecutionDAGVisualizer.hpp"
 #include "utility/Macros.hpp"
 #include "utility/PtrVector.hpp"
+#include "utility/ScopedReassignment.hpp"
 #include "utility/SqlError.hpp"
 #include "utility/StringUtil.hpp"
 
@@ -105,6 +106,7 @@ using quickstep::PtrVector;
 using quickstep::QueryExecutionUtil;
 using quickstep::QueryHandle;
 using quickstep::QueryProcessor;
+using quickstep::ScopedReassignment;
 using quickstep::SqlParserWrapper;
 using quickstep::Worker;
 using quickstep::WorkerDirectory;
@@ -150,6 +152,7 @@ DEFINE_string(mode, "local",
               "same manner as with the local cli.");
 
 DECLARE_bool(profile_and_report_workorder_perf);
+DECLARE_bool(timing);
 DECLARE_bool(visualize_execution_dag);
 
 }  // namespace quickstep
@@ -303,6 +306,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_stdout(stdout, io_handle->out());
+    ScopedReassignment<FILE*> reassign_stderr(stderr, io_handle->err());
+
     *command_string = io_handle->getCommand();
     LOG(INFO) << "Command received: " << *command_string;
     if (command_string->size() == 0) {
@@ -397,10 +403,12 @@ int main(int argc, char* argv[]) {
           }
 
           query_processor->saveCatalog();
-          std::chrono::duration<double, std::milli> time_ms = end - start;
-          fprintf(io_handle->out(), "Time: %s ms\n",
-                 quickstep::DoubleToStringWithSignificantDigits(
-                     time_ms.count(), 3).c_str());
+          if (quickstep::FLAGS_timing) {
+            std::chrono::duration<double, std::milli> time_ms = end - start;
+            fprintf(io_handle->out(), "Time: %s ms\n",
+                   quickstep::DoubleToStringWithSignificantDigits(
+                       time_ms.count(), 3).c_str());
+          }
           if (quickstep::FLAGS_profile_and_report_workorder_perf) {
             // TODO(harshad) - Allow user specified file instead of stdout.
             foreman.printWorkOrderProfilingResults(query_id, stdout);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt
index a832404..49cafad 100644
--- a/utility/CMakeLists.txt
+++ b/utility/CMakeLists.txt
@@ -196,6 +196,7 @@ add_library(quickstep_utility_PtrMap ../empty_src.cpp PtrMap.hpp)
 add_library(quickstep_utility_PtrVector ../empty_src.cpp PtrVector.hpp)
 add_library(quickstep_utility_ScopedBuffer ../empty_src.cpp ScopedBuffer.hpp)
 add_library(quickstep_utility_ScopedDeleter ../empty_src.cpp ScopedDeleter.hpp)
+add_library(quickstep_utility_ScopedReassignment ../empty_src.cpp ScopedReassignment.hpp)
 add_library(quickstep_utility_ShardedLockManager ../empty_src.cpp ShardedLockManager.hpp)
 add_library(quickstep_utility_SortConfiguration SortConfiguration.cpp SortConfiguration.hpp)
 add_library(quickstep_utility_SortConfiguration_proto
@@ -313,6 +314,8 @@ target_link_libraries(quickstep_utility_ScopedBuffer
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_utility_ScopedDeleter
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_utility_ScopedReassignment
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_utility_SqlError
                       glog)
 target_link_libraries(quickstep_utility_SortConfiguration
@@ -462,6 +465,14 @@ target_link_libraries(ScopedDeleter_unittest
                       ${LIBS})
 add_test(ScopedDeleter_unittest ScopedDeleter_unittest)
 
+add_executable(ScopedReassignment_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/ScopedReassignment_unittest.cpp")
+target_link_libraries(ScopedReassignment_unittest
+                      gtest
+                      gtest_main
+                      quickstep_utility_ScopedReassignment
+                      ${LIBS})
+add_test(ScopedReassignment_unittest ScopedReassignment_unittest)
+
 add_executable(SqlError_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/SqlError_unittest.cpp")
 target_link_libraries(SqlError_unittest
                       glog

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/utility/ScopedReassignment.hpp
----------------------------------------------------------------------
diff --git a/utility/ScopedReassignment.hpp b/utility/ScopedReassignment.hpp
new file mode 100644
index 0000000..ff308b3
--- /dev/null
+++ b/utility/ScopedReassignment.hpp
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_SCOPED_REASSIGNMENT_HPP_
+#define QUICKSTEP_UTILITY_SCOPED_REASSIGNMENT_HPP_
+
+#include <utility>
+#include <type_traits>
+
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+/**
+ * @brief RAII helper object that assigns a new value to a variable and restores
+ *        the old value when it goes out of scope.
+ **/
+template <typename T>
+class ScopedReassignment {
+ public:
+  /**
+   * @brief Constructor.
+   *
+   * @param var The variable.
+   * @param new_value The new value to be assigned to \p var.
+   **/
+  template <typename U>
+  ScopedReassignment(T &var, U &&new_value)
+      : var_(var),
+        old_value_(std::move(var)) {
+    var = std::forward<U>(new_value);
+  }
+
+  /**
+   * @brief Destructor. Restores the old value to \p var_.
+   **/
+  ~ScopedReassignment() {
+    var_ = std::move(old_value_);
+  }
+
+  /**
+   * @brief Get the old value.
+   *
+   * @return A const reference to the old value.
+   */
+  inline const T& old_value() const {
+    return old_value_;
+  }
+
+ private:
+  T &var_;
+  T old_value_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedReassignment);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_SCOPED_REASSIGNMENT_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/78c3541f/utility/tests/ScopedReassignment_unittest.cpp
----------------------------------------------------------------------
diff --git a/utility/tests/ScopedReassignment_unittest.cpp b/utility/tests/ScopedReassignment_unittest.cpp
new file mode 100644
index 0000000..3a08e6f
--- /dev/null
+++ b/utility/tests/ScopedReassignment_unittest.cpp
@@ -0,0 +1,184 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "utility/ScopedReassignment.hpp"
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "utility/Macros.hpp"
+
+#include "gtest/gtest.h"
+
+namespace quickstep {
+
+/**
+ * @brief A test class that is movable but not copyable.
+ */
+class NonCopyable {
+ public:
+  explicit NonCopyable(const int value)
+      : value_(value) {}
+
+  explicit NonCopyable(NonCopyable &&other)
+      : value_(other.value_) {}
+
+  NonCopyable& operator=(NonCopyable &&other) {
+    value_ = other.value_;
+    return *this;
+  }
+
+  int value() const {
+    return value_;
+  }
+
+ private:
+  int value_;
+
+  DISALLOW_COPY_AND_ASSIGN(NonCopyable);
+};
+
+/**
+ * @brief A test class that is copyable but not movable.
+ */
+class NonMovable {
+ public:
+  explicit NonMovable(const int value)
+      : value_(value) {}
+
+  explicit NonMovable(const NonMovable &other)
+      : value_(other.value_) {}
+
+  NonMovable& operator=(const NonMovable &other) {
+    value_ = other.value_;
+    return *this;
+  }
+
+  int value() const {
+    return value_;
+  }
+
+ private:
+  int value_;
+};
+
+/**
+ * @brief A test class that is copyable and movable.
+ */
+class CopyableMovable {
+ public:
+  explicit CopyableMovable(const int value)
+      : value_(value) {}
+
+  explicit CopyableMovable(const CopyableMovable &other)
+      : value_(other.value_),
+        copy_constructed_(true) {}
+
+  explicit CopyableMovable(CopyableMovable &&other)
+      : value_(other.value_) {}
+
+  CopyableMovable& operator=(const CopyableMovable &other) {
+    value_ = other.value_;
+    copy_assigned_ = true;
+    return *this;
+  }
+
+  CopyableMovable& operator=(CopyableMovable &&other) {
+    value_ = other.value_;
+    copy_assigned_ = false;
+    return *this;
+  }
+
+  int value() const {
+    return value_;
+  }
+
+  bool copy_constructed() const {
+    return copy_constructed_;
+  }
+
+  bool copy_assigned() const {
+    return copy_assigned_;
+  }
+
+ private:
+  int value_;
+  bool copy_constructed_ = false;
+  bool copy_assigned_ = false;
+};
+
+TEST(ScopedReassignment, NonCopyableTest) {
+  NonCopyable var_a(10);
+  NonCopyable other(20);
+  {
+    ScopedReassignment<NonCopyable> reassign(var_a, std::move(other));
+    EXPECT_EQ(20, var_a.value());
+  }
+  EXPECT_EQ(10, var_a.value());
+
+  NonCopyable var_b(30);
+  {
+    ScopedReassignment<NonCopyable> reassign(var_b, NonCopyable(40));
+    EXPECT_EQ(40, var_b.value());
+  }
+  EXPECT_EQ(30, var_b.value());
+}
+
+TEST(ScopedReassignment, NonMovableTest) {
+  NonMovable var_a(10);
+  NonMovable other(20);
+  {
+    ScopedReassignment<NonMovable> reassign(var_a, other);
+    EXPECT_EQ(20, var_a.value());
+  }
+  EXPECT_EQ(10, var_a.value());
+
+  NonMovable var_b(30);
+  {
+    ScopedReassignment<NonMovable> reassign(var_b, NonMovable(40));
+    EXPECT_EQ(40, var_b.value());
+  }
+  EXPECT_EQ(30, var_b.value());
+}
+
+TEST(ScopedReassignment, CopyableMovableTest) {
+  CopyableMovable var_a(10);
+  CopyableMovable other(20);
+  {
+    ScopedReassignment<CopyableMovable> reassign(var_a, other);
+    EXPECT_EQ(20, var_a.value());
+    EXPECT_FALSE(reassign.old_value().copy_constructed());
+    EXPECT_TRUE(var_a.copy_assigned());
+  }
+  EXPECT_EQ(10, var_a.value());
+  EXPECT_FALSE(var_a.copy_assigned());
+
+  CopyableMovable var_b(30);
+  {
+    ScopedReassignment<CopyableMovable> reassign(var_b, std::move(other));
+    EXPECT_EQ(20, var_b.value());
+    EXPECT_FALSE(reassign.old_value().copy_constructed());
+    EXPECT_FALSE(var_b.copy_assigned());
+  }
+  EXPECT_EQ(30, var_b.value());
+  EXPECT_FALSE(var_b.copy_assigned());
+}
+
+}  // namespace quickstep