@@ -91,7 +91,7 @@ actor DuckDBConnectionActor {
9191 }
9292
9393 var raw = Self . extractResult ( from: & result, startTime: startTime)
94- Self . patchTzColumns ( & raw, query: query, connection: conn)
94+ Self . patchCastedColumns ( & raw, query: query, connection: conn)
9595 return raw
9696 }
9797
@@ -163,7 +163,7 @@ actor DuckDBConnectionActor {
163163 }
164164
165165 var raw = Self . extractResult ( from: & result, startTime: startTime)
166- Self . patchTzColumns ( & raw, query: query, connection: conn)
166+ Self . patchCastedColumns ( & raw, query: query, connection: conn)
167167 return raw
168168 }
169169
@@ -204,7 +204,7 @@ actor DuckDBConnectionActor {
204204 columnTypeNames. append ( Self . typeName ( for: colType) )
205205 }
206206
207- if columnTypes. contains ( where: Self . isUnrenderable ) {
207+ if columnTypes. contains ( where: Self . requiresTextCast ) {
208208 duckdb_destroy_result ( & result)
209209 try Self . streamWrappedQuery (
210210 query: query,
@@ -235,7 +235,7 @@ actor DuckDBConnectionActor {
235235 continuation: AsyncThrowingStream < PluginStreamElement , Error > . Continuation
236236 ) throws {
237237 let castExprs = columns. enumerated ( ) . map { i, name in
238- castExpression ( for: columnTypes [ i] , column: name)
238+ projection ( for: columnTypes [ i] , column: name)
239239 }
240240 let wrappedQuery = buildWrappedQuery ( originalQuery: query, castExprs: castExprs)
241241
@@ -484,16 +484,16 @@ actor DuckDBConnectionActor {
484484 }
485485 }
486486
487- static func patchTzColumns (
487+ static func patchCastedColumns (
488488 _ raw: inout DuckDBRawResult , query: String , connection: duckdb_connection
489489 ) {
490490 let patchedColIndices = raw. columnTypes. enumerated ( ) . compactMap { idx, type in
491- isUnrenderable ( type) ? idx : nil
491+ requiresTextCast ( type) ? idx : nil
492492 }
493493 guard !patchedColIndices. isEmpty, !raw. rows. isEmpty else { return }
494494
495495 let castExprs = raw. columns. enumerated ( ) . map { i, name in
496- castExpression ( for: raw. columnTypes [ i] , column: name)
496+ projection ( for: raw. columnTypes [ i] , column: name)
497497 }
498498 let wrappedQuery = buildWrappedQuery ( originalQuery: query, castExprs: castExprs)
499499
@@ -514,25 +514,36 @@ actor DuckDBConnectionActor {
514514 }
515515 }
516516
517- static func isUnrenderable ( _ type: duckdb_type ) -> Bool {
517+ static func isNativelyRenderable ( _ type: duckdb_type ) -> Bool {
518518 switch type {
519- case DUCKDB_TYPE_INVALID, DUCKDB_TYPE_TIMESTAMP_TZ, DUCKDB_TYPE_TIME_TZ, DUCKDB_TYPE_GEOMETRY:
519+ case DUCKDB_TYPE_BOOLEAN,
520+ DUCKDB_TYPE_TINYINT, DUCKDB_TYPE_SMALLINT, DUCKDB_TYPE_INTEGER, DUCKDB_TYPE_BIGINT, DUCKDB_TYPE_HUGEINT,
521+ DUCKDB_TYPE_UTINYINT, DUCKDB_TYPE_USMALLINT, DUCKDB_TYPE_UINTEGER, DUCKDB_TYPE_UBIGINT, DUCKDB_TYPE_UHUGEINT,
522+ DUCKDB_TYPE_FLOAT, DUCKDB_TYPE_DOUBLE, DUCKDB_TYPE_DECIMAL,
523+ DUCKDB_TYPE_VARCHAR, DUCKDB_TYPE_BLOB, DUCKDB_TYPE_UUID, DUCKDB_TYPE_BIT, DUCKDB_TYPE_ENUM,
524+ DUCKDB_TYPE_DATE, DUCKDB_TYPE_TIME, DUCKDB_TYPE_TIME_NS, DUCKDB_TYPE_INTERVAL,
525+ DUCKDB_TYPE_TIMESTAMP, DUCKDB_TYPE_TIMESTAMP_S, DUCKDB_TYPE_TIMESTAMP_MS, DUCKDB_TYPE_TIMESTAMP_NS,
526+ DUCKDB_TYPE_LIST, DUCKDB_TYPE_STRUCT, DUCKDB_TYPE_MAP, DUCKDB_TYPE_ARRAY, DUCKDB_TYPE_UNION:
520527 return true
521528 default :
522529 return false
523530 }
524531 }
525532
533+ static func requiresTextCast( _ type: duckdb_type ) -> Bool {
534+ !isNativelyRenderable( type)
535+ }
536+
526537 static func castExpression( for type: duckdb_type , column: String ) -> String {
527538 let quoted = quoteIdentifier ( column)
528- switch type {
529- case DUCKDB_TYPE_GEOMETRY:
539+ if type == DUCKDB_TYPE_GEOMETRY {
530540 return " CASE WHEN \( quoted) IS NULL THEN NULL ELSE ST_AsText( \( quoted) ) END AS \( quoted) "
531- case DUCKDB_TYPE_INVALID, DUCKDB_TYPE_TIMESTAMP_TZ, DUCKDB_TYPE_TIME_TZ:
532- return " CASE WHEN \( quoted) IS NULL THEN NULL ELSE CAST( \( quoted) AS VARCHAR) END AS \( quoted) "
533- default :
534- return quoted
535541 }
542+ return " CASE WHEN \( quoted) IS NULL THEN NULL ELSE CAST( \( quoted) AS VARCHAR) END AS \( quoted) "
543+ }
544+
545+ static func projection( for type: duckdb_type , column: String ) -> String {
546+ requiresTextCast ( type) ? castExpression ( for: type, column: column) : quoteIdentifier ( column)
536547 }
537548
538549 static func buildWrappedQuery( originalQuery: String , castExprs: [ String ] ) -> String {
0 commit comments