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

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


The following commit(s) were added to refs/heads/main by this push:
     new 8ac730436 fix(csharp/src/Apache.Arrow.Adbc/C): correctly handle null 
driver entries for imported drivers (#1812)
8ac730436 is described below

commit 8ac730436474b48cccebb58f79048cba8b0d8adf
Author: Curt Hagenlocher <[email protected]>
AuthorDate: Sat May 4 04:22:24 2024 -0700

    fix(csharp/src/Apache.Arrow.Adbc/C): correctly handle null driver entries 
for imported drivers (#1812)
    
    Validates that required function pointers are present in an imported
    driver and backfills optional functions to return
    ADBC_STATUS_NOT_IMPLEMENTED.
    
    Closes #1811
---
 csharp/src/Apache.Arrow.Adbc/AdbcException.cs      |   5 +
 .../src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs |  10 +-
 .../src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs | 248 ++++++++++++++++++++-
 csharp/src/Apache.Arrow.Adbc/C/Delegates.cs        |   8 +-
 4 files changed, 263 insertions(+), 8 deletions(-)

diff --git a/csharp/src/Apache.Arrow.Adbc/AdbcException.cs 
b/csharp/src/Apache.Arrow.Adbc/AdbcException.cs
index 98faefa6c..c4deada39 100644
--- a/csharp/src/Apache.Arrow.Adbc/AdbcException.cs
+++ b/csharp/src/Apache.Arrow.Adbc/AdbcException.cs
@@ -56,6 +56,11 @@ namespace Apache.Arrow.Adbc
             return new AdbcException(message, AdbcStatusCode.NotImplemented);
         }
 
+        internal static AdbcException Missing(string name)
+        {
+            return new AdbcException($"Driver does not implement required 
function Adbc{name}", AdbcStatusCode.InternalError);
+        }
+
         /// <summary>
         /// For database providers which support it, contains a standard
         /// SQL 5-character return code indicating the success or failure
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs
index 7352e3480..2b77315f2 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs
@@ -30,7 +30,7 @@ namespace Apache.Arrow.Adbc.C
         private static unsafe readonly NativeDelegate<ErrorRelease> 
s_releaseError = new NativeDelegate<ErrorRelease>(ReleaseError);
 
 #if NET5_0_OR_GREATER
-        private static unsafe delegate* unmanaged<CAdbcError*, void> 
ReleaseErrorPtr => (delegate* unmanaged<CAdbcError*, 
void>)s_releaseError.Pointer;
+        internal static unsafe delegate* unmanaged<CAdbcError*, void> 
ReleaseErrorPtr => (delegate* unmanaged<CAdbcError*, 
void>)s_releaseError.Pointer;
         private static unsafe delegate* unmanaged<CAdbcDriver*, CAdbcError*, 
AdbcStatusCode> ReleaseDriverPtr => &ReleaseDriver;
         private static unsafe delegate* unmanaged<CAdbcPartitions*, void> 
ReleasePartitionsPtr => &ReleasePartitions;
 
@@ -60,7 +60,7 @@ namespace Apache.Arrow.Adbc.C
         private static unsafe delegate* unmanaged<CAdbcStatement*, byte*, int, 
CAdbcError*, AdbcStatusCode> StatementSetSubstraitPlanPtr => 
&SetStatementSubstraitPlan;
         private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowSchema*, CAdbcError*, AdbcStatusCode> StatementGetParameterSchemaPtr => 
&GetStatementParameterSchema;
 #else
-        private static unsafe IntPtr ReleaseErrorPtr => s_releaseError.Pointer;
+        internal static unsafe IntPtr ReleaseErrorPtr => 
s_releaseError.Pointer;
         private static unsafe IntPtr ReleaseDriverPtr = 
NativeDelegate<DriverRelease>.AsNativePointer(ReleaseDriver);
         private static unsafe IntPtr ReleasePartitionsPtr = 
NativeDelegate<PartitionsRelease>.AsNativePointer(ReleasePartitions);
 
@@ -84,8 +84,8 @@ namespace Apache.Arrow.Adbc.C
         private static unsafe IntPtr StatementExecuteQueryPtr = 
NativeDelegate<StatementExecuteQuery>.AsNativePointer(ExecuteStatementQuery);
         private static unsafe IntPtr StatementExecutePartitionsPtr = 
NativeDelegate<StatementExecutePartitions>.AsNativePointer(ExecuteStatementPartitions);
         private static unsafe IntPtr StatementNewPtr = 
NativeDelegate<StatementNew>.AsNativePointer(NewStatement);
-        private static unsafe IntPtr StatementReleasePtr = 
NativeDelegate<StatementFn>.AsNativePointer(ReleaseStatement);
-        private static unsafe IntPtr StatementPreparePtr = 
NativeDelegate<StatementFn>.AsNativePointer(PrepareStatement);
+        private static unsafe IntPtr StatementReleasePtr = 
NativeDelegate<StatementRelease>.AsNativePointer(ReleaseStatement);
+        private static unsafe IntPtr StatementPreparePtr = 
NativeDelegate<StatementPrepare>.AsNativePointer(PrepareStatement);
         private static unsafe IntPtr StatementSetSqlQueryPtr = 
NativeDelegate<StatementSetSqlQuery>.AsNativePointer(SetStatementSqlQuery);
         private static unsafe IntPtr StatementSetSubstraitPlanPtr = 
NativeDelegate<StatementSetSubstraitPlan>.AsNativePointer(SetStatementSubstraitPlan);
         private static unsafe IntPtr StatementGetParameterSchemaPtr = 
NativeDelegate<StatementGetParameterSchema>.AsNativePointer(GetStatementParameterSchema);
@@ -129,7 +129,7 @@ namespace Apache.Arrow.Adbc.C
             return 0;
         }
 
-        private unsafe static void ReleaseError(CAdbcError* error)
+        internal unsafe static void ReleaseError(CAdbcError* error)
         {
             if (error != null && ((IntPtr)error->message) != IntPtr.Zero)
             {
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs
index a191775ec..24c820631 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs
@@ -75,6 +75,9 @@ namespace Apache.Arrow.Adbc.C
                 using (CallHelper caller = new CallHelper())
                 {
                     caller.Call(init, ADBC_VERSION_1_0_0, ref driver);
+
+                    ValidateDriver(ref driver, ADBC_VERSION_1_0_0);
+
                     ImportedAdbcDriver result = new 
ImportedAdbcDriver(library, driver);
                     library = IntPtr.Zero;
                     return result;
@@ -86,6 +89,249 @@ namespace Apache.Arrow.Adbc.C
             }
         }
 
+        private static unsafe void ValidateDriver(ref CAdbcDriver driver, int 
version)
+        {
+#if NET5_0_OR_GREATER
+            void* empty = null;
+#else
+            IntPtr empty = IntPtr.Zero;
+#endif
+            if (driver.DatabaseNew == empty) { throw 
AdbcException.Missing(nameof(driver.DatabaseNew)); }
+            if (driver.DatabaseInit == empty) { throw 
AdbcException.Missing(nameof(driver.DatabaseInit)); }
+            if (driver.DatabaseRelease == empty) { throw 
AdbcException.Missing(nameof(driver.DatabaseRelease)); }
+            if (driver.DatabaseSetOption == empty) { driver.DatabaseSetOption 
= DatabaseSetOptionDefault; }
+
+            if (driver.ConnectionNew == empty) { throw 
AdbcException.Missing(nameof(driver.ConnectionNew)); }
+            if (driver.ConnectionInit == empty) { throw 
AdbcException.Missing(nameof(driver.ConnectionInit)); }
+            if (driver.ConnectionRelease == empty) { throw 
AdbcException.Missing(nameof(driver.ConnectionRelease)); }
+            if (driver.ConnectionCommit == empty) { driver.ConnectionCommit = 
ConnectionCommitDefault; }
+            if (driver.ConnectionGetInfo == empty) { driver.ConnectionGetInfo 
= ConnectionGetInfoDefault; }
+            if (driver.ConnectionGetObjects == empty) { 
driver.ConnectionGetObjects = ConnectionGetObjectsDefault; }
+            if (driver.ConnectionGetTableSchema == empty) { 
driver.ConnectionGetTableSchema = ConnectionGetTableSchemaDefault; }
+            if (driver.ConnectionGetTableTypes == empty) { 
driver.ConnectionGetTableTypes = ConnectionGetTableTypesDefault; }
+            if (driver.ConnectionReadPartition == empty) { 
driver.ConnectionReadPartition = ConnectionReadPartitionDefault; }
+            if (driver.ConnectionRollback == empty) { 
driver.ConnectionRollback = ConnectionRollbackDefault; }
+            if (driver.ConnectionSetOption == empty) { 
driver.ConnectionSetOption = ConnectionSetOptionDefault; }
+
+            if (driver.StatementExecutePartitions == empty) { 
driver.StatementExecutePartitions = StatementExecutePartitionsDefault; }
+            if (driver.StatementExecuteQuery == empty) { throw 
AdbcException.Missing(nameof(driver.StatementExecuteQuery)); }
+            if (driver.StatementNew == empty) { throw 
AdbcException.Missing(nameof(driver.StatementNew)); }
+            if (driver.StatementRelease == empty) { throw 
AdbcException.Missing(nameof(driver.StatementRelease)); }
+            if (driver.StatementBind == empty) { driver.StatementBind = 
StatementBindDefault; }
+            if (driver.StatementBindStream == empty) { 
driver.StatementBindStream = StatementBindStreamDefault; }
+            if (driver.StatementGetParameterSchema == empty) { 
driver.StatementGetParameterSchema = StatementGetParameterSchemaDefault; }
+            if (driver.StatementPrepare == empty) { driver.StatementPrepare = 
StatementPrepareDefault; }
+            if (driver.StatementSetOption == empty) { 
driver.StatementSetOption = StatementSetOptionDefault; }
+            if (driver.StatementSetSqlQuery == empty) { 
driver.StatementSetSqlQuery = StatementSetSqlQueryDefault; }
+            if (driver.StatementSetSubstraitPlan == empty) { 
driver.StatementSetSubstraitPlan = StatementSetSubstraitPlanDefault; }
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr DatabaseSetOptionDefault = 
NativeDelegate<DatabaseSetOption>.AsNativePointer(DatabaseSetOptionDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcDatabase*, byte*, 
byte*, CAdbcError*, AdbcStatusCode> DatabaseSetOptionDefault => 
&DatabaseSetOptionDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
DatabaseSetOptionDefaultImpl(CAdbcDatabase* database, byte* key, byte* value, 
CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.DatabaseSetOption));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionCommitDefault = 
NativeDelegate<ConnectionCommit>.AsNativePointer(ConnectionCommitDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcError*, AdbcStatusCode> ConnectionCommitDefault => 
&ConnectionCommitDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionCommitDefaultImpl(CAdbcConnection* connection, CAdbcError* error)
+        {
+            return NotImplemented(error, nameof(CAdbcDriver.ConnectionCommit));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionGetInfoDefault = 
NativeDelegate<ConnectionGetInfo>.AsNativePointer(ConnectionGetInfoDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, int*, int, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetInfoDefault => 
&ConnectionGetInfoDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionGetInfoDefaultImpl(CAdbcConnection* connection, int* info_codes, int 
info_codes_length, CArrowArrayStream* stream, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionGetInfo));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionGetObjectsDefault = 
NativeDelegate<ConnectionGetObjects>.AsNativePointer(ConnectionGetObjectsDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, int, 
byte*, byte*, byte*, byte**, byte*, CArrowArrayStream*, CAdbcError*, 
AdbcStatusCode> ConnectionGetObjectsDefault => &ConnectionGetObjectsDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionGetObjectsDefaultImpl(CAdbcConnection* connection, int depth, byte* 
catalog, byte* db_schema, byte* table_name, byte** table_type, byte* 
column_name, CArrowArrayStream* stream, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionGetObjects));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionGetTableSchemaDefault = 
NativeDelegate<ConnectionGetTableSchema>.AsNativePointer(ConnectionGetTableSchemaDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
byte*, byte*, CArrowSchema*, CAdbcError*, AdbcStatusCode> 
ConnectionGetTableSchemaDefault => &ConnectionGetTableSchemaDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionGetTableSchemaDefaultImpl(CAdbcConnection* connection, byte* catalog, 
byte* db_schema, byte* table_name, CArrowSchema* schema, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionGetTableSchema));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionGetTableTypesDefault = 
NativeDelegate<ConnectionGetTableTypes>.AsNativePointer(ConnectionGetTableTypesDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetTableTypesDefault 
=> &ConnectionGetTableTypesDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionGetTableTypesDefaultImpl(CAdbcConnection* connection, 
CArrowArrayStream* stream, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionGetTableTypes));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionReadPartitionDefault = 
NativeDelegate<ConnectionReadPartition>.AsNativePointer(ConnectionReadPartitionDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
int, CArrowArrayStream*, CAdbcError*, AdbcStatusCode> 
ConnectionReadPartitionDefault => &ConnectionReadPartitionDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionReadPartitionDefaultImpl(CAdbcConnection* connection, byte* 
serialized_partition, int serialized_length, CArrowArrayStream* stream, 
CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionReadPartition));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionRollbackDefault = 
NativeDelegate<ConnectionRollback>.AsNativePointer(ConnectionRollbackDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcError*, AdbcStatusCode> ConnectionRollbackDefault => 
&ConnectionRollbackDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionRollbackDefaultImpl(CAdbcConnection* connection, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionRollback));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr ConnectionSetOptionDefault = 
NativeDelegate<ConnectionSetOption>.AsNativePointer(ConnectionSetOptionDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
byte*, CAdbcError*, AdbcStatusCode> ConnectionSetOptionDefault => 
&ConnectionSetOptionDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
ConnectionSetOptionDefaultImpl(CAdbcConnection* connection, byte* name, byte* 
value, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.ConnectionSetOption));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementExecutePartitionsDefault = 
NativeDelegate<StatementExecutePartitions>.AsNativePointer(StatementExecutePartitionsDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowSchema*, CAdbcPartitions*, long*, CAdbcError*, AdbcStatusCode> 
StatementExecutePartitionsDefault => &StatementExecutePartitionsDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementExecutePartitionsDefaultImpl(CAdbcStatement* statement, CArrowSchema* 
schema, CAdbcPartitions* partitions, long* rows, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.StatementExecutePartitions));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementBindDefault = 
NativeDelegate<StatementBind>.AsNativePointer(StatementBindDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowArray*, CArrowSchema*, CAdbcError*, AdbcStatusCode> StatementBindDefault 
=> &StatementBindDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementBindDefaultImpl(CAdbcStatement* statement, CArrowArray* array, 
CArrowSchema* schema, CAdbcError* error)
+        {
+            return NotImplemented(error, nameof(CAdbcDriver.StatementBind));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementBindStreamDefault = 
NativeDelegate<StatementBindStream>.AsNativePointer(StatementBindStreamDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> StatementBindStreamDefault => 
&StatementBindStreamDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementBindStreamDefaultImpl(CAdbcStatement* statement, CArrowArrayStream* 
stream, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.StatementBindStream));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementGetParameterSchemaDefault = 
NativeDelegate<StatementGetParameterSchema>.AsNativePointer(StatementGetParameterSchemaDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowSchema*, CAdbcError*, AdbcStatusCode> StatementGetParameterSchemaDefault 
=> &StatementGetParameterSchemaDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementGetParameterSchemaDefaultImpl(CAdbcStatement* statement, CArrowSchema* 
schema, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.StatementGetParameterSchema));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementPrepareDefault = 
NativeDelegate<StatementPrepare>.AsNativePointer(StatementPrepareDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CAdbcError*, AdbcStatusCode> StatementPrepareDefault => 
&StatementPrepareDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementPrepareDefaultImpl(CAdbcStatement* statement, CAdbcError* error)
+        {
+            return NotImplemented(error, nameof(CAdbcDriver.StatementPrepare));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementSetOptionDefault = 
NativeDelegate<StatementSetOption>.AsNativePointer(StatementSetOptionDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, byte*, 
byte*, CAdbcError*, AdbcStatusCode> StatementSetOptionDefault => 
&StatementSetOptionDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementSetOptionDefaultImpl(CAdbcStatement* statement, byte* name, byte* 
value, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.StatementSetOption));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementSetSqlQueryDefault = 
NativeDelegate<StatementSetSqlQuery>.AsNativePointer(StatementSetSqlQueryDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, byte*, 
CAdbcError*, AdbcStatusCode> StatementSetSqlQueryDefault => 
&StatementSetSqlQueryDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementSetSqlQueryDefaultImpl(CAdbcStatement* statement, byte* text, 
CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.StatementSetSqlQuery));
+        }
+
+#if !NET5_0_OR_GREATER
+        private static unsafe IntPtr StatementSetSubstraitPlanDefault = 
NativeDelegate<StatementSetSubstraitPlan>.AsNativePointer(StatementSetSubstraitPlanDefaultImpl);
+#else
+        private static unsafe delegate* unmanaged<CAdbcStatement*, byte*, int, 
CAdbcError*, AdbcStatusCode> StatementSetSubstraitPlanDefault => 
&StatementSetSubstraitPlanDefaultImpl;
+        [UnmanagedCallersOnly]
+#endif
+        private static unsafe AdbcStatusCode 
StatementSetSubstraitPlanDefaultImpl(CAdbcStatement* statement, byte* plan, int 
length, CAdbcError* error)
+        {
+            return NotImplemented(error, 
nameof(CAdbcDriver.StatementSetSubstraitPlan));
+        }
+
+        private static unsafe AdbcStatusCode NotImplemented(CAdbcError* error, 
string name)
+        {
+            if (error != null)
+            {
+                CAdbcDriverExporter.ReleaseError(error);
+
+                error->message = 
(byte*)MarshalExtensions.StringToCoTaskMemUTF8($"Adbc{name} not implemented");
+                error->sqlstate0 = (byte)0;
+                error->sqlstate1 = (byte)0;
+                error->sqlstate2 = (byte)0;
+                error->sqlstate3 = (byte)0;
+                error->sqlstate4 = (byte)0;
+                error->vendor_code = 0;
+                error->release = CAdbcDriverExporter.ReleaseErrorPtr;
+            }
+
+            return AdbcStatusCode.NotImplemented;
+        }
+
         /// <summary>
         /// Native implementation of <see cref="AdbcDriver"/>
         /// </summary>
@@ -1026,7 +1272,7 @@ namespace Apache.Arrow.Adbc.C
                 fixed (CAdbcStatement* stmt = &nativeStatement)
                 fixed (CAdbcError* e = &_error)
                 {
-                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<StatementFn>(fn)(stmt, e));
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<StatementPrepare>(fn)(stmt, 
e));
                 }
             }
 #endif
diff --git a/csharp/src/Apache.Arrow.Adbc/C/Delegates.cs 
b/csharp/src/Apache.Arrow.Adbc/C/Delegates.cs
index 482580159..e1fa475ff 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/Delegates.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/Delegates.cs
@@ -27,21 +27,25 @@ namespace Apache.Arrow.Adbc.C
     internal unsafe delegate AdbcStatusCode DriverRelease(CAdbcDriver* driver, 
CAdbcError* error);
     internal unsafe delegate void PartitionsRelease(CAdbcPartitions* 
partitions);
     internal unsafe delegate AdbcStatusCode DatabaseSetOption(CAdbcDatabase* 
database, byte* name, byte* value, CAdbcError* error);
+    internal unsafe delegate AdbcStatusCode ConnectionCommit(CAdbcConnection* 
connection, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
ConnectionGetObjects(CAdbcConnection* connection, int depth, byte* catalog, 
byte* db_schema, byte* table_name, byte** table_type, byte* column_name, 
CArrowArrayStream* stream, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
ConnectionGetTableSchema(CAdbcConnection* connection, byte* catalog, byte* 
db_schema, byte* table_name, CArrowSchema* schema, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
ConnectionGetTableTypes(CAdbcConnection* connection, CArrowArrayStream* stream, 
CAdbcError* error);
     internal unsafe delegate AdbcStatusCode ConnectionInit(CAdbcConnection* 
connection, CAdbcDatabase* database, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode ConnectionGetInfo(CAdbcConnection* 
connection, int* info_codes, int info_codes_length, CArrowArrayStream* stream, 
CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
ConnectionReadPartition(CAdbcConnection* connection, byte* 
serialized_partition, int serialized_length, CArrowArrayStream* stream, 
CAdbcError* error);
+    internal unsafe delegate AdbcStatusCode 
ConnectionRollback(CAdbcConnection* connection, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
ConnectionSetOption(CAdbcConnection* connection, byte* name, byte* value, 
CAdbcError* error);
     internal unsafe delegate AdbcStatusCode StatementBind(CAdbcStatement* 
statement, CArrowArray* array, CArrowSchema* schema, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
StatementBindStream(CAdbcStatement* statement, CArrowArrayStream* stream, 
CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
StatementExecuteQuery(CAdbcStatement* statement, CArrowArrayStream* stream, 
long* rows, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
StatementExecutePartitions(CAdbcStatement* statement, CArrowSchema* schema, 
CAdbcPartitions* partitions, long* rows, CAdbcError* error);
+    internal unsafe delegate AdbcStatusCode 
StatementGetParameterSchema(CAdbcStatement* statement, CArrowSchema* schema, 
CAdbcError* error);
     internal unsafe delegate AdbcStatusCode StatementNew(CAdbcConnection* 
connection, CAdbcStatement* statement, CAdbcError* error);
-    internal unsafe delegate AdbcStatusCode StatementFn(CAdbcStatement* 
statement, CAdbcError* error);
+    internal unsafe delegate AdbcStatusCode StatementPrepare(CAdbcStatement* 
statement, CAdbcError* error);
+    internal unsafe delegate AdbcStatusCode StatementSetOption(CAdbcStatement* 
statement, byte* name, byte* value, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
StatementSetSqlQuery(CAdbcStatement* statement, byte* text, CAdbcError* error);
     internal unsafe delegate AdbcStatusCode 
StatementSetSubstraitPlan(CAdbcStatement* statement, byte* plan, int length, 
CAdbcError* error);
-    internal unsafe delegate AdbcStatusCode 
StatementGetParameterSchema(CAdbcStatement* statement, CArrowSchema* schema, 
CAdbcError* error);
+    internal unsafe delegate AdbcStatusCode StatementRelease(CAdbcStatement* 
statement, CAdbcError* error);
 #endif
 }

Reply via email to