@@ -575,20 +575,34 @@ export class ExpressionTransformer<Schema extends SchemaDef> {
575575 }
576576
577577 const fromModel = context . model ;
578+ const relationFieldDef = QueryUtils . requireField ( this . schema , fromModel , field ) ;
578579 const { keyPairs, ownedByModel } = QueryUtils . getRelationForeignKeyFieldPairs ( this . schema , fromModel , field ) ;
579580
580581 let condition : OperationNode ;
581582 if ( ownedByModel ) {
582583 // `fromModel` owns the fk
584+
583585 condition = conjunction (
584586 this . dialect ,
585- keyPairs . map ( ( { fk, pk } ) =>
586- BinaryOperationNode . create (
587- ReferenceNode . create ( ColumnNode . create ( fk ) , TableNode . create ( context . alias ?? fromModel ) ) ,
587+ keyPairs . map ( ( { fk, pk } ) => {
588+ let fkRef : OperationNode = ReferenceNode . create (
589+ ColumnNode . create ( fk ) ,
590+ TableNode . create ( context . alias ?? fromModel ) ,
591+ ) ;
592+ if ( relationFieldDef . originModel && relationFieldDef . originModel !== fromModel ) {
593+ fkRef = this . buildDelegateBaseFieldSelect (
594+ fromModel ,
595+ context . alias ?? fromModel ,
596+ fk ,
597+ relationFieldDef . originModel ,
598+ ) ;
599+ }
600+ return BinaryOperationNode . create (
601+ fkRef ,
588602 OperatorNode . create ( '=' ) ,
589603 ReferenceNode . create ( ColumnNode . create ( pk ) , TableNode . create ( relationModel ) ) ,
590- ) ,
591- ) ,
604+ ) ;
605+ } ) ,
592606 ) ;
593607 } else {
594608 // `relationModel` owns the fk
@@ -633,8 +647,47 @@ export class ExpressionTransformer<Schema extends SchemaDef> {
633647 return relationQuery . toOperationNode ( ) ;
634648 }
635649
636- private createColumnRef ( column : string , context : ExpressionTransformerContext < Schema > ) : ReferenceNode {
637- return ReferenceNode . create ( ColumnNode . create ( column ) , TableNode . create ( context . alias ?? context . model ) ) ;
650+ private createColumnRef ( column : string , context : ExpressionTransformerContext < Schema > ) {
651+ // if field comes from a delegate base model, we need to use the join alias
652+ // of that base model
653+
654+ const tableName = context . alias ?? context . model ;
655+
656+ // "create" policies evaluate table from "VALUES" node so no join from delegate bases are
657+ // created and thus we should directly use the model table name
658+ if ( context . operation === 'create' ) {
659+ return ReferenceNode . create ( ColumnNode . create ( column ) , TableNode . create ( tableName ) ) ;
660+ }
661+
662+ const fieldDef = QueryUtils . requireField ( this . schema , context . model , column ) ;
663+ if ( ! fieldDef . originModel || fieldDef . originModel === context . model ) {
664+ return ReferenceNode . create ( ColumnNode . create ( column ) , TableNode . create ( tableName ) ) ;
665+ }
666+
667+ return this . buildDelegateBaseFieldSelect ( context . model , tableName , column , fieldDef . originModel ) ;
668+ }
669+
670+ private buildDelegateBaseFieldSelect ( model : string , modelAlias : string , field : string , baseModel : string ) {
671+ const idFields = QueryUtils . requireIdFields ( this . client . $schema , model ) ;
672+ return {
673+ kind : 'SelectQueryNode' ,
674+ from : FromNode . create ( [ TableNode . create ( baseModel ) ] ) ,
675+ selections : [
676+ SelectionNode . create ( ReferenceNode . create ( ColumnNode . create ( field ) , TableNode . create ( baseModel ) ) ) ,
677+ ] ,
678+ where : WhereNode . create (
679+ conjunction (
680+ this . dialect ,
681+ idFields . map ( ( idField ) =>
682+ BinaryOperationNode . create (
683+ ReferenceNode . create ( ColumnNode . create ( idField ) , TableNode . create ( baseModel ) ) ,
684+ OperatorNode . create ( '=' ) ,
685+ ReferenceNode . create ( ColumnNode . create ( idField ) , TableNode . create ( modelAlias ) ) ,
686+ ) ,
687+ ) ,
688+ ) ,
689+ ) ,
690+ } satisfies SelectQueryNode ;
638691 }
639692
640693 private isAuthCall ( value : unknown ) : value is CallExpression {
0 commit comments