fix(scan): bind connector sample methods and add duckdb aggregate dialect

description-generation extracted sampleTable/sampleColumn as bare locals and
called them without `this`, crashing every class-based connector with
"Cannot read properties of undefined (reading 'assertConnection')" during
deep ingest. Binding restores method context.

relationship-profiling fell back to SQLite-flavored GROUP_CONCAT for any
driver without an explicit branch, breaking DuckDB statistical validation
with a parser error and stranding all proposals in review. Added a duckdb
branch using STRING_AGG/CHR(31).
This commit is contained in:
Andrey Avtomonov 2026-05-18 18:12:31 +02:00
parent abdaff1c11
commit 0ecea6e548
2 changed files with 5 additions and 2 deletions

View file

@ -457,7 +457,7 @@ export class KtxDescriptionGenerator {
}
}
const sampleTable = input.connector.sampleTable;
const sampleTable = input.connector.sampleTable?.bind(input.connector);
let sampleData: KtxTableSampleResult | null = null;
let fallbackReason: 'capability_missing' | 'sampling_failed' | 'empty_sample' | null = null;
@ -678,7 +678,7 @@ export class KtxDescriptionGenerator {
});
columnValues = [];
} else {
const sampleColumn = input.connector.sampleColumn;
const sampleColumn = input.connector.sampleColumn.bind(input.connector);
try {
const sample = await retryAsync(
() =>

View file

@ -214,6 +214,9 @@ function sampleAggregateSql(driver: KtxConnectionDriver, innerSql: string): stri
if (driver === 'postgres') {
return `(SELECT STRING_AGG(CAST(value AS TEXT), CHR(31)) FROM (${innerSql}) AS relationship_profile_values)`;
}
if (driver === 'duckdb') {
return `(SELECT STRING_AGG(CAST(value AS VARCHAR), CHR(31)) FROM (${innerSql}) AS relationship_profile_values)`;
}
if (driver === 'bigquery') {
return `(SELECT STRING_AGG(CAST(value AS STRING), '\\u001F') FROM (${innerSql}) AS relationship_profile_values)`;
}