drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From par...@apache.org
Subject [10/15] drill git commit: DRILL-4420: C++ API for metadata access and prepared statements
Date Tue, 01 Nov 2016 20:29:55 GMT
http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/include/drill/drillClient.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/drillClient.hpp b/contrib/native/client/src/include/drill/drillClient.hpp
index a74f4bd..5e59885 100644
--- a/contrib/native/client/src/include/drill/drillClient.hpp
+++ b/contrib/native/client/src/include/drill/drillClient.hpp
@@ -23,27 +23,9 @@
 #include <vector>
 #include <boost/thread.hpp>
 #include "drill/common.hpp"
+#include "drill/collections.hpp"
 #include "drill/protobuf/Types.pb.h"
 
-
-#if defined _WIN32 || defined __CYGWIN__
-  #ifdef DRILL_CLIENT_EXPORTS
-      #define DECLSPEC_DRILL_CLIENT __declspec(dllexport)
-  #else
-    #ifdef USE_STATIC_LIBDRILL
-      #define DECLSPEC_DRILL_CLIENT
-    #else
-      #define DECLSPEC_DRILL_CLIENT  __declspec(dllimport)
-    #endif
-  #endif
-#else
-  #if __GNUC__ >= 4
-    #define DECLSPEC_DRILL_CLIENT __attribute__ ((visibility ("default")))
-  #else
-    #define DECLSPEC_DRILL_CLIENT
-  #endif
-#endif
-
 namespace exec{
     namespace shared{
         class DrillPBError;
@@ -57,6 +39,7 @@ class  DrillClientImplBase;
 class  DrillClientImpl;
 class  DrillClientQueryResult;
 class  FieldMetadata;
+class  PreparedStatement;
 class  RecordBatch;
 class  SchemaDef;
 
@@ -188,6 +171,17 @@ typedef status_t (*pfnQueryResultsListener)(QueryHandle_t ctx, RecordBatch* b, D
  */
 typedef status_t (*pfnSchemaListener)(void* ctx, FieldDefPtr f, DrillClientError* err);
 
+/**
+ * The prepared statement creation listener
+ *
+ * This function is called when a prepared statement is created, or if an error occurs during the prepared statement creation.
+ * This callback is only invoked once. 
+ * @param[in] ctx the listener context provided to getColumns
+ * @param[in] pstmt the prepared statement handle, NULL in case of error
+ * @param[in] err an error object, NULL in case of success
+ */
+typedef status_t (*pfnPreparedStatementListener)(void* ctx, PreparedStatement* pstmt, DrillClientError* err);
+
 /*
  * A Record Iterator instance is returned by the SubmitQuery class. Calls block until some data
  * is available, or until all data has been returned.
@@ -244,6 +238,938 @@ class DECLSPEC_DRILL_CLIENT RecordIterator{
     // first record batch with this definition
 };
 
+namespace meta {
+  // Set of template functions to create bitmasks
+  template<typename T>
+  inline T
+  operator&(T __a, T __b)
+  { return T(static_cast<int>(__a) & static_cast<int>(__b)); }
+  template<typename T>
+  inline T
+  operator|(T __a, T __b)
+  { return T(static_cast<int>(__a) | static_cast<int>(__b)); }
+  template<typename T>
+  inline T
+  operator^(T __a, T __b)
+  { return T(static_cast<int>(__a) ^ static_cast<int>(__b)); }
+  template<typename T>
+  inline T&
+  operator|=(T& __a, T __b)
+  { return __a = __a | __b; }
+  template<typename T>
+  inline T&
+  operator&=(T& __a, T __b)
+  { return __a = __a & __b; }
+  template<typename T>
+  inline T&
+  operator^=(T& __a, T __b)
+  { return __a = __a ^ __b; }
+  template<typename T>
+  inline T
+  operator~(T __a)
+  { return T(~static_cast<int>(__a)); }
+
+  /*
+   * Internal type for Date/Time literals support
+   */
+  enum _DateTimeLiteralSupport {
+    _DL_NONE                      = 0,
+    _DL_DATE                      = 1 << 1L,
+    _DL_TIME                      = 1 << 2L,
+    _DL_TIMESTAMP                 = 1 << 3L,
+    _DL_INTERVAL_YEAR             = 1 << 4L,
+    _DL_INTERVAL_MONTH            = 1 << 5L,
+    _DL_INTERVAL_DAY              = 1 << 6L,
+    _DL_INTERVAL_HOUR             = 1 << 7L,
+    _DL_INTERVAL_MINUTE           = 1 << 8L,
+    _DL_INTERVAL_SECOND           = 1 << 9L,
+    _DL_INTERVAL_YEAR_TO_MONTH    = 1 << 10L,
+    _DL_INTERVAL_DAY_TO_HOUR      = 1 << 11L,
+    _DL_INTERVAL_DAY_TO_MINUTE    = 1 << 12L,
+    _DL_INTERVAL_DAY_TO_SECOND    = 1 << 13L,
+    _DL_INTERVAL_HOUR_TO_MINUTE   = 1 << 14L,
+    _DL_INTERVAL_HOUR_TO_SECOND   = 1 << 15L,
+    _DL_INTERVAL_MINUTE_TO_SECOND = 1 << 16L
+  };
+
+  template inline _DateTimeLiteralSupport operator&(_DateTimeLiteralSupport __a, _DateTimeLiteralSupport __b);
+  template inline _DateTimeLiteralSupport operator|(_DateTimeLiteralSupport __a, _DateTimeLiteralSupport __b);
+  template inline _DateTimeLiteralSupport operator^(_DateTimeLiteralSupport __a, _DateTimeLiteralSupport __b);
+
+  template inline _DateTimeLiteralSupport& operator&=(_DateTimeLiteralSupport& __a, _DateTimeLiteralSupport __b);
+  template inline _DateTimeLiteralSupport& operator|=(_DateTimeLiteralSupport& __a, _DateTimeLiteralSupport __b);
+  template inline _DateTimeLiteralSupport& operator^=(_DateTimeLiteralSupport& __a, _DateTimeLiteralSupport __b);
+
+  template inline _DateTimeLiteralSupport operator~(_DateTimeLiteralSupport __a);
+
+  /**
+   * Date time literal support flags
+   */
+  typedef _DateTimeLiteralSupport DateTimeLiteralSupport;
+
+  /** Does not support Date/Time literals */
+  static const DateTimeLiteralSupport DL_NONE = _DL_NONE;
+  /** Supports DATE literal */
+  static const DateTimeLiteralSupport DL_DATE = _DL_DATE;
+  /** Supports TIME literal */
+  static const DateTimeLiteralSupport DL_TIME = _DL_TIME;
+  /** Supports TIMESTAMP literal */
+  static const DateTimeLiteralSupport DL_TIMESTAMP = _DL_TIMESTAMP;
+  /** Supports INTERVAL YEAR literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_YEAR = _DL_INTERVAL_YEAR;
+  /** Supports INTERVAL MONTH literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_MONTH = _DL_INTERVAL_MONTH;
+  /** Supports INTERVAL DAY literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_DAY = _DL_INTERVAL_DAY;
+  /** Supports INTERVAL HOUR literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_HOUR = _DL_INTERVAL_HOUR;
+  /** Supports INTERVAL MINUTE literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_MINUTE = _DL_INTERVAL_MINUTE;
+  /** Supports INTERVAL SECOND literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_SECOND = _DL_INTERVAL_SECOND;
+  /** Supports INTERVAL YEAR TO MONTH literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_YEAR_TO_MONTH = _DL_INTERVAL_YEAR_TO_MONTH;
+  /** Supports INTERVAL DAY TO HOUR literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_DAY_TO_HOUR = _DL_INTERVAL_DAY_TO_HOUR;
+  /** Supports INTERVAL DAY TO MINUTE literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_DAY_TO_MINUTE = _DL_INTERVAL_DAY_TO_MINUTE;
+  /** Supports INTERVAL DAY TO SECOND literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_DAY_TO_SECOND = _DL_INTERVAL_DAY_TO_SECOND;
+  /** Supports INTERVAL HOUR TO MINUTE literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_HOUR_TO_MINUTE = _DL_INTERVAL_HOUR_TO_MINUTE;
+  /** Supports INTERVAL HOUR TO SECOND literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_HOUR_TO_SECOND = _DL_INTERVAL_HOUR_TO_SECOND;
+  /** Supports INTERVAL MINUTE TO SECOND literal */
+  static const DateTimeLiteralSupport DL_INTERVAL_MINUTE_TO_SECOND = _DL_INTERVAL_MINUTE_TO_SECOND;
+
+  /*
+   * Internal type for COLLATE support
+   */
+  enum _CollateSupport {
+      _C_NONE       = 0,
+      _C_GROUPBY    = 1 << 1L
+  };
+
+  template inline _CollateSupport operator&(_CollateSupport __a, _CollateSupport __b);
+  template inline _CollateSupport operator|(_CollateSupport __a, _CollateSupport __b);
+  template inline _CollateSupport operator^(_CollateSupport __a, _CollateSupport __b);
+
+  template inline _CollateSupport& operator&=(_CollateSupport& __a, _CollateSupport __b);
+  template inline _CollateSupport& operator|=(_CollateSupport& __a, _CollateSupport __b);
+  template inline _CollateSupport& operator^=(_CollateSupport& __a, _CollateSupport __b);
+
+  template inline _CollateSupport operator~(_CollateSupport __a);
+
+
+  /**
+   * COLLATE support flags
+   */
+  typedef _CollateSupport CollateSupport;
+  static const CollateSupport C_NONE = _C_NONE;       /**< COLLATE clauses are not supported */
+  static const CollateSupport C_GROUPBY = _C_GROUPBY; /**< a COLLATE clause can be added after each grouping column */
+
+  /**
+   * Correlation names support flags
+   */
+  enum CorrelationNamesSupport {
+    CN_NONE            = 1, /**< Correlation names are not supported */
+    CN_DIFFERENT_NAMES = 2, /**< Correlation names are supported, but names have to be different
+    							 from the tables they represent */
+    CN_ANY_NAMES       = 3  /**< Correlation names are supported with no restriction on names */
+  };
+
+  /**
+   * Group by support
+   */
+  enum GroupBySupport {
+      GB_NONE,         /**< Do not support GROUP BY */
+      GB_SELECT_ONLY,  /**< Only support GROUP BY clause with non aggregated columns in the select list */
+      GB_BEYOND_SELECT,/**< Support GROUP BY clauses with columns absent from the select list
+      	  	  	  	  	    if all the non-aggregated column from the select list are also added. */
+      GB_UNRELATED     /** Support GROUP BY clauses with columns absent from the select list */
+  };
+
+  /**
+   * Identified case support
+   */
+  enum IdentifierCase {
+      IC_STORES_LOWER,  /**< Mixed case unquoted SQL identifier are treated as
+	  	  	  	  	  	    case insensitive and stored in lower case */
+      IC_STORES_MIXED,  /**< Mixed case unquoted SQL identifier are treated as
+	  	  	  	  	  	    case insensitive and stored in mixed case */
+      IC_STORES_UPPER,  /**< Mixed case unquoted SQL identifier are treated as
+	  	  	  	  	  	    case insensitive and stored in upper case */
+      IC_SUPPORTS_MIXED /**< Mixed case unquoted SQL identifier are treated as
+	  	  	  	  	  	    case sensitive and stored in mixed case */
+  };
+
+  /**
+   * Null collation support
+   */
+  enum NullCollation {
+      NC_AT_START,/**< NULL values are sorted at the start regardless of the order*/
+      NC_AT_END,  /**< NULL values are sorted at the end regardless of the order*/
+      NC_HIGH,    /**< NULL is the highest value */
+      NC_LOW      /**< NULL is the lowest value */
+  };
+
+
+  /*
+   * Internal type for Outer join support flags
+   */
+  enum _OuterJoinSupport {
+      _OJ_NONE                  = 0,      //!< _OJ_NONE
+      _OJ_LEFT                  = 1 << 1L,//!< _OJ_LEFT
+      _OJ_RIGHT                 = 1 << 2L,//!< _OJ_RIGHT
+      _OJ_FULL                  = 1 << 3L,//!< _OJ_FULL
+      _OJ_NESTED                = 1 << 4L,//!< _OJ_NESTED
+      _OJ_NOT_ORDERED           = 1 << 5L,//!< _OJ_NOT_ORDERED
+      _OJ_INNER                 = 1 << 6L,//!< _OJ_INNER
+      _OJ_ALL_COMPARISON_OPS    = 1 << 7L //!< _OJ_ALL_COMPARISON_OPS
+  };
+
+  template inline _OuterJoinSupport operator&(_OuterJoinSupport __a, _OuterJoinSupport __b);
+  template inline _OuterJoinSupport operator|(_OuterJoinSupport __a, _OuterJoinSupport __b);
+  template inline _OuterJoinSupport operator^(_OuterJoinSupport __a, _OuterJoinSupport __b);
+
+  template inline _OuterJoinSupport& operator&=(_OuterJoinSupport& __a, _OuterJoinSupport __b);
+  template inline _OuterJoinSupport& operator|=(_OuterJoinSupport& __a, _OuterJoinSupport __b);
+  template inline _OuterJoinSupport& operator^=(_OuterJoinSupport& __a, _OuterJoinSupport __b);
+
+  template inline _OuterJoinSupport operator~(_OuterJoinSupport __a);
+
+  /**
+   * Outer join support flags
+   */
+  typedef _OuterJoinSupport OuterJoinSupport;
+  /** Outer join is not supported */
+  static const OuterJoinSupport OJ_NONE                 = _OJ_NONE;
+  /** Left outer join is supported */
+  static const OuterJoinSupport OJ_LEFT                 = _OJ_LEFT;
+  /** Right outer join is supported */
+  static const OuterJoinSupport OJ_RIGHT                = _OJ_RIGHT;
+  /** Full outer join is supported */
+  static const OuterJoinSupport OJ_FULL                 = _OJ_FULL;
+  /** Nested outer join is supported */
+  static const OuterJoinSupport OJ_NESTED               = _OJ_NESTED;
+  /**
+   * The columns names in the ON clause of a outer join don't have to share the same
+   * order as their respective table names in the OUTER JOIN clause
+   */
+  static const OuterJoinSupport OJ_NOT_ORDERED          = _OJ_NOT_ORDERED;
+  /**
+   * The inner table can also be used in an inner join
+   */
+  static const OuterJoinSupport OJ_INNER                = _OJ_INNER;
+  /**
+   * Any comparison operator in supported in the ON clause.
+   */
+  static const OuterJoinSupport OJ_ALL_COMPARISON_OPS   = _OJ_ALL_COMPARISON_OPS;
+
+  /**
+   * Quoted Identified case support
+   */
+  enum QuotedIdentifierCase {
+      QIC_STORES_LOWER,  /**< Mixed case quoted SQL identifier are treated as
+	  	  	  	  	  	    case insensitive and stored in lower case */
+      QIC_STORES_MIXED,  /**< Mixed case quoted SQL identifier are treated as
+	  	  	  	  	  	    case insensitive and stored in mixed case */
+      QIC_STORES_UPPER,  /**< Mixed case quoted SQL identifier are treated as
+	  	  	  	  	  	    case insensitive and stored in upper case */
+      QIC_SUPPORTS_MIXED /**< Mixed case quoted SQL identifier are treated as
+	  	  	  	  	  	    case sensitive and stored in mixed case */
+  };
+
+  /*
+   * Internal Subquery support flags type
+   */
+  enum _SubQuerySupport {
+      _SQ_NONE          = 0,
+      _SQ_CORRELATED    = 1 << 1L,
+      _SQ_IN_COMPARISON = 1 << 2L,
+      _SQ_IN_EXISTS     = 1 << 3L,
+      _SQ_IN_INSERT     = 1 << 4L,
+      _SQ_IN_QUANTIFIED = 1 << 5L
+  };
+
+  template inline _SubQuerySupport operator&(_SubQuerySupport __a, _SubQuerySupport __b);
+  template inline _SubQuerySupport operator|(_SubQuerySupport __a, _SubQuerySupport __b);
+  template inline _SubQuerySupport operator^(_SubQuerySupport __a, _SubQuerySupport __b);
+
+  template inline _SubQuerySupport& operator&=(_SubQuerySupport& __a, _SubQuerySupport __b);
+  template inline _SubQuerySupport& operator|=(_SubQuerySupport& __a, _SubQuerySupport __b);
+  template inline _SubQuerySupport& operator^=(_SubQuerySupport& __a, _SubQuerySupport __b);
+
+  template inline _SubQuerySupport operator~(_SubQuerySupport __a);
+
+  /**
+   * SubQuery support flags
+   */
+  typedef _SubQuerySupport SubQuerySupport;
+  /**
+   * Subqueries are not supported
+   */
+  static const SubQuerySupport SQ_NONE             = _SQ_NONE;
+  /** Correlated subqueries are supported */
+  static const SubQuerySupport SQ_CORRELATED       = _SQ_CORRELATED;
+  /** Subqueries in comparison expressions are supported */
+  static const SubQuerySupport SQ_IN_COMPARISON    = _SQ_IN_COMPARISON;
+  /** Subqueries in EXISTS expressions are supported */
+  static const SubQuerySupport SQ_IN_EXISTS        = _SQ_IN_EXISTS;
+  /** Subqueries in INSERT expressions are supported */
+  static const SubQuerySupport SQ_IN_INSERT        = _SQ_IN_INSERT;
+  /** Subqueries in quantified expressions are supported */
+  static const SubQuerySupport SQ_IN_QUANTIFIED    = _SQ_IN_QUANTIFIED;
+
+  /*
+   * Internal Union support flags type
+   */
+  enum _UnionSupport {
+      _U_NONE       = 0,      //!< _U_NONE
+      _U_UNION      = 1 << 1L,//!< _U_UNION
+      _U_UNION_ALL  = 1 << 2L //!< _U_UNION_ALL
+  };
+
+  template inline _UnionSupport operator&(_UnionSupport __a, _UnionSupport __b);
+  template inline _UnionSupport operator|(_UnionSupport __a, _UnionSupport __b);
+  template inline _UnionSupport operator^(_UnionSupport __a, _UnionSupport __b);
+
+  template inline _UnionSupport& operator&=(_UnionSupport& __a, _UnionSupport __b);
+  template inline _UnionSupport& operator|=(_UnionSupport& __a, _UnionSupport __b);
+  template inline _UnionSupport& operator^=(_UnionSupport& __a, _UnionSupport __b);
+
+  template inline _UnionSupport operator~(_UnionSupport __a);
+
+  /**
+   * Union support flags
+   */
+  typedef _UnionSupport UnionSupport;
+  /** Union is not supported */
+  static const UnionSupport U_NONE       = _U_NONE;
+  /** UNION is supported */
+  static const UnionSupport U_UNION      = _U_UNION;
+  /** UNION ALL is supported */
+  static const UnionSupport U_UNION_ALL  = _U_UNION_ALL;
+
+  class DECLSPEC_DRILL_CLIENT CatalogMetadata {
+      protected:
+      CatalogMetadata() {};
+      public:
+      virtual ~CatalogMetadata() {};
+
+      virtual bool               hasCatalogName() const = 0;
+      virtual const std::string& getCatalogName() const = 0;
+
+      virtual bool               hasDescription() const = 0;
+      virtual const std::string& getDescription() const = 0;
+
+      virtual bool               hasConnect() const = 0;
+      virtual const std::string& getConnect() const = 0;
+  };
+
+  class DECLSPEC_DRILL_CLIENT SchemaMetadata {
+      protected:
+      SchemaMetadata() {};
+
+      public:
+      virtual ~SchemaMetadata() {};
+
+      virtual bool               hasCatalogName() const = 0;
+      virtual const std::string& getCatalogName() const = 0;
+
+      virtual bool               hasSchemaName() const = 0;
+      virtual const std::string& getSchemaName() const = 0;
+
+      virtual bool               hasOwnerName() const = 0;
+      virtual const std::string& getOwner() const = 0;
+
+      virtual bool               hasType() const = 0;
+      virtual const std::string& getType() const = 0;
+
+      virtual bool               hasMutable() const = 0;
+      virtual const std::string& getMutable() const = 0;
+  };
+
+  class DECLSPEC_DRILL_CLIENT TableMetadata {
+      protected:
+      TableMetadata() {};
+
+      public:
+      virtual ~TableMetadata() {};
+
+      virtual bool               hasCatalogName() const = 0;
+      virtual const std::string& getCatalogName() const = 0;
+
+      virtual bool               hasSchemaName() const = 0;
+      virtual const std::string& getSchemaName() const = 0;
+
+      virtual bool               hasTableName() const = 0;
+      virtual const std::string& getTableName() const = 0;
+
+      virtual bool               hasType() const = 0;
+      virtual const std::string& getType() const = 0;
+  };
+
+  class DECLSPEC_DRILL_CLIENT ColumnMetadata {
+      protected:
+      ColumnMetadata() {};
+
+      public:
+      virtual ~ColumnMetadata() {};
+
+      virtual bool               hasCatalogName() const = 0;
+      virtual const std::string& getCatalogName() const = 0;
+
+      virtual bool               hasSchemaName() const = 0;
+      virtual const std::string& getSchemaName() const = 0;
+
+      virtual bool               hasTableName() const = 0;
+      virtual const std::string& getTableName() const = 0;
+
+      virtual bool               hasColumnName() const = 0;
+      virtual const std::string& getColumnName() const = 0;
+
+      virtual bool               hasOrdinalPosition() const = 0;
+      virtual std::size_t        getOrdinalPosition() const = 0;
+
+      virtual bool               hasDefaultValue() const = 0;
+      virtual const std::string& getDefaultValue() const = 0;
+
+      virtual bool               hasNullable() const = 0;
+      virtual bool               isNullable() const = 0;
+
+      virtual bool               hasDataType() const = 0;
+      virtual const std::string& getDataType() const = 0;
+
+      virtual bool               hasColumnSize() const = 0;
+      virtual std::size_t        getColumnSize() const = 0;
+
+      virtual bool               hasCharMaxLength() const = 0;
+      virtual std::size_t        getCharMaxLength() const = 0;
+
+      virtual bool               hasCharOctetLength() const = 0;
+      virtual std::size_t        getCharOctetLength() const = 0;
+
+      virtual bool               hasNumericPrecision() const = 0;
+      virtual int32_t            getNumericPrecision() const = 0;
+
+      virtual bool               hasNumericRadix() const = 0;
+      virtual int32_t            getNumericRadix() const = 0;
+
+      virtual bool               hasNumericScale() const = 0;
+      virtual int32_t            getNumericScale() const = 0;
+
+      virtual bool               hasIntervalType() const = 0;
+      virtual const std::string& getIntervalType() const = 0;
+
+      virtual bool               hasIntervalPrecision() const = 0;
+      virtual int32_t            getIntervalPrecision() const = 0;
+  };
+}
+
+class DECLSPEC_DRILL_CLIENT Metadata {
+  public:
+    virtual ~Metadata() {};
+
+    /**
+     * Returns the connector name
+     *
+     * @return the connector name
+     */
+    virtual const std::string& getConnectorName() const = 0;
+
+    /**
+     * Returns the connector version string
+     *
+     * @return the connector version string
+     */
+    virtual const std::string& getConnectorVersion() const = 0;
+
+    /**
+     * Returns the connector major version
+     *
+     * @return the connector major version
+     */
+    virtual uint32_t getConnectorMajorVersion() const = 0;
+
+    /**
+     * Returns the connector minor version
+     *
+     * @return the connector minor version
+     */
+    virtual uint32_t getConnectorMinorVersion() const = 0;
+
+    /**
+     * Returns the connector patch version
+     *
+     * @return the connector patch version
+     */
+    virtual uint32_t getConnectorPatchVersion() const = 0;
+
+    /**
+     * Returns the server name
+     *
+     * @return the server name
+     */
+    virtual const std::string& getServerName() const = 0;
+
+    /**
+     * Returns the server version string
+     *
+     * @return the server version string
+     */
+    virtual const std::string& getServerVersion() const = 0;
+
+    /**
+     * Returns the server major version
+     *
+     * @return the server major version
+     */
+    virtual uint32_t getServerMajorVersion() const = 0;
+
+    /**
+     * Returns the server minor version
+     *
+     * @return the server minor version
+     */
+    virtual uint32_t getServerMinorVersion() const = 0;
+
+    /**
+     * Returns the server patch version
+     *
+     * @return the server patch version
+     */
+    virtual uint32_t getServerPatchVersion() const = 0;
+
+    /**
+     * Callback function invoked by getCatalogs when receiving results
+     *
+     * This callback is only invoked once. 
+     * @param[in] ctx the listener context provided to getCatalogs
+     * @param[in] metadata the catalog metadata, or NULL in case of error
+     * @param[in] err an error object, NULL in case of success
+     */
+    typedef status_t (*pfnCatalogMetadataListener)(void* ctx, const DrillCollection<meta::CatalogMetadata>* metadata, DrillClientError* err);
+
+    /**
+     * Get a list of catalogPattern available to the current connection.
+     * Only catalogs matching the catalogPattern LIKE expression are returned.
+     *
+     * @param[in] catalogPattern a catalog pattern
+     * @param[in] listener a metadata listener
+     * @param[in] context to be passed to the listener
+     * @param[out] the query handle
+     */
+    virtual status_t getCatalogs(const std::string& catalogPattern, pfnCatalogMetadataListener listener, void* listenerCtx, QueryHandle_t* qHandle) = 0;
+
+    /**
+     * Callback function invoked by getSchemas when receiving results
+     *
+     * This callback is only invoked once. 
+     * @param[in] ctx the listener context provided to getSchemas
+     * @param[in] metadata the schema metadata, or NULL in case of error
+     * @param[in] err an error object, NULL in case of success
+     */
+    typedef status_t (*pfnSchemaMetadataListener)(void* ctx, const DrillCollection<meta::SchemaMetadata>* metadata, DrillClientError* err);
+
+    /**
+     * Get a list of schemas available to the current connection.
+     * Only schemas matching the catalogPattern and schemaPattern LIKE expressions are returned.
+     *
+     * @param[in] catalogPattern a catalog pattern
+     * @param[in] schemaPattern a schema pattern
+     * @param[in] listener a metadata query listener
+     * @param[in] context to be passed to the listener
+     * @param[out] the query handle
+     */
+    virtual status_t getSchemas(const std::string& catalogPattern, const std::string& schemaPattern, pfnSchemaMetadataListener listener, void* listenerCtx, QueryHandle_t* qHandle) = 0;
+
+    /**
+     * Callback function invoked by getTables when receiving results
+     *
+     * This callback is only invoked once. 
+     * @param[in] ctx the listener context provided to getTables
+     * @param[in] metadata the table metadata, or NULL in case of error
+     * @param[in] err an error object, NULL in case of success
+     */
+    typedef status_t (*pfnTableMetadataListener)(void* ctx, const DrillCollection<meta::TableMetadata>* metadata, DrillClientError* err);
+
+    /**
+     * Get a list of tables available to the current connection.
+     * Only tables matching the catalogPattern, schemaPattern and tablePattern LIKE expressions are returned.
+     *
+     * @param[in] catalogPattern a catalog pattern
+     * @param[in] schemaPattern a schema pattern
+     * @param[in] tablePattern a table pattern
+     * @param[in] tableTypes a list of table types to look for. Pass NULL to not filter
+     * @param[in] listener a metadata query listener
+     * @param[in] context to be passed to the listener
+     * @param[out] the query handle
+     */
+    virtual status_t getTables(const std::string& catalogPattern, const std::string& schemaPattern, const std::string& tablePattern, const std::vector<std::string>* tableTypes, 
+                               pfnTableMetadataListener listener, void* listenerCtx, QueryHandle_t* qHandle) = 0;
+
+    /**
+     * Callback function invoked by getColumns when receiving results
+     *
+     * This callback is only invoked once. 
+     * @param[in] ctx the listener context provided to getColumns
+     * @param[in] metadata the columns metadata, or NULL in case of error
+     * @param[in] err an error object, NULL in case of success
+     */
+    typedef status_t (*pfnColumnMetadataListener)(void* ctx, const DrillCollection<meta::ColumnMetadata>* metadata, DrillClientError* err);
+
+    /**
+     * Get a list of columns available to the current connection.
+     * Only columns matching the catalogPattern, schemaPattern, tablePattern and columnPattern LIKE expressions are returned.
+     *
+     * @param[in] catalogPattern a catalog pattern
+     * @param[in] schemaPattern a schema pattern
+     * @param[in] tablePattern a table pattern
+     * @param[in] columnPattern a colum name pattern
+     * @param[in] listener a metadata query listener
+     * @param[in] context to be passed to the listener
+     * @param[out] the query handle
+     */
+    virtual status_t getColumns(const std::string& catalogPattern, const std::string& schemaPattern, const std:: string& tablePattern, const std::string& columnPattern, pfnColumnMetadataListener listener, void* listenerCtx, QueryHandle_t* qHandle) = 0;
+
+    // Capabilities
+    /**
+     * Return if the current user can use all tables returned by the getTables method
+     *
+     * @result true if the user can select any table, false otherwise
+     */
+    virtual bool areAllTableSelectable() const = 0;
+
+    /**
+     * Return if the catalog name is at the start of a fully qualified table name
+     *
+     * @return true if the catalog name is at the start, false otherwise.
+     */
+    virtual bool isCatalogAtStart() const = 0;
+
+    /**
+     * Return the string used as a separator between the catalog and the table name
+     *
+     * @return the catalog separator
+     */
+    virtual const std::string& getCatalogSeparator() const = 0;
+
+    /**
+     * Return the term used by the server to designate a catalog
+     *
+     * @return the catalog term
+     */
+    virtual const std::string& getCatalogTerm() const = 0;
+
+    /**
+     * Return if the server supports column aliasing
+     *
+     * @return true if the server supports column aliasing, false otherwise
+     */
+    virtual bool isColumnAliasingSupported() const = 0;
+
+    /**
+     * Return if the result of a NULL and a non-NULL values concatenation is NULL
+     *
+     * @return true if the result is NULL, false otherwise
+     */
+    virtual bool isNullPlusNonNullNull() const = 0;
+
+    /**
+     * Return if the CONVERT function supports conversion for the given types
+     *
+     * @return true if the conversion is supported, false otherwise
+     */
+    virtual bool isConvertSupported(common::MinorType from, common::MinorType to) const = 0;
+
+    /**
+     * Return what kind of correlation name support the server provides
+     *
+     * @return the correlation name supported by the server
+     */
+    virtual meta::CorrelationNamesSupport getCorrelationNames() const = 0;
+
+    /**
+     * Returns if the connection to the server is read-only
+     *
+     * @return true if the connection is read-only, false otherwise
+     */
+    virtual bool isReadOnly() const = 0;
+
+    /**
+     * Return what kind of date time literals the server supports
+     *
+     * @return a bitmask of supported date/time literals
+     */
+    virtual meta::DateTimeLiteralSupport getDateTimeLiteralsSupport() const = 0;
+
+    /**
+     * Return what kind of COLLATE expressions are supported
+     */
+    virtual meta::CollateSupport getCollateSupport() const = 0;
+
+    /**
+     * Return what kind of GROUP BY support the server provides
+     *
+     * @return the group by support
+     */
+    virtual meta::GroupBySupport getGroupBySupport() const = 0;
+
+    /**
+     * Returns how unquoted identifier are stored
+     *
+     * @return the unquoted identifier storage policy
+     */
+    virtual meta::IdentifierCase getIdentifierCase() const = 0;
+
+    /**
+     * Returns the string used to quote SQL identifiers
+     *
+     * @return the quote string
+     */
+    virtual const std::string& getIdentifierQuoteString() const = 0;
+
+    /**
+     * Returns the list of SQL keywords supported by the database
+     *
+     * @return a list of keywords
+     */
+    virtual const std::vector<std::string>& getSQLKeywords() const = 0;
+
+    /**
+     * Returns if LIKE operator supports an escape clause
+     *
+     * @return true if escape claused are supported
+     */
+    virtual bool isLikeEscapeClauseSupported() const = 0;
+
+    /**
+     * Returns the maximum number of hexa characters supported for binary literals
+     *
+     * @return the length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxBinaryLiteralLength() const = 0;
+
+    /**
+     * Returns the maximum length of catalog names
+     *
+     * @return the length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxCatalogNameLength() const = 0;
+
+    /**
+     * Returns the maximum number of characters for string literals
+     *
+     * @return the length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxCharLiteralLength() const = 0;
+
+    /**
+     * Returns the maximum length of column names
+     *
+     * @return the length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxColumnNameLength() const = 0;
+
+    /**
+     * Returns the maximum number of columns in GROUP BY expressions
+     *
+     * @return the maximum number, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxColumnsInGroupBy() const = 0;
+
+    /**
+     * Returns the maximum number of columns in ORDER BY expressions
+     *
+     * @return the maximum number, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxColumnsInOrderBy() const = 0;
+
+    /**
+     * Returns the maximum number of columns in a SELECT list
+     *
+     * @return the maximum number, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxColumnsInSelect() const = 0;
+
+    /**
+     * Returns the maximum length for cursor names
+     *
+     * @return the maximum length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxCursorNameLength() const = 0;
+
+    /**
+     * Returns the maximum logical size for LOB types
+     *
+     * @return the maximum size, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxLogicalLobSize() const = 0;
+
+    /**
+     * Returns the maximum number of statements
+     *
+     * @return the maximum number, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxStatements() const = 0;
+
+    /**
+     * Returns the maximum number of bytes for a single row
+     * @return the maximum size, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxRowSize() const = 0;
+
+    /**
+     * Returns if BLOB types are included in the maximum row size
+     *
+     * @return true if BLOB are included
+     */
+    virtual bool isBlobIncludedInMaxRowSize() const = 0;
+
+    /**
+     * Returns the maximum length for schema names
+     * @return the maximum length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxSchemaNameLength() const = 0;
+
+    /**
+     * Returns the maximum length for statements
+     * @return the maximum length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxStatementLength() const = 0;
+
+    /**
+     * Returns the maximum length for table names
+     * @return the maximum length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxTableNameLength() const = 0;
+
+    /**
+     * Returns the maximum number of tables in a SELECT expression
+     * @return the maximum number, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxTablesInSelect() const = 0;
+
+    /**
+     * Returns the maximum length for user names
+     * @return the maximum length, 0 if unlimited or unknown
+     */
+    virtual std::size_t getMaxUserNameLength() const = 0;
+
+    /**
+     * Returns how NULL are sorted
+     *
+     * @return the NULL collation policy
+     */
+    virtual meta::NullCollation getNullCollation() const = 0;
+
+    /**
+     * Returns the list of supported numeric functions
+     * @return a list of function names
+     */
+    virtual const std::vector<std::string>& getNumericFunctions() const = 0;
+
+    /**
+     * Returns how outer joins are supported
+     * @return outer join support (as flags)
+     */
+    virtual meta::OuterJoinSupport getOuterJoinSupport() const = 0;
+
+    /**
+     * Returns if columns not in the SELECT column lists can be used
+     * in the ORDER BY expression
+     *
+     * @return true if unrelated columns are supported in ORDER BY
+     */
+    virtual bool isUnrelatedColumnsInOrderBySupported() const = 0;
+
+    /**
+     * Returns how quoted identifier are stored
+     *
+     * @return the quoted identifier storage policy
+     */
+    virtual meta::QuotedIdentifierCase getQuotedIdentifierCase() const = 0;
+
+    /**
+     * Returns the term used to designate schemas
+     *
+     * @return the term
+     */
+    virtual const std::string& getSchemaTerm() const = 0;
+
+    /**
+     * Return the string for escaping patterns in metadata queries
+     *
+     * @return the characters for escaping, empty if not supported
+     */
+    virtual const std::string& getSearchEscapeString() const = 0;
+
+    /**
+     * Returns the list of extra characters that can be used in identifier names
+     *
+     * Extra characters are those characters beyond a-z, A-Z, 0-9 and '_' (underscore)
+     *
+     * @return a list of characters
+     */
+    virtual const std::string& getSpecialCharacters() const = 0;
+
+    /**
+     * Returns the list of supported string functions
+     *
+     * @return a list of function names
+     */
+    virtual const std::vector<std::string>& getStringFunctions() const = 0;
+
+    /**
+     * Returns how subqueries are supported
+     *
+     * @return the subqueries support (as flags)
+     */
+    virtual meta::SubQuerySupport getSubQuerySupport() const = 0;
+
+    /**
+     * Returns the list of supported system functions
+     *
+     * @return a list of function names
+     */
+    virtual const std::vector<std::string>& getSystemFunctions() const = 0;
+
+    /**
+     * Returns the term used to designate tables
+     *
+     * @return the term
+     */
+    virtual const std::string& getTableTerm() const = 0;
+
+    /**
+     * Returns the list of supported date/time functions
+     *
+     * @return a list of function names
+     */
+    virtual const std::vector<std::string>& getDateTimeFunctions() const = 0;
+
+    /**
+     * Returns if transactions are supported
+     * @return true if transactions are supported
+     */
+    virtual bool isTransactionSupported() const = 0;
+
+    /**
+     * Returns how unions are supported
+     *
+     * @return the union support (as flags)
+     */
+    virtual meta::UnionSupport getUnionSupport() const = 0;
+
+    /**
+     * Returns if SELECT FOR UPDATE expressions are supported
+     *
+     * @return true if SELECT FOR UPDATE is supported
+     */
+    virtual bool isSelectForUpdateSupported() const = 0;
+};
+
 class DECLSPEC_DRILL_CLIENT DrillClient{
     public:
         /*
@@ -273,7 +1199,7 @@ class DECLSPEC_DRILL_CLIENT DrillClient{
          */
         DEPRECATED connectionStatus_t connect(const char* connectStr, const char* defaultSchema=NULL);
 
-        /*  
+        /*
          * Connect the client to a Drillbit using connection string and a set of user properties.
          * The connection string format can be found in comments of
          * [DRILL-780](https://issues.apache.org/jira/browse/DRILL-780)
@@ -325,10 +1251,30 @@ class DECLSPEC_DRILL_CLIENT DrillClient{
 
         /*
          * Submit a query asynchronously and wait for results to be returned through an iterator that returns
-         * results synchronously. The client app needs to call delete on the iterator when done.
+         * results synchronously. The client app needs to call freeQueryIterator on the iterator when done.
          */
         RecordIterator* submitQuery(Drill::QueryType t, const std::string& plan, DrillClientError* err);
 
+        /**
+         * Prepare a query.
+         *
+         * @param[in] sql the query to prepare
+         * @param[in] listener a callback to be notified when the prepared statement is created, or if an error occured
+         * @param[in] user context to provide to the callback
+         * @param[out] a handle on the query
+         */
+        status_t prepareQuery(const std::string& sql, pfnPreparedStatementListener listener, void* listenerCtx, QueryHandle_t* qHandle);
+
+        /*
+         * Execute a prepared statement.
+         *
+         * @param[in] pstmt the prepared statement to execute
+         * @param[in] listener a callback to be notified when results have arrived, or if an error occured
+         * @param[in] user context to provide to the callback
+         * @param[out] a handle on the query
+         */
+        status_t executeQuery(const PreparedStatement& pstmt, pfnQueryResultsListener listener, void* listenerCtx, QueryHandle_t* qHandle);
+
         /*
          * The client application should call this function to wait for results if it has registered a
          * listener.
@@ -360,7 +1306,7 @@ class DECLSPEC_DRILL_CLIENT DrillClient{
          * Applications using the sync query submit method should call freeQueryIterator to free up resources
          * once the RecordIterator is no longer being processed.
          */
-        void freeQueryIterator(RecordIterator** pIter){ delete *pIter; *pIter=NULL;};
+        void freeQueryIterator(RecordIterator** pIter){ delete *pIter; *pIter=NULL;}
 
         /*
          * Applications using the async query submit method should call freeRecordBatch to free up resources
@@ -368,7 +1314,15 @@ class DECLSPEC_DRILL_CLIENT DrillClient{
          */
         void freeRecordBatch(RecordBatch* pRecordBatch);
 
+        /**
+         * Get access to the server metadata
+         */
+        Metadata* getMetadata();
 
+        /**
+         * Free resources associated with the metadata object
+         */
+        void freeMetadata(Metadata** metadata);
 
     private:
         static DrillClientInitializer s_init;

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/include/drill/drillc.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/drillc.hpp b/contrib/native/client/src/include/drill/drillc.hpp
index 3697ee8..c8593f5 100644
--- a/contrib/native/client/src/include/drill/drillc.hpp
+++ b/contrib/native/client/src/include/drill/drillc.hpp
@@ -21,6 +21,8 @@
 
 #include "drill/common.hpp"
 #include "drill/drillClient.hpp"
+#include "drill/fieldmeta.hpp"
+#include "drill/preparedStatement.hpp"
 #include "drill/recordBatch.hpp"
 #include "drill/protobuf/Types.pb.h"
 

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/include/drill/fieldmeta.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/fieldmeta.hpp b/contrib/native/client/src/include/drill/fieldmeta.hpp
new file mode 100644
index 0000000..40c9cca
--- /dev/null
+++ b/contrib/native/client/src/include/drill/fieldmeta.hpp
@@ -0,0 +1,122 @@
+/*
+ * 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 FIELDMETA_H
+#define FIELDMETA_H
+
+#include "drill/common.hpp"
+#include "drill/protobuf/Types.pb.h"
+
+namespace exec{
+    namespace shared{
+        class SerializedField;
+    };
+    namespace user{
+        class ResultColumnMetadata;
+    };
+};
+
+
+namespace Drill {
+
+class DECLSPEC_DRILL_CLIENT FieldMetadata{
+    public:
+        enum ColumnSearchability { UNKNOWN_SEARCHABILITY = 0, NONE = 1, CHAR = 2, NUMBER = 3, ALL = 4 };
+        enum ColumnUpdatability { UNKNOWN_UPDATABILITY = 0, READ_ONLY = 1, WRITABLE = 2 };
+
+        FieldMetadata(){};
+        void set(const exec::shared::SerializedField& f);
+        void set(const exec::user::ResultColumnMetadata& m);
+        const std::string& getName() const{ return m_name;}
+        common::MinorType getMinorType() const{ return m_minorType;}
+        common::DataMode getDataMode() const{return m_dataMode;}
+        uint32_t getValueCount() const{return m_valueCount;}
+        uint32_t getScale() const{return m_scale;}
+        uint32_t getPrecision() const{return m_precision;}
+        uint32_t getBufferLength() const{return m_bufferLength;}
+        const std::string& getCatalogName() const{return m_catalogName;}
+        const std::string& getSchemaName() const{return m_schemaName;}
+        const std::string& getTableName() const{return m_tableName;}
+        const std::string& getLabel() const{return m_label;}
+        const std::string& getSQLType() const{return m_sqlType;}
+        bool isNullable() const{return m_nullable;}
+        bool isSigned() const{return m_signed;}
+        uint32_t getDisplaySize() const{return m_displaySize;}
+        bool isAliased() const{return m_aliased;}
+        ColumnSearchability getSearchability() const{return m_searchability;}
+        ColumnUpdatability getUpdatability() const{return m_updatability;}
+        bool isAutoIncremented() const{return m_autoIncremented;}
+        bool isCaseSensitive() const{return m_caseSensitive;}
+        bool isSortable() const{return m_sortable;}
+        bool isCurrency() const{return m_currency;}
+        void copy(Drill::FieldMetadata& f){
+            m_name=f.m_name;
+            m_minorType=f.m_minorType;
+            m_dataMode=f.m_dataMode;
+            m_valueCount=f.m_valueCount;
+            m_scale=f.m_scale;
+            m_precision=f.m_precision;
+            m_bufferLength=f.m_bufferLength;
+            m_catalogName=f.m_catalogName;
+            m_schemaName=f.m_schemaName;
+            m_tableName=f.m_tableName;
+            m_label=f.m_label;
+            m_sqlType=f.m_sqlType;
+            m_nullable=f.m_nullable;
+            m_signed=f.m_signed;
+            m_displaySize=f.m_displaySize;
+            m_aliased=f.m_aliased;
+            m_searchability=f.m_searchability;
+            m_updatability=f.m_updatability;
+            m_autoIncremented=f.m_autoIncremented;
+            m_caseSensitive=f.m_caseSensitive;
+            m_sortable=f.m_sortable;
+            m_currency=f.m_currency;
+            m_columnSize=f.m_columnSize;
+        }
+
+    private:
+        std::string m_name;
+        common::MinorType m_minorType;
+        common::DataMode m_dataMode;
+        uint32_t m_valueCount;
+        uint32_t m_scale;
+        uint32_t m_precision;
+        uint32_t m_bufferLength;
+        std::string m_catalogName;
+        std::string m_schemaName;
+        std::string m_tableName;
+        std::string m_label;
+        std::string m_sqlType;
+        bool m_nullable;
+        bool m_signed;
+        uint32_t m_displaySize;
+        bool m_aliased;
+        ColumnSearchability m_searchability;
+        ColumnUpdatability m_updatability;
+        bool m_autoIncremented;
+        bool m_caseSensitive;
+        bool m_sortable;
+        bool m_currency;
+        uint32_t m_columnSize;
+
+};
+} // namespace
+
+#endif
+

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/include/drill/preparedStatement.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/preparedStatement.hpp b/contrib/native/client/src/include/drill/preparedStatement.hpp
new file mode 100644
index 0000000..2a7d15a
--- /dev/null
+++ b/contrib/native/client/src/include/drill/preparedStatement.hpp
@@ -0,0 +1,38 @@
+/*
+ * 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 PREPAREDSTATEMENT_H
+#define PREPAREDSTATEMENT_H
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+namespace Drill {
+class DECLSPEC_DRILL_CLIENT PreparedStatement{
+public:
+	virtual std::size_t getNumFields() const = 0;
+	virtual const Drill::FieldMetadata& getFieldMetadata(std::size_t index) const = 0;
+
+	virtual ~PreparedStatement() {};
+};
+
+} // namespace Drill
+
+#endif // PREPAREDSTATEMENT_H
+

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/include/drill/recordBatch.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/recordBatch.hpp b/contrib/native/client/src/include/drill/recordBatch.hpp
index 12cbad4..8d1a0a3 100644
--- a/contrib/native/client/src/include/drill/recordBatch.hpp
+++ b/contrib/native/client/src/include/drill/recordBatch.hpp
@@ -647,7 +647,7 @@ template <class VALUEHOLDER_CLASS_TYPE, class VALUE_VECTOR_TYPE>
                     sstr<<"NULL";
                     strncpy(buf, sstr.str().c_str(), nChars);
                 }else{
-                    return m_pVector->getValueAt(index, buf, nChars);
+                    m_pVector->getValueAt(index, buf, nChars);
                 }
             }
 
@@ -786,39 +786,6 @@ typedef NullableValueVectorTyped<IntervalHolder, ValueVectorInterval>  NullableV
 typedef NullableValueVectorTyped<IntervalDayHolder, ValueVectorIntervalDay>  NullableValueVectorIntervalDay;
 typedef NullableValueVectorTyped<IntervalYearHolder, ValueVectorIntervalYear>  NullableValueVectorIntervalYear;
 
-class DECLSPEC_DRILL_CLIENT FieldMetadata{
-    public:
-
-        FieldMetadata(){};
-        void set(const exec::shared::SerializedField& f);
-        const std::string& getName() const{ return m_name;}
-        common::MinorType getMinorType() const{ return m_minorType;}
-        common::DataMode getDataMode() const{return m_dataMode;}
-        uint32_t getValueCount() const{return m_valueCount;}
-        uint32_t getScale() const{return m_scale;}
-        uint32_t getPrecision() const{return m_precision;}
-        uint32_t getBufferLength() const{return m_bufferLength;}
-        void copy(Drill::FieldMetadata& f){
-            m_name=f.m_name;
-            m_minorType=f.m_minorType;
-            m_dataMode=f.m_dataMode;
-            m_valueCount=f.m_valueCount;
-            m_scale=f.m_scale;
-            m_precision=f.m_precision;
-            m_bufferLength=f.m_bufferLength;
-        }
-
-    private:
-        //exec::shared::FieldMetadata* m_pFieldMetadata;
-        std::string m_name;
-        common::MinorType m_minorType;
-        common::DataMode m_dataMode;
-        uint32_t m_valueCount;
-        uint32_t m_scale;
-        uint32_t m_precision;
-        uint32_t m_bufferLength;
-};
-
 class FieldBatch{
     public:
         FieldBatch(const Drill::FieldMetadata& fmd, const ByteBuf_t data, size_t start, size_t length):

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/test/CMakeLists.txt b/contrib/native/client/src/test/CMakeLists.txt
index 892b58c..523734b 100644
--- a/contrib/native/client/src/test/CMakeLists.txt
+++ b/contrib/native/client/src/test/CMakeLists.txt
@@ -18,6 +18,7 @@
 
 # Drill Client unit tests
 set (TESTS_SRC_FILES
+    ${CMAKE_CURRENT_SOURCE_DIR}/CollectionsTest.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/UtilsTest.cpp
     )
 

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/contrib/native/client/src/test/CollectionsTest.cpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/test/CollectionsTest.cpp b/contrib/native/client/src/test/CollectionsTest.cpp
new file mode 100644
index 0000000..ebac941
--- /dev/null
+++ b/contrib/native/client/src/test/CollectionsTest.cpp
@@ -0,0 +1,215 @@
+/*
+ * 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 <string>
+#include <vector>
+
+#include <boost/assign.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "drill/collections.hpp"
+#include "collectionsImpl.hpp"
+
+namespace {
+template<typename T, typename Iter>
+class DrillVectorIteratorImpl: public Drill::impl::DrillIteratorImpl<T> {
+public:
+	typedef DrillVectorIteratorImpl<T, Iter> type;
+	typedef Drill::impl::DrillIteratorImpl<T> supertype;
+
+	DrillVectorIteratorImpl(const Iter& it): m_it(it) {};
+
+	T& operator*() const { return m_it.operator *();}
+	T* operator->() const { return m_it.operator->(); }
+
+	operator typename Drill::impl::DrillIteratorImpl<const T>::iterator_ptr() const { return typename Drill::impl::DrillIteratorImpl<const T>::iterator_ptr(new DrillVectorIteratorImpl<const T, Iter>(m_it)); }
+
+	DrillVectorIteratorImpl& operator++() {
+		m_it++; return *this;
+	}
+
+	bool operator==(const supertype& x) const {
+		const type& other(dynamic_cast<const type&>(x));
+		return m_it == other.m_it;
+	}
+
+	bool operator!=(const supertype& x) const { return !(*this==x); }
+
+private:
+	Iter m_it;
+};
+
+template<typename T>
+class DrillVectorImpl: public Drill::impl::DrillCollectionImpl<T> {
+public:
+	typedef Drill::impl::DrillCollectionImpl<T> supertype;
+
+	typedef typename supertype::iterator_ptr iterator_ptr;
+	typedef typename supertype::const_iterator_ptr const_iterator_ptr;
+
+	DrillVectorImpl() {}
+	DrillVectorImpl(const std::vector<T>& v): m_vector(v) {};
+
+	iterator_ptr begin() { return iterator_ptr(new IteratorImpl(m_vector.begin()));}
+	const_iterator_ptr begin() const { return const_iterator_ptr(new ConstIteratorImpl(m_vector.begin()));}
+	iterator_ptr end() { return iterator_ptr(new IteratorImpl(m_vector.end()));}
+	const_iterator_ptr end() const { return const_iterator_ptr(new ConstIteratorImpl(m_vector.end()));}
+
+private:
+	typedef DrillVectorIteratorImpl<T, typename std::vector<T>::iterator> IteratorImpl;
+	typedef DrillVectorIteratorImpl<const T, typename std::vector<T>::const_iterator> ConstIteratorImpl;
+	std::vector<T> m_vector;
+};
+
+template<typename T>
+class DrillVector: public Drill::DrillCollection<T> {
+public:
+	DrillVector(const std::vector<T>& v): Drill::DrillCollection<T>(typename Drill::DrillCollection<T>::ImplPtr(new DrillVectorImpl<T>(v))) {}
+};
+
+
+struct SimpleInterface {
+	virtual ~SimpleInterface() {}
+	virtual const std::string& foo() const = 0;
+	virtual std::string bar() = 0;
+};
+
+class SimpleImplementation: public SimpleInterface {
+public:
+	SimpleImplementation(const std::string& foo, const std::string& bar): m_foo(foo), m_bar(bar) {}
+
+	const std::string& foo() const { return m_foo; }
+	std::string bar() { return m_bar; }
+
+private:
+	std::string m_foo;
+	std::string m_bar;
+};
+
+} // anonymous namespace
+
+class CollectionsTest: public CppUnit::TestFixture {
+public:
+	CollectionsTest() {}
+
+
+	CPPUNIT_TEST_SUITE( CollectionsTest );
+	CPPUNIT_TEST( testSimpleCollection );
+	CPPUNIT_TEST( testSimpleConstCollection );
+	CPPUNIT_TEST( testDrillVectorConstIterator );
+	CPPUNIT_TEST( testDrillVectorIterator );
+	CPPUNIT_TEST( testDrillVectorConstPointer );
+	CPPUNIT_TEST_SUITE_END();
+
+	void testSimpleCollection() {
+		// basic test/proof of concept for collections.hpp
+
+		std::vector<std::string> v = boost::assign::list_of("foo")("bar");
+
+		DrillVector<std::string> drillCollection(v);
+		std::vector<std::string> result;
+		for(DrillVector<std::string>::const_iterator it = drillCollection.begin(); it != drillCollection.end(); ++it) {
+			result.push_back(*it);
+		}
+
+		CPPUNIT_ASSERT(result == v);
+	}
+
+	void testSimpleConstCollection() {
+		std::vector<std::string> v = boost::assign::list_of("foo")("bar");
+
+		const DrillVector<std::string> drillCollection(v);
+		std::vector<std::string> result;
+		for(DrillVector<std::string>::const_iterator it = drillCollection.begin(); it != drillCollection.end(); ++it) {
+			result.push_back(*it);
+		}
+
+		CPPUNIT_ASSERT(result == v);
+	}
+
+	void testDrillVectorConstIterator() {
+		typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector;
+		SimpleInterfaceVector v;
+
+		v.push_back(SimpleImplementation("foo1", "bar1"));
+		v.push_back(SimpleImplementation("foo2", "bar2"));
+
+		std::vector<std::string> resultFoo;
+		SimpleInterfaceVector::const_iterator it(v.begin());
+		for(; it != v.end(); ++it) {
+			resultFoo.push_back(it->foo());
+			// const-correctness: The following line does not compile if uncommented!
+			// resultBar.push_back(it->bar());
+		}
+
+		std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2");
+
+		CPPUNIT_ASSERT(resultFoo == expectedFoo);
+	}
+
+	void testDrillVectorIterator() {
+		typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector;
+		SimpleInterfaceVector v;
+
+		v.push_back(SimpleImplementation("foo1", "bar1"));
+		v.push_back(SimpleImplementation("foo2", "bar2"));
+
+		std::vector<std::string> resultFoo;
+		std::vector<std::string> resultBar;
+		SimpleInterfaceVector::iterator it;
+		for(it = v.begin(); it != v.end(); ++it) {
+			resultFoo.push_back(it->foo());
+			resultBar.push_back(it->bar());
+		}
+
+		std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2");
+		std::vector<std::string> expectedBar = boost::assign::list_of("bar1")("bar2");
+
+		CPPUNIT_ASSERT(resultFoo == expectedFoo);
+		CPPUNIT_ASSERT(resultBar == expectedBar);
+	}
+
+	// Check some const-correctness issues
+	// by getting iterators of a const collection
+	void testDrillVectorConstPointer() {
+		typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector;
+		boost::shared_ptr<SimpleInterfaceVector> v(new SimpleInterfaceVector);
+
+		const SimpleInterfaceVector* vv(v.get());
+
+		v->push_back(SimpleImplementation("foo1", "bar1"));
+		v->push_back(SimpleImplementation("foo2", "bar2"));
+
+		std::vector<std::string> resultFoo;
+		std::vector<std::string> resultBar;
+		SimpleInterfaceVector::const_iterator it;
+		for(it = vv->begin(); it != vv->end(); ++it) {
+			resultFoo.push_back(it->foo());
+		}
+
+		std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2");
+
+		CPPUNIT_ASSERT(resultFoo == expectedFoo);
+	}
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( CollectionsTest );

http://git-wip-us.apache.org/repos/asf/drill/blob/166c4ce7/protocol/src/main/protobuf/User.proto
----------------------------------------------------------------------
diff --git a/protocol/src/main/protobuf/User.proto b/protocol/src/main/protobuf/User.proto
index f78ea2b..96d0477 100644
--- a/protocol/src/main/protobuf/User.proto
+++ b/protocol/src/main/protobuf/User.proto
@@ -361,7 +361,7 @@ message ResultColumnMetadata {
   optional ColumnSearchability searchability = 13;
 
   /*
-   * Defaults to READ_ONLU
+   * Defaults to READ_ONLY
    */
   optional ColumnUpdatability updatability = 14;
 


Mime
View raw message