CurtHagenlocher commented on code in PR #4885:
URL: https://github.com/apache/arrow-adbc/pull/4885#discussion_r4261095502


##########
csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs:
##########
@@ -502,12 +591,87 @@ public unsafe override AdbcConnection 
Connect(IReadOnlyDictionary<string, string
 
             public unsafe override void SetOption(string key, string value)
             {
-                using (CallHelper caller = new CallHelper())
+                using (CallHelper caller = new CallHelper(_driver))
                 {
                     caller.Call(Driver.DatabaseSetOption, ref _nativeDatabase, 
key, value);
                 }
             }
 
+            public unsafe override void SetOptionInt64(string key, long value)
+            {
+                if (_driver.DriverVersion < AdbcVersion.Version_1_1_0) { 
base.SetOptionInt64(key, value); return; }
+                fixed (CAdbcDatabase* database = &_nativeDatabase)
+                {
+                    CAdbcDriverImporter.SetOptionInt64(_driver, 
Options.SetOptionInt, database, key, value);
+                }
+            }
+
+            public unsafe override void SetOptionDouble(string key, double 
value)
+            {
+                if (_driver.DriverVersion < AdbcVersion.Version_1_1_0) { 
base.SetOptionDouble(key, value); return; }
+                fixed (CAdbcDatabase* database = &_nativeDatabase)
+                {
+                    CAdbcDriverImporter.SetOptionDouble(_driver, 
Options.SetOptionDouble, database, key, value);
+                }
+            }
+
+            public unsafe override void SetOptionBytes(string key, 
ReadOnlySpan<byte> value)
+            {
+                fixed (CAdbcDatabase* database = &_nativeDatabase)
+                {
+                    CAdbcDriverImporter.SetOptionBytes(_driver, 
Options.SetOptionBytes, database, key, value);
+                }
+            }

Review Comment:
   These calls never reach the native pointer on a 1.0 driver. `Options` goes 
through `ImportedAdbcDriver.Driver11`, and `Driver11` throws 
`AdbcException.NotImplemented` when the negotiated version is below 1.1.0. That 
happens before any function pointer is read, so the caller gets 
`NotImplemented`, the same status as the base implementation. The same applies 
at lines 874 and 1526.
   
   c38fb4f6e extends `Version1_0DriverFallsBackForTypedSetters` to check 
`SetOptionBytes` at all three levels against a 1.0 driver.
   



##########
csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs:
##########
@@ -606,21 +778,193 @@ public override IsolationLevel IsolationLevel
 
             public override bool ReadOnly
             {
-                get => _readOnly ?? throw AdbcException.NotImplemented("no 
value has been set for ReadOnly");
+                get => _readOnly ??
+                    (TryGetNativeOption(AdbcOptions.Connection.ReadOnly, 
AdbcOptions.GetEnabled, out bool value)
+                        ? value
+                        : throw AdbcException.NotImplemented("no value has 
been set for ReadOnly"));
                 set
                 {
                     SetOption(AdbcOptions.Connection.ReadOnly, 
AdbcOptions.GetEnabled(value));
                     _readOnly = value;
                 }
             }
 
+            public override string? CurrentCatalog
+            {
+                get => GetOptionOrNull(AdbcOptions.Connection.CurrentCatalog);
+            }
+
+            public override string? CurrentDbSchema
+            {
+                get => GetOptionOrNull(AdbcOptions.Connection.CurrentDbSchema);
+            }
+
+            /// <summary>
+            /// Asks an ADBC 1.1 driver for a value that hasn't been set 
through this object.
+            /// Any failure yields null so that callers keep their ADBC 1.0 
behavior.
+            /// </summary>
+            private bool TryGetNativeOption<T>(string key, Func<string, T> 
parse, out T value)
+            {
+                if (IsVersion1_1)
+                {
+                    try
+                    {
+                        value = parse(GetOption(key));
+                        return true;
+                    }
+                    catch (AdbcException)
+                    {
+                    }
+                    catch (NotSupportedException)
+                    {
+                        // The driver reported a value that isn't one of the 
standard ones
+                    }
+                }
+
+                value = default!;
+                return false;
+            }
+
+            private string? GetOptionOrNull(string key)
+            {
+                // A 1.0 driver can't report the value. Don't call GetOption, 
whose 1.0
+                // fallback reads these properties.
+                if (!IsVersion1_1)
+                {
+                    return null;
+                }
+
+                try
+                {
+                    return GetOption(key);
+                }
+                catch (AdbcException e) when (e.Status == 
AdbcStatusCode.NotFound || e.Status == AdbcStatusCode.NotImplemented)
+                {
+                    return null;
+                }
+            }
+
+            private OptionFunctions Options
+            {
+                get
+                {
+                    if (_disposed) { throw new 
ObjectDisposedException(nameof(ImportedAdbcConnection)); }
+                    return _driver.ConnectionOptions;
+                }
+            }
+
+            public unsafe override void SetOptionInt64(string key, long value)
+            {
+                if (!IsVersion1_1) { base.SetOptionInt64(key, value); return; }
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    CAdbcDriverImporter.SetOptionInt64(_driver, 
Options.SetOptionInt, connection, key, value);
+                }
+            }
+
+            public unsafe override void SetOptionDouble(string key, double 
value)
+            {
+                if (!IsVersion1_1) { base.SetOptionDouble(key, value); return; 
}
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    CAdbcDriverImporter.SetOptionDouble(_driver, 
Options.SetOptionDouble, connection, key, value);
+                }
+            }
+
+            public unsafe override void SetOptionBytes(string key, 
ReadOnlySpan<byte> value)
+            {
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    CAdbcDriverImporter.SetOptionBytes(_driver, 
Options.SetOptionBytes, connection, key, value);
+                }
+            }
+
+            public unsafe override string GetOption(string key)
+            {
+                if (_driver.DriverVersion < AdbcVersion.Version_1_1_0) { 
return base.GetOption(key); }
+
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    return GetOptionString(_driver, Options.GetOption, 
connection, key);
+                }
+            }
+
+            public unsafe override long GetOptionInt64(string key)
+            {
+                if (_driver.DriverVersion < AdbcVersion.Version_1_1_0) { 
return base.GetOptionInt64(key); }
+
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    return CAdbcDriverImporter.GetOptionInt64(_driver, 
Options.GetOptionInt, connection, key);
+                }
+            }
+
+            public unsafe override double GetOptionDouble(string key)
+            {
+                if (_driver.DriverVersion < AdbcVersion.Version_1_1_0) { 
return base.GetOptionDouble(key); }
+
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    return CAdbcDriverImporter.GetOptionDouble(_driver, 
Options.GetOptionDouble, connection, key);
+                }
+            }
+
+            public unsafe override byte[] GetOptionBytes(string key)
+            {
+                if (_driver.DriverVersion < AdbcVersion.Version_1_1_0) { 
return base.GetOptionBytes(key); }
+
+                fixed (CAdbcConnection* connection = &_nativeConnection)
+                {
+                    return GetOptionBuffer(_driver, Options.GetOptionBytes, 
connection, key);
+                }
+            }
+
+            public unsafe override IArrowArrayStream GetStatistics(string? 
catalogPattern, string? schemaPattern, string tableNamePattern, bool 
approximate)
+            {
+                using (Utf8Helper utf8Catalog = new Utf8Helper(catalogPattern))
+                using (Utf8Helper utf8Schema = new Utf8Helper(schemaPattern))
+                using (Utf8Helper utf8Table = new Utf8Helper(tableNamePattern))
+                using (CallHelper caller = new CallHelper(_driver))

Review Comment:
   Same as above: `GetStatistics` and `GetStatisticNames` read the pointer 
through `Driver11`, which throws `NotImplemented` for a 1.0 driver before the 
pointer is used. c38fb4f6e adds both calls to 
`Version1_0DriverFallsBackForTypedSetters`.
   



##########
csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs:
##########
@@ -1022,7 +1366,7 @@ public unsafe override QueryResult ExecuteQuery()
 
             public override unsafe Schema ExecuteSchema()
             {
-                using (CallHelper caller = new CallHelper())
+                using (CallHelper caller = new CallHelper(_driver))
                 {
                     fixed (CAdbcStatement* statement = &_nativeStatement)

Review Comment:
   `ExecuteSchema` also reads the pointer through `Driver11`, which throws 
`NotImplemented` for a 1.0 driver before any native call. c38fb4f6e adds it to 
`Version1_0DriverFallsBackForTypedSetters`.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to