Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b4f536c
feat(go/adbc): extend tracing lifecycle helpers
v-birschick-msft Aug 4, 2026
0214000
feat(go/adbc): add Flight SQL tracing utilities
v-birschick-msft Aug 4, 2026
0398194
feat(go/adbc): trace Flight SQL record readers
v-birschick-msft Aug 4, 2026
d951702
feat(go/adbc): trace Flight SQL connections
v-birschick-msft Aug 4, 2026
776cb83
feat(go/adbc): trace Flight SQL statements
v-birschick-msft Aug 4, 2026
7974884
fix codespell finding
v-birschick-msft Aug 4, 2026
fb5fd6c
Merge branch 'dev/birschick-bq/flight-sql-log-to-trace-3-reader' into…
v-birschick-msft Aug 4, 2026
b890d10
Merge branch 'dev/birschick-bq/flight-sql-log-to-trace-3-reader' into…
v-birschick-msft Aug 4, 2026
bc3dffb
remove unused methods (golangci findings)
v-birschick-msft Aug 4, 2026
8f08d10
remove unused methods (golangci-lint finding)
v-birschick-msft Aug 4, 2026
e3edd42
empty - retest
v-birschick-msft Aug 4, 2026
2e1088b
remove unused methods (golangci-lint findings)
v-birschick-msft Aug 4, 2026
cb93aa4
remove unused type (golangci-lint finding)
v-birschick-msft Aug 4, 2026
f13818a
Merge branch 'dev/birschick-bq/flight-sql-log-to-trace-4-connection' …
v-birschick-msft Aug 4, 2026
6412a0d
remove unused type (golangci-lint finding)
v-birschick-msft Aug 4, 2026
eb2797c
empty - retest
v-birschick-msft Aug 4, 2026
8446e81
improvements from code review comments
v-birschick-msft Aug 11, 2026
d602600
empty - retest
v-birschick-msft Aug 11, 2026
7165bc7
Address code review comment to add documentation for EndSpanHelper
v-birschick-msft Aug 17, 2026
f39374b
Merge branch 'dev/birschick-bq/flight-sql-log-to-trace-3-reader' into…
v-birschick-msft Aug 18, 2026
7809374
add unsaved changes
v-birschick-msft Aug 18, 2026
a49a9e8
merged dev/birschick-bq/flight-sql-log-to-trace-4-connection
v-birschick-msft Aug 18, 2026
28c90fc
correct bad merge changes to correct test failures
v-birschick-msft Aug 18, 2026
cc8ed36
Merge branch 'dev/birschick-bq/flight-sql-log-to-trace-4-connection' …
v-birschick-msft Aug 18, 2026
e3a77c3
fix race condition test errors
v-birschick-msft Aug 18, 2026
85bd804
correct test failure
v-birschick-msft Aug 18, 2026
1cf5b4b
empty - retest
v-birschick-msft Aug 19, 2026
a80a4d7
Merge branch 'main' into dev/birschick-bq/flight-sql-log-to-trace-4-c…
v-birschick-msft Aug 19, 2026
47c5660
code review updates
v-birschick-msft Aug 20, 2026
d9c5c84
Merge remote-tracking branch 'upstream/main' into dev/birschick-bq/fl…
v-birschick-msft Aug 20, 2026
c4bf15c
inline single use closeTracing function
v-birschick-msft Aug 20, 2026
6c0c4b2
Merge branch 'dev/birschick-bq/flight-sql-log-to-trace-4-connection' …
v-birschick-msft Aug 20, 2026
af5503a
removal of unused code.
v-birschick-msft Aug 20, 2026
3a80a16
review comments for UnaryInterceptor
v-birschick-msft Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions go/adbc/driver/flightsql/flightsql_adbc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,41 @@ func TestFlightSQLTracingProducesTraceFiles(t *testing.T) {
}

output := traceOutput.String()
require.Contains(t, output, "FlightSQLDatabase.Open")
require.Contains(t, output, "FlightSQLStatement.ExecuteQuery")
require.Contains(t, output, "FlightSQL.Database.Open")
require.Contains(t, output, "FlightSQL.Database.Close")
require.Contains(t, output, "FlightSQL.Statement.ExecuteQuery")
}

func TestFlightSQLTracingCleansUpAfterConstructionFailure(t *testing.T) {
alloc := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer alloc.AssertSize(t, 0)
drv := driver.NewDriver(alloc)

for _, test := range []struct {
name string
uri string
extraOp map[string]string
}{
{name: "invalid URI", uri: "grpc://%"},
{name: "invalid option", uri: "grpc://localhost", extraOp: map[string]string{"unknown option": "value"}},
} {
t.Run(test.name, func(t *testing.T) {
traceDir := t.TempDir()
opts := map[string]string{
adbc.OptionKeyURI: test.uri,
adbc.OptionKeyTelemetryTracesExporter: string(adbc.TelemetryExporterAdbcFile),
adbc.OptionKeyTelemetryTracesFolderPath: traceDir,
}
for key, value := range test.extraOp {
opts[key] = value
}

_, err := drv.NewDatabase(opts)
require.Error(t, err)
require.IsType(t, adbc.Error{}, err)
require.NoError(t, os.RemoveAll(traceDir))
})
}
}

// Run the test suite, but validating that a header set on the database is ALWAYS passed
Expand Down
71 changes: 42 additions & 29 deletions go/adbc/driver/flightsql/flightsql_bulk_ingest.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ package flightsql
import (
"context"
"fmt"
"log/slog"
"time"

"github.com/apache/arrow-adbc/go/adbc"
"github.com/apache/arrow-adbc/go/adbc/driver/internal"
"github.com/apache/arrow-go/v18/arrow"
"github.com/apache/arrow-go/v18/arrow/array"
"github.com/apache/arrow-go/v18/arrow/flight/flightsql"
pb "github.com/apache/arrow-go/v18/arrow/flight/gen/flight"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
Expand Down Expand Up @@ -105,15 +107,26 @@ func createRecordReaderFromBatch(batch arrow.RecordBatch) (array.RecordReader, e

// executeIngest performs bulk ingestion using the FlightSQL client's ExecuteIngest method.
// This is called from the statement when a target table has been set for bulk ingest.
func (s *statement) executeIngest(ctx context.Context) (int64, error) {
func (s *statement) executeIngest(ctx context.Context) (nRows int64, err error) {
var startTime = time.Now()
ctx, span := internal.StartSpan(ctx, "FlightSQL.BulkIngest.Execute", s.cnxn)
errorRecorded := false
defer func() {
internal.NewEndSpanHelper(span).
WithError(err).
WithStartTime(startTime).
WithRecordedError(errorRecorded).
EndSpan()
}()

if s.streamBind == nil && s.bound == nil {
return -1, adbc.Error{
err = adbc.Error{
Msg: "[Flight SQL Statement] must call Bind before bulk ingestion",
Code: adbc.StatusInvalidState,
}
return -1, err
}

startTime := time.Now()
catalogStr := ""
if s.catalog != nil {
catalogStr = *s.catalog
Expand All @@ -122,16 +135,16 @@ func (s *statement) executeIngest(ctx context.Context) (int64, error) {
if s.dbSchema != nil {
dbSchemaStr = *s.dbSchema
}
startAttrs := []any{
slog.String("target_table", s.targetTable),
slog.String("mode", s.ingestMode),
slog.String("catalog", catalogStr),
slog.String("db_schema", dbSchemaStr),
slog.Bool("temporary", s.temporary),
slog.Bool("streamBind", s.streamBind != nil),
slog.Bool("recordBound", s.bound != nil),
startAttrs := []attribute.KeyValue{
attribute.String("target_table", s.targetTable),
attribute.String("mode", s.ingestMode),
attribute.String("catalog", catalogStr),
attribute.String("db_schema", dbSchemaStr),
attribute.Bool("temporary", s.temporary),
attribute.Bool("streamBind", s.streamBind != nil),
attribute.Bool("recordBound", s.bound != nil),
}
s.log.InfoContext(ctx, "FlightSQL ExecuteIngest start", startAttrs...)
span.AddEvent("flight.ingest.started", trace.WithAttributes(startAttrs...))

opts := ingestOptions{
targetTable: s.targetTable,
Expand All @@ -145,16 +158,16 @@ func (s *statement) executeIngest(ctx context.Context) (int64, error) {

// Get the record reader to ingest
var rdr array.RecordReader
var err error
if s.streamBind != nil {
rdr = s.streamBind
} else {
rdr, err = createRecordReaderFromBatch(s.bound)
if err != nil {
s.log.WarnContext(ctx, "FlightSQL ExecuteIngest finished with error",
slog.Duration("duration", time.Since(startTime)),
"err", err,
)
span.RecordError(err, trace.WithAttributes(
attribute.String("flight.stage", "create_record_reader"),
attribute.Float64("duration_s", time.Since(startTime).Seconds()),
), trace.WithStackTrace(true))
errorRecorded = true
return -1, err
}
}
Expand All @@ -163,20 +176,20 @@ func (s *statement) executeIngest(ctx context.Context) (int64, error) {
var header, trailer metadata.MD
callOpts := append([]grpc.CallOption{}, grpc.Header(&header), grpc.Trailer(&trailer), s.timeouts)

nRows, err := s.cnxn.cl.ExecuteIngest(ctx, rdr, ingestOpts, callOpts...)
finishAttrs := []any{
slog.Duration("duration", time.Since(startTime)),
slog.Int64("rowsIngested", nRows),
nRows, err = s.cnxn.cl.ExecuteIngest(ctx, rdr, ingestOpts, callOpts...)
finishAttrs := []attribute.KeyValue{
attribute.Float64("duration_s", time.Since(startTime).Seconds()),
attribute.Int64("rowsIngested", nRows),
}
finishAttrs = append(finishAttrs, correlationHeaderAttrs(header)...)
finishAttrs = append(finishAttrs, correlationHeaderAttrs(trailer)...)
finishAttrs = append(finishAttrs, correlationHeaderKeyValues(header)...)
finishAttrs = append(finishAttrs, correlationHeaderKeyValues(trailer)...)
if err != nil {
wrapped := adbcFromFlightStatusWithDetails(err, header, trailer, "ExecuteIngest")
finishAttrs = append(finishAttrs, "err", wrapped)
s.log.WarnContext(ctx, "FlightSQL ExecuteIngest finished with error", finishAttrs...)
return -1, wrapped
err = adbcFromFlightStatusWithDetails(err, header, trailer, "FlightSQL.BulkIngest.Execute")
span.RecordError(err, trace.WithAttributes(finishAttrs...), trace.WithStackTrace(true))
errorRecorded = true
return -1, err
}
s.log.InfoContext(ctx, "FlightSQL ExecuteIngest finished", finishAttrs...)
span.AddEvent("flight.ingest.completed", trace.WithAttributes(finishAttrs...))

return nRows, nil
}
Loading
Loading