yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.23k stars 6.91k forks source link

yii\db\conditions\SimpleCondition cause error on my working query #17343

Closed hyquoccuong closed 5 years ago

hyquoccuong commented 5 years ago

What steps will reproduce the problem?

New class in version 2.0.14 cause error on old working query https://www.yiiframework.com/doc/api/2.0/yii-db-conditions-simplecondition

This is my code snippet:

        $condition = ['is_active' => FConstant::STATE_ACTIVE];
        $android_condition = array_merge($condition, [['OR', ['type' => 1], ['type' => 'android']]]);
        $all_android_devices = AppDeviceAPI::find()->select('token')->where($android_condition)->all();

What is the expected result?

Hope this will be fixed on following versions after I update my Yii

What do you get instead?

{
name: "Exception",
message: "Operator '1' requires two operands.",
code: 0,
type: "yii\base\InvalidArgumentException",
file: "C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\conditions\SimpleCondition.php",
line: 79,
stack-trace: [
"#0 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\QueryBuilder.php(1534): yii\db\conditions\SimpleCondition::fromArrayDefinition('1', Array)",
"#1 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\QueryBuilder.php(1504): yii\db\QueryBuilder->createConditionFromArray(Array)",
"#2 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\QueryBuilder.php(1317): yii\db\QueryBuilder->buildCondition(Array, Array)",
"#3 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\QueryBuilder.php(216): yii\db\QueryBuilder->buildWhere(Array, Array)",
"#4 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\ActiveQuery.php(316): yii\db\QueryBuilder->build(Object(yii\db\Query))",
"#5 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\Query.php(237): yii\db\ActiveQuery->createCommand(Object(yii\db\Connection))",
"#6 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\db\ActiveQuery.php(133): yii\db\Query->all(NULL)",
"#7 C:\xampp\htdocs\framework\backend\modules\app\actions\PushNotificationAction.php(31): yii\db\ActiveQuery->all()",
"#8 [internal function]: backend\modules\app\actions\PushNotificationAction->run()",
"#9 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\base\Action.php(94): call_user_func_array(Array, Array)",
"#10 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\base\Controller.php(157): yii\base\Action->runWithParams(Array)",
"#11 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('push-notificati...', Array)",
"#12 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\web\Application.php(103): yii\base\Module->runAction('app/api/push-no...', Array)",
"#13 C:\xampp\htdocs\framework\vendor\yiisoft\yii2\base\Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))",
"#14 C:\xampp\htdocs\framework\backend\web\index.php(20): yii\base\Application->run()",
"#15 {main}",
],
}

Additional info

Q A
Yii version 2.0.14
PHP version 7.1
Operating system Windows 10 Pro
vuongxuongminh commented 5 years ago

You are using wrong syntax, try this:

        $condition = ['is_active' => FConstant::STATE_ACTIVE];
        $android_condition = ['AND', $condition, ['OR', ['type' => 1], ['type' => 'android']];
        $all_android_devices = AppDeviceAPI::find()->select('token')->where($android_condition)->all();
hyquoccuong commented 5 years ago

Yeah your syntax is full version query but yii also known the array of child condition is a big AND condition and I think many people use my syntax so the this change maybe affect to curent working code.

samdark commented 5 years ago

@hyquoccuong result of your array_merge would be:

[
    'is_active' => FConstant::STATE_ACTIVE,
    ['OR', ['type' => 1], ['type' => 'android']]
];

It is a mix of hash condition and operator condition. Such format was never officially documented or supported. See https://www.yiiframework.com/doc/api/2.0/yii-db-queryinterface#where()-detail