kak-clickhouse
kak-clickhouse copied to clipboard
Strict field types
Реализую выдачу из ClickHouse в GridView с фильтрацией. Соответственно, использую SearchModel, расширяющую модель соответствующей таблицы.
В этой SearchModel есть следующий абстрактный код:
$query = Stat::find()->where(['user_string_id' => Yii::$app->user->identity->user_custom_id), 'user_int_id' => Yii::$app->user->identity->user_id,]);
Если в таком случае user_custom_id будет строкой, идентичной числу, в модель будет передано число и в запросе значение экранироваться не будет, не смотря на указание для этого поля в rules (['user_string_id','string']
), что вызовет ошибку движка ClickHouse
DB::Exception: Illegal types of arguments (String, UInt8) of function equals.
Если возможно, приведение к типам, указанным в rules, было бы весьма полезным.
Привет Правила в модели используются только при записях, так-как родной AR не заботится о конвертации все делает PDO
Для поиска вам нужно самим соблюдать тип. (Возможно можно будет сделать проверку типа на основе схемы если используем ActiveQuery и если запрос без связей, над подумать, идея интересная и думаю реализуема)
Мы у себя решаем с поиском вопрос вот так: Для поиска создаем поисковую модель так проще создавать фильтры, под запросы пользователей (а хотелок бывает много)
Поля которые мы ищем мы задаем вот так:
$query = $stat = Stat::find();
$filterArray = [
'название колонки' => $this->user_id
];
$query = $this->andFilterWhereCaseInt($query, $filterArray);
сам доп. метод
public function andFilterWhereCaseInt(Query $query, array $params): Query
{
foreach ($params as $key => $value) {
if (!empty($value) && !is_array($value)) {
$query->andFilterWhere([$key => (int) $value]);
} else if (is_array($value) && count($value)) {
$condition = 'IN';
$query->andFilterWhere([
$condition,
$key, array_map(function ($data) {
return (int)$data;
}, $value)
]);
}
}
}
return $query;
}
В моём случае изначально было достаточно обернуть передаваемое значение в strval(), что, конечно, просто костыль. В итоге в целом отказался от AQ, так как, насколько я понимаю, QueryBuilder не полностью поддерживает синтаксис запросов ClickHouse (в моём случае всё упёрлось в необходимость использования ANY LEFT JOIN () USING)
JOIN не подерживаются в AQ.