@@ -355,6 +355,45 @@ describe('ObjectQL Engine', () => {
355355 expect ( mockDriver . find ) . toHaveBeenCalledTimes ( 1 ) ;
356356 } ) ;
357357
358+ it ( 'should drop formula fields from driver projection and evaluate them after fetch' , async ( ) => {
359+ // Regression: planFormulaProjection used to add ALL schema fields
360+ // (including the formula fields themselves) back to projected,
361+ // which caused the SQL driver to emit `SELECT response_rate ...`
362+ // and fail silently with [] (no such column).
363+ vi . mocked ( SchemaRegistry . getObject ) . mockReturnValue ( {
364+ name : 'campaign' ,
365+ fields : {
366+ id : { type : 'text' } ,
367+ name : { type : 'text' } ,
368+ budgeted_cost : { type : 'number' } ,
369+ actual_cost : { type : 'number' } ,
370+ response_rate : {
371+ type : 'formula' ,
372+ expression : { dialect : 'cel' , source : 'record.budgeted_cost - record.actual_cost' } ,
373+ } ,
374+ } ,
375+ } as any ) ;
376+
377+ vi . mocked ( mockDriver . find ) . mockResolvedValueOnce ( [
378+ { id : 'c1' , name : 'Campaign A' , budgeted_cost : 100 , actual_cost : 30 } ,
379+ ] ) ;
380+
381+ const result = await engine . find ( 'campaign' , {
382+ fields : [ 'id' , 'name' , 'response_rate' ] ,
383+ } as any ) ;
384+
385+ // Driver should NOT receive the formula field in its projection
386+ const driverCall = vi . mocked ( mockDriver . find ) . mock . calls [ 0 ] ?. [ 1 ] as any ;
387+ expect ( driverCall . fields ) . toContain ( 'id' ) ;
388+ expect ( driverCall . fields ) . toContain ( 'name' ) ;
389+ expect ( driverCall . fields ) . toContain ( 'budgeted_cost' ) ;
390+ expect ( driverCall . fields ) . toContain ( 'actual_cost' ) ;
391+ expect ( driverCall . fields ) . not . toContain ( 'response_rate' ) ;
392+
393+ // But the result still carries the computed formula value
394+ expect ( result [ 0 ] . response_rate ) . toBe ( 70 ) ;
395+ } ) ;
396+
358397 it ( 'should handle null values gracefully during expand' , async ( ) => {
359398 vi . mocked ( SchemaRegistry . getObject ) . mockImplementation ( ( name ) => {
360399 if ( name === 'task' ) return {
0 commit comments