Skip to content

Commit

Permalink
feat(format): introduce ADBC_VERSION_1_1_0
Browse files Browse the repository at this point in the history
Fixes apache#317.

Co-authored-by: Matt Topol <zotthewizard@gmail.com>
  • Loading branch information
lidavidm and zeroshade committed May 22, 2023
1 parent c3202e6 commit 02bd0a0
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 9 deletions.
214 changes: 213 additions & 1 deletion adbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ struct ADBC_EXPORT AdbcError {
/// point to an AdbcDriver.
#define ADBC_VERSION_1_0_0 1000000

/// \brief ADBC revision 1.1.0.
///
/// When passed to an AdbcDriverInitFunc(), the driver parameter must
/// point to an AdbcDriver.
///
/// \addtogroup adbc-1.1.0
#define ADBC_VERSION_1_1_0 1001000

/// \brief Canonical option value for enabling an option.
///
/// For use as the value in SetOption calls.
Expand All @@ -288,6 +296,31 @@ struct ADBC_EXPORT AdbcError {
/// For use as the value in SetOption calls.
#define ADBC_OPTION_VALUE_DISABLED "false"

/// \brief Canonical option name for URIs.
///
/// Should be used as the expected option name to specify a URI for
/// any ADBC driver.
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_OPTION_URI "uri"
/// \brief Canonical option name for usernames.
///
/// Should be used as the expected option name to specify a username
/// to a driver for authentication.
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_OPTION_USERNAME "username"
/// \brief Canonical option name for passwords.
///
/// Should be used as the expected option name to specify a password
/// for authentication to a driver.
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_OPTION_PASSWORD "password"

/// \brief The database vendor/product name (e.g. the server name).
/// (type: utf8).
///
Expand Down Expand Up @@ -316,6 +349,16 @@ struct ADBC_EXPORT AdbcError {
/// \see AdbcConnectionGetInfo
#define ADBC_INFO_DRIVER_ARROW_VERSION 102

/// \brief The current catalog (type: utf8).
///
/// \see AdbcConnectionGetInfo
#define ADBC_INFO_CURRENT_CATALOG 200

/// \brief The current schema (type: utf8).
///
/// \see AdbcConnectionGetInfo
#define ADBC_INFO_CURRENT_DB_SCHEMA 201

/// \brief Return metadata on catalogs, schemas, tables, and columns.
///
/// \see AdbcConnectionGetObjects
Expand Down Expand Up @@ -349,6 +392,47 @@ struct ADBC_EXPORT AdbcError {
/// \see AdbcConnectionSetOption
#define ADBC_CONNECTION_OPTION_READ_ONLY "adbc.connection.readonly"

/// \brief The name of the canonical option for setting the current
/// catalog.
///
/// \see AdbcConnectionSetOption
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_CONNECTION_OPTION_CURRENT_CATALOG "adbc.connection.catalog"

/// \brief The name of the canonical option for setting the current
/// schema.
///
/// \see AdbcConnectionSetOption
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_CONNECTION_OPTION_CURRENT_DB_SCHEMA "adbc.connection.db_schema"

/// \brief The name of the canonical option for making query execution
/// nonblocking.
///
/// When enabled, AdbcStatementExecutePartitions will return
/// partitions as soon as they are available, instead of returning
/// them all at the end. When there are no more to return, it will
/// return an empty set of partitions. AdbcStatementExecuteQuery and
/// AdbcStatementExecuteSchema are not affected.
///
/// The default is ADBC_OPTION_VALUE_DISABLED.
///
/// \see AdbcStatementSetOption
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_STATEMENT_OPTION_INCREMENTAL "adbc.statement.exec.incremental"

/// \brief The name of the property for getting the progress of a query.
///
/// Progress is a value in [0.0, 1.0].
///
/// \see AdbcStatementGetDouble
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_STATEMENT_PROPERTY_PROGRESS "adbc.statement.exec.progress"

/// \brief The name of the canonical option for setting the isolation
/// level of a transaction.
///
Expand Down Expand Up @@ -458,6 +542,17 @@ struct ADBC_EXPORT AdbcError {
/// table does not exist (ADBC_STATUS_NOT_FOUND) or does not match
/// the schema of the data to append (ADBC_STATUS_ALREADY_EXISTS).
#define ADBC_INGEST_OPTION_MODE_APPEND "adbc.ingest.mode.append"
/// \brief Create the table and insert data; drop the original table
/// if it already exists.
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_INGEST_OPTION_MODE_REPLACE "adbc.ingest.mode.replace"
/// \brief Insert data; create the table if it does not exist, or
/// error if the table exists, but the schema does not match the
/// schema of the data to append (ADBC_STATUS_ALREADY_EXISTS).
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_INGEST_OPTION_MODE_CREATE_APPEND "adbc.ingest.mode.create_append"

/// @}

Expand Down Expand Up @@ -667,8 +762,54 @@ struct ADBC_EXPORT AdbcDriver {
struct AdbcError*);
AdbcStatusCode (*StatementSetSubstraitPlan)(struct AdbcStatement*, const uint8_t*,
size_t, struct AdbcError*);

/// \defgroup adbc-1.1.0 ADBC API Revision 1.1.0
///
/// Functions added in ADBC 1.1.0. For backwards compatibility,
/// these members must not be accessed unless the version passed to
/// the AdbcDriverInitFunc is greater than or equal to
/// ADBC_VERSION_1_1_0.
///
/// For a 1.0.0 driver being loaded by a 1.1.0 driver manager: the
/// 1.1.0 manager will allocate the new, expanded AdbcDriver struct
/// and attempt to have the driver initialize it with
/// ADBC_VERSION_1_1_0. This must return an error, after which the
/// driver will try again with ADBC_VERSION_1_0_0. The driver must
/// not access the new fields.
///
/// For a 1.1.0 driver being loaded by a 1.0.0 driver manager: the
/// 1.0.0 manager will allocate the old AdbcDriver struct and
/// attempt to have the driver initialize it with
/// ADBC_VERSION_1_0_0. The driver must not access the new fields,
/// and should initialize the old fields.
///
/// @{

AdbcStatusCode (*StatementCancel)(struct AdbcStatement*, struct AdbcError*);
AdbcStatusCode (*StatementExecuteSchema)(struct AdbcStatement*, struct ArrowSchema*,
struct AdbcError*);
AdbcStatusCode (*StatementGetDouble)(struct AdbcStatement*, const char*, double*,
struct AdbcError*);

/// Pad the struct to have 64 pointers. Space reserved for future
/// growth.
void* reserved[32];

/// @}
};

/// \brief The size of the AdbcDriver structure in ADBC 1.0.0.
/// Drivers written for ADBC 1.1.0 and later should never touch more
/// than this portion of an AdbcDriver struct when given
/// ADBC_VERSION_1_0_0.
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
#define ADBC_DRIVER_1_0_0_SIZE \
((size_t)(((uintptr_t)(&((struct AdbcDriver*)NULL) /* NOLINT(runtime/casting) */ \
->StatementSetSubstraitPlan)) + \
sizeof(void*)))

/// @}

/// \addtogroup adbc-database
Expand Down Expand Up @@ -799,6 +940,10 @@ AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
/// for ADBC usage. Drivers/vendors will ignore requests for
/// unrecognized codes (the row will be omitted from the result).
///
/// Since ADBC 1.1.0: the range [500, 1_000) is reserved for "XDBC"
/// information, which is the same metadata provided by the same info
/// code range in the Arrow Flight SQL GetSqlInfo RPC.
///
/// \param[in] connection The connection to query.
/// \param[in] info_codes A list of metadata codes to fetch, or NULL
/// to fetch all.
Expand Down Expand Up @@ -1044,6 +1189,9 @@ AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
///
/// This invalidates any prior result sets.
///
/// Since ADBC 1.1.0: releasing the returned ArrowArrayStream without
/// consuming it fully is equivalent to calling AdbcStatementCancel.
///
/// \param[in] statement The statement to execute.
/// \param[out] out The results. Pass NULL if the client does not
/// expect a result set.
Expand All @@ -1056,6 +1204,25 @@ AdbcStatusCode AdbcStatementExecuteQuery(struct AdbcStatement* statement,
struct ArrowArrayStream* out,
int64_t* rows_affected, struct AdbcError* error);

/// \brief Get the schema of the result set of a query without
/// executing it.
///
/// This invalidates any prior result sets.
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
///
/// \param[in] statement The statement to execute.
/// \param[out] out The result schema.
/// \param[out] error An optional location to return an error
/// message if necessary.
///
/// \return ADBC_STATUS_NOT_IMPLEMENTED if the driver does not support this.
ADBC_EXPORT
AdbcStatusCode AdbcStatementExecuteSchema(struct AdbcStatement* statement,
struct ArrowSchema* schema,
struct AdbcError* error);

/// \brief Turn this statement into a prepared statement to be
/// executed multiple times.
///
Expand Down Expand Up @@ -1138,6 +1305,43 @@ AdbcStatusCode AdbcStatementBindStream(struct AdbcStatement* statement,
struct ArrowArrayStream* stream,
struct AdbcError* error);

/// \brief Cancel execution of an in-progress query.
///
/// This can be called during AdbcStatementExecuteQuery (or similar),
/// or while consuming an ArrowArrayStream returned from such.
/// Calling this function should make the other functions return
/// ADBC_STATUS_CANCELLED or ECANCELED (for ArrowArrayStream).
///
/// This must always be thread-safe (other operations are not).
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
///
/// \param[in] statement The statement to cancel.
/// \param[out] error An optional location to return an error
/// message if necessary.
///
/// \return ADBC_STATUS_INVALID_STATE if there is no query to cancel.
/// \return ADBC_STATUS_UNKNOWN if the query could not be cancelled.
ADBC_EXPORT
AdbcStatusCode AdbcStatementCancel(struct AdbcStatement* statement,
struct AdbcError* error);

/// \brief Get a double property of the statement.
///
/// This must always be thread-safe (other operations are not).
///
/// \since ADBC API revision 1.1.0
/// \addtogroup adbc-1.1.0
/// \param[in] statement The statement to cancel.
/// \param[in] key The property to get.
/// \param[out] value The property value.
/// \param[out] error An optional location to return an error
/// message if necessary.
/// \return ADBC_STATUS_NOT_IMPLEMENTED if the property is not recognized.
AdbcStatusCode AdbcStatementGetDouble(struct AdbcStatement* statement, const char* key,
double* value, struct AdbcError* error);

/// \brief Get the schema for bound parameters.
///
/// This retrieves an Arrow schema describing the number, names, and
Expand Down Expand Up @@ -1198,7 +1402,15 @@ AdbcStatusCode AdbcStatementExecutePartitions(struct AdbcStatement* statement,
/// driver.
///
/// Although drivers may choose any name for this function, the
/// recommended name is "AdbcDriverInit".
/// recommended name is "AdbcDriverInit", or a name derived from the
/// name of the driver's shared library as follows: remove the 'lib'
/// prefix (on Unix systems) and all file extensions, then PascalCase
/// the driver name, append Init, and prepend Adbc (if not already
/// there). For example:
///
/// - libadbc_driver_sqlite.so.2.0.0 -> AdbcDriverSqliteInit
/// - adbc_driver_sqlite.dll -> AdbcDriverSqliteInit
/// - proprietary_driver.dll -> AdbcProprietaryDriverInit
///
/// \param[in] version The ADBC revision to attempt to initialize (see
/// ADBC_VERSION_1_0_0).
Expand Down
2 changes: 1 addition & 1 deletion c/driver/postgresql/postgresql.cc
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ AdbcStatusCode AdbcDriverInit(int version, void* raw_driver, struct AdbcError* e
if (version != ADBC_VERSION_1_0_0) return ADBC_STATUS_NOT_IMPLEMENTED;

auto* driver = reinterpret_cast<struct AdbcDriver*>(raw_driver);
std::memset(driver, 0, sizeof(*driver));
std::memset(driver, 0, ADBC_DRIVER_1_0_0_SIZE);
driver->DatabaseInit = PostgresDatabaseInit;
driver->DatabaseNew = PostgresDatabaseNew;
driver->DatabaseRelease = PostgresDatabaseRelease;
Expand Down
2 changes: 1 addition & 1 deletion c/driver/sqlite/sqlite.c
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ AdbcStatusCode SqliteDriverInit(int version, void* raw_driver, struct AdbcError*
}

struct AdbcDriver* driver = (struct AdbcDriver*)raw_driver;
memset(driver, 0, sizeof(*driver));
memset(driver, 0, ADBC_DRIVER_1_0_0_SIZE);
driver->DatabaseInit = SqliteDatabaseInit;
driver->DatabaseNew = SqliteDatabaseNew;
driver->DatabaseRelease = SqliteDatabaseRelease;
Expand Down
Loading

0 comments on commit 02bd0a0

Please sign in to comment.