mirror of
https://github.com/Kaelio/ktx.git
synced 2026-07-13 11:22:11 +02:00
feat(athena): first-class AWS Athena warehouse identity (SL + BI mapping) (#332)
* feat: support Athena warehouse identity * fix: support Athena and DuckDB BI table parsing
This commit is contained in:
parent
fe7e6bd1fa
commit
f310391da5
14 changed files with 252 additions and 45 deletions
|
|
@ -960,6 +960,28 @@ describe('validateWithProposedSource', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('uses the Athena sqlglot dialect when validating Athena sources', async () => {
|
||||
pythonPort.validateSources.mockResolvedValue({
|
||||
data: { errors: [], warnings: [] },
|
||||
});
|
||||
service = new SemanticLayerService(configService as never, connectionCatalog('ATHENA'), pythonPort);
|
||||
|
||||
await service.validateWithProposedSource('conn-1', {
|
||||
name: 'orders',
|
||||
table: 'analytics.orders',
|
||||
grain: ['id'],
|
||||
columns: [{ name: 'id', type: 'number' }],
|
||||
joins: [],
|
||||
measures: [],
|
||||
});
|
||||
|
||||
expect(pythonPort.validateSources).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
dialect: 'athena',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('composes a bare overlay with its manifest base before validating', async () => {
|
||||
const schemaPath = 'semantic-layer/conn-1/_schema/core.yaml';
|
||||
const listFilesImpl = (dir: string): Promise<{ files: string[] }> => {
|
||||
|
|
@ -1326,6 +1348,44 @@ describe('validateWithProposedSource', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('executeQuery dialect resolution', () => {
|
||||
it('passes the Athena sqlglot dialect to the Python query engine for Athena connections', async () => {
|
||||
pythonPort.query.mockResolvedValue({ data: { sql: 'SELECT * FROM orders' } });
|
||||
const catalog = connectionCatalog('ATHENA');
|
||||
catalog.executeQuery.mockResolvedValue({ headers: ['id'], rows: [[1]], totalRows: 1 });
|
||||
const configService = {
|
||||
listFiles: vi.fn().mockResolvedValue({
|
||||
files: ['semantic-layer/conn-1/orders.yaml'],
|
||||
}),
|
||||
readFile: vi.fn().mockResolvedValue({
|
||||
content: [
|
||||
'name: orders',
|
||||
'table: analytics.orders',
|
||||
'grain:',
|
||||
' - id',
|
||||
'columns:',
|
||||
' - name: id',
|
||||
' type: number',
|
||||
'joins: []',
|
||||
'measures:',
|
||||
' - name: count',
|
||||
' expr: count(*)',
|
||||
].join('\n'),
|
||||
}),
|
||||
};
|
||||
const service = new SemanticLayerService(configService as never, catalog, pythonPort);
|
||||
|
||||
await service.executeQuery('conn-1', { measures: ['count'] } as never);
|
||||
|
||||
expect(pythonPort.query).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
dialect: 'athena',
|
||||
}),
|
||||
);
|
||||
expect(catalog.executeQuery).toHaveBeenCalledWith('conn-1', 'SELECT * FROM orders');
|
||||
});
|
||||
});
|
||||
|
||||
describe('findDanglingSegmentRefs', () => {
|
||||
it('returns empty when every measure segment resolves', () => {
|
||||
const source = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue