Skip to content
This repository was archived by the owner on Oct 20, 2025. It is now read-only.

Commit 9d4f1fc

Browse files
committed
Merge branch 'main' into stream-arrow-reader
2 parents 1cdfb8e + 9f4f8de commit 9d4f1fc

File tree

10 files changed

+60
-36
lines changed

10 files changed

+60
-36
lines changed

appender.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
// Appender holds the DuckDB appender. It allows efficient bulk loading into a DuckDB database.
1515
type Appender struct {
16-
con *conn
16+
con *Conn
1717
schema string
1818
table string
1919
duckdbAppender C.duckdb_appender
@@ -31,7 +31,7 @@ type Appender struct {
3131

3232
// NewAppenderFromConn returns a new Appender from a DuckDB driver connection.
3333
func NewAppenderFromConn(driverConn driver.Conn, schema, table string) (*Appender, error) {
34-
con, ok := driverConn.(*conn)
34+
con, ok := driverConn.(*Conn)
3535
if !ok {
3636
return nil, getError(errInvalidCon, nil)
3737
}

arrow.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ import (
7474
// Arrow exposes DuckDB Apache Arrow interface.
7575
// https://duckdb.org/docs/api/c/api#arrow-interface
7676
type Arrow struct {
77-
c *conn
77+
c *Conn
7878
}
7979

8080
// NewArrowFromConn returns a new Arrow from a DuckDB driver connection.
8181
func NewArrowFromConn(driverConn driver.Conn) (*Arrow, error) {
82-
dbConn, ok := driverConn.(*conn)
82+
dbConn, ok := driverConn.(*Conn)
8383
if !ok {
8484
return nil, fmt.Errorf("not a duckdb driver connection")
8585
}
@@ -264,7 +264,7 @@ func queryArrowArray(res *C.duckdb_arrow, sc *arrow.Schema) (arrow.Record, error
264264
return rec, nil
265265
}
266266

267-
func (a *Arrow) execute(s *stmt, args []driver.NamedValue) (*C.duckdb_arrow, error) {
267+
func (a *Arrow) execute(s *Stmt, args []driver.NamedValue) (*C.duckdb_arrow, error) {
268268
if s.closed {
269269
return nil, errClosedCon
270270
}

connection.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,26 @@ import (
1414
"unsafe"
1515
)
1616

17-
type conn struct {
17+
// Conn holds a connection to a DuckDB database.
18+
// It implements the driver.Conn interface.
19+
type Conn struct {
1820
duckdbCon C.duckdb_connection
1921
closed bool
2022
tx bool
2123
}
2224

23-
func (c *conn) CheckNamedValue(nv *driver.NamedValue) error {
25+
// CheckNamedValue implements the driver.NamedValueChecker interface.
26+
func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error {
2427
switch nv.Value.(type) {
2528
case *big.Int, Interval:
2629
return nil
2730
}
2831
return driver.ErrSkip
2932
}
3033

31-
func (c *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
34+
// ExecContext executes a query that doesn't return rows, such as an INSERT or UPDATE.
35+
// It implements the driver.ExecerContext interface.
36+
func (c *Conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
3237
prepared, err := c.prepareStmts(ctx, query)
3338
if err != nil {
3439
return nil, err
@@ -48,7 +53,9 @@ func (c *conn) ExecContext(ctx context.Context, query string, args []driver.Name
4853
return res, nil
4954
}
5055

51-
func (c *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
56+
// QueryContext executes a query that may return rows, such as a SELECT.
57+
// It implements the driver.QueryerContext interface.
58+
func (c *Conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
5259
prepared, err := c.prepareStmts(ctx, query)
5360
if err != nil {
5461
return nil, err
@@ -68,11 +75,15 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
6875
return r, nil
6976
}
7077

71-
func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
78+
// PrepareContext returns a prepared statement, bound to this connection.
79+
// It implements the driver.ConnPrepareContext interface.
80+
func (c *Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
7281
return c.prepareStmts(ctx, query)
7382
}
7483

75-
func (c *conn) Prepare(query string) (driver.Stmt, error) {
84+
// Prepare returns a prepared statement, bound to this connection.
85+
// It implements the driver.Conn interface.
86+
func (c *Conn) Prepare(query string) (driver.Stmt, error) {
7687
if c.closed {
7788
return nil, errors.Join(errPrepare, errClosedCon)
7889
}
@@ -90,11 +101,13 @@ func (c *conn) Prepare(query string) (driver.Stmt, error) {
90101
}
91102

92103
// Begin is deprecated: Use BeginTx instead.
93-
func (c *conn) Begin() (driver.Tx, error) {
104+
func (c *Conn) Begin() (driver.Tx, error) {
94105
return c.BeginTx(context.Background(), driver.TxOptions{})
95106
}
96107

97-
func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
108+
// BeginTx starts and returns a new transaction.
109+
// It implements the driver.ConnBeginTx interface.
110+
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
98111
if c.tx {
99112
return nil, errors.Join(errBeginTx, errMultipleTx)
100113
}
@@ -117,7 +130,9 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e
117130
return &tx{c}, nil
118131
}
119132

120-
func (c *conn) Close() error {
133+
// Close closes the connection to the database.
134+
// It implements the driver.Conn interface.
135+
func (c *Conn) Close() error {
121136
if c.closed {
122137
return errClosedCon
123138
}
@@ -126,7 +141,7 @@ func (c *conn) Close() error {
126141
return nil
127142
}
128143

129-
func (c *conn) extractStmts(query string) (C.duckdb_extracted_statements, C.idx_t, error) {
144+
func (c *Conn) extractStmts(query string) (C.duckdb_extracted_statements, C.idx_t, error) {
130145
cQuery := C.CString(query)
131146
defer C.duckdb_free(unsafe.Pointer(cQuery))
132147

@@ -145,7 +160,7 @@ func (c *conn) extractStmts(query string) (C.duckdb_extracted_statements, C.idx_
145160
return stmts, count, nil
146161
}
147162

148-
func (c *conn) prepareExtractedStmt(stmts C.duckdb_extracted_statements, i C.idx_t) (*stmt, error) {
163+
func (c *Conn) prepareExtractedStmt(stmts C.duckdb_extracted_statements, i C.idx_t) (*Stmt, error) {
149164
var s C.duckdb_prepared_statement
150165
state := C.duckdb_prepare_extracted_statement(c.duckdbCon, stmts, i, &s)
151166

@@ -155,10 +170,10 @@ func (c *conn) prepareExtractedStmt(stmts C.duckdb_extracted_statements, i C.idx
155170
return nil, err
156171
}
157172

158-
return &stmt{c: c, stmt: &s}, nil
173+
return &Stmt{c: c, stmt: &s}, nil
159174
}
160175

161-
func (c *conn) prepareStmts(ctx context.Context, query string) (*stmt, error) {
176+
func (c *Conn) prepareStmts(ctx context.Context, query string) (*Stmt, error) {
162177
if c.closed {
163178
return nil, errClosedCon
164179
}

duckdb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (c *Connector) Connect(context.Context) (driver.Conn, error) {
8787
return nil, getError(errConnect, nil)
8888
}
8989

90-
con := &conn{duckdbCon: duckdbCon}
90+
con := &Conn{duckdbCon: duckdbCon}
9191

9292
if c.connInitFn != nil {
9393
if err := c.connInitFn(con); err != nil {

profiling.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type ProfilingInfo struct {
2626
func GetProfilingInfo(c *sql.Conn) (ProfilingInfo, error) {
2727
info := ProfilingInfo{}
2828
err := c.Raw(func(driverConn any) error {
29-
con := driverConn.(*conn)
29+
con := driverConn.(*Conn)
3030
duckdbInfo := C.duckdb_get_profiling_info(con.duckdbCon)
3131
if duckdbInfo == nil {
3232
return getError(errProfilingInfoEmpty, nil)

rows.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
// rows is a helper struct for scanning a duckdb result.
2020
type rows struct {
2121
// stmt is a pointer to the stmt of which we are scanning the result.
22-
stmt *stmt
22+
stmt *Stmt
2323
// res is the result of stmt.
2424
res C.duckdb_result
2525
// chunk holds the currently active data chunk.
@@ -32,7 +32,7 @@ type rows struct {
3232
rowCount int
3333
}
3434

35-
func newRowsWithStmt(res C.duckdb_result, stmt *stmt) *rows {
35+
func newRowsWithStmt(res C.duckdb_result, stmt *Stmt) *rows {
3636
columnCount := C.duckdb_column_count(&res)
3737
r := rows{
3838
res: res,

scalarUDF.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func RegisterScalarUDF(c *sql.Conn, name string, f ScalarFunc) error {
7070

7171
// Register the function on the underlying driver connection exposed by c.Raw.
7272
err = c.Raw(func(driverConn any) error {
73-
con := driverConn.(*conn)
73+
con := driverConn.(*Conn)
7474
state := C.duckdb_register_scalar_function(con.duckdbCon, function)
7575
C.duckdb_destroy_scalar_function(&function)
7676
if state == C.DuckDBError {
@@ -111,7 +111,7 @@ func RegisterScalarUDFSet(c *sql.Conn, name string, functions ...ScalarFunc) err
111111

112112
// Register the function set on the underlying driver connection exposed by c.Raw.
113113
err := c.Raw(func(driverConn any) error {
114-
con := driverConn.(*conn)
114+
con := driverConn.(*Conn)
115115
state := C.duckdb_register_scalar_function_set(con.duckdbCon, set)
116116
C.duckdb_destroy_scalar_function_set(&set)
117117
if state == C.DuckDBError {

statement.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ import (
1515
"unsafe"
1616
)
1717

18-
type stmt struct {
19-
c *conn
18+
// Stmt implements the driver.Stmt interface.
19+
type Stmt struct {
20+
c *Conn
2021
stmt *C.duckdb_prepared_statement
2122
closeOnRowsClose bool
2223
closed bool
2324
rows bool
2425
}
2526

26-
func (s *stmt) Close() error {
27+
// Close closes the statement.
28+
// It implements the driver.Stmt interface.
29+
func (s *Stmt) Close() error {
2730
if s.rows {
2831
panic("database/sql/driver: misuse of duckdb driver: Close with active Rows")
2932
}
@@ -36,15 +39,17 @@ func (s *stmt) Close() error {
3639
return nil
3740
}
3841

39-
func (s *stmt) NumInput() int {
42+
// NumInput returns the number of placeholder parameters.
43+
// It implements the driver.Stmt interface.
44+
func (s *Stmt) NumInput() int {
4045
if s.closed {
4146
panic("database/sql/driver: misuse of duckdb driver: NumInput after Close")
4247
}
4348
paramCount := C.duckdb_nparams(*s.stmt)
4449
return int(paramCount)
4550
}
4651

47-
func (s *stmt) bind(args []driver.NamedValue) error {
52+
func (s *Stmt) bind(args []driver.NamedValue) error {
4853
if s.NumInput() > len(args) {
4954
return fmt.Errorf("incorrect argument count for command: have %d want %d", len(args), s.NumInput())
5055
}
@@ -175,11 +180,13 @@ func (s *stmt) bind(args []driver.NamedValue) error {
175180
}
176181

177182
// Deprecated: Use ExecContext instead.
178-
func (s *stmt) Exec(args []driver.Value) (driver.Result, error) {
183+
func (s *Stmt) Exec(args []driver.Value) (driver.Result, error) {
179184
return s.ExecContext(context.Background(), argsToNamedArgs(args))
180185
}
181186

182-
func (s *stmt) ExecContext(ctx context.Context, nargs []driver.NamedValue) (driver.Result, error) {
187+
// ExecContext executes a query that doesn't return rows, such as an INSERT or UPDATE.
188+
// It implements the driver.StmtExecContext interface.
189+
func (s *Stmt) ExecContext(ctx context.Context, nargs []driver.NamedValue) (driver.Result, error) {
183190
res, err := s.execute(ctx, nargs)
184191
if err != nil {
185192
return nil, err
@@ -191,11 +198,13 @@ func (s *stmt) ExecContext(ctx context.Context, nargs []driver.NamedValue) (driv
191198
}
192199

193200
// Deprecated: Use QueryContext instead.
194-
func (s *stmt) Query(args []driver.Value) (driver.Rows, error) {
201+
func (s *Stmt) Query(args []driver.Value) (driver.Rows, error) {
195202
return s.QueryContext(context.Background(), argsToNamedArgs(args))
196203
}
197204

198-
func (s *stmt) QueryContext(ctx context.Context, nargs []driver.NamedValue) (driver.Rows, error) {
205+
// QueryContext executes a query that may return rows, such as a SELECT.
206+
// It implements the driver.StmtQueryContext interface.
207+
func (s *Stmt) QueryContext(ctx context.Context, nargs []driver.NamedValue) (driver.Rows, error) {
199208
res, err := s.execute(ctx, nargs)
200209
if err != nil {
201210
return nil, err
@@ -206,7 +215,7 @@ func (s *stmt) QueryContext(ctx context.Context, nargs []driver.NamedValue) (dri
206215

207216
// This method executes the query in steps and checks if context is cancelled before executing each step.
208217
// It uses Pending Result Interface C APIs to achieve this. Reference - https://duckdb.org/docs/api/c/api#pending-result-interface
209-
func (s *stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb_result, error) {
218+
func (s *Stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb_result, error) {
210219
if s.closed {
211220
panic("database/sql/driver: misuse of duckdb driver: ExecContext or QueryContext after Close")
212221
}

tableUDF.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ func RegisterTableUDF[TFT TableFunction](c *sql.Conn, name string, f TFT) error
472472

473473
// Register the function on the underlying driver connection exposed by c.Raw.
474474
err := c.Raw(func(driverConn any) error {
475-
con := driverConn.(*conn)
475+
con := driverConn.(*Conn)
476476
state := C.duckdb_register_table_function(con.duckdbCon, function)
477477
C.duckdb_destroy_table_function(&function)
478478
if state == C.DuckDBError {

transaction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package duckdb
33
import "context"
44

55
type tx struct {
6-
c *conn
6+
c *Conn
77
}
88

99
func (t *tx) Commit() error {

0 commit comments

Comments
 (0)