You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by li...@apache.org on 2023/06/06 14:11:34 UTC

[arrow-adbc] branch spec-1.1.0 updated: feat(format): introduce ADBC API revision 1.1.0 (#692)

This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch spec-1.1.0
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/spec-1.1.0 by this push:
     new de770ef5 feat(format): introduce ADBC API revision 1.1.0 (#692)
de770ef5 is described below

commit de770ef562958b625e9a121b451a29257c172bcf
Author: David Li <li...@gmail.com>
AuthorDate: Tue Jun 6 10:11:27 2023 -0400

    feat(format): introduce ADBC API revision 1.1.0 (#692)
    
    Fixes #317.
    
    ---------
    
    Co-authored-by: Matt Topol <zo...@gmail.com>
    Co-authored-by: Sutou Kouhei <ko...@cozmixng.org>
---
 .pre-commit-config.yaml                            |   4 +-
 adbc.h                                             | 598 ++++++++++++++++++++-
 c/driver/postgresql/postgresql.cc                  |   3 +-
 c/driver/sqlite/sqlite.c                           |   2 +-
 c/driver_manager/adbc_driver_manager.cc            |  68 ++-
 c/driver_manager/adbc_driver_manager_test.cc       |  34 ++
 go/adbc/adbc.go                                    |  93 +++-
 go/adbc/infocode_string.go                         |   7 +-
 go/adbc/pkg/_tmpl/driver.go.tmpl                   |   2 +-
 go/adbc/pkg/flightsql/driver.go                    |   2 +-
 go/adbc/pkg/snowflake/driver.go                    |   2 +-
 .../org/apache/arrow/adbc/core/AdbcConnection.java |  38 +-
 .../org/apache/arrow/adbc/core/AdbcDatabase.java   |   2 +-
 .../org/apache/arrow/adbc/core/AdbcDriver.java     |  35 +-
 .../org/apache/arrow/adbc/core/AdbcInfoCode.java   |  17 +-
 .../org/apache/arrow/adbc/core/AdbcOptionKey.java  |  69 +++
 .../core/{AdbcDriver.java => AdbcOptions.java}     |  32 +-
 .../org/apache/arrow/adbc/core/AdbcStatement.java  |  51 +-
 .../org/apache/arrow/adbc/core/BulkIngestMode.java |  15 +-
 19 files changed, 1026 insertions(+), 48 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8353583c..ab8b4b29 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -43,12 +43,12 @@ repos:
     - id: cmake-format
       args: [--in-place]
   - repo: https://github.com/cpplint/cpplint
-    rev: 1.6.0
+    rev: 1.6.1
     hooks:
     - id: cpplint
       args:
         # From Arrow's config
-        - "--filter=-whitespace/comments,-readability/casting,-readability/todo,-readability/alt_tokens,-build/header_guard,-build/c++11,-build/include_order,-build/include_subdir"
+        - "--filter=-whitespace/comments,-whitespace/indent,-readability/braces,-readability/casting,-readability/todo,-readability/alt_tokens,-build/header_guard,-build/c++11,-build/include_order,-build/include_subdir"
         - "--linelength=90"
         - "--verbose=2"
   - repo: https://github.com/golangci/golangci-lint
diff --git a/adbc.h b/adbc.h
index 154e8812..756288da 100644
--- a/adbc.h
+++ b/adbc.h
@@ -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.
@@ -288,6 +296,37 @@ 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.
+///
+/// The type is char*.
+///
+/// \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.
+///
+/// The type is char*.
+///
+/// \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.
+///
+/// The type is char*.
+///
+/// \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).
 ///
@@ -315,6 +354,16 @@ struct ADBC_EXPORT AdbcError {
 ///
 /// \see AdbcConnectionGetInfo
 #define ADBC_INFO_DRIVER_ARROW_VERSION 102
+/// \brief The driver ADBC API version (type: int64).
+///
+/// The value should be one of the ADBC_VERSION constants.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \see AdbcConnectionGetInfo
+/// \see ADBC_VERSION_1_0_0
+/// \see ADBC_VERSION_1_1_0
+#define ADBC_INFO_DRIVER_ADBC_VERSION 103
 
 /// \brief Return metadata on catalogs, schemas, tables, and columns.
 ///
@@ -340,15 +389,68 @@ struct ADBC_EXPORT AdbcError {
 /// \brief The name of the canonical option for whether autocommit is
 ///   enabled.
 ///
+/// The type is char*.
+///
 /// \see AdbcConnectionSetOption
 #define ADBC_CONNECTION_OPTION_AUTOCOMMIT "adbc.connection.autocommit"
 
 /// \brief The name of the canonical option for whether the current
 ///   connection should be restricted to being read-only.
 ///
+/// The type is char*.
+///
 /// \see AdbcConnectionSetOption
 #define ADBC_CONNECTION_OPTION_READ_ONLY "adbc.connection.readonly"
 
+/// \brief The name of the canonical option for the current catalog.
+///
+/// The type is char*.
+///
+/// \see AdbcConnectionGetOption
+/// \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 the current schema.
+///
+/// The type is char*.
+///
+/// \see AdbcConnectionGetOption
+/// \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.
+///
+/// The type is char*.
+///
+/// \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 option for getting the progress of a query.
+///
+/// Progress is a value in [0.0, 1.0].
+///
+/// The type is double.
+///
+/// \see AdbcStatementGetOptionDouble
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+#define ADBC_STATEMENT_OPTION_PROGRESS "adbc.statement.exec.progress"
+
 /// \brief The name of the canonical option for setting the isolation
 ///   level of a transaction.
 ///
@@ -357,6 +459,8 @@ struct ADBC_EXPORT AdbcError {
 /// isolation level is not supported by a driver, it should return an
 /// appropriate error.
 ///
+/// The type is char*.
+///
 /// \see AdbcConnectionSetOption
 #define ADBC_CONNECTION_OPTION_ISOLATION_LEVEL \
   "adbc.connection.transaction.isolation_level"
@@ -449,8 +553,12 @@ struct ADBC_EXPORT AdbcError {
 /// exist.  If the table exists but has a different schema,
 /// ADBC_STATUS_ALREADY_EXISTS should be raised.  Else, data should be
 /// appended to the target table.
+///
+/// The type is char*.
 #define ADBC_INGEST_OPTION_TARGET_TABLE "adbc.ingest.target_table"
 /// \brief Whether to create (the default) or append.
+///
+/// The type is char*.
 #define ADBC_INGEST_OPTION_MODE "adbc.ingest.mode"
 /// \brief Create the table and insert data; error if the table exists.
 #define ADBC_INGEST_OPTION_MODE_CREATE "adbc.ingest.mode.create"
@@ -458,6 +566,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"
 
 /// @}
 
@@ -667,8 +786,89 @@ 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 (*DatabaseGetOption)(struct AdbcDatabase*, const char*, const char**,
+                                      struct AdbcError*);
+  AdbcStatusCode (*DatabaseGetOptionInt)(struct AdbcDatabase*, const char*, int64_t*,
+                                         struct AdbcError*);
+  AdbcStatusCode (*DatabaseGetOptionDouble)(struct AdbcDatabase*, const char*, double*,
+                                            struct AdbcError*);
+  AdbcStatusCode (*DatabaseSetOptionInt)(struct AdbcDatabase*, const char*, int64_t,
+                                         struct AdbcError*);
+  AdbcStatusCode (*DatabaseSetOptionDouble)(struct AdbcDatabase*, const char*, double,
+                                            struct AdbcError*);
+
+  AdbcStatusCode (*ConnectionGetOption)(struct AdbcConnection*, const char*, const char**,
+                                        struct AdbcError*);
+  AdbcStatusCode (*ConnectionGetOptionInt)(struct AdbcConnection*, const char*, int64_t*,
+                                           struct AdbcError*);
+  AdbcStatusCode (*ConnectionGetOptionDouble)(struct AdbcConnection*, const char*,
+                                              double*, struct AdbcError*);
+  AdbcStatusCode (*ConnectionSetOptionInt)(struct AdbcConnection*, const char*, int64_t,
+                                           struct AdbcError*);
+  AdbcStatusCode (*ConnectionSetOptionDouble)(struct AdbcConnection*, const char*, double,
+                                              struct AdbcError*);
+
+  AdbcStatusCode (*StatementCancel)(struct AdbcStatement*, struct AdbcError*);
+  AdbcStatusCode (*StatementExecuteSchema)(struct AdbcStatement*, struct ArrowSchema*,
+                                           struct AdbcError*);
+  AdbcStatusCode (*StatementGetOption)(struct AdbcStatement*, const char*, const char**,
+                                       struct AdbcError*);
+  AdbcStatusCode (*StatementGetOptionInt)(struct AdbcStatement*, const char*, int64_t*,
+                                          struct AdbcError*);
+  AdbcStatusCode (*StatementGetOptionDouble)(struct AdbcStatement*, const char*, double*,
+                                             struct AdbcError*);
+  AdbcStatusCode (*StatementSetOptionInt)(struct AdbcStatement*, const char*, int64_t,
+                                          struct AdbcError*);
+  AdbcStatusCode (*StatementSetOptionDouble)(struct AdbcStatement*, const char*, double,
+                                             struct AdbcError*);
+
+  /// Pad the struct to have 96 pointers.  Space reserved for future growth.
+  void* reserved[50];
+
+  /// @}
 };
 
+/// \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 (offsetof(struct AdbcDriver, DatabaseGetOption))
+
+/// \brief The size of the AdbcDriver structure in ADBC 1.1.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_1_0.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+#define ADBC_DRIVER_1_1_0_SIZE (sizeof(struct AdbcDriver))
+
 /// @}
 
 /// \addtogroup adbc-database
@@ -684,16 +884,121 @@ struct ADBC_EXPORT AdbcDriver {
 ADBC_EXPORT
 AdbcStatusCode AdbcDatabaseNew(struct AdbcDatabase* database, struct AdbcError* error);
 
+/// \brief Get a string option of the database.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// The returned option value is only valid until the next call to
+/// GetOption or Release.
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] database The database.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcDatabaseGetOption(struct AdbcDatabase* database, const char* key,
+                                     const char** value, struct AdbcError* error);
+
+/// \brief Get an integer option of the database.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the integer
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] database The database.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcDatabaseGetOptionInt(struct AdbcDatabase* database, const char* key,
+                                        int64_t* value, struct AdbcError* error);
+
+/// \brief Get a double option of the database.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the double
+/// representation of an integer option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] database The database.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcDatabaseGetOptionDouble(struct AdbcDatabase* database, const char* key,
+                                           double* value, struct AdbcError* error);
+
 /// \brief Set a char* option.
 ///
 /// Options may be set before AdbcDatabaseInit.  Some drivers may
 /// support setting options after initialization as well.
 ///
+/// \param[in] database The database.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
 /// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
 ADBC_EXPORT
 AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* key,
                                      const char* value, struct AdbcError* error);
 
+/// \brief Set an integer option on a database.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] database The database.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
+ADBC_EXPORT
+AdbcStatusCode AdbcDatabaseSetOptionInt(struct AdbcDatabase* database, const char* key,
+                                        int64_t value, struct AdbcError* error);
+
+/// \brief Set a double option on a database.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] database The database.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
+ADBC_EXPORT
+AdbcStatusCode AdbcDatabaseSetOptionDouble(struct AdbcDatabase* database, const char* key,
+                                           double value, struct AdbcError* error);
+
 /// \brief Finish setting options and initialize the database.
 ///
 /// Some drivers may support setting options after initialization
@@ -730,11 +1035,52 @@ AdbcStatusCode AdbcConnectionNew(struct AdbcConnection* connection,
 /// Options may be set before AdbcConnectionInit.  Some drivers may
 /// support setting options after initialization as well.
 ///
+/// \param[in] connection The database connection.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
 /// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
 ADBC_EXPORT
 AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const char* key,
                                        const char* value, struct AdbcError* error);
 
+/// \brief Set an integer option.
+///
+/// Options may be set before AdbcConnectionInit.  Some drivers may
+/// support setting options after initialization as well.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] connection The database connection.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
+ADBC_EXPORT
+AdbcStatusCode AdbcConnectionSetOptionInt(struct AdbcConnection* connection,
+                                          const char* key, int64_t value,
+                                          struct AdbcError* error);
+
+/// \brief Set a double option.
+///
+/// Options may be set before AdbcConnectionInit.  Some drivers may
+/// support setting options after initialization as well.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] connection The database connection.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
+ADBC_EXPORT
+AdbcStatusCode AdbcConnectionSetOptionDouble(struct AdbcConnection* connection,
+                                             const char* key, double value,
+                                             struct AdbcError* error);
+
 /// \brief Finish setting options and initialize the connection.
 ///
 /// Some drivers may support setting options after initialization
@@ -765,6 +1111,8 @@ AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
 /// concurrent active statements and it must execute a SQL query
 /// internally in order to implement the metadata function).
 ///
+/// This AdbcConnection must outlive the returned ArrowArrayStream.
+///
 /// Some functions accept "search pattern" arguments, which are
 /// strings that can contain the special character "%" to match zero
 /// or more characters, or "_" to match exactly one character.  (See
@@ -799,6 +1147,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.
@@ -891,6 +1243,8 @@ AdbcStatusCode AdbcConnectionGetInfo(struct AdbcConnection* connection,
 /// | fk_table                 | utf8 not null           |
 /// | fk_column_name           | utf8 not null           |
 ///
+/// This AdbcConnection must outlive the returned ArrowArrayStream.
+///
 /// \param[in] connection The database connection.
 /// \param[in] depth The level of nesting to display. If 0, display
 ///   all levels. If 1, display only catalogs (i.e.  catalog_schemas
@@ -922,6 +1276,80 @@ AdbcStatusCode AdbcConnectionGetObjects(struct AdbcConnection* connection, int d
                                         struct ArrowArrayStream* out,
                                         struct AdbcError* error);
 
+/// \brief Get a string option of the connection.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// The returned option value is only valid until the next call to
+/// GetOption or Release.
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] connection The database connection.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcConnectionGetOption(struct AdbcConnection* connection, const char* key,
+                                       const char** value, struct AdbcError* error);
+
+/// \brief Get an integer option of the connection.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] connection The database connection.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcConnectionGetOptionInt(struct AdbcConnection* connection,
+                                          const char* key, int64_t* value,
+                                          struct AdbcError* error);
+
+/// \brief Get a double option of the connection.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] connection The database connection.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcConnectionGetOptionDouble(struct AdbcConnection* connection,
+                                             const char* key, double* value,
+                                             struct AdbcError* error);
+
 /// \brief Get the Arrow schema of a table.
 ///
 /// \param[in] connection The database connection.
@@ -945,6 +1373,8 @@ AdbcStatusCode AdbcConnectionGetTableSchema(struct AdbcConnection* connection,
 /// ---------------|--------------
 /// table_type     | utf8 not null
 ///
+/// This AdbcConnection must outlive the returned ArrowArrayStream.
+///
 /// \param[in] connection The database connection.
 /// \param[out] out The result set.
 /// \param[out] error Error details, if an error occurs.
@@ -973,6 +1403,8 @@ AdbcStatusCode AdbcConnectionGetTableTypes(struct AdbcConnection* connection,
 ///
 /// A partition can be retrieved from AdbcPartitions.
 ///
+/// This AdbcConnection must outlive the returned ArrowArrayStream.
+///
 /// \param[in] connection The connection to use.  This does not have
 ///   to be the same connection that the partition was created on.
 /// \param[in] serialized_partition The partition descriptor.
@@ -1042,7 +1474,11 @@ AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
 
 /// \brief Execute a statement and get the results.
 ///
-/// This invalidates any prior result sets.
+/// This invalidates any prior result sets.  This AdbcStatement must
+/// outlive the returned ArrowArrayStream.
+///
+/// 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
@@ -1056,6 +1492,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.
 ///
@@ -1138,6 +1593,102 @@ 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 (from ADBC functions) or ECANCELED (from
+/// methods of 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 string option of the statement.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// The returned option value is only valid until the next call to
+/// GetOption or Release.
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] statement The statement.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcStatementGetOption(struct AdbcStatement* statement, const char* key,
+                                      const char** value, struct AdbcError* error);
+
+/// \brief Get an integer option of the statement.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] statement The statement.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcStatementGetOptionInt(struct AdbcStatement* statement, const char* key,
+                                         int64_t* value, struct AdbcError* error);
+
+/// \brief Get a double option of the statement.
+///
+/// This must always be thread-safe (other operations are not).
+///
+/// For standard options, drivers must always support getting the
+/// option value (if they support getting option values at all) via
+/// the type specified in the option.  (For example, an option set via
+/// SetOptionDouble must be retrievable via GetOptionDouble.)  Drivers
+/// may also support getting a converted option value via other
+/// getters if needed.  (For example, getting the string
+/// representation of a double option.)
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] statement The statement.
+/// \param[in] key The option to get.
+/// \param[out] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_FOUND if the option is not recognized.
+AdbcStatusCode AdbcStatementGetOptionDouble(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
@@ -1159,10 +1710,45 @@ AdbcStatusCode AdbcStatementGetParameterSchema(struct AdbcStatement* statement,
                                                struct AdbcError* error);
 
 /// \brief Set a string option on a statement.
+/// \param[in] statement The statement.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized.
 ADBC_EXPORT
 AdbcStatusCode AdbcStatementSetOption(struct AdbcStatement* statement, const char* key,
                                       const char* value, struct AdbcError* error);
 
+/// \brief Set an integer option on a statement.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] statement The statement.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
+ADBC_EXPORT
+AdbcStatusCode AdbcStatementSetOptionInt(struct AdbcStatement* statement, const char* key,
+                                         int64_t value, struct AdbcError* error);
+
+/// \brief Set a double option on a statement.
+///
+/// \since ADBC API revision 1.1.0
+/// \addtogroup adbc-1.1.0
+/// \param[in] statement The statement.
+/// \param[in] key The option to set.
+/// \param[in] value The option value.
+/// \param[out] error An optional location to return an error
+///   message if necessary.
+/// \return ADBC_STATUS_NOT_IMPLEMENTED if the option is not recognized
+ADBC_EXPORT
+AdbcStatusCode AdbcStatementSetOptionDouble(struct AdbcStatement* statement,
+                                            const char* key, double value,
+                                            struct AdbcError* error);
+
 /// \addtogroup adbc-statement-partition
 /// @{
 
@@ -1198,7 +1784,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).
diff --git a/c/driver/postgresql/postgresql.cc b/c/driver/postgresql/postgresql.cc
index 51f152ac..e9a2338b 100644
--- a/c/driver/postgresql/postgresql.cc
+++ b/c/driver/postgresql/postgresql.cc
@@ -471,9 +471,10 @@ extern "C" {
 ADBC_EXPORT
 AdbcStatusCode AdbcDriverInit(int version, void* raw_driver, struct AdbcError* error) {
   if (version != ADBC_VERSION_1_0_0) return ADBC_STATUS_NOT_IMPLEMENTED;
+  if (!raw_driver) return ADBC_STATUS_INVALID_ARGUMENT;
 
   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;
diff --git a/c/driver/sqlite/sqlite.c b/c/driver/sqlite/sqlite.c
index d671bc75..9d78dfb1 100644
--- a/c/driver/sqlite/sqlite.c
+++ b/c/driver/sqlite/sqlite.c
@@ -1337,7 +1337,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;
diff --git a/c/driver_manager/adbc_driver_manager.cc b/c/driver_manager/adbc_driver_manager.cc
index c63560a4..888c48a6 100644
--- a/c/driver_manager/adbc_driver_manager.cc
+++ b/c/driver_manager/adbc_driver_manager.cc
@@ -19,6 +19,7 @@
 #include <adbc.h>
 
 #include <algorithm>
+#include <array>
 #include <cstring>
 #include <string>
 #include <unordered_map>
@@ -191,6 +192,12 @@ AdbcStatusCode StatementExecutePartitions(struct AdbcStatement* statement,
   return ADBC_STATUS_NOT_IMPLEMENTED;
 }
 
+AdbcStatusCode StatementExecuteSchema(struct AdbcStatement* statement,
+                                      struct ArrowSchema* schema,
+                                      struct AdbcError* error) {
+  return ADBC_STATUS_NOT_IMPLEMENTED;
+}
+
 AdbcStatusCode StatementGetParameterSchema(struct AdbcStatement* statement,
                                            struct ArrowSchema* schema,
                                            struct AdbcError* error) {
@@ -540,6 +547,15 @@ AdbcStatusCode AdbcStatementExecuteQuery(struct AdbcStatement* statement,
                                                           error);
 }
 
+AdbcStatusCode AdbcStatementExecuteSchema(struct AdbcStatement* statement,
+                                          struct ArrowSchema* schema,
+                                          struct AdbcError* error) {
+  if (!statement->private_driver) {
+    return ADBC_STATUS_INVALID_STATE;
+  }
+  return statement->private_driver->StatementExecuteSchema(statement, schema, error);
+}
+
 AdbcStatusCode AdbcStatementGetParameterSchema(struct AdbcStatement* statement,
                                                struct ArrowSchema* schema,
                                                struct AdbcError* error) {
@@ -640,11 +656,19 @@ AdbcStatusCode AdbcLoadDriver(const char* driver_name, const char* entrypoint,
   AdbcDriverInitFunc init_func;
   std::string error_message;
 
-  if (version != ADBC_VERSION_1_0_0) {
-    SetError(error, "Only ADBC 1.0.0 is supported");
-    return ADBC_STATUS_NOT_IMPLEMENTED;
+  switch (version) {
+    case ADBC_VERSION_1_0_0:
+    case ADBC_VERSION_1_1_0:
+      break;
+    default:
+      SetError(error, "Only ADBC 1.0.0 and 1.1.0 are supported");
+      return ADBC_STATUS_NOT_IMPLEMENTED;
   }
 
+  if (!raw_driver) {
+    SetError(error, "Must provide non-NULL raw_driver");
+    return ADBC_STATUS_INVALID_ARGUMENT;
+  }
   auto* driver = reinterpret_cast<struct AdbcDriver*>(raw_driver);
 
   if (!entrypoint) {
@@ -771,6 +795,25 @@ AdbcStatusCode AdbcLoadDriver(const char* driver_name, const char* entrypoint,
 
 AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int version,
                                           void* raw_driver, struct AdbcError* error) {
+  constexpr std::array<int, 2> kSupportedVersions = {
+      ADBC_VERSION_1_1_0,
+      ADBC_VERSION_1_0_0,
+  };
+
+  if (!raw_driver) {
+    SetError(error, "Must provide non-NULL raw_driver");
+    return ADBC_STATUS_INVALID_ARGUMENT;
+  }
+
+  switch (version) {
+    case ADBC_VERSION_1_0_0:
+    case ADBC_VERSION_1_1_0:
+      break;
+    default:
+      SetError(error, "Only ADBC 1.0.0 and 1.1.0 are supported");
+      return ADBC_STATUS_NOT_IMPLEMENTED;
+  }
+
 #define FILL_DEFAULT(DRIVER, STUB) \
   if (!DRIVER->STUB) {             \
     DRIVER->STUB = &STUB;          \
@@ -781,12 +824,20 @@ AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int vers
     return ADBC_STATUS_INTERNAL;                                               \
   }
 
-  auto result = init_func(version, raw_driver, error);
+  // Starting from the passed version, try each (older) version in
+  // succession with the underlying driver until we find one that's
+  // accepted.
+  AdbcStatusCode result = ADBC_STATUS_NOT_IMPLEMENTED;
+  for (const int try_version : kSupportedVersions) {
+    if (try_version > version) continue;
+    result = init_func(try_version, raw_driver, error);
+    if (result != ADBC_STATUS_NOT_IMPLEMENTED) break;
+  }
   if (result != ADBC_STATUS_OK) {
     return result;
   }
 
-  if (version == ADBC_VERSION_1_0_0) {
+  if (version >= ADBC_VERSION_1_0_0) {
     auto* driver = reinterpret_cast<struct AdbcDriver*>(raw_driver);
     CHECK_REQUIRED(driver, DatabaseNew);
     CHECK_REQUIRED(driver, DatabaseInit);
@@ -816,6 +867,13 @@ AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int vers
     FILL_DEFAULT(driver, StatementSetSqlQuery);
     FILL_DEFAULT(driver, StatementSetSubstraitPlan);
   }
+  if (version >= ADBC_VERSION_1_1_0) {
+    auto* driver = reinterpret_cast<struct AdbcDriver*>(raw_driver);
+    FILL_DEFAULT(driver, StatementExecuteSchema);
+
+    // Zero out the padding
+    std::memset(driver->reserved, 0, sizeof(driver->reserved));
+  }
 
   return ADBC_STATUS_OK;
 
diff --git a/c/driver_manager/adbc_driver_manager_test.cc b/c/driver_manager/adbc_driver_manager_test.cc
index 99fa477b..26c8dc61 100644
--- a/c/driver_manager/adbc_driver_manager_test.cc
+++ b/c/driver_manager/adbc_driver_manager_test.cc
@@ -34,6 +34,8 @@ namespace adbc {
 using adbc_validation::IsOkStatus;
 using adbc_validation::IsStatus;
 
+TEST(Adbc, AdbcDriverSize) { ASSERT_EQ(sizeof(AdbcDriver), 96 * sizeof(void*)); }
+
 class DriverManager : public ::testing::Test {
  public:
   void SetUp() override {
@@ -157,6 +159,38 @@ TEST_F(DriverManager, MultiDriverTest) {
   error->release(&error.value);
 }
 
+class AdbcVersion : public ::testing::Test {
+ public:
+  void SetUp() override {
+    std::memset(&driver, 0, sizeof(driver));
+    std::memset(&error, 0, sizeof(error));
+  }
+
+  void TearDown() override {
+    if (error.release) {
+      error.release(&error);
+    }
+
+    if (driver.release) {
+      ASSERT_THAT(driver.release(&driver, &error), IsOkStatus(&error));
+      ASSERT_EQ(driver.private_data, nullptr);
+      ASSERT_EQ(driver.private_manager, nullptr);
+    }
+  }
+
+ protected:
+  struct AdbcDriver driver = {};
+  struct AdbcError error = {};
+};
+
+// TODO: set up a dummy driver to test behavior more deterministically
+
+TEST_F(AdbcVersion, ForwardsCompatible) {
+  ASSERT_THAT(
+      AdbcLoadDriver("adbc_driver_sqlite", nullptr, ADBC_VERSION_1_1_0, &driver, &error),
+      IsOkStatus(&error));
+}
+
 class SqliteQuirks : public adbc_validation::DriverQuirks {
  public:
   AdbcStatusCode SetupDatabase(struct AdbcDatabase* database,
diff --git a/go/adbc/adbc.go b/go/adbc/adbc.go
index 2ecd4154..c71ce82a 100644
--- a/go/adbc/adbc.go
+++ b/go/adbc/adbc.go
@@ -142,20 +142,35 @@ const (
 	StatusUnauthorized // Unauthorized
 )
 
+const (
+	AdbcVersion1_0_0 int64 = 1_000_000
+	AdbcVersion1_1_0 int64 = 1_001_000
+)
+
 // Canonical option values
 const (
-	OptionValueEnabled          = "true"
-	OptionValueDisabled         = "false"
-	OptionKeyAutoCommit         = "adbc.connection.autocommit"
-	OptionKeyIngestTargetTable  = "adbc.ingest.target_table"
-	OptionKeyIngestMode         = "adbc.ingest.mode"
-	OptionKeyIsolationLevel     = "adbc.connection.transaction.isolation_level"
-	OptionKeyReadOnly           = "adbc.connection.readonly"
-	OptionValueIngestModeCreate = "adbc.ingest.mode.create"
-	OptionValueIngestModeAppend = "adbc.ingest.mode.append"
-	OptionKeyURI                = "uri"
-	OptionKeyUsername           = "username"
-	OptionKeyPassword           = "password"
+	OptionValueEnabled  = "true"
+	OptionValueDisabled = "false"
+	OptionKeyAutoCommit = "adbc.connection.autocommit"
+	// The current catalog.
+	OptionKeyCurrentCatalog = "adbc.connection.catalog"
+	// The current schema.
+	OptionKeyCurrentDbSchema = "adbc.connection.db_schema"
+	// Make ExecutePartitions nonblocking.
+	OptionKeyIncremental = "adbc.statement.exec.incremental"
+	// Get the progress
+	OptionKeyProgress                 = "adbc.statement.exec.progress"
+	OptionKeyIngestTargetTable        = "adbc.ingest.target_table"
+	OptionKeyIngestMode               = "adbc.ingest.mode"
+	OptionKeyIsolationLevel           = "adbc.connection.transaction.isolation_level"
+	OptionKeyReadOnly                 = "adbc.connection.readonly"
+	OptionValueIngestModeCreate       = "adbc.ingest.mode.create"
+	OptionValueIngestModeAppend       = "adbc.ingest.mode.append"
+	OptionValueIngestModeReplace      = "adbc.ingest.mode.replace"
+	OptionValueIngestModeCreateAppend = "adbc.ingest.mode.create_append"
+	OptionKeyURI                      = "uri"
+	OptionKeyUsername                 = "username"
+	OptionKeyPassword                 = "password"
 )
 
 type OptionIsolationLevel string
@@ -170,6 +185,11 @@ const (
 	LevelLinearizable    OptionIsolationLevel = "adbc.connection.transaction.isolation.linearizable"
 )
 
+// Canonical property values
+const (
+	PropertyProgress = "adbc.statement.exec.progress"
+)
+
 // Driver is the entry point for the interface. It is similar to
 // database/sql.Driver taking a map of keys and values as options
 // to initialize a Connection to the database. Any common connection
@@ -212,6 +232,8 @@ const (
 	InfoDriverVersion InfoCode = 101 // DriverVersion
 	// The driver Arrow library version (type: utf8)
 	InfoDriverArrowVersion InfoCode = 102 // DriverArrowVersion
+	// The driver ADBC API version (type: int64)
+	InfoDriverADBCVersion InfoCode = 103 // DriverADBCVersion
 )
 
 type ObjectDepth int
@@ -275,6 +297,10 @@ type Connection interface {
 	// codes are defined as constants. Codes [0, 10_000) are reserved
 	// 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.
 	GetInfo(ctx context.Context, infoCodes []InfoCode) (array.RecordReader, error)
 
 	// GetObjects gets a hierarchical view of all catalogs, database schemas,
@@ -470,6 +496,9 @@ type Statement interface {
 	// of rows affected if known, otherwise it will be -1.
 	//
 	// This invalidates any prior result sets on this statement.
+	//
+	// Since ADBC 1.1.0: releasing the returned RecordReader without
+	// consuming it fully is equivalent to calling AdbcStatementCancel.
 	ExecuteQuery(context.Context) (array.RecordReader, int64, error)
 
 	// ExecuteUpdate executes a statement that does not generate a result
@@ -534,5 +563,45 @@ type Statement interface {
 	//
 	// If the driver does not support partitioned results, this will return
 	// an error with a StatusNotImplemented code.
+	//
+	// When OptionKeyIncremental is set, this should be called
+	// repeatedly until receiving an empty Partitions.
 	ExecutePartitions(context.Context) (*arrow.Schema, Partitions, int64, error)
 }
+
+// StatementCancel is a Statement that also supports Cancel.
+//
+// Since ADBC API revision 1.1.0.
+type StatementCancel interface {
+	// Cancel stops execution of an in-progress query.
+	//
+	// This can be called during ExecuteQuery (or similar), or while
+	// consuming a RecordReader returned from such.  Calling this
+	// function should make the other functions return an error with a
+	// StatusCancelled code.
+	//
+	// This must always be thread-safe (other operations are not
+	// necessarily thread-safe).
+	Cancel() error
+}
+
+// StatementExecuteSchema is a Statement that also supports ExecuteSchema.
+//
+// Since ADBC API revision 1.1.0.
+type StatementExecuteSchema interface {
+	// ExecuteSchema gets the schema of the result set of a query without executing it.
+	ExecuteSchema(context.Context) (*arrow.Schema, error)
+}
+
+// GetSetOptions is a PostInitOptions that also supports getting and setting property values of different types.
+//
+// Since ADBC API revision 1.1.0.
+type GetSetOptions interface {
+	PostInitOptions
+
+	SetOption(key, value string) error
+	SetOptionInt(key, value int64) error
+	SetOptionDouble(key, value float64) error
+	GetOptionInt(key string) (int64, error)
+	GetOptionDouble(key string) (float64, error)
+}
diff --git a/go/adbc/infocode_string.go b/go/adbc/infocode_string.go
index 73af20c1..df0fd74b 100644
--- a/go/adbc/infocode_string.go
+++ b/go/adbc/infocode_string.go
@@ -14,23 +14,24 @@ func _() {
 	_ = x[InfoDriverName-100]
 	_ = x[InfoDriverVersion-101]
 	_ = x[InfoDriverArrowVersion-102]
+	_ = x[InfoDriverADBCVersion-103]
 }
 
 const (
 	_InfoCode_name_0 = "VendorNameVendorVersionVendorArrowVersion"
-	_InfoCode_name_1 = "DriverNameDriverVersionDriverArrowVersion"
+	_InfoCode_name_1 = "DriverNameDriverVersionDriverArrowVersionDriverADBCVersion"
 )
 
 var (
 	_InfoCode_index_0 = [...]uint8{0, 10, 23, 41}
-	_InfoCode_index_1 = [...]uint8{0, 10, 23, 41}
+	_InfoCode_index_1 = [...]uint8{0, 10, 23, 41, 58}
 )
 
 func (i InfoCode) String() string {
 	switch {
 	case i <= 2:
 		return _InfoCode_name_0[_InfoCode_index_0[i]:_InfoCode_index_0[i+1]]
-	case 100 <= i && i <= 102:
+	case 100 <= i && i <= 103:
 		i -= 100
 		return _InfoCode_name_1[_InfoCode_index_1[i]:_InfoCode_index_1[i+1]]
 	default:
diff --git a/go/adbc/pkg/_tmpl/driver.go.tmpl b/go/adbc/pkg/_tmpl/driver.go.tmpl
index fe24bf9e..706a0fb1 100644
--- a/go/adbc/pkg/_tmpl/driver.go.tmpl
+++ b/go/adbc/pkg/_tmpl/driver.go.tmpl
@@ -689,7 +689,7 @@ func {{.Prefix}}DriverInit(version C.int, rawDriver *C.void, err *C.struct_AdbcE
 	}
 
 	driver := (*C.struct_AdbcDriver)(unsafe.Pointer(rawDriver))
-	C.memset(unsafe.Pointer(driver), 0, C.sizeof_struct_AdbcDriver)
+	C.memset(unsafe.Pointer(driver), 0, C.ADBC_DRIVER_1_0_0_SIZE)
 	driver.DatabaseInit = (*[0]byte)(C.{{.Prefix}}DatabaseInit)
 	driver.DatabaseNew = (*[0]byte)(C.{{.Prefix}}DatabaseNew)
 	driver.DatabaseRelease = (*[0]byte)(C.{{.Prefix}}DatabaseRelease)
diff --git a/go/adbc/pkg/flightsql/driver.go b/go/adbc/pkg/flightsql/driver.go
index a3107e58..77e39c6f 100644
--- a/go/adbc/pkg/flightsql/driver.go
+++ b/go/adbc/pkg/flightsql/driver.go
@@ -692,7 +692,7 @@ func FlightSQLDriverInit(version C.int, rawDriver *C.void, err *C.struct_AdbcErr
 	}
 
 	driver := (*C.struct_AdbcDriver)(unsafe.Pointer(rawDriver))
-	C.memset(unsafe.Pointer(driver), 0, C.sizeof_struct_AdbcDriver)
+	C.memset(unsafe.Pointer(driver), 0, C.ADBC_DRIVER_1_0_0_SIZE)
 	driver.DatabaseInit = (*[0]byte)(C.FlightSQLDatabaseInit)
 	driver.DatabaseNew = (*[0]byte)(C.FlightSQLDatabaseNew)
 	driver.DatabaseRelease = (*[0]byte)(C.FlightSQLDatabaseRelease)
diff --git a/go/adbc/pkg/snowflake/driver.go b/go/adbc/pkg/snowflake/driver.go
index 296c6718..18751077 100644
--- a/go/adbc/pkg/snowflake/driver.go
+++ b/go/adbc/pkg/snowflake/driver.go
@@ -692,7 +692,7 @@ func SnowflakeDriverInit(version C.int, rawDriver *C.void, err *C.struct_AdbcErr
 	}
 
 	driver := (*C.struct_AdbcDriver)(unsafe.Pointer(rawDriver))
-	C.memset(unsafe.Pointer(driver), 0, C.sizeof_struct_AdbcDriver)
+	C.memset(unsafe.Pointer(driver), 0, C.ADBC_DRIVER_1_0_0_SIZE)
 	driver.DatabaseInit = (*[0]byte)(C.SnowflakeDatabaseInit)
 	driver.DatabaseNew = (*[0]byte)(C.SnowflakeDatabaseNew)
 	driver.DatabaseRelease = (*[0]byte)(C.SnowflakeDatabaseRelease)
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java
index fea70548..d3c81191 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java
@@ -27,7 +27,7 @@ import org.apache.arrow.vector.types.pojo.Schema;
  * <p>Connections are not required to be thread-safe, but they can be used from multiple threads so
  * long as clients take care to serialize accesses to a connection.
  */
-public interface AdbcConnection extends AutoCloseable {
+public interface AdbcConnection extends AutoCloseable, AdbcOptions {
   /** Commit the pending transaction. */
   default void commit() throws AdbcException {
     throw AdbcException.notImplemented("Connection does not support transactions");
@@ -285,6 +285,42 @@ public interface AdbcConnection extends AutoCloseable {
     throw AdbcException.notImplemented("Connection does not support transactions");
   }
 
+  /**
+   * Get the current catalog.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default String getCurrentCatalog() throws AdbcException {
+    throw AdbcException.notImplemented("Connection does not support current catalog");
+  }
+
+  /**
+   * Set the current catalog.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default void setCurrentCatalog(String catalog) throws AdbcException {
+    throw AdbcException.notImplemented("Connection does not support current catalog");
+  }
+
+  /**
+   * Get the current schema.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default String getCurrentDbSchema() throws AdbcException {
+    throw AdbcException.notImplemented("Connection does not support current catalog");
+  }
+
+  /**
+   * Set the current schema.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default void setCurrentDbSchema(String catalog) throws AdbcException {
+    throw AdbcException.notImplemented("Connection does not support current catalog");
+  }
+
   /**
    * Get whether the connection is read-only.
    *
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDatabase.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDatabase.java
index e63c598b..723acfc0 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDatabase.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDatabase.java
@@ -24,7 +24,7 @@ package org.apache.arrow.adbc.core;
  * remote/networked databases, for in-memory databases, this object provides an explicit point of
  * ownership.
  */
-public interface AdbcDatabase extends AutoCloseable {
+public interface AdbcDatabase extends AutoCloseable, AdbcOptions {
   /** Create a new connection to the database. */
   AdbcConnection connect() throws AdbcException;
 }
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java
index 80abd185..9386b880 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java
@@ -21,11 +21,42 @@ import java.util.Map;
 
 /** A handle to an ADBC database driver. */
 public interface AdbcDriver {
-  /** The standard parameter name for a connection URL (type String). */
-  String PARAM_URL = "adbc.url";
+  /**
+   * The standard parameter name for a password (type String).
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  AdbcOptionKey<String> PARAM_PASSWORD = new AdbcOptionKey<>("password", String.class);
+
+  /**
+   * The standard parameter name for a connection URI (type String).
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  AdbcOptionKey<String> PARAM_URI = new AdbcOptionKey<>("uri", String.class);
+
+  /**
+   * The standard parameter name for a connection URL (type String).
+   *
+   * @deprecated Prefer {@link #PARAM_URI} instead.
+   */
+  @Deprecated String PARAM_URL = "adbc.url";
+
+  /**
+   * The standard parameter name for a username (type String).
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  AdbcOptionKey<String> PARAM_USERNAME = new AdbcOptionKey<>("username", String.class);
+
   /** The standard parameter name for SQL quirks configuration (type SqlQuirks). */
   String PARAM_SQL_QUIRKS = "adbc.sql.quirks";
 
+  /** ADBC API revision 1.0.0. */
+  long ADBC_VERSION_1_0_0 = 1_000_000;
+  /** ADBC API revision 1.1.0. */
+  long ADBC_VERSION_1_1_0 = 1_001_000;
+
   /**
    * Open a database via this driver.
    *
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcInfoCode.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcInfoCode.java
index 52c09565..8d5c73ba 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcInfoCode.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcInfoCode.java
@@ -16,7 +16,12 @@
  */
 package org.apache.arrow.adbc.core;
 
-/** Integer IDs used for requesting information about the database/driver. */
+/**
+ * Integer IDs used for requesting information about the database/driver.
+ *
+ * <p>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.
+ */
 public enum AdbcInfoCode {
   /** The database vendor/product name (e.g. the server name) (type: utf8). */
   VENDOR_NAME(0),
@@ -31,6 +36,16 @@ public enum AdbcInfoCode {
   DRIVER_VERSION(101),
   /** The driver Arrow library version (type: utf8). */
   DRIVER_ARROW_VERSION(102),
+  /**
+   * The ADBC API version (type: int64).
+   *
+   * <p>The value should be one of the ADBC_VERSION constants.
+   *
+   * @see AdbcDriver#ADBC_VERSION_1_0_0
+   * @see AdbcDriver#ADBC_VERSION_1_1_0
+   * @since ADBC API revision 1.1.0
+   */
+  DRIVER_ADBC_VERSION(103),
   ;
 
   private final int value;
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcOptionKey.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcOptionKey.java
new file mode 100644
index 00000000..d5947036
--- /dev/null
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcOptionKey.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package org.apache.arrow.adbc.core;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A typesafe option key.
+ *
+ * @since ADBC API revision 1.1.0
+ * @param <T> The option value type.
+ */
+public final class AdbcOptionKey<T> {
+  private final String key;
+  private final Class<T> type;
+
+  public AdbcOptionKey(String key, Class<T> type) {
+    this.key = Objects.requireNonNull(key);
+    this.type = Objects.requireNonNull(type);
+  }
+
+  /**
+   * Set this option in an options map (like for {@link AdbcDriver#open(Map)}.
+   *
+   * @param options The options.
+   * @param value The option value.
+   */
+  public void set(Map<String, Object> options, T value) {
+    options.put(key, value);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    AdbcOptionKey<?> that = (AdbcOptionKey<?>) o;
+    return Objects.equals(key, that.key) && Objects.equals(type, that.type);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(key, type);
+  }
+
+  @Override
+  public String toString() {
+    return "AdbcOptionKey{" + key + ", " + type + '}';
+  }
+}
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcOptions.java
similarity index 52%
copy from java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java
copy to java/core/src/main/java/org/apache/arrow/adbc/core/AdbcOptions.java
index 80abd185..efd8eab7 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcDriver.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcOptions.java
@@ -17,19 +17,29 @@
 
 package org.apache.arrow.adbc.core;
 
-import java.util.Map;
-
-/** A handle to an ADBC database driver. */
-public interface AdbcDriver {
-  /** The standard parameter name for a connection URL (type String). */
-  String PARAM_URL = "adbc.url";
-  /** The standard parameter name for SQL quirks configuration (type SqlQuirks). */
-  String PARAM_SQL_QUIRKS = "adbc.sql.quirks";
+/** An ADBC object that supports getting/setting generic options. */
+public interface AdbcOptions {
+  /**
+   * Get a generic option.
+   *
+   * @since ADBC API revision 1.1.0
+   * @param key The option to retrieve.
+   * @return The option value.
+   * @param <T> The option value type.
+   */
+  default <T> T getOption(AdbcOptionKey<T> key) throws AdbcException {
+    throw AdbcException.notImplemented("Unsupported option " + key);
+  }
 
   /**
-   * Open a database via this driver.
+   * Set a generic option.
    *
-   * @param parameters Driver-specific parameters.
+   * @since ADBC API revision 1.1.0
+   * @param key The option to set.
+   * @param value The option value.
+   * @param <T> The option value type.
    */
-  AdbcDatabase open(Map<String, Object> parameters) throws AdbcException;
+  default <T> void setOption(AdbcOptionKey<T> key, T value) throws AdbcException {
+    throw AdbcException.notImplemented("Unsupported option " + key);
+  }
 }
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcStatement.java b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcStatement.java
index ef2be487..a033726b 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcStatement.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcStatement.java
@@ -19,6 +19,7 @@ package org.apache.arrow.adbc.core;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.Iterator;
 import java.util.List;
 import org.apache.arrow.vector.VectorSchemaRoot;
 import org.apache.arrow.vector.ipc.ArrowReader;
@@ -40,8 +41,23 @@ import org.apache.arrow.vector.types.pojo.Schema;
  * <p>Statements are not required to be thread-safe, but they can be used from multiple threads so
  * long as clients take care to serialize accesses to a statement.
  */
-public interface AdbcStatement extends AutoCloseable {
-  /** Set a generic query option. */
+public interface AdbcStatement extends AutoCloseable, AdbcOptions {
+  /**
+   * Cancel execution of a query.
+   *
+   * <p>This method must be thread-safe (other method are not necessarily thread-safe).
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default void cancel() throws AdbcException {
+    throw AdbcException.notImplemented("Statement does not support cancel");
+  }
+
+  /**
+   * Set a generic query option.
+   *
+   * @deprecated Prefer {@link #setOption(AdbcOptionKey, Object)}.
+   */
   default void setOption(String key, Object value) throws AdbcException {
     throw AdbcException.notImplemented("Unsupported option " + key);
   }
@@ -94,6 +110,37 @@ public interface AdbcStatement extends AutoCloseable {
     throw AdbcException.notImplemented("Statement does not support executePartitioned");
   }
 
+  /**
+   * Get the schema of the result set without executing the query.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default Schema executeSchema() throws AdbcException {
+    throw AdbcException.notImplemented("Statement does not support executeSchema");
+  }
+
+  /**
+   * Execute a result set-generating query and get a list of partitions of the result set.
+   *
+   * <p>These can be serialized and deserialized for parallel and/or distributed fetching.
+   *
+   * <p>This may invalidate any prior result sets.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default Iterator<PartitionResult> pollPartitioned() throws AdbcException {
+    throw AdbcException.notImplemented("Statement does not support pollPartitioned");
+  }
+
+  /**
+   * Get the progress of executing a query.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  default double getProgress() throws AdbcException {
+    throw AdbcException.notImplemented("Statement does not support getProgress");
+  }
+
   /**
    * Get the schema for bound parameters.
    *
diff --git a/java/core/src/main/java/org/apache/arrow/adbc/core/BulkIngestMode.java b/java/core/src/main/java/org/apache/arrow/adbc/core/BulkIngestMode.java
index 2ab16ac4..e23e8de4 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/BulkIngestMode.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/BulkIngestMode.java
@@ -24,7 +24,20 @@ public enum BulkIngestMode {
   /**
    * Do not create the table and append data; error if the table does not exist ({@link
    * AdbcStatusCode#NOT_FOUND}) or does not match the schema of the data to append ({@link
-   * AdbcStatusCode#ALREADY_EXISTS}). *
+   * AdbcStatusCode#ALREADY_EXISTS}).
    */
   APPEND,
+  /**
+   * Create the table and insert data; drop the original table if it already exists.
+   *
+   * @since ADBC API revision 1.1.0
+   */
+  REPLACE,
+  /**
+   * Insert data; create the table if it does not exist, or error ({@link
+   * AdbcStatusCode#ALREADY_EXISTS}) if the table exists, but the schema does not match the schema
+   * of the data to append.
+   */
+  CREATE_APPEND,
+  ;
 }