feat: add ducklake schema support to the database manager (#9633)

* feat: add ducklake schema support to the database manager

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat: support schema in wmill.ducklake("name:schema") template helper

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: preserve schema when parsing ducklake asset/favorite paths

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: regenerate system prompts for ducklake schema syntax doc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Diego Imbert
2026-06-17 17:23:14 +00:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 25a891041d
commit 3eeccaf968
20 changed files with 188 additions and 52 deletions
+29 -3
View File
@@ -51,17 +51,25 @@ function datatableProvider(name: string, schema?: string): SqlProvider {
};
}
function ducklakeProvider(name: string): SqlProvider {
function ducklakeProvider(name: string, schema?: string): SqlProvider {
return {
providerName: "ducklake",
language: "duckdb",
extraArgs: {},
formatArgDecl: (argNum, argType) => `-- $arg${argNum} (${argType})`,
formatArgUsage: (argNum) => `$arg${argNum}`,
preamble: () => `ATTACH 'ducklake://${name}' AS dl;USE dl;\n`,
preamble: () =>
`ATTACH 'ducklake://${name}' AS dl;USE dl${schema ? `."${schema}"` : ""};\n`,
};
}
function parseName(name: string | undefined): { name: string; schema?: string } {
if (!name) return { name: "main" };
let [assetName, schemaName] = name.split(":");
if (schemaName) return { name: assetName || "main", schema: schemaName };
return { name };
}
function inferSqlType(value: any): string {
if (typeof value === "bigint") return "BIGINT";
if (typeof value === "number") {
@@ -231,7 +239,10 @@ function templateTag(provider: SqlProvider) {
}
const dt = (name = "main") => templateTag(datatableProvider(name));
const dl = (name = "main") => templateTag(ducklakeProvider(name));
const dl = (name = "main") => {
const { name: n, schema } = parseName(name);
return templateTag(ducklakeProvider(n, schema));
};
const datatableQuery = (name = "main") => {
const provider = datatableProvider(name);
return (sql: string, ...params: any[]) =>
@@ -604,6 +615,21 @@ describe("ducklake() — DuckDB shape", () => {
const out = sql`SELECT 1`;
expect(out.args).not.toHaveProperty("database");
});
test("name:schema sets the active schema via USE dl.<schema>", () => {
const sql = dl("my_lake:analytics");
const out = sql`SELECT 1`;
expect(out.content).toContain(
`ATTACH 'ducklake://my_lake' AS dl;USE dl."analytics";`
);
});
test("no schema keeps the bare USE dl preamble", () => {
const sql = dl("my_lake");
const out = sql`SELECT 1`;
expect(out.content).toContain("ATTACH 'ducklake://my_lake' AS dl;USE dl;");
expect(out.content).not.toContain("USE dl.");
});
});
// =============================================================================