lidavidm commented on code in PR #3239:
URL: https://github.com/apache/arrow-adbc/pull/3239#discussion_r2255552566


##########
go/adbc/ext.go:
##########
@@ -159,3 +160,136 @@ func IngestStream(ctx context.Context, cnxn Connection, 
reader array.RecordReade
 
        return count, nil
 }
+
+// VersionInfo contains comprehensive driver and library version information.
+type VersionInfo struct {
+       DriverName    string            `json:"driver_name"`    // e.g., "ADBC 
PostgreSQL Driver"
+       DriverVersion string            `json:"driver_version"` // e.g., 
"15.13.0000"
+       LibraryInfo   map[string]string `json:"library_info"`   // Additional 
library versions, protocol info, etc.
+}
+
+// GetVersionInfo retrieves comprehensive driver version information from a 
connection.
+// This helper function encapsulates the complex process of querying driver 
info codes,
+// handling streaming record batches and union arrays, extracting and safely 
cloning
+// string values, and managing errors with fallback defaults.
+//
+// Returns detailed version information including driver name, version, and 
additional
+// library information such as Arrow version, vendor details, and ADBC version.
+//
+// This is not part of the ADBC API specification.
+func GetVersionInfo(ctx context.Context, cnxn Connection) (*VersionInfo, 
error) {
+       stream, err := cnxn.GetInfo(ctx, []InfoCode{
+               InfoDriverName,
+               InfoDriverVersion,
+               InfoDriverArrowVersion,
+               InfoDriverADBCVersion,
+               InfoVendorName,
+               InfoVendorVersion,
+               InfoVendorArrowVersion,
+               InfoVendorSql,
+               InfoVendorSubstrait,
+               InfoVendorSubstraitMinVersion,
+               InfoVendorSubstraitMaxVersion,
+       })
+       if err != nil {
+               return nil, fmt.Errorf("error during GetInfo: %w", err)
+       }
+       defer stream.Release()
+
+       var name, version string
+       libInfo := make(map[string]string)
+
+       for stream.Next() {
+               batch := stream.Record()
+               defer batch.Release()
+               codeArr := batch.Column(0).(*array.Uint32)
+               unionArr := batch.Column(1).(*array.DenseUnion)
+
+               for i := 0; i < int(batch.NumRows()); i++ {
+                       code := InfoCode(codeArr.Value(i))
+                       child := unionArr.Field(unionArr.ChildID(i))
+                       offset := int(unionArr.ValueOffset(i))
+                       unionArr.GetOneForMarshal(i)
+
+                       if child.IsNull(offset) {
+                               continue
+                       }
+
+                       // Handle different union types based on child ID 
(similar to validation tests)
+                       switch unionArr.ChildID(i) {
+                       case 0: // String values
+                               if strArray, ok := child.(*array.String); ok {
+                                       // Create a copy of the string to avoid 
memory issues
+                                       val := 
strings.Clone(strArray.Value(offset))
+
+                                       switch code {
+                                       case InfoDriverName:
+                                               name = val
+                                       case InfoDriverVersion:
+                                               version = val
+                                       case InfoDriverArrowVersion:
+                                               libInfo["driver_arrow_version"] 
= val
+                                       case InfoVendorName:
+                                               libInfo["vendor_name"] = val
+                                       case InfoVendorVersion:
+                                               libInfo["vendor_version"] = val

Review Comment:
   I think these should be top level 



##########
go/adbc/ext.go:
##########
@@ -159,3 +160,136 @@ func IngestStream(ctx context.Context, cnxn Connection, 
reader array.RecordReade
 
        return count, nil
 }
+
+// VersionInfo contains comprehensive driver and library version information.
+type VersionInfo struct {
+       DriverName    string            `json:"driver_name"`    // e.g., "ADBC 
PostgreSQL Driver"
+       DriverVersion string            `json:"driver_version"` // e.g., 
"15.13.0000"
+       LibraryInfo   map[string]string `json:"library_info"`   // Additional 
library versions, protocol info, etc.
+}
+
+// GetVersionInfo retrieves comprehensive driver version information from a 
connection.
+// This helper function encapsulates the complex process of querying driver 
info codes,
+// handling streaming record batches and union arrays, extracting and safely 
cloning
+// string values, and managing errors with fallback defaults.
+//
+// Returns detailed version information including driver name, version, and 
additional
+// library information such as Arrow version, vendor details, and ADBC version.
+//
+// This is not part of the ADBC API specification.
+func GetVersionInfo(ctx context.Context, cnxn Connection) (*VersionInfo, 
error) {
+       stream, err := cnxn.GetInfo(ctx, []InfoCode{
+               InfoDriverName,
+               InfoDriverVersion,
+               InfoDriverArrowVersion,
+               InfoDriverADBCVersion,
+               InfoVendorName,
+               InfoVendorVersion,
+               InfoVendorArrowVersion,
+               InfoVendorSql,
+               InfoVendorSubstrait,
+               InfoVendorSubstraitMinVersion,
+               InfoVendorSubstraitMaxVersion,
+       })
+       if err != nil {
+               return nil, fmt.Errorf("error during GetInfo: %w", err)
+       }
+       defer stream.Release()
+
+       var name, version string
+       libInfo := make(map[string]string)
+
+       for stream.Next() {
+               batch := stream.Record()
+               defer batch.Release()
+               codeArr := batch.Column(0).(*array.Uint32)
+               unionArr := batch.Column(1).(*array.DenseUnion)
+
+               for i := 0; i < int(batch.NumRows()); i++ {
+                       code := InfoCode(codeArr.Value(i))
+                       child := unionArr.Field(unionArr.ChildID(i))
+                       offset := int(unionArr.ValueOffset(i))
+                       unionArr.GetOneForMarshal(i)
+
+                       if child.IsNull(offset) {
+                               continue
+                       }
+
+                       // Handle different union types based on child ID 
(similar to validation tests)
+                       switch unionArr.ChildID(i) {
+                       case 0: // String values
+                               if strArray, ok := child.(*array.String); ok {
+                                       // Create a copy of the string to avoid 
memory issues
+                                       val := 
strings.Clone(strArray.Value(offset))
+
+                                       switch code {
+                                       case InfoDriverName:
+                                               name = val
+                                       case InfoDriverVersion:
+                                               version = val
+                                       case InfoDriverArrowVersion:
+                                               libInfo["driver_arrow_version"] 
= val
+                                       case InfoVendorName:
+                                               libInfo["vendor_name"] = val
+                                       case InfoVendorVersion:
+                                               libInfo["vendor_version"] = val
+                                       case InfoVendorArrowVersion:
+                                               libInfo["vendor_arrow_version"] 
= val
+                                       case InfoVendorSubstraitMinVersion:
+                                               
libInfo["vendor_substrait_min_version"] = val
+                                       case InfoVendorSubstraitMaxVersion:
+                                               
libInfo["vendor_substrait_max_version"] = val
+                                       }
+                               }
+
+                       case 1: // Boolean values
+                               if boolArray, ok := child.(*array.Boolean); ok {
+                                       val := boolArray.Value(offset)
+
+                                       switch code {
+                                       case InfoVendorSql:
+                                               if val {
+                                                       
libInfo["vendor_sql_support"] = "true"
+                                               } else {
+                                                       
libInfo["vendor_sql_support"] = "false"
+                                               }
+                                       case InfoVendorSubstrait:
+                                               if val {
+                                                       
libInfo["vendor_substrait_support"] = "true"
+                                               } else {
+                                                       
libInfo["vendor_substrait_support"] = "false"
+                                               }
+                                       }
+                               }
+
+                       case 2: // Int64 values
+                               if int64Array, ok := child.(*array.Int64); ok {
+                                       val := int64Array.Value(offset)
+
+                                       switch code {
+                                       case InfoDriverADBCVersion:
+                                               libInfo["driver_adbc_version"] 
= fmt.Sprintf("%d", val)
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if err := stream.Err(); err != nil {
+               return nil, fmt.Errorf("error reading info stream: %w", err)
+       }
+
+       // Set defaults if not provided
+       if name == "" {
+               name = "ADBC Driver"
+       }
+       if version == "" {
+               version = "unknown"
+       }

Review Comment:
   I'm not sure this is necessary (at least, name should always exist)



##########
go/adbc/ext.go:
##########
@@ -159,3 +160,136 @@ func IngestStream(ctx context.Context, cnxn Connection, 
reader array.RecordReade
 
        return count, nil
 }
+
+// VersionInfo contains comprehensive driver and library version information.
+type VersionInfo struct {

Review Comment:
   nit, but this isn't really versions? maybe just `DriverInfo`?



##########
go/adbc/ext.go:
##########
@@ -159,3 +160,136 @@ func IngestStream(ctx context.Context, cnxn Connection, 
reader array.RecordReade
 
        return count, nil
 }
+
+// VersionInfo contains comprehensive driver and library version information.
+type VersionInfo struct {
+       DriverName    string            `json:"driver_name"`    // e.g., "ADBC 
PostgreSQL Driver"
+       DriverVersion string            `json:"driver_version"` // e.g., 
"15.13.0000"
+       LibraryInfo   map[string]string `json:"library_info"`   // Additional 
library versions, protocol info, etc.
+}
+
+// GetVersionInfo retrieves comprehensive driver version information from a 
connection.
+// This helper function encapsulates the complex process of querying driver 
info codes,
+// handling streaming record batches and union arrays, extracting and safely 
cloning
+// string values, and managing errors with fallback defaults.
+//
+// Returns detailed version information including driver name, version, and 
additional
+// library information such as Arrow version, vendor details, and ADBC version.
+//
+// This is not part of the ADBC API specification.
+func GetVersionInfo(ctx context.Context, cnxn Connection) (*VersionInfo, 
error) {
+       stream, err := cnxn.GetInfo(ctx, []InfoCode{
+               InfoDriverName,
+               InfoDriverVersion,
+               InfoDriverArrowVersion,
+               InfoDriverADBCVersion,
+               InfoVendorName,
+               InfoVendorVersion,
+               InfoVendorArrowVersion,
+               InfoVendorSql,
+               InfoVendorSubstrait,
+               InfoVendorSubstraitMinVersion,
+               InfoVendorSubstraitMaxVersion,

Review Comment:
   I think we also need to define a backwards compatibility story, i.e. if we 
end up adding new top-level members, maybe we should specify the values will 
still exist in the LibraryInfo map so that old code is not suddenly broken



##########
go/adbc/ext.go:
##########
@@ -159,3 +160,136 @@ func IngestStream(ctx context.Context, cnxn Connection, 
reader array.RecordReade
 
        return count, nil
 }
+
+// VersionInfo contains comprehensive driver and library version information.
+type VersionInfo struct {
+       DriverName    string            `json:"driver_name"`    // e.g., "ADBC 
PostgreSQL Driver"
+       DriverVersion string            `json:"driver_version"` // e.g., 
"15.13.0000"
+       LibraryInfo   map[string]string `json:"library_info"`   // Additional 
library versions, protocol info, etc.
+}
+
+// GetVersionInfo retrieves comprehensive driver version information from a 
connection.
+// This helper function encapsulates the complex process of querying driver 
info codes,
+// handling streaming record batches and union arrays, extracting and safely 
cloning
+// string values, and managing errors with fallback defaults.
+//
+// Returns detailed version information including driver name, version, and 
additional
+// library information such as Arrow version, vendor details, and ADBC version.
+//
+// This is not part of the ADBC API specification.
+func GetVersionInfo(ctx context.Context, cnxn Connection) (*VersionInfo, 
error) {
+       stream, err := cnxn.GetInfo(ctx, []InfoCode{
+               InfoDriverName,
+               InfoDriverVersion,
+               InfoDriverArrowVersion,
+               InfoDriverADBCVersion,
+               InfoVendorName,
+               InfoVendorVersion,
+               InfoVendorArrowVersion,
+               InfoVendorSql,
+               InfoVendorSubstrait,
+               InfoVendorSubstraitMinVersion,
+               InfoVendorSubstraitMaxVersion,
+       })
+       if err != nil {
+               return nil, fmt.Errorf("error during GetInfo: %w", err)
+       }
+       defer stream.Release()
+
+       var name, version string
+       libInfo := make(map[string]string)
+
+       for stream.Next() {
+               batch := stream.Record()
+               defer batch.Release()
+               codeArr := batch.Column(0).(*array.Uint32)
+               unionArr := batch.Column(1).(*array.DenseUnion)
+
+               for i := 0; i < int(batch.NumRows()); i++ {
+                       code := InfoCode(codeArr.Value(i))
+                       child := unionArr.Field(unionArr.ChildID(i))
+                       offset := int(unionArr.ValueOffset(i))
+                       unionArr.GetOneForMarshal(i)
+
+                       if child.IsNull(offset) {
+                               continue
+                       }
+
+                       // Handle different union types based on child ID 
(similar to validation tests)
+                       switch unionArr.ChildID(i) {
+                       case 0: // String values
+                               if strArray, ok := child.(*array.String); ok {
+                                       // Create a copy of the string to avoid 
memory issues
+                                       val := 
strings.Clone(strArray.Value(offset))
+
+                                       switch code {
+                                       case InfoDriverName:
+                                               name = val
+                                       case InfoDriverVersion:
+                                               version = val
+                                       case InfoDriverArrowVersion:
+                                               libInfo["driver_arrow_version"] 
= val
+                                       case InfoVendorName:
+                                               libInfo["vendor_name"] = val
+                                       case InfoVendorVersion:
+                                               libInfo["vendor_version"] = val
+                                       case InfoVendorArrowVersion:
+                                               libInfo["vendor_arrow_version"] 
= val
+                                       case InfoVendorSubstraitMinVersion:
+                                               
libInfo["vendor_substrait_min_version"] = val
+                                       case InfoVendorSubstraitMaxVersion:
+                                               
libInfo["vendor_substrait_max_version"] = val
+                                       }
+                               }
+
+                       case 1: // Boolean values
+                               if boolArray, ok := child.(*array.Boolean); ok {
+                                       val := boolArray.Value(offset)
+
+                                       switch code {
+                                       case InfoVendorSql:
+                                               if val {
+                                                       
libInfo["vendor_sql_support"] = "true"
+                                               } else {
+                                                       
libInfo["vendor_sql_support"] = "false"
+                                               }
+                                       case InfoVendorSubstrait:
+                                               if val {
+                                                       
libInfo["vendor_substrait_support"] = "true"
+                                               } else {
+                                                       
libInfo["vendor_substrait_support"] = "false"
+                                               }
+                                       }
+                               }
+
+                       case 2: // Int64 values
+                               if int64Array, ok := child.(*array.Int64); ok {
+                                       val := int64Array.Value(offset)
+
+                                       switch code {
+                                       case InfoDriverADBCVersion:
+                                               libInfo["driver_adbc_version"] 
= fmt.Sprintf("%d", val)

Review Comment:
   This should be top level



##########
go/adbc/ext.go:
##########
@@ -159,3 +160,136 @@ func IngestStream(ctx context.Context, cnxn Connection, 
reader array.RecordReade
 
        return count, nil
 }
+
+// VersionInfo contains comprehensive driver and library version information.
+type VersionInfo struct {
+       DriverName    string            `json:"driver_name"`    // e.g., "ADBC 
PostgreSQL Driver"
+       DriverVersion string            `json:"driver_version"` // e.g., 
"15.13.0000"
+       LibraryInfo   map[string]string `json:"library_info"`   // Additional 
library versions, protocol info, etc.
+}
+
+// GetVersionInfo retrieves comprehensive driver version information from a 
connection.
+// This helper function encapsulates the complex process of querying driver 
info codes,
+// handling streaming record batches and union arrays, extracting and safely 
cloning
+// string values, and managing errors with fallback defaults.
+//
+// Returns detailed version information including driver name, version, and 
additional
+// library information such as Arrow version, vendor details, and ADBC version.
+//
+// This is not part of the ADBC API specification.
+func GetVersionInfo(ctx context.Context, cnxn Connection) (*VersionInfo, 
error) {
+       stream, err := cnxn.GetInfo(ctx, []InfoCode{
+               InfoDriverName,
+               InfoDriverVersion,
+               InfoDriverArrowVersion,
+               InfoDriverADBCVersion,
+               InfoVendorName,
+               InfoVendorVersion,
+               InfoVendorArrowVersion,
+               InfoVendorSql,
+               InfoVendorSubstrait,
+               InfoVendorSubstraitMinVersion,
+               InfoVendorSubstraitMaxVersion,
+       })
+       if err != nil {
+               return nil, fmt.Errorf("error during GetInfo: %w", err)
+       }
+       defer stream.Release()
+
+       var name, version string
+       libInfo := make(map[string]string)

Review Comment:
   Why not just directly put values into the struct here?



-- 
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