66
77import type { Column } from "../dataModels/dataModelTypes" ;
88import { sql , Sql , quoteIdentifier } from "../sqlHelpers" ;
9- import { OlapTable } from "../dmv2" ;
9+ import { OlapTable , MaterializedView } from "../dmv2" ;
1010import { QueryClient } from "../consumption-apis/helpers" ;
1111import {
1212 raw ,
@@ -49,6 +49,14 @@ const applyFilter = filterSql as (
4949
5050const identity = ( v : SqlValue ) : SqlValue => v ;
5151
52+ function resolveTable < T > (
53+ tableOrMv : OlapTable < T > | MaterializedView < T > ,
54+ ) : OlapTable < T > {
55+ return tableOrMv instanceof MaterializedView ?
56+ tableOrMv . targetTable
57+ : tableOrMv ;
58+ }
59+
5260/**
5361 * Apply a transform function to a filter value, respecting operator-specific
5462 * value shapes (scalar, list, tuple, boolean).
@@ -145,8 +153,8 @@ export interface QueryModelConfig<
145153 name ?: string ;
146154 /** Tool description used by registerModelTools */
147155 description ?: string ;
148- /** The OlapTable to query */
149- table : OlapTable < TTable > ;
156+ /** The OlapTable or MaterializedView to query. If a MaterializedView is passed, its targetTable is used. */
157+ table : OlapTable < TTable > | MaterializedView < TTable > ;
150158
151159 /**
152160 * Dimension fields — columns used for grouping, filtering, and display.
@@ -373,7 +381,7 @@ export function defineQueryModel<
373381 > ;
374382
375383 const {
376- table,
384+ table : tableOrMv ,
377385 dimensions,
378386 metrics,
379387 columns : columnDefs ,
@@ -382,6 +390,7 @@ export function defineQueryModel<
382390 sortable,
383391 defaults = { } ,
384392 } = config ;
393+ const table = resolveTable ( tableOrMv ) ;
385394 const { maxLimit = 1000 } = defaults ;
386395
387396 const primaryTableName = table . name ;
@@ -429,7 +438,7 @@ export function defineQueryModel<
429438 `Column '${ name } ' references unknown join '${ def . join } '` ,
430439 ) ;
431440 }
432- const joinTableName = joinDef . table . name ;
441+ const joinTableName = resolveTable ( joinDef . table ) . name ;
433442 normalizedColumns [ name ] = {
434443 expression : raw (
435444 `${ quoteIdentifier ( joinTableName ) } .${ quoteIdentifier ( String ( def . column ) ) } ` ,
@@ -679,10 +688,11 @@ export function defineQueryModel<
679688 let fromClause = sql `FROM ${ table } ` ;
680689 for ( const [ , joinDef ] of Object . entries ( joinDefs ! ) ) {
681690 const joinType = joinDef . type ?? "LEFT" ;
691+ const joinTable = resolveTable ( joinDef . table ) ;
682692
683693 let onClause : Sql ;
684694 if ( joinDef . leftKey && joinDef . rightKey ) {
685- const joinTableName = joinDef . table . name ;
695+ const joinTableName = joinTable . name ;
686696 onClause = raw (
687697 `${ quoteIdentifier ( primaryTableName ) } .${ quoteIdentifier ( joinDef . leftKey ) } = ${ quoteIdentifier ( joinTableName ) } .${ quoteIdentifier ( joinDef . rightKey ) } ` ,
688698 ) ;
@@ -692,7 +702,7 @@ export function defineQueryModel<
692702 throw new Error ( "JoinDef must specify either leftKey/rightKey or on" ) ;
693703 }
694704
695- fromClause = sql `${ fromClause } ${ raw ( joinType ) } JOIN ${ joinDef . table } ON ${ onClause } ` ;
705+ fromClause = sql `${ fromClause } ${ raw ( joinType ) } JOIN ${ joinTable } ON ${ onClause } ` ;
696706 }
697707 return fromClause ;
698708 }
0 commit comments