@@ -38,16 +38,30 @@ private actor DuckDBConnectionActor {
3838
3939 func open( path: String ) throws {
4040 var db : duckdb_database ?
41- let state = duckdb_open ( path, & db)
41+ var errorPtr : UnsafeMutablePointer < CChar > ?
42+ let state = duckdb_open_ext ( path, & db, nil , & errorPtr)
4243
4344 if state == DuckDBError {
45+ let detail : String
46+ if let errPtr = errorPtr {
47+ detail = String ( cString: errPtr)
48+ duckdb_free ( errPtr)
49+ } else {
50+ detail = " unknown error "
51+ }
52+ throw DuckDBPluginError . connectionFailed (
53+ " Failed to open DuckDB database at ' \( path) ': \( detail) "
54+ )
55+ }
56+
57+ guard let openedDB = db else {
4458 throw DuckDBPluginError . connectionFailed (
4559 " Failed to open DuckDB database at ' \( path) ' "
4660 )
4761 }
4862
4963 var conn : duckdb_connection ?
50- let connState = duckdb_connect ( db , & conn)
64+ let connState = duckdb_connect ( openedDB , & conn)
5165
5266 if connState == DuckDBError {
5367 duckdb_close ( & db)
@@ -59,12 +73,12 @@ private actor DuckDBConnectionActor {
5973 }
6074
6175 func close( ) {
62- if var conn = connection {
63- duckdb_disconnect ( & conn )
76+ if connection != nil {
77+ duckdb_disconnect ( & connection )
6478 connection = nil
6579 }
66- if var db = database {
67- duckdb_close ( & db )
80+ if database != nil {
81+ duckdb_close ( & database )
6882 database = nil
6983 }
7084 }
@@ -103,22 +117,26 @@ private actor DuckDBConnectionActor {
103117 }
104118
105119 let startTime = Date ( )
106- var stmt : duckdb_prepared_statement ?
120+ var stmtOpt : duckdb_prepared_statement ?
107121
108- let prepState = duckdb_prepare ( conn, query, & stmt )
122+ let prepState = duckdb_prepare ( conn, query, & stmtOpt )
109123 if prepState == DuckDBError {
110124 let errorMsg : String
111- if let errPtr = duckdb_prepare_error ( stmt ) {
125+ if let s = stmtOpt , let errPtr = duckdb_prepare_error ( s ) {
112126 errorMsg = String ( cString: errPtr)
113127 } else {
114128 errorMsg = " Failed to prepare statement "
115129 }
116- duckdb_destroy_prepare ( & stmt )
130+ duckdb_destroy_prepare ( & stmtOpt )
117131 throw DuckDBPluginError . queryFailed ( errorMsg)
118132 }
119133
134+ guard let stmt = stmtOpt else {
135+ throw DuckDBPluginError . queryFailed ( " Failed to prepare statement " )
136+ }
137+
120138 defer {
121- duckdb_destroy_prepare ( & stmt )
139+ duckdb_destroy_prepare ( & stmtOpt )
122140 }
123141
124142 for (index, param) in parameters. enumerated ( ) {
@@ -298,6 +316,10 @@ final class DuckDBPluginDriver: PluginDatabaseDriver, @unchecked Sendable {
298316
299317 try await connectionActor. open ( path: path)
300318
319+ // Enable auto-install and auto-load of extensions (e.g. core_functions)
320+ try ? await connectionActor. executeQuery ( " SET autoinstall_known_extensions=1 " )
321+ try ? await connectionActor. executeQuery ( " SET autoload_known_extensions=1 " )
322+
301323 if let conn = await connectionActor. connectionHandleForInterrupt {
302324 setInterruptHandle ( conn)
303325 }
0 commit comments