Closed mcd-php closed 10 years ago
What's your use case for it?
as far as I see you can fix this in the QueryBuilder by implementing IN condition in a different way.
WHERE (col1,col2) IN ((v11,v12),(v21,v22))
breaks Apache Cassandra, replaced by WHERE col1 IN (v11,v21) AND col2 IN (v12,v22)
and hope what \yii\db\ActiveRelationTrait::buildBuckets
will sort out possible relation algebra breakage and resulting extra rows.
your two conditions are not equal so the transformation is not correct.
as already said, you can implement the QueryBuilder::buildCompositeInCondition to create a condition that works for cassandra.
Should be something like (col1 = v11 AND col2 = v21) OR (col1 = v12 AND col2 = v22)
.
You do not need to touch query internals for this.
Thank you ! Just implemented - Cassandra rejects it.
Questions:
\yii\db\ActiveRelationTrait::buildBuckets
fix my relationally broken replacement, at least in "narrow down" scenario, like country and region, not fruit kind and color ?Now I patched it again and wrote trait that asks more data than needed, just by primary keys, in hope what buckets will filter off the extra. In future, i maybe will filter off the extra in all()
and one()
, applying non-PK 'where' by something like array LINQ.
Question: how would you work around crippled IN()
without raising visibility, by asking for more than needed and then filtering off the result set, both in relations and in direct query ?
namespace app\components\cassandra;
use \Yii;
trait ActiveRelationPartialLinkTrait {
protected function filterByModels($models) {
$linkSaved = $this->link;
$modelClassName = $this->modelClass;
$primaryKeyNames = \Yii::$app->db
->getSchema()
->getTableSchema($modelClassName::tableName())
->primaryKey;
$this->link = array_intersect_key(
$this->link,
array_fill_keys($primaryKeyNames,1)
);
parent::filterByModels($models);
$this->link = $linkSaved;
}
}
namespace app\components\cassandra;
class ActiveQuery extends \yii\db\ActiveQuery {
use AllowFilteringTrait; // Just ignore it for this case
use ActiveRelationPartialLinkTrait;
}
Need to override, had to patch to
protected
for non-relational DB with limited IN() capability.Is where any solid reason behind making so many methods private and so non-overridable ? Maybe, need more relaxed visibility policy ?