Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cc70d01
Implemented the credential-chain fallback for Redshift
Aug 4, 2026
d7696e2
fix(filesys): resolve GCS auth collision and add credential aliases
flarco Aug 5, 2026
07b32e7
update KILL MUTATION logging
flarco Aug 5, 2026
75ef38e
fix(database): separate bool and int casting to string
flarco Aug 5, 2026
7dc0296
fix(core): include ExecStatusSkipped in IsFinished
flarco Aug 5, 2026
13a515c
test(oracle): add state watermark format regression test
flarco Aug 6, 2026
2b39e12
fix: improve DuckDB concurrency and Arrow mode reliability
flarco Aug 6, 2026
c20fe3b
feat: add Windows support for ADBC driver manager discovery
flarco Aug 7, 2026
5b07994
feat(adbc): auto-install ADBC drivers via dbc CLI
flarco Aug 7, 2026
ef96528
feat(adbc): auto-download ADBC driver manager
flarco Aug 7, 2026
cb3648c
fix: add actionable diagnostics for ADBC library load errors
flarco Aug 7, 2026
e2fb379
fix: handle SQL expressions in column select logic
flarco Aug 7, 2026
c88f62e
test: skip failing TestCSV and fix skiplines test file path
flarco Aug 7, 2026
f0b2fbe
fix(adbc): correct connection keys and expand auth support
flarco Aug 7, 2026
71c4c81
Merge pull request #782 from macraesdirtysocks/add_credential_chain_f…
flarco Aug 9, 2026
abeb363
fix(duckdb): correct copy_method property name typo
flarco Aug 9, 2026
d5059d8
fix: improve Redshift AWS credential chain handling
flarco Aug 9, 2026
bc0ae47
fix: handle NULL _sling_synced_op in Redshift soft delete
flarco Aug 9, 2026
9bc2971
fix: make soft-merge delete guard NULL-safe across dialects
flarco Aug 9, 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
19 changes: 11 additions & 8 deletions cmd/sling/sling_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1158,23 +1158,26 @@ func TestSuiteDatabaseD1(t *testing.T) {

func TestSuiteDatabaseDuckDb(t *testing.T) {
t.Parallel()

// DUCKDB
testSuite(t, dbio.TypeDbDuckDb)
}
if os.Getenv("DUCKDB_USE_ARROW") == "" {
os.Setenv("DUCKDB_USE_ARROW", "true")
testSuite(t, dbio.TypeDbDuckDb)
os.Setenv("DUCKDB_USE_ARROW", "false")
}

func TestSuiteDatabaseDuckLake(t *testing.T) {
t.Parallel()
// MOTHERDUCK
testSuite(t, dbio.TypeDbMotherDuck)

// DUCKLAKE
tests := "1-17,19+" // soft-delete is not supported
testSuite(t, dbio.TypeDbDuckLake, tests)
// testSuite(t, dbio.Type("ducklake_az"), tests)
testSuite(t, dbio.Type("ducklake_r2"), tests)
testSuite(t, dbio.Type("ducklake_s3"), tests)
}

func TestSuiteDatabaseMotherDuck(t *testing.T) {
t.Parallel()
testSuite(t, dbio.TypeDbMotherDuck)
}

func TestSuiteDatabaseExasol(t *testing.T) {
t.Skip() // FIXME: cannot drop table, cannot create view without auto-commit
t.Parallel()
Expand Down
42 changes: 42 additions & 0 deletions core/dbio/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,47 @@ func (c *Connection) AsAPIContext(ctx context.Context, options ...AsConnOptions)
return c.API, nil
}

// setUseADBC turns on ADBC for supported databases when SLING_USE_ADBC is set,
// so a whole environment can be switched over without editing every connection.
// An explicit use_adbc on the connection always wins.
func (c *Connection) setUseADBC() {

// adbcSupportedTypes are the database types that can be driven over ADBC.
// Must stay in sync with the switch in database.NewAdbcConn.
var adbcSupportedTypes = []dbio.Type{
dbio.TypeDbPostgres,
dbio.TypeDbSQLServer,
dbio.TypeDbSnowflake,
dbio.TypeDbSQLite,
dbio.TypeDbDuckDb,
dbio.TypeDbBigQuery,
dbio.TypeDbMySQL,
dbio.TypeDbTrino,
}

if !cast.ToBool(os.Getenv("SLING_USE_ADBC")) {
return
}

if _, ok := c.Data["use_adbc"]; ok {
return // explicitly set on the connection, leave it alone
}

// c.Type is not resolved yet at this point, so derive it
connType := c.Type
if connType == "" {
if t, ok := c.Data["type"]; ok {
connType = dbio.Type(cast.ToString(t))
} else if url := c.URL(); url != "" {
connType = SchemeType(url)
}
}

if g.In(connType, adbcSupportedTypes...) {
c.Data["use_adbc"] = true
}
}

func (c *Connection) setFromEnv() {
if c.Name == "" && strings.HasPrefix(c.URL(), "$") {
c.Name = strings.TrimLeft(c.URL(), "$")
Expand Down Expand Up @@ -513,6 +554,7 @@ func (c *Connection) ConnSetDatabase(dbName string) *Connection {

func (c *Connection) setURL() (err error) {
c.setFromEnv()
c.setUseADBC()

// setIfMissing sets a default value if key is not present
setIfMissing := func(key string, val interface{}) {
Expand Down
116 changes: 0 additions & 116 deletions core/dbio/database/clickhouse_test.go

This file was deleted.

9 changes: 7 additions & 2 deletions core/dbio/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -2385,8 +2385,8 @@ func (conn *BaseConn) castBoolForSelect(srcCol iop.Column, tgtCol iop.Column) (s
castExpr := g.R(castFuncInt, "field", qName, "type", intType)
sql := `case when {col} = 'true' then 1 when {col} = 'false' then 0 else {col_as_int} end`
selectStr = g.R(sql, "col", qName, "col_as_int", castExpr)
case (srcCol.IsInteger() || srcCol.IsBool()) && tgtCol.IsString():
// assume bool, convert from 1/0 to true/false
case srcCol.IsInteger() && tgtCol.IsString():
// assume bool-as-int, convert from 1/0 to true/false
stringType := conn.GetType().GetTemplateValue("general_type_map.string")
if g.In(conn.GetType(), dbio.TypeDbMySQL, dbio.TypeDbMariaDB) {
// MySQL/MariaDB needs `CAST(column AS CHAR(length))`
Expand All @@ -2397,6 +2397,11 @@ func (conn *BaseConn) castBoolForSelect(srcCol iop.Column, tgtCol iop.Column) (s
castExpr := g.R(castFunc, "field", qName, "type", stringType)
sql := `case when {col} = 1 then 'true' when {col} = 0 then 'false' else {col_as_string} end`
selectStr = g.R(sql, "col", qName, "col_as_string", castExpr)
case srcCol.IsBool() && tgtCol.IsString():
// Genuine boolean: PG-family rejects `boolean = integer`, and Redshift
// rejects `CAST(boolean AS varchar)`. Use truthiness (no = 1 / no cast).
sql := `case when {col} is null then null when {col} then 'true' else 'false' end`
selectStr = g.R(sql, "col", qName)
default:
selectStr = qName
}
Expand Down
Loading