@@ -1607,16 +1607,48 @@ export class ObjectQL implements IDataEngine {
16071607 }
16081608
16091609 async execute ( command : any , options ?: Record < string , any > ) : Promise < any > {
1610- // Direct pass-through implies we know which driver to use?
1611- // Usually execute is tied to a specific object context OR we need a way to select driver.
1612- // If command has 'object', we use that.
1610+ // Driver selection priority:
1611+ // 1. options.object → route via getDriver(objectName)
1612+ // 2. options.datasource → explicit driver name
1613+ // 3. default driver (set via datasourceMapping or defaultDriver)
1614+ // This lets system services (e.g. PackageService, AuditService) issue raw
1615+ // SQL against the control-plane / default DB without having to know the
1616+ // object name behind every CREATE TABLE / SELECT statement.
1617+ let driver : DriverInterface | undefined ;
16131618 if ( options ?. object ) {
1614- const driver = this . getDriver ( options . object ) ;
1615- if ( driver . execute ) {
1616- return driver . execute ( command , undefined , options ) ;
1619+ driver = this . getDriver ( options . object ) ;
1620+ } else if ( options ?. datasource && this . drivers . has ( options . datasource ) ) {
1621+ driver = this . drivers . get ( options . datasource ) ;
1622+ } else if ( this . defaultDriver && this . drivers . has ( this . defaultDriver ) ) {
1623+ driver = this . drivers . get ( this . defaultDriver ) ;
1624+ } else if ( this . drivers . size === 1 ) {
1625+ // Single registered driver — unambiguously the right one.
1626+ driver = this . drivers . values ( ) . next ( ) . value ;
1627+ }
1628+
1629+ if ( ! driver ) {
1630+ throw new Error (
1631+ 'Execute requires options.object to select a driver, or a default driver to be configured. ' +
1632+ 'Configure datasourceMapping with `default: true` or pass `{ object }` / `{ datasource }` in options.' ,
1633+ ) ;
1634+ }
1635+ if ( ! driver . execute ) {
1636+ throw new Error ( 'Selected driver does not implement execute()' ) ;
1637+ }
1638+
1639+ // Support both call shapes:
1640+ // execute('SELECT ...', { args: [...] })
1641+ // execute({ sql: 'SELECT ...', args: [...] })
1642+ let rawCommand : any = command ;
1643+ let params : any [ ] | undefined = options ?. args ?? options ?. params ;
1644+ if ( command && typeof command === 'object' && ! Array . isArray ( command ) && 'sql' in command ) {
1645+ rawCommand = command . sql ;
1646+ if ( params === undefined ) {
1647+ params = command . args ?? command . params ;
16171648 }
16181649 }
1619- throw new Error ( 'Execute requires options.object to select driver' ) ;
1650+
1651+ return driver . execute ( rawCommand , params , options ) ;
16201652 }
16211653
16221654 // ============================================
0 commit comments