From 85efd7bb0aaa3b9fc22a47d58331c79ceaa649bc Mon Sep 17 00:00:00 2001 From: Konovalov Maxim Date: Wed, 12 Dec 2012 22:04:07 +1000 Subject: [PATCH] #1515 Use index support in relations --- CHANGELOG | 1 + framework/db/ar/CActiveFinder.php | 35 ++++++++++++++++++++++++------- framework/db/ar/CActiveRecord.php | 4 ++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a3fa9c304..ced04f588 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Version 1.1.13 work in progress ------------------------------- +- Enh #1515 Post-join operations (use|force|ignore index()) support in relational queries (KonovalovMaxim) - Bug #93: Criteria modification in CActiveRecord::beforeFind() did not apply when record was loaded in relational context. See UPGRADE instructions for details on behavior change. (cebe) - Bug #109: formatNumber() now uses number_format() instead of round(), because of round() error in IEEE754 accuracy limitations (SonkoDmitry) - Bug #110: MSSQL: fixed empty $primaryKey value after saving CActiveRecord model (resurtm) diff --git a/framework/db/ar/CActiveFinder.php b/framework/db/ar/CActiveFinder.php index b44152588..dcbbe138e 100644 --- a/framework/db/ar/CActiveFinder.php +++ b/framework/db/ar/CActiveFinder.php @@ -231,7 +231,11 @@ class CActiveFinder extends CComponent if(!empty($options['scopes'])) $scopes=array_merge($scopes,(array)$options['scopes']); // no need for complex merging - $model->resetScope(false); + if(!empty($options['joinOptions'])) + $relation->joinOptions = $options['joinOptions']; + + + $model->resetScope(false); $criteria=$model->getDbCriteria(); $criteria->scopes=$scopes; $model->beforeFindInternal(); @@ -1060,7 +1064,11 @@ class CJoinElement } if(!empty($this->relation->on)) $joins[]=$this->relation->on; - return $this->relation->joinType . ' ' . $this->getTableNameWithAlias() . ' ON (' . implode(') AND (',$joins).')'; + + if(!empty($this->relation->joinOptions) && is_string($this->relation->joinOptions)) + return $this->relation->joinType . ' ' . $this->getTableNameWithAlias() . ' ' . $this->relation->joinOptions . ' ON (' . implode(') AND (',$joins).')'; + else + return $this->relation->joinType . ' ' . $this->getTableNameWithAlias() . ' ON (' . implode(') AND (',$joins).')'; } /** @@ -1128,12 +1136,23 @@ class CJoinElement if($parentCondition!==array() && $childCondition!==array()) { $join=$this->relation->joinType.' '.$joinTable->rawName.' '.$joinAlias; - $join.=' ON ('.implode(') AND (',$parentCondition).')'; - $join.=' '.$this->relation->joinType.' '.$this->getTableNameWithAlias(); - $join.=' ON ('.implode(') AND (',$childCondition).')'; - if(!empty($this->relation->on)) - $join.=' AND ('.$this->relation->on.')'; - return $join; + + if(is_array($this->relation->joinOptions) && array_key_exists(0,$this->relation->joinOptions) && is_string($this->relation->joinOptions[0])) + $join .= ' ' . $this->relation->joinOptions[0]; + else + if(!empty($this->relation->joinOptions) && is_string($this->relation->joinOptions)) + $join .= ' ' . $this->relation->joinOptions; + + $join.=' ON ('.implode(') AND (',$parentCondition).')'; + $join.=' '.$this->relation->joinType.' '.$this->getTableNameWithAlias(); + + if(is_array($this->relation->joinOptions) && array_key_exists(1,$this->relation->joinOptions) && is_string($this->relation->joinOptions[1])) + $join .= ' ' . $this->relation->joinOptions[1]; + + $join.=' ON ('.implode(') AND (',$childCondition).')'; + if(!empty($this->relation->on)) + $join.=' AND ('.$this->relation->on.')'; + return $join; } else throw new CDbException(Yii::t('yii','The relation "{relation}" in active record class "{class}" is specified with an incomplete foreign key. The foreign key must consist of columns referencing both joining tables.', diff --git a/framework/db/ar/CActiveRecord.php b/framework/db/ar/CActiveRecord.php index cb419d1ec..51cd1c94f 100644 --- a/framework/db/ar/CActiveRecord.php +++ b/framework/db/ar/CActiveRecord.php @@ -1914,6 +1914,10 @@ class CBaseActiveRelation extends CComponent * @since 1.1.3 */ public $join=''; + /** + * @var string property for setting post-join operations such us USE INDEX + */ + public $joinOptions=''; /** * @var string HAVING clause. For {@link CActiveRelation} descendant classes, column names * referenced in this property should be disambiguated with prefix 'relationName.'.