[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