[Solar-svn] Revision 2944

pmjones at solarphp.com pmjones at solarphp.com
Wed Nov 14 16:26:35 CST 2007


Solar_Sql_Model_Related, _Related_HasMany: fix to has-many eager fetching

* [CHG] Method newSelect() now accepts a Solar_Sql_Select object for finding the native set of IDs to fetch related records for.  When a Select is passed, _modSelect() now clears all its columsn and selects on the $native_col column for the JOIN.




Modified: trunk/Solar/Sql/Model/Related/HasMany.php
===================================================================
--- trunk/Solar/Sql/Model/Related/HasMany.php	2007-11-14 22:15:06 UTC (rev 2943)
+++ trunk/Solar/Sql/Model/Related/HasMany.php	2007-11-14 22:26:35 UTC (rev 2944)
@@ -206,10 +206,18 @@
                 $spec->{$this->native_col} // this is where we set the filtering clause
             );
         } else {
-            // $spec is a Select object. restrict to a sub-query of IDs
-            // from the native table as an inner join.
-            $inner = str_replace("\n", "\n\t", $spec->fetchSql());
+            // $spec is a Select object. restrict to a sub-select of IDs from
+            // the native table.
+            $clone = clone $spec;
             
+            // sub-select **only** the native column, so that we're not
+            // pulling back everything, just the part we need to join on.
+            // this also helps SQLite, which is picky about fully-qualified
+            // names in sub-selects.
+            $clone->clear('cols');
+            $clone->cols($this->native_col);
+            $inner = str_replace("\n", "\n\t\t", $clone->fetchSql());
+            
             // add the native table ID at the top through a join
             $select->innerJoin(
                 "($inner) AS {$this->native_alias}",

Modified: trunk/Solar/Sql/Model/Related.php
===================================================================
--- trunk/Solar/Sql/Model/Related.php	2007-11-14 22:15:06 UTC (rev 2943)
+++ trunk/Solar/Sql/Model/Related.php	2007-11-14 22:26:35 UTC (rev 2944)
@@ -386,15 +386,22 @@
      * @param mixed $spec If an array, treated as params for a select 
      * statement (where, group, having, etc) for finding the native-model IDs.
      * If a Record object, the record's primary-key is used for the native-
-     * model ID.
+     * model ID.  If a Solar_Sql_Select, used as-is for finding the native-
+     * model IDs.
      * 
      * @return Solar_Sql_Select
      * 
+     * @todo Can we get away without using a params array at all, and use only
+     * Select or Record for the $spec?
+     * 
      */
     public function newSelect($spec)
     {
-        // specification must be a record, or params for a select
-        if (! ($spec instanceof Solar_Sql_Model_Record) && ! is_array($spec)) {
+        // specification must be a record, or params for a select, or a select
+        if (! ($spec instanceof Solar_Sql_Model_Record)
+            && ! is_array($spec)
+            && ! ($spec instanceof Solar_Sql_Select)) {
+            // problem
             throw $this->_exception('ERR_RELATED_SPEC', array(
                 'spec' => $spec
             ));
@@ -461,9 +468,18 @@
                 $spec->{$this->native_col}
             );
         } else {
-            // $spec is a Select object
-            // restrict to a sub-select of IDs from the native table
-            $inner = str_replace("\n", "\n\t\t", $spec->fetchSql());
+            // $spec is a Select object. restrict to a sub-select of IDs from
+            // the native table.
+            $clone = clone $spec;
+            
+            // sub-select **only** the native column, so that we're not
+            // pulling back everything, just the part we need to join on.
+            // this also helps SQLite, which is picky about fully-qualified
+            // names in sub-selects.
+            $clone->clear('cols');
+            $clone->cols($this->native_col);
+            $inner = str_replace("\n", "\n\t\t", $clone->fetchSql());
+            
             // add the native table ID at the top through a join
             $select->innerJoin(
                 "($inner) AS {$this->native_alias}",




More information about the Solar-svn mailing list