diff --git a/c/driver_manager/adbc_driver_manager.cc b/c/driver_manager/adbc_driver_manager.cc index 15d98c00bd..7cf2c424b9 100644 --- a/c/driver_manager/adbc_driver_manager.cc +++ b/c/driver_manager/adbc_driver_manager.cc @@ -1764,6 +1764,12 @@ AdbcStatusCode StatementSetSubstraitPlan(struct AdbcStatement*, const uint8_t*, return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode StatementRequestSchema(struct AdbcStatement*, struct ArrowSchema*, + struct AdbcError* error) { + SetError(error, "AdbcStatementRequestSchema not implemented"); + return ADBC_STATUS_NOT_IMPLEMENTED; +} + /// Temporary state while the database is being configured. struct TempDatabase { std::unordered_map options; @@ -3159,6 +3165,17 @@ AdbcStatusCode AdbcStatementSetSubstraitPlan(struct AdbcStatement* statement, error); } +AdbcStatusCode AdbcStatementRequestSchema(struct AdbcStatement* statement, + struct ArrowSchema* schema, + struct AdbcError* error) { + if (!statement->private_driver) { + SetError(error, "AdbcStatementRequestSchema: must call AdbcStatementNew first"); + return ADBC_STATUS_INVALID_STATE; + } + INIT_ERROR(error, statement); + return statement->private_driver->StatementRequestSchema(statement, schema, error); +} + const char* AdbcStatusCodeMessage(AdbcStatusCode code) { #define CASE(CONSTANT) \ case ADBC_STATUS_##CONSTANT: \ @@ -3382,6 +3399,10 @@ AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int vers FILL_DEFAULT(driver, StatementSetOptionDouble); FILL_DEFAULT(driver, StatementSetOptionInt); } + if (version >= ADBC_VERSION_1_2_0) { + auto* driver = reinterpret_cast(raw_driver); + FILL_DEFAULT(driver, StatementRequestSchema); + } return ADBC_STATUS_OK; diff --git a/c/include/arrow-adbc/adbc.h b/c/include/arrow-adbc/adbc.h index 5982e31572..70696c4a6e 100644 --- a/c/include/arrow-adbc/adbc.h +++ b/c/include/arrow-adbc/adbc.h @@ -1290,6 +1290,9 @@ struct ADBC_EXPORT AdbcDriver { AdbcStatusCode (*StatementExecuteMulti)(struct AdbcStatement*, struct AdbcMultiResultSet*, struct AdbcError*); + AdbcStatusCode (*StatementRequestSchema)(struct AdbcStatement*, struct ArrowSchema*, + struct AdbcError*); + /// @} }; @@ -2293,6 +2296,36 @@ AdbcStatusCode AdbcStatementExecuteSchema(struct AdbcStatement* statement, struct ArrowSchema* schema, struct AdbcError* error); +/// \brief Request the schema of the next statement execution +/// +/// Allows the caller to request a specific schema based on prior +/// information or user input. This may be used to ensure a +/// consistent schema when executing queries against a database +/// with row-based types (e.g., SQLite) or a database whose types +/// are implemented with row-based parameters where Arrow prefers +/// type-level parameters (e.g., NUMERIC for PostgreSQL). +/// +/// The provided schema is a request and not a guarantee (i.e., +/// callers must use the schema provided by the output stream to +/// interpret the result). +/// +/// Calling AdbcStatementRequestSchema() must not affect the result +/// of AdbcStatementExecuteSchema (which always infers its result +/// from the input query). +/// +/// \since ADBC API revision 1.2.0 +/// +/// \param[in] statement The statement to execute. +/// \param[in] schema The requested 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 AdbcStatementRequestSchema(struct AdbcStatement* statement, + struct ArrowSchema* schema, + struct AdbcError* error); + /// \brief Turn this statement into a prepared statement to be /// executed multiple times. /// diff --git a/go/adbc/drivermgr/adbc_driver_manager.cc b/go/adbc/drivermgr/adbc_driver_manager.cc index 15d98c00bd..7cf2c424b9 100644 --- a/go/adbc/drivermgr/adbc_driver_manager.cc +++ b/go/adbc/drivermgr/adbc_driver_manager.cc @@ -1764,6 +1764,12 @@ AdbcStatusCode StatementSetSubstraitPlan(struct AdbcStatement*, const uint8_t*, return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode StatementRequestSchema(struct AdbcStatement*, struct ArrowSchema*, + struct AdbcError* error) { + SetError(error, "AdbcStatementRequestSchema not implemented"); + return ADBC_STATUS_NOT_IMPLEMENTED; +} + /// Temporary state while the database is being configured. struct TempDatabase { std::unordered_map options; @@ -3159,6 +3165,17 @@ AdbcStatusCode AdbcStatementSetSubstraitPlan(struct AdbcStatement* statement, error); } +AdbcStatusCode AdbcStatementRequestSchema(struct AdbcStatement* statement, + struct ArrowSchema* schema, + struct AdbcError* error) { + if (!statement->private_driver) { + SetError(error, "AdbcStatementRequestSchema: must call AdbcStatementNew first"); + return ADBC_STATUS_INVALID_STATE; + } + INIT_ERROR(error, statement); + return statement->private_driver->StatementRequestSchema(statement, schema, error); +} + const char* AdbcStatusCodeMessage(AdbcStatusCode code) { #define CASE(CONSTANT) \ case ADBC_STATUS_##CONSTANT: \ @@ -3382,6 +3399,10 @@ AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int vers FILL_DEFAULT(driver, StatementSetOptionDouble); FILL_DEFAULT(driver, StatementSetOptionInt); } + if (version >= ADBC_VERSION_1_2_0) { + auto* driver = reinterpret_cast(raw_driver); + FILL_DEFAULT(driver, StatementRequestSchema); + } return ADBC_STATUS_OK; diff --git a/go/adbc/drivermgr/arrow-adbc/adbc.h b/go/adbc/drivermgr/arrow-adbc/adbc.h index 5982e31572..70696c4a6e 100644 --- a/go/adbc/drivermgr/arrow-adbc/adbc.h +++ b/go/adbc/drivermgr/arrow-adbc/adbc.h @@ -1290,6 +1290,9 @@ struct ADBC_EXPORT AdbcDriver { AdbcStatusCode (*StatementExecuteMulti)(struct AdbcStatement*, struct AdbcMultiResultSet*, struct AdbcError*); + AdbcStatusCode (*StatementRequestSchema)(struct AdbcStatement*, struct ArrowSchema*, + struct AdbcError*); + /// @} }; @@ -2293,6 +2296,36 @@ AdbcStatusCode AdbcStatementExecuteSchema(struct AdbcStatement* statement, struct ArrowSchema* schema, struct AdbcError* error); +/// \brief Request the schema of the next statement execution +/// +/// Allows the caller to request a specific schema based on prior +/// information or user input. This may be used to ensure a +/// consistent schema when executing queries against a database +/// with row-based types (e.g., SQLite) or a database whose types +/// are implemented with row-based parameters where Arrow prefers +/// type-level parameters (e.g., NUMERIC for PostgreSQL). +/// +/// The provided schema is a request and not a guarantee (i.e., +/// callers must use the schema provided by the output stream to +/// interpret the result). +/// +/// Calling AdbcStatementRequestSchema() must not affect the result +/// of AdbcStatementExecuteSchema (which always infers its result +/// from the input query). +/// +/// \since ADBC API revision 1.2.0 +/// +/// \param[in] statement The statement to execute. +/// \param[in] schema The requested 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 AdbcStatementRequestSchema(struct AdbcStatement* statement, + struct ArrowSchema* schema, + struct AdbcError* error); + /// \brief Turn this statement into a prepared statement to be /// executed multiple times. ///