diff --git a/runtime/drivers/duckdb/transporter_duckDB_to_duckDB.go b/runtime/drivers/duckdb/transporter_duckDB_to_duckDB.go index 5ddc904a703..dba839c925d 100644 --- a/runtime/drivers/duckdb/transporter_duckDB_to_duckDB.go +++ b/runtime/drivers/duckdb/transporter_duckDB_to_duckDB.go @@ -97,11 +97,11 @@ func (t *duckDBToDuckDB) Transfer(ctx context.Context, srcProps, sinkProps map[s // If the path is a local file reference, rewrite to a safe and repo-relative path. if uri.Scheme == "" && uri.Host == "" { - sql, err := rewriteLocalPaths(ast, opts.RepoRoot, opts.AllowHostAccess) + rewrittenSQL, err := rewriteLocalPaths(ast, opts.RepoRoot, opts.AllowHostAccess) if err != nil { return fmt.Errorf("invalid local path: %w", err) } - srcCfg.SQL = sql + srcCfg.SQL = rewrittenSQL } return t.to.CreateTableAsSelect(ctx, sinkCfg.Table, false, srcCfg.SQL) @@ -138,7 +138,7 @@ func (t *duckDBToDuckDB) transferFromExternalDB(ctx context.Context, srcProps *d } }() - if err = t.to.Exec(ctx, &drivers.Statement{Query: fmt.Sprintf("USE %s;", safeName(dbName))}); err != nil { + if err := t.to.Exec(ctx, &drivers.Statement{Query: fmt.Sprintf("USE %s;", safeName(dbName))}); err != nil { return err } diff --git a/runtime/drivers/duckdb/transporter_duckDB_to_duckDB_test.go b/runtime/drivers/duckdb/transporter_duckDB_to_duckDB_test.go new file mode 100644 index 00000000000..a750ec637c9 --- /dev/null +++ b/runtime/drivers/duckdb/transporter_duckDB_to_duckDB_test.go @@ -0,0 +1,65 @@ +package duckdb + +import ( + "context" + "fmt" + "path/filepath" + "testing" + + "github.com/rilldata/rill/runtime/drivers" + activity "github.com/rilldata/rill/runtime/pkg/activity" + "github.com/stretchr/testify/require" + "go.uber.org/zap" +) + +func TestDuckDBToDuckDBTransfer(t *testing.T) { + tempDir := t.TempDir() + conn, err := Driver{}.Open(map[string]any{"dsn": fmt.Sprintf("%s.db?access_mode=read_write", filepath.Join(tempDir, "tranfser"))}, false, activity.NewNoopClient(), zap.NewNop()) + require.NoError(t, err) + + olap, ok := conn.AsOLAP("") + require.True(t, ok) + + err = olap.Exec(context.Background(), &drivers.Statement{ + Query: "CREATE TABLE foo(bar VARCHAR, baz INTEGER)", + }) + require.NoError(t, err) + + err = olap.Exec(context.Background(), &drivers.Statement{ + Query: "INSERT INTO foo VALUES ('a', 1), ('a', 2), ('b', 3), ('c', 4)", + }) + require.NoError(t, err) + require.NoError(t, conn.Close()) + + to, err := Driver{}.Open(map[string]any{"dsn": ""}, false, activity.NewNoopClient(), zap.NewNop()) + require.NoError(t, err) + + olap, _ = to.AsOLAP("") + + tr := NewDuckDBToDuckDB(olap, zap.NewNop()) + + // transfer once + err = tr.Transfer(context.Background(), map[string]any{"sql": "SELECT * FROM foo", "db": filepath.Join(tempDir, "tranfser.db")}, map[string]any{"table": "test"}, &drivers.TransferOptions{Progress: drivers.NoOpProgress{}}) + require.NoError(t, err) + + rows, err := olap.Execute(context.Background(), &drivers.Statement{Query: "SELECT COUNT(*) FROM test"}) + require.NoError(t, err) + + var count int + rows.Next() + require.NoError(t, rows.Scan(&count)) + require.Equal(t, 4, count) + require.NoError(t, rows.Close()) + + // transfer again + err = tr.Transfer(context.Background(), map[string]any{"sql": "SELECT * FROM foo", "db": filepath.Join(tempDir, "tranfser.db")}, map[string]any{"table": "test"}, &drivers.TransferOptions{Progress: drivers.NoOpProgress{}}) + require.NoError(t, err) + + rows, err = olap.Execute(context.Background(), &drivers.Statement{Query: "SELECT COUNT(*) FROM test"}) + require.NoError(t, err) + + rows.Next() + require.NoError(t, rows.Scan(&count)) + require.Equal(t, 4, count) + require.NoError(t, rows.Close()) +} diff --git a/web-common/src/features/sources/sourceUtils.ts b/web-common/src/features/sources/sourceUtils.ts index 083c4d223c0..ec9959e1afe 100644 --- a/web-common/src/features/sources/sourceUtils.ts +++ b/web-common/src/features/sources/sourceUtils.ts @@ -40,10 +40,10 @@ export function compileCreateSourceYAML( delete values.table; break; case "duckdb": - var db = values.db as string + var db = values.db as string; if (db.startsWith("md:")) { connectorName = "motherduck"; - values.db = db.replace("md:", "") + values.db = db.replace("md:", ""); } break; }