@@ -54,10 +54,16 @@ export class QueryNameMapper extends OperationNodeTransformer {
5454 if ( ! node . from ?. froms ) {
5555 return super . transformSelectQuery ( node ) ;
5656 }
57+
58+ // all table names in "from" are pushed as scopes, each "from" is expanded
59+ // as nested query to apply column name mapping, so the scopes are marked
60+ // "namesMapped" so no additional name mapping is applied when resolving
61+ // columns
5762 const scopes = this . createScopesFromFroms ( node . from , true ) ;
5863 return this . withScopes ( scopes , ( ) => {
5964 return {
6065 ...super . transformSelectQuery ( node ) ,
66+ // convert "from" to nested query as needed
6167 from : this . processFrom ( node . from ! ) ,
6268 } ;
6369 } ) ;
@@ -69,10 +75,11 @@ export class QueryNameMapper extends OperationNodeTransformer {
6975 }
7076
7177 return this . withScope (
72- { model : node . into . table . identifier . name , alias : undefined } ,
78+ { model : node . into . table . identifier . name } ,
7379 ( ) =>
7480 ( {
7581 ...super . transformInsertQuery ( node ) ,
82+ // map table name
7683 into : this . processTableRef ( node . into ! ) ,
7784 } ) satisfies InsertQueryNode ,
7885 ) ;
@@ -81,6 +88,7 @@ export class QueryNameMapper extends OperationNodeTransformer {
8188 protected override transformReturning ( node : ReturningNode ) {
8289 return {
8390 kind : node . kind ,
91+ // map column names in returning selections (include returningAll)
8492 selections : this . processSelections ( node . selections ) ,
8593 } ;
8694 }
@@ -89,8 +97,11 @@ export class QueryNameMapper extends OperationNodeTransformer {
8997 const { alias, node : innerNode } = this . stripAlias ( node . table ) ;
9098 if ( TableNode . is ( innerNode ! ) ) {
9199 const modelName = innerNode . table . identifier . name ;
92- const select = this . createSelectAll ( modelName ) ;
93- return { ...super . transformJoin ( node ) , table : this . wrapAlias ( select , alias ?? modelName ) } ;
100+ if ( this . hasMappedColumns ( modelName ) ) {
101+ // create a nested query with all fields selected and names mapped
102+ const select = this . createSelectAll ( modelName ) ;
103+ return { ...super . transformJoin ( node ) , table : this . wrapAlias ( select , alias ?? modelName ) } ;
104+ }
94105 }
95106 return super . transformJoin ( node ) ;
96107 }
@@ -99,15 +110,30 @@ export class QueryNameMapper extends OperationNodeTransformer {
99110 if ( ! ColumnNode . is ( node . column ) ) {
100111 return super . transformReference ( node ) ;
101112 }
113+
114+ // resolve the reference to a field from outer scopes
102115 const { fieldDef, modelDef, scope } = this . resolveFieldFromScopes (
103116 node . column . column . name ,
104117 node . table ?. table . identifier . name ,
105118 ) ;
106119 if ( fieldDef && ! scope . namesMapped ) {
107- const mappedName = this . mapFieldName ( modelDef . name , fieldDef . name ) ;
120+ // map column name and table name as needed
121+ const mappedFieldName = this . mapFieldName ( modelDef . name , fieldDef . name ) ;
122+
123+ // map table name depending on how it is resolved
124+ let mappedTableName = node . table ?. table . identifier . name ;
125+ if ( mappedTableName ) {
126+ if ( scope . alias === mappedTableName ) {
127+ // table name is resolved to an alias, no mapping needed
128+ } else if ( scope . model === mappedTableName ) {
129+ // table name is resolved to a model, map the name as needed
130+ mappedTableName = this . mapTableName ( scope . model ) ;
131+ }
132+ }
133+
108134 return ReferenceNode . create (
109- ColumnNode . create ( mappedName ) ,
110- node . table ? this . processTableRef ( node . table ) : undefined ,
135+ ColumnNode . create ( mappedFieldName ) ,
136+ mappedTableName ? TableNode . create ( mappedTableName ) : undefined ,
111137 ) ;
112138 } else {
113139 return super . transformReference ( node ) ;
@@ -132,21 +158,27 @@ export class QueryNameMapper extends OperationNodeTransformer {
132158 return this . withScope ( { model : innerTable . table . identifier . name , alias } , ( ) => {
133159 return {
134160 ...super . transformUpdateQuery ( node ) ,
161+ // map table name
135162 table : this . wrapAlias ( this . processTableRef ( innerTable ) , alias ) ,
136163 } ;
137164 } ) ;
138165 }
139166
140167 protected override transformDeleteQuery ( node : DeleteQueryNode ) {
168+ // all "from" nodes are pushed as scopes
141169 const scopes = this . createScopesFromFroms ( node . from , false ) ;
170+
171+ // process name mapping in each "from"
142172 const froms = node . from . froms . map ( ( from ) => {
143173 const { alias, node : innerNode } = this . stripAlias ( from ) ;
144174 if ( TableNode . is ( innerNode ! ) ) {
175+ // map table name
145176 return this . wrapAlias ( this . processTableRef ( innerNode ) , alias ) ;
146177 } else {
147178 return super . transformNode ( from ) ;
148179 }
149180 } ) ;
181+
150182 return this . withScopes ( scopes , ( ) => {
151183 return {
152184 ...super . transformDeleteQuery ( node ) ,
@@ -285,7 +317,8 @@ export class QueryNameMapper extends OperationNodeTransformer {
285317 . filter ( ( s ) => ! ! s ) ;
286318 }
287319
288- private processFrom ( node : FromNode ) {
320+ // convert a "from" node to a nested query if there are columns with name mapping
321+ private processFrom ( node : FromNode ) : FromNode {
289322 return {
290323 ...super . transformFrom ( node ) ,
291324 froms : node . froms . map ( ( from ) => {
@@ -295,15 +328,20 @@ export class QueryNameMapper extends OperationNodeTransformer {
295328 }
296329 if ( TableNode . is ( innerNode ) ) {
297330 if ( this . hasMappedColumns ( innerNode . table . identifier . name ) ) {
331+ // create a nested query with all fields selected and names mapped
298332 const selectAll = this . createSelectAll ( innerNode . table . identifier . name ) ;
333+
334+ // use the original alias or table name as the alias for the nested query
335+ // so its transparent to the outer scope
299336 return this . ensureAlias ( selectAll , alias , innerNode . table . identifier . name ) ;
300337 }
301338 }
302339 return this . transformNode ( from ) ;
303340 } ) ,
304- } satisfies FromNode ;
341+ } ;
305342 }
306343
344+ // create a `SelectQueryNode` for the given model with all columns mapped
307345 private createSelectAll ( model : string ) : SelectQueryNode {
308346 const modelDef = requireModel ( this . schema , model ) ;
309347 const tableName = this . mapTableName ( model ) ;
@@ -331,10 +369,13 @@ export class QueryNameMapper extends OperationNodeTransformer {
331369 const result : SelectionNode [ ] = [ ] ;
332370 selections . forEach ( ( selection ) => {
333371 if ( SelectAllNode . is ( selection . selection ) ) {
372+ // expand "select *" to a list of selections if name mapping is needed
334373 const processed = this . processSelectAll ( selection . selection ) ;
335374 if ( Array . isArray ( processed ) ) {
375+ // expanded and names mapped
336376 result . push ( ...processed . map ( ( s ) => SelectionNode . create ( s ) ) ) ;
337377 } else {
378+ // not expanded
338379 result . push ( SelectionNode . create ( processed ) ) ;
339380 }
340381 } else {
@@ -356,10 +397,13 @@ export class QueryNameMapper extends OperationNodeTransformer {
356397 private processSelectAll ( node : SelectAllNode ) {
357398 const scope = this . modelScopes [ this . modelScopes . length - 1 ] ;
358399 invariant ( scope ) ;
400+
359401 if ( ! this . hasMappedColumns ( scope . model ) ) {
402+ // no name mapping needed, preserve the select all
360403 return super . transformSelectAll ( node ) ;
361404 }
362405
406+ // expand select all to a list of selections with name mapping
363407 const modelDef = requireModel ( this . schema , scope . model ) ;
364408 return this . getModelFields ( modelDef ) . map ( ( fieldDef ) => {
365409 const columnName = this . mapFieldName ( scope . model , fieldDef . name ) ;
0 commit comments