datafusion

package module
v0.550000.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

README

datafusion-go

Go Reference CI Go Report Card License

datafusion-go provides a database/sql driver and Arrow APIs for Apache DataFusion. It is an unofficial community binding in datafusion-contrib.

Go API reference | User guide | Releases | Changelog | Contributing

Install

The package requires Go 1.26 or newer, a C toolchain, and cgo enabled. On Windows, use a MinGW/GNU toolchain for the x86_64-pc-windows-gnu Rust ABI.

Prebuilt native libraries support these platforms:

Operating system Go platforms
macOS darwin-arm64, darwin-amd64
Linux linux-amd64, linux-arm64
Windows windows-amd64

The shell examples use POSIX shell syntax.

If you do not have a Go module, run these commands in order:

mkdir datafusion-quickstart
cd datafusion-quickstart
go mod init example.com/datafusion-quickstart

From your module directory, install the package:

go get github.com/datafusion-contrib/datafusion-go

On first use, the driver downloads libdatafusion_go from the GitHub release for the installed module version. It verifies the library checksum. For library selection and download controls, see Native Runtime.

Use a tagged release for applications. Development snapshots from @main can lack native libraries with the same version.

Quick Start

Use the module directory from Install for this example.

  1. Create trips.csv:

    printf 'city,trips\nnyc,3\nnyc,5\nsf,2\n' > trips.csv
    
  2. Save this code as main.go in the same directory:

    package main
    
    import (
    	"context"
    	"database/sql"
    	"fmt"
    	"log"
    
    	_ "github.com/datafusion-contrib/datafusion-go"
    )
    
    func main() {
    	ctx := context.Background()
    
    	db, err := sql.Open("datafusion", "")
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer db.Close()
    
    	_, err = db.ExecContext(ctx, `create external table trips
    		stored as csv location 'trips.csv'
    		options ('format.has_header' 'true')`)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	rows, err := db.QueryContext(ctx, `select city, sum(trips) as total
    		from trips group by city order by total desc`)
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer rows.Close()
    
    	for rows.Next() {
    		var city string
    		var total int64
    		if err := rows.Scan(&city, &total); err != nil {
    			log.Fatal(err)
    		}
    		fmt.Printf("%s\t%d\n", city, total)
    	}
    	if err := rows.Err(); err != nil {
    		log.Fatal(err)
    	}
    }
    
  3. Run the program:

    go run .
    

    The output is:

    nyc	8
    sf	2
    

More examples: simple queries, parameters, and Arrow.

User Guide

This guide describes the Go binding. For SQL syntax and session options, see DataFusion's SQL reference and configuration reference.

Go API Guide
sql.Open / sql.OpenDB Sessions, DSNs, and initialization
QueryContext / QueryRowContext Parameters and type conversion
QueryArrowContext Arrow batches
RegisterArrowReader / RegisterArrowReaderZeroCopy Arrow tables and buffer ownership
RegisterFFITableProvider Foreign table providers
ExecStatements Multiple setup statements

For driver limits and deployment, see Semantics and Limits and Native Runtime.

Driver and Sessions

By default, connections from one connector share a DataFusion SessionContext. Catalog and configuration changes apply across pooled connections from the same sql.DB.

If each physical connection must have its own session state, use isolated sessions:

db, err := sql.Open("datafusion", "?datafusion.go.shared_session=false")

To select isolated sessions on a connector, use WithSharedSession(false):

connector, err := datafusion.NewConnectorWithInitContext(
	"",
	nil,
	datafusion.WithSharedSession(false),
)

When you close a *sql.Conn, its physical connection returns to the pool. On reuse, shared sessions keep their state. The driver resets isolated sessions and prepares cached statements again. Connection closure does not immediately release registered tables or Arrow batches that callers still hold.

By default, the memory pool for DataFusion queries has no limit. Set a memory budget in the connector initializer:

connector, err := datafusion.NewConnectorWithInitContext("",
	func(ctx context.Context, exec driver.ExecerContext) error {
		_, err := exec.ExecContext(ctx,
			"SET datafusion.runtime.memory_limit = '512M'", nil)
		return err
	},
)
// After checking err:
db := sql.OpenDB(connector)

The initializer applies the budget before queries run and after isolated-session resets. The budget limits only the query-execution memory that DataFusion tracks.

Set different budgets for registered in-memory tables, Arrow batches that callers keep, and Go allocations.

DSNs

The driver accepts these data source name (DSN) forms:

  • An empty string, ""
  • Options after a question mark, ?<options>
  • The URL form, datafusion://
  • The URL form with options, datafusion://?<options>.

The driver passes query parameters to DataFusion as session configuration options:

?datafusion.execution.batch_size=8192

Driver-owned options use the datafusion.go. prefix. The driver removes these options before it passes the remaining options to DataFusion:

?datafusion.go.shared_session=false

The driver rejects file paths, hosts, and other URL forms. For file tables, put the path in CREATE EXTERNAL TABLE SQL.

Initialization

If setup SQL is necessary before you use a pooled database, use NewConnector or NewConnectorWithInitContext:

connector, err := datafusion.NewConnectorWithInitContext(
	"",
	func(ctx context.Context, exec driver.ExecerContext) error {
		_, err := exec.ExecContext(ctx, "create view nums as select 1 as n", nil)
		return err
	},
)
if err != nil {
	return err
}
defer connector.Close()

db := sql.OpenDB(connector)
defer db.Close()

In shared-session mode, the initialization callback runs one time for each connector. In isolated-session mode, it runs for each connection and reset.

Multiple Setup Statements

DataFusion prepares one SQL statement at a time.

  1. Split migration or setup scripts into individual SQL statements.

  2. Execute the statements in order with ExecStatements:

    err := datafusion.ExecStatements(ctx, db, []string{
    	"create view one as select 1 as n",
    	"create view two as select 2 as n",
    })
    

The helper skips blank statements. If a statement fails, the helper includes its index in the error.

Context Cancellation

The driver connects Go query contexts to native cancellation. It checks for cancellation during query planning, stream creation, and record-batch reads:

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

rows, err := db.QueryContext(ctx, "select * from some_large_table")

To identify native cancellation errors, use errors.Is(err, datafusion.ErrNativeCancelled).

SQL Parameters

The driver supports DataFusion SQL parameters through database/sql:

row := db.QueryRowContext(ctx, "select ? + 1, ?", int64(41), "x")

The driver accepts these ordinary parameter values:

  • A null value, nil
  • A Boolean value, bool
  • Signed integer types in the int64 range
  • Unsigned integer types as DataFusion UInt64
  • Floating-point values as float64
  • A string, string
  • A byte slice, []byte
  • A time value, time.Time, as Timestamp[ns]
  • A duration, time.Duration, as Duration[ns].

The time.Time conversion keeps loadable IANA locations, such as America/New_York. Fixed-offset, local, and other non-loadable locations bind as UTC. To supply an explicit Arrow time zone, use TimestampWithTimeZone.

The database/sql conversion promotes float32 values to DataFusion Float64. Before native execution, CheckNamedValue rejects other value types.

If type inference is ambiguous or exact Arrow/DataFusion types are necessary, use typed wrappers:

row := db.QueryRowContext(
	ctx,
	"select $1, $2, $3, $4, $5",
	datafusion.DateFromTime(day),
	datafusion.TimeFromTime(clock),
	datafusion.DurationFromTime(2*time.Second),
	datafusion.DecimalString("123.45", 10, 2),
	datafusion.NullOf(datafusion.ParameterInt64),
)

The wrappers support UInt64, Date, Time, Timestamp, Duration, and Decimal. Bare nil binds as an untyped DataFusion null. If a concrete null type is necessary, use NullOf, NullDecimal, or NullTimestamp. For example, select $1 + 1 accepts NullOf(ParameterInt64).

Prepared statements report Stmt.NumInput for these parameter styles:

  • Each ? occurrence counts as a separate positional parameter.
  • Dollar-numbered parameters, such as $1 and $2, use positional counts.
  • Each name, such as $name, counts as one parameter regardless of the number of occurrences.

The driver rejects statements that mix question-mark, dollar-numbered, and named parameter styles during preparation.

Positional statements require positional arguments. Named statements require sql.Named arguments with matching names. The driver rejects missing, extra, or duplicate supplied names before query execution.

Arrow-Native Usage
Query Arrow Batches

For exact schemas or values that database/sql cannot scan, use QueryArrowContext on a *sql.Conn:

conn, err := db.Conn(ctx)
if err != nil {
	return err
}
defer conn.Close()

reader, err := datafusion.QueryArrowContext(ctx, conn, "select $1", int64(42))
if err != nil {
	return err
}
defer reader.Close()

for {
	record, err := reader.Read()
	if err == io.EOF {
		break
	}
	if err != nil {
		return err
	}
	// Use record.
	record.Release()
}

Call Release on each record after use. Call Close on the reader to release its native stream resources. The finalizer does not guarantee immediate cleanup.

Register Arrow Tables

To register an Arrow record reader as an in-memory DataFusion table, use RegisterArrowReader:

rdr, err := array.NewRecordReader(schema, []arrow.RecordBatch{batch})
if err != nil {
	return err
}
defer rdr.Release()

if err := datafusion.RegisterArrowReader(ctx, conn, "events", rdr); err != nil {
	return err
}

RegisterArrowReader consumes the remaining batches from the reader. It serializes the batches as an Arrow IPC stream, then registers decoded Rust-owned batches. The copy lets the table outlive the cgo call. Ordinary Go Arrow arrays can contain Go-owned buffers that native code must not keep after that call.

RegisterArrowReaderZeroCopy exports the reader through the Arrow C Stream Interface without an IPC copy. Each exported buffer must stay valid for native use until table removal or closure of its session or connector.

Before you use RegisterArrowReaderZeroCopy, make sure that native code can keep all exported buffers for this period. Examples include buffers from Arrow Go's memory/mallocator package and other C or foreign allocators.

For Go-allocated buffers, obey the cgo pointer rules during the full period of native use. Keep these buffers valid for this period. If you cannot satisfy these requirements, use RegisterArrowReader.

Register Foreign FFI Table Providers

To register a datafusion-ffi FFI_TableProvider from a foreign library, use RegisterFFITableProvider:

// providerPtr is an *FFI_TableProvider handed to you by the producing library,
// and providerVersion is the datafusion version that library was built against.
table, err := datafusion.RegisterFFITableProvider(ctx, conn, "t", providerPtr, providerVersion)
if err != nil {
	return err
}
defer table.Deregister(ctx)

rows, err := db.QueryContext(ctx, `SELECT ... FROM t WHERE ...`)

Version and ownership

  1. Get providerVersion from the library that supplies the provider.
  2. Make sure that providerVersion equals this package's DataFusionVersion.

Do not substitute this package's DataFusionVersion for the version from the foreign library. The driver compares versions before it dereferences the provider pointer. A mismatch returns an error.

Exact version equality is stricter than the major-version ABI contract of datafusion-ffi.

The provider pointer must refer to memory that the foreign C or Rust library owns. Do not supply a pointer to Go heap memory. Native code retains cloned callback pointers after registration returns.

Registration clones the provider and increases its reference count. You retain ownership of the original pointer. After registration returns, you can free the original pointer through its library.

Library lifetime

The foreign library must stay loaded while registrations or dependent foreign objects exist. These objects include views, query plans, readers, and returned Arrow batches. They can invoke foreign callbacks after deregistration.

Before you unload the library, complete these steps:

  1. Stop new queries.
  2. Deregister the tables.
  3. Remove dependent views.
  4. Close the readers.
  5. Release the Arrow batches.
  6. Free the original provider through its library.
  7. Release all other dependent foreign objects.

Deregistration

RegisterFFITableProvider returns a *RegisteredTable handle. While its *sql.Conn is open, call Deregister to remove the catalog entry.

In shared and isolated modes, connection closure normally returns the physical connection to the pool. It does not guarantee table release. Queries can retain foreign objects even after the connector closes. The driver does not deregister a table when you discard its registration handle.

Type Conversion

The database/sql row conversion supports these types:

Arrow type family Go value
Null nil
Bool bool
Signed integers int64
Unsigned integers int64 when in range
Float16/Float32/Float64 float64
Utf8/LargeUtf8/StringView string
Binary/LargeBinary/FixedSizeBinary/BinaryView []byte
Date/Time/Timestamp time.Time
Duration int64 nanoseconds
Decimal string
Intervals string

Where the Arrow schema provides precise information, the driver exposes column metadata through database/sql:

  • Nullable columns use typed sql.Null* scan types where practical.
  • Fixed-size binary columns report length.
  • Decimal columns report precision and scale.
  • Temporal and interval database type names include their Arrow unit or interval subtype.

Variable-width string and binary columns do not report declared lengths. The Arrow result schema does not preserve SQL declarations such as VARCHAR(32).

The driver converts time-only values to UTC time.Time values on the Unix epoch date. It converts durations to int64 nanoseconds because database/sql/driver.Value does not accept time.Duration. Interval strings keep the month, day, millisecond, and nanosecond components.

When schema information is available, row conversion rejects lists, structs, maps, unions, dictionaries, extensions, and run-end encoded values. For these types or exact batch data, use QueryArrowContext.

Semantics and Limits
  • PrepareContext validates SQL syntax with the DataFusion parser. A prepared query must contain exactly one SQL statement.
  • The driver does not support multiple result sets. Rows.NextResultSet reports no additional result sets.
  • The connector serializes non-query statements across ExecContext, QueryContext, and QueryArrowContext. Concurrent queries and DDL can still have ordering effects.
  • Connections implement driver.Validator. The driver reports closed connections as invalid before they return to the pool.
  • Native errors carry machine-readable kinds across the C ABI. The driver exposes these kinds on *datafusion.Error.NativeKind.
  • errors.Is matches the native sentinels ErrNativeCancelled, ErrNativeInvalidArgument, ErrNativeFailure, and ErrNativePanic.
  • RowsAffected returns 0 by default. If DataFusion emits a single integer output column named count, rows_affected, or rowsaffected, the driver reports its sum.
  • LastInsertId returns 0, nil. DataFusion does not expose insert IDs through this driver.
  • The driver reuses statement handles for db.Prepare and conn.PrepareContext. DataFusion plans and executes each run. The driver does not cache physical plans.
  • Close is idempotent for connectors, connections, statements, rows, and Arrow readers.
  • Transactions return explicit unsupported errors. For an already-canceled context, BeginTx returns the context error.

SQL executes with the filesystem and network permissions of the host process. Isolated sessions have independent catalogs. They do not sandbox hostile SQL or native FFI providers.

Run untrusted workloads in a different process with restricted operating-system permissions and resource limits.

Native Runtime

Default builds use cgo but do not link DataFusion at Go link time. At runtime, the driver searches for a shared libdatafusion_go library in this order:

  1. The path in DATAFUSION_GO_LIBRARY, if set
  2. The source-checkout directory internal/native/lib/<goos>-<goarch>/
  3. The user cache, with automatic download from the GitHub release for the installed module version.

These environment variables control library selection and downloads:

Variable Effect
DATAFUSION_GO_LIBRARY Selects an explicit absolute path to a trusted shared library.
DATAFUSION_GO_NO_DOWNLOAD=1 Disables automatic release-asset downloads.
DATAFUSION_GO_DOWNLOAD_BASE Selects an alternative HTTPS base URL for release downloads. Redirects must also use HTTPS.

Automatic source and cache resolution checks ownership and write permissions for the library and its ancestor directories. Keep these directories private to the service account or system administrators. An explicit library path is trusted configuration and bypasses automatic permission checks.

For setuid, setgid, or Linux file-capability processes, use datafusion_use_bundled or datafusion_use_source. These processes must link the library at build time. The driver disables runtime resolution for them.

Before you run driver examples or Go tests from a source checkout, run make bundle or make test. Each target builds the Rust shim and copies the native archive and shared library into internal/native/lib/<goos>-<goarch>/.

The package also has these link modes:

Build tag Library source
datafusion_use_bundled The static archive in internal/native/lib/<goos>-<goarch>/.
datafusion_use_source The static archive from the Rust release build in the source checkout.
datafusion_use_static_lib The same static archive as datafusion_use_source.
datafusion_use_lib A system library that the linker finds through -ldatafusion_go.

Select one link mode with go build -tags=<build-tag>. For datafusion_use_lib, use CGO_LDFLAGS to add the library directory with -L. Configure the runtime loader to find the shared library on your operating system.

For native-build setup and tests, see CONTRIBUTING.md.

Troubleshooting

Problem Action
datafusion-go requires cgo Install a C toolchain. Set CGO_ENABLED=1.
Native library not found Set DATAFUSION_GO_LIBRARY to a local library. For a source checkout, run make bundle. See Native Runtime.
Local checkout tests fail before the driver opens Run make test from the repository root to build the native library before the Go tests.
DSN rejected Use an empty DSN or session options.
database/sql cannot scan a result column Use QueryArrowContext for complex Arrow values.
Windows build or test failures Use a MinGW/GNU C toolchain for the x86_64-pc-windows-gnu Rust ABI.

Developing

For setup, test modes, version changes, and the release process, see CONTRIBUTING.md.

Before you submit code changes, run these commands from the repository root:

make lint
make test
make test.source
make rust.test

For questions and ordinary bug reports, use GitHub Issues. Code and documentation contributions are welcome through pull requests.

Versioning

Release tags encode the bundled DataFusion version as v<major>.<encoded-datafusion-version>.<patch>: DataFusion 53.1.0 encodes as 530100, so v0.530100.1 bundles DataFusion 53.1.0.

versions.toml contains the release metadata. For version changes and the release workflow, see CONTRIBUTING.md.

License

Licensed under the Apache License, Version 2.0.

Documentation

Overview

Package datafusion provides a database/sql driver backed by Apache DataFusion.

The driver registers as "datafusion". It is intended for in-process analytic SQL over DataFusion's memory/session catalog and Arrow execution engine. Standard database/sql row scanning is supported for scalar Arrow types, and QueryArrowContext exposes native Arrow record batches for callers that need exact Arrow schemas or complex values. RegisterArrowReader registers Go Arrow record readers as DataFusion in-memory tables.

Index

Constants

View Source
const (
	// DataFusionVersion is the exact Rust datafusion crate version pinned by this release.
	DataFusionVersion = "55.0.0"

	// DataFusionVersionEncoded is used in Go module tags: v<major>.<encoded-datafusion-version>.<patch>.
	DataFusionVersionEncoded = "550000"

	// DataFusionGoMajor is the major component of datafusion-go release tags.
	DataFusionGoMajor = 0

	// DataFusionGoPatch is the patch component of datafusion-go release tags.
	DataFusionGoPatch = 3

	// DataFusionGoVersion is the full datafusion-go module version without the leading v.
	DataFusionGoVersion = "0.550000.3"
)

Variables

View Source
var (
	// ErrNativeCancelled matches errors caused by native query cancellation.
	ErrNativeCancelled = errors.New("datafusion native query canceled")
	// ErrNativeInvalidArgument matches native invalid-argument errors.
	ErrNativeInvalidArgument = errors.New("datafusion native invalid argument")
	// ErrNativeFailure matches uncategorized native DataFusion failures.
	ErrNativeFailure = errors.New("datafusion native failure")
	// ErrNativePanic matches panics caught on the Rust side of the FFI boundary.
	ErrNativePanic = errors.New("datafusion native panic")
)

Functions

func ExecStatements

func ExecStatements(ctx context.Context, execer SQLExecerContext, statements []string) error

ExecStatements executes already-split SQL statements in order.

DataFusion prepares exactly one SQL statement at a time, so callers handling migration files should split the script before calling this helper.

func RegisterArrowReader

func RegisterArrowReader(ctx context.Context, sqlConn *sql.Conn, tableName string, reader array.RecordReader) error

RegisterArrowReader registers the remaining batches in reader as a DataFusion in-memory table visible to SQL executed on sqlConn.

This safe path serializes the reader to an Arrow IPC stream and lets the native side decode that stream into Rust-owned Arrow batches. That copy is intentional: the registered table can outlive this call, while ordinary Go Arrow arrays may use Go-owned buffers that must not be retained by native code after a cgo call returns.

func RegisterArrowReaderZeroCopy

func RegisterArrowReaderZeroCopy(ctx context.Context, sqlConn *sql.Conn, tableName string, reader array.RecordReader) error

RegisterArrowReaderZeroCopy registers the remaining batches in reader as a DataFusion in-memory table by exporting reader through the Arrow C Stream Interface.

Unlike RegisterArrowReader, this path does not copy buffers into Rust-owned memory. Use it only when every exported Arrow buffer is safe for native code to retain until the registered table is dropped or the owning DataFusion session/connector is closed, for example buffers allocated with Arrow Go's mallocator or another C/foreign allocator. Passing ordinary Go-allocated Arrow buffers can violate cgo pointer lifetime rules because DataFusion keeps table batches after this call returns.

Types

type ArrowReader

type ArrowReader interface {
	arrio.Reader
	Schema() *arrow.Schema
	Close() error
}

ArrowReader streams Arrow record batches returned by DataFusion.

Callers must close the reader when they are done with it. Close cancels any in-flight native execution and releases native Arrow stream resources.

func QueryArrowContext

func QueryArrowContext(ctx context.Context, sqlConn *sql.Conn, query string, args ...any) (ArrowReader, error)

QueryArrowContext runs query on a DataFusion *sql.Conn and returns Arrow record batches without converting them through database/sql values.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a single database/sql driver connection to a DataFusion SessionContext.

func (*Conn) Begin

func (conn *Conn) Begin() (driver.Tx, error)

Begin returns an unsupported error because DataFusion transactions are not supported.

func (*Conn) BeginTx

func (conn *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error)

BeginTx returns an unsupported error after honoring an already-canceled context.

func (*Conn) CheckNamedValue

func (conn *Conn) CheckNamedValue(nv *driver.NamedValue) error

CheckNamedValue normalizes DataFusion-specific parameter wrapper types.

func (*Conn) Close

func (conn *Conn) Close() error

Close releases the native connection handle.

func (*Conn) ExecContext

func (conn *Conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error)

ExecContext executes a statement and returns a database/sql result.

func (*Conn) IsValid

func (conn *Conn) IsValid() bool

IsValid reports whether the connection can be reused by database/sql.

func (*Conn) Ping

func (conn *Conn) Ping(ctx context.Context) error

Ping validates that the connection is open.

func (*Conn) Prepare

func (conn *Conn) Prepare(query string) (driver.Stmt, error)

Prepare validates and prepares query using a background context.

func (*Conn) PrepareContext

func (conn *Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error)

PrepareContext validates and prepares query.

func (*Conn) QueryArrowContext

func (conn *Conn) QueryArrowContext(ctx context.Context, query string, args []driver.NamedValue) (ArrowReader, error)

QueryArrowContext executes a query and returns Arrow record batches.

func (*Conn) QueryContext

func (conn *Conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error)

QueryContext executes a query and adapts Arrow record batches to database/sql rows.

func (*Conn) ResetSession

func (conn *Conn) ResetSession(ctx context.Context) error

ResetSession resets isolated sessions and validates shared sessions for pool reuse.

type Connector

type Connector struct {
	// contains filtered or unexported fields
}

Connector owns the native DataFusion database handle used to open pooled connections.

func NewConnector

func NewConnector(dsn string, initFn func(driver.ExecerContext) error) (*Connector, error)

NewConnector creates a DataFusion connector for database/sql.

func NewConnectorWithInitContext

func NewConnectorWithInitContext(dsn string, initFn func(context.Context, driver.ExecerContext) error, options ...ConnectorOption) (*Connector, error)

NewConnectorWithInitContext creates a DataFusion connector with an optional initialization callback and connector options.

func (*Connector) Close

func (c *Connector) Close() error

Close releases the connector's DataFusion database resources.

func (*Connector) Connect

func (c *Connector) Connect(ctx context.Context) (driver.Conn, error)

Connect opens a new DataFusion connection.

func (*Connector) Driver

func (c *Connector) Driver() driver.Driver

Driver returns the database/sql driver used by the connector.

type ConnectorOption

type ConnectorOption func(*connectorOptions)

ConnectorOption configures a DataFusion connector.

func WithSharedSession

func WithSharedSession(shared bool) ConnectorOption

WithSharedSession controls whether connections from one Connector share a DataFusion SessionContext.

type Date

type Date struct {
	// contains filtered or unexported fields
}

Date binds a parameter as an Arrow Date32 value.

func DateFromTime

func DateFromTime(t time.Time) Date

DateFromTime returns a Date using t's calendar date in t's location.

func (Date) Days

func (value Date) Days() int32

Days returns the Arrow Date32 day count since the Unix epoch.

func (Date) Time

func (value Date) Time() time.Time

Time returns the date as a UTC time at midnight.

type Decimal

type Decimal struct {
	// contains filtered or unexported fields
}

Decimal binds a parameter as an Arrow Decimal128 value.

func DecimalString

func DecimalString(value string, precision uint8, scale int8) Decimal

DecimalString returns a Decimal parameter from a base-10 string, precision, and scale.

func NewDecimalString

func NewDecimalString(value string, precision uint8, scale int8) (Decimal, error)

NewDecimalString validates and returns a Decimal parameter from a base-10 string, precision, and scale.

func (Decimal) Precision

func (value Decimal) Precision() uint8

Precision returns the Arrow decimal precision.

func (Decimal) Scale

func (value Decimal) Scale() int8

Scale returns the Arrow decimal scale.

func (Decimal) String

func (value Decimal) String() string

String returns the decimal value's base-10 representation.

type Driver

type Driver struct{}

Driver implements database/sql/driver.Driver for DataFusion.

func (Driver) Open

func (d Driver) Open(dsn string) (driver.Conn, error)

func (Driver) OpenConnector

func (Driver) OpenConnector(dsn string) (driver.Connector, error)

type Duration

type Duration struct {
	// contains filtered or unexported fields
}

Duration binds a parameter as an Arrow duration with nanosecond precision.

func DurationFromTime

func DurationFromTime(d time.Duration) Duration

DurationFromTime returns a Duration from a Go time.Duration.

func DurationNanos

func DurationNanos(nanoseconds int64) Duration

DurationNanos returns a Duration from nanoseconds.

func (Duration) Duration

func (value Duration) Duration() time.Duration

Duration returns the value as a Go time.Duration.

func (Duration) Nanoseconds

func (value Duration) Nanoseconds() int64

Nanoseconds returns the duration as nanoseconds.

type Error

type Error struct {
	// Type identifies the driver operation that failed.
	Type ErrorType
	// NativeKind identifies native DataFusion failures when available.
	NativeKind NativeErrorKind
	// Message is the driver-level error message.
	Message string
	// Cause is the wrapped native or lower-level error.
	Cause error
}

Error is the structured error type returned by this driver.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Is

func (e *Error) Is(target error) bool

func (*Error) Unwrap

func (e *Error) Unwrap() error

type ErrorType

type ErrorType string

ErrorType identifies the operation that failed.

const (
	// ErrorConnect marks failures while opening a database or connection.
	ErrorConnect ErrorType = "connect"
	// ErrorPrepare marks failures while parsing or preparing SQL.
	ErrorPrepare ErrorType = "prepare"
	// ErrorBind marks failures while binding SQL parameters.
	ErrorBind ErrorType = "bind"
	// ErrorExecute marks failures while executing SQL or reading result batches.
	ErrorExecute ErrorType = "execute"
	// ErrorScan marks failures while adapting Arrow values to database/sql rows.
	ErrorScan ErrorType = "scan"
	// ErrorClosed marks use of a closed connector, connection, statement, or reader.
	ErrorClosed ErrorType = "closed"
	// ErrorUnsupported marks operations DataFusion does not support through this driver.
	ErrorUnsupported ErrorType = "unsupported"
	// ErrorNative marks uncategorized native FFI failures.
	ErrorNative ErrorType = "native"
)

type NativeErrorKind

type NativeErrorKind string

NativeErrorKind is the stable public classification for native DataFusion errors.

const (
	// NativeErrorKindCancelled indicates a query canceled through context cancellation.
	NativeErrorKindCancelled NativeErrorKind = "cancelled"
	// NativeErrorKindInvalidArgument indicates invalid SQL, parameters, or API input.
	NativeErrorKindInvalidArgument NativeErrorKind = "invalid_argument"
	// NativeErrorKindNative indicates an uncategorized native DataFusion failure.
	NativeErrorKindNative NativeErrorKind = "native"
	// NativeErrorKindPanic indicates a panic caught on the Rust side of the FFI boundary.
	NativeErrorKindPanic NativeErrorKind = "panic"
)

type Null

type Null struct {
	// contains filtered or unexported fields
}

Null binds a typed null parameter.

func NullDecimal

func NullDecimal(precision uint8, scale int8) Null

NullDecimal returns a typed decimal null.

func NullOf

func NullOf(typ ParameterType) Null

NullOf returns a typed null for non-decimal parameter types.

func NullTimestamp

func NullTimestamp(timeZone string) Null

NullTimestamp returns a typed timestamp null with an explicit Arrow time zone string.

func (Null) Precision

func (value Null) Precision() uint8

Precision returns the decimal precision for decimal typed nulls.

func (Null) Scale

func (value Null) Scale() int8

Scale returns the decimal scale for decimal typed nulls.

func (Null) TimeZone

func (value Null) TimeZone() string

TimeZone returns the Arrow timestamp timezone string for timestamp typed nulls.

func (Null) Type

func (value Null) Type() ParameterType

Type returns the typed-null parameter type.

type ParameterType

type ParameterType int

ParameterType names a DataFusion scalar type for typed null parameters.

const (
	// ParameterBool identifies a boolean parameter.
	ParameterBool ParameterType = iota + 1
	// ParameterInt64 identifies a signed 64-bit integer parameter.
	ParameterInt64
	// ParameterUInt64 identifies an unsigned 64-bit integer parameter.
	ParameterUInt64
	// ParameterFloat64 identifies a 64-bit floating point parameter.
	ParameterFloat64
	// ParameterString identifies a UTF-8 string parameter.
	ParameterString
	// ParameterBinary identifies a binary parameter.
	ParameterBinary
	// ParameterDate identifies an Arrow Date32 parameter.
	ParameterDate
	// ParameterTime identifies an Arrow Time64 nanosecond parameter.
	ParameterTime
	// ParameterTimestamp identifies an Arrow timestamp parameter.
	ParameterTimestamp
	// ParameterDuration identifies an Arrow duration nanosecond parameter.
	ParameterDuration
	// ParameterDecimal identifies an Arrow Decimal128 parameter.
	ParameterDecimal
)

type RegisteredTable added in v0.530100.2

type RegisteredTable struct {
	// contains filtered or unexported fields
}

RegisteredTable is a handle to a table registered on a connection by RegisterFFITableProvider. The handle is safe for concurrent use.

The table's lifetime follows the session it was registered on, not this handle. Closing sqlConn returns its physical connection to the pool, and does not guarantee table release in either session mode. An isolated session is discarded when that connection is reset or physically closed; a shared session can outlive every individual sqlConn. Deregister explicitly while sqlConn is open when deterministic catalog removal is needed.

Catalog removal does not invalidate already-created query plans, views, readers, or Arrow batches. Before unloading the producing library, callers must stop new queries, remove every registration and dependent view, close all dependent readers, and release their batches. The library must remain loaded until all foreign objects (including the original provider) are freed.

Dropping the handle never deregisters the table: a caller may legitimately keep querying it after dropping the handle. Deregistration is therefore always explicit.

func RegisterFFITableProvider added in v0.530100.2

func RegisterFFITableProvider(ctx context.Context, sqlConn *sql.Conn, tableName string, provider unsafe.Pointer, providerDataFusionVersion string) (*RegisteredTable, error)

RegisterFFITableProvider registers a foreign datafusion-ffi FFI_TableProvider, produced by another library, as a queryable table named tableName on the DataFusion connection backing sqlConn. Once registered, SQL executed on sqlConn can scan the table, and projection/filter predicates are pushed down into the foreign provider.

The table is registered on sqlConn's session, following the usual session semantics: with WithSharedSession it is registered on the shared session and is therefore visible to every connection sharing it, not just sqlConn.

provider must point to a valid, initialized datafusion-ffi FFI_TableProvider that is owned by the producing foreign library — memory allocated by that library (C/Rust), not Go heap memory. Registration clones callback pointers out of the provider and native code invokes them long after this call returns, so passing a Go-allocated pointer would violate cgo's pointer-passing rules and risk corruption once Go's garbage collector moves or frees it. providerDataFusionVersion is the datafusion version the library that produced provider was built against; obtain it from that library (not from DataFusionVersion). Registration fails with an error if it does not equal this package's DataFusionVersion — the two sides must link the same datafusion version for the provider's memory layout to be compatible. This check happens before provider is dereferenced, so a version mismatch is a clean error rather than a crash; it is cooperative and cannot detect a mislabeled provider.

Lifetime: registration clones the provider (bumping its internal refcount), so the caller still owns the original FFI_TableProvider pointer and may free it through its producing library once this call returns. The producing library itself must stay loaded until every registration and dependent foreign object is released, including query plans, views, readers, and returned Arrow batches (see RegisteredTable). Deregister or closing sqlConn alone does not establish that lifetime. Unloading earlier leaves foreign callbacks dangling. The DataFusion session backing the provider should also outlive all dependent queries; if it does not, queries fail with an error.

func (*RegisteredTable) Deregister added in v0.530100.2

func (t *RegisteredTable) Deregister(ctx context.Context) error

Deregister removes the table from the session it was registered on. Under WithSharedSession that is the shared session, so the table is removed for every connection sharing it, not just sqlConn. Calling it more than once is a no-op that returns nil, and deregistering a name that is no longer registered is not an error.

Deregister removes the catalog entry in either session mode. Existing views, query plans, readers, and batches can retain foreign objects afterward, so the producing library must still outlive them. Deregister runs on sqlConn, which must remain open; a closed connection returns sql.ErrConnDone.

func (*RegisteredTable) Name added in v0.530100.2

func (t *RegisteredTable) Name() string

Name returns the table name this handle refers to.

type SQLExecerContext

type SQLExecerContext interface {
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
}

SQLExecerContext is implemented by *sql.DB, *sql.Conn, and *sql.Tx.

type Stmt

type Stmt struct {
	// contains filtered or unexported fields
}

Stmt is a prepared DataFusion statement.

func (*Stmt) CheckNamedValue

func (s *Stmt) CheckNamedValue(nv *driver.NamedValue) error

CheckNamedValue normalizes DataFusion-specific parameter wrapper types.

func (*Stmt) Close

func (s *Stmt) Close() error

Close releases the native prepared statement handle.

func (*Stmt) Exec

func (s *Stmt) Exec(args []driver.Value) (driver.Result, error)

Exec executes the statement with positional driver values.

func (*Stmt) ExecContext

func (s *Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error)

ExecContext executes the statement with normalized named values.

func (*Stmt) NumInput

func (s *Stmt) NumInput() int

NumInput returns the number of SQL parameters found while preparing the statement.

func (*Stmt) Query

func (s *Stmt) Query(args []driver.Value) (driver.Rows, error)

Query executes the statement with positional driver values.

func (*Stmt) QueryContext

func (s *Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error)

QueryContext executes the statement with normalized named values.

type Time

type Time struct {
	// contains filtered or unexported fields
}

Time binds a parameter as an Arrow Time64 nanosecond value.

func NewTimeNanos

func NewTimeNanos(nanoseconds int64) (Time, error)

NewTimeNanos validates and returns a Time from nanoseconds since midnight.

func TimeFromTime

func TimeFromTime(t time.Time) Time

TimeFromTime returns a Time using only t's clock fields in t's location.

func TimeNanos

func TimeNanos(nanoseconds int64) Time

TimeNanos returns a Time from nanoseconds since midnight.

func (Time) Nanoseconds

func (value Time) Nanoseconds() int64

Nanoseconds returns the nanoseconds since midnight.

func (Time) Time

func (value Time) Time() time.Time

Time returns the clock value as a UTC time on the Unix epoch date.

type Timestamp

type Timestamp struct {
	// contains filtered or unexported fields
}

Timestamp binds a parameter as an Arrow timestamp with nanosecond precision.

func TimestampFromTime

func TimestampFromTime(t time.Time) Timestamp

TimestampFromTime returns a UTC timestamp parameter for t.

func TimestampWithTimeZone

func TimestampWithTimeZone(t time.Time, timeZone string) Timestamp

TimestampWithTimeZone returns a timestamp parameter with an explicit Arrow time zone string.

func (Timestamp) Time

func (value Timestamp) Time() time.Time

Time returns the timestamp value.

func (Timestamp) TimeZone

func (value Timestamp) TimeZone() string

TimeZone returns the Arrow timestamp timezone string.

type UInt64

type UInt64 uint64

UInt64 binds a parameter as an unsigned 64-bit integer.

func (UInt64) Uint64

func (value UInt64) Uint64() uint64

Uint64 returns the parameter value as a uint64.

Directories

Path Synopsis
examples
arrow command
parameters command
simple command
internal
conformance
Package conformance describes the query fixtures shared by the Go, Rust, and SQLite test runners.
Package conformance describes the query fixtures shared by the Go, Rust, and SQLite test runners.
tools/genabi command
Command genabi derives loader declarations and contract tests from the C ABI.
Command genabi derives loader declarations and contract tests from the C ABI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL