pingcap / tidb

TiDB is an open-source, cloud-native, distributed, MySQL-Compatible database for elastic scale and real-time analytics. Try AI-powered Chat2Query free at : https://www.pingcap.com/tidb-serverless/
https://pingcap.com
Apache License 2.0
36.61k stars 5.76k forks source link

Unexpected short circuit expression evaluation #31444

Open where2me opened 2 years ago

where2me commented 2 years ago

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 NUMERIC); INSERT INTO t0 VALUES(1); UPDATE t0 SET c0 = 2 WHERE TRUE OR 'a';

2. What did you expect to see? (Required)

The update statement should succeed to update, as the where clause is a short circuit expression evaluated to true.

3. What did you see instead (Required)

mysql> UPDATE t0 SET c0 = 2 WHERE TRUE OR 'a'; ERROR 1292 (22007): Truncated incorrect INTEGER value: 'a'

4. What is your TiDB version? (Required)

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tidb_version()

                               |

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Release Version: v5.3.0 Edition: Community Git Commit Hash: 4a1b2e9fe5b5afb1068c56de47adb07098d768d6 Git Branch: heads/refs/tags/v5.3.0 UTC Build Time: 2021-11-24 13:32:39 GoVersion: go1.16.4 Race Enabled: false TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306 Check Table Before Drop: false | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)

ywqzzy commented 2 years ago

This bug occurs in TiKV compute, since the logical_or function doesn't support the short circuit computation. Here is the evaluation in tidb:

func (b *builtinLogicOrSig) evalInt(row chunk.Row) (int64, bool, error) {
    arg0, isNull0, err := b.args[0].EvalInt(b.ctx, row)
    if err != nil {
        return 0, true, err
    }
    if !isNull0 && arg0 != 0 {
        return 1, false, nil
    }
    arg1, isNull1, err := b.args[1].EvalInt(b.ctx, row)
    if err != nil {
        return 0, true, err
    }
    if !isNull1 && arg1 != 0 {
        return 1, false, nil
    }
    if isNull0 || isNull1 {
        return 0, true, nil
    }
    return 0, false, nil
}

We don't need to calculate the left-hand-side and right-hand-side simultaneously.

Same bug detected in https://github.com/pingcap/tidb/issues/32671.

zanmato1984 commented 2 years ago

Adjusting severity to moderate.