Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 5.5(EOL), 10.0(EOL), 10.1(EOL), 10.2(EOL), 10.3(EOL), 10.4(EOL)
    • 10.4(EOL)
    • None

    Description

      In MariaDB the pipes operator || stands for boolean OR by default. For compatibility purposes || can change its meaning to concatenation when PIPES_AS_CONCAT is enabled, either as a separate flag, or as a part of these sql_mode aliases:

      • ANSI
      • ORACLE
      • MSSQL
      • POSTGRESQL
      • DB2
      • MAXDB

      However, the precedence of the concatenation operator || is not compatible with the emulated databases.

      In MariaDB, concatenation has higher priority over + and * and bit shift

      SET sql_mode=PIPES_AS_CONCAT;
      SELECT -1+1||1;   -- -1+(1||1)
      

      10

      SET sql_mode=PIPES_AS_CONCAT;
      SELECT -1||0+1;   --  (-1||0)+1
      

      -9

      SET sql_mode=PIPES_AS_CONCAT;
      SELECT 1*1||-1;   --  1*(1||-1)
      

      1
      Truncated incorrect DOUBLE value: '1-1'

      SET sql_mode=PIPES_AS_CONCAT;
      SELECT 1||1*-1;   --  (1||1)*-1
      

      -11

      SELECT 1<<1||1;  --  1<<(1||1)
      

      2048

      SELECT 1||1<<-1;  -- (1||1)<<-1
      

      0

      In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

      PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

      In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

      SELECT -1+1||1;
      

      ERROR: operator does not exist: integer || integer

      SELECT -1||0+1;
      

      ERROR: operator does not exist: integer || integer

      SELECT 1*1||-1;
      

      ERROR: operator does not exist: integer || integer

      SELECT 1||1*-1;
      

      ERROR: operator does not exist: integer || integer

      Adding quotes reveals that concatenation has a priority lower than + and lower than *

      SELECT -1+1||'1';  --  (-1+1)||'1'
      

      01

      SELECT '-1'||0+1;  -- -1||(0+1)
      

      -11

      SELECT 1*1||'-1';  -- (1*1)||'-1'
      

      1-1

      SELECT '1'||1*-1;  -- '1'||(1*-1)
      

      1-1

      Further studies tell that concatenation has the same priority with bit shift:

      SELECT 1<<1||'1';  --  (1<<1)||'1'
      

      21

      SELECT '1'||1<<1;  -- ('1'||1)<<1
      

      ERROR: operator does not exist: text << integer

      PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP

      SET sql_mode=POSTGRESQL;
      SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
      

      +---------------------+
      | c1                  |
      +---------------------+
      | 2011-01-01 10:20:30 |
      +---------------------+
      1 row in set, 1 warning (0.00 sec)
      

      Looks wrong. The expected result is 2011-01-01 10:20:30x, i.e. it should do the following:

      • add 10 years to the given timestamp first
      • convert the result to string and append 'x' to the end

      PostgreSQL returns a correct result for the same query:

                c1          
      ----------------------
       2011-01-01 10:20:30x
      

      This query erroneously returns a syntax error in MariaDB:

      SET sql_mode=POSTGRESQL;
      SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR || 'x' AS c1;
      

      ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '|| 'x' AS c1' at line 1
      

      The expected result is to return string '2011-01-01 10:20:30x'.

      PostgreSQL returns a correct result for the same query:

                c1          
      ----------------------
       2011-01-01 10:20:30x
      

      In Oracle, concatenation has the same priority with + (and lower than *)

      This is reported as a separate issue MDEV-16186

      The SQL standard and DB2 require string arguments for concatenation

      For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

      MSSQL does not support pipes

      It's not clear why PIPES_AS_CONCAT is a part of MSSQL:

      SET sql_mode=MSSQL;
      SELECT @@sql_mode;
      

      +-------------------------------------------------------------------------------------------------+
      | @@sql_mode                                                                                      |
      +-------------------------------------------------------------------------------------------------+
      | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
      +-------------------------------------------------------------------------------------------------+
      

      In SQL Server, concatenation is performed by the operator + when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.

      Attachments

        Issue Links

          Activity

            bar Alexander Barkov created issue -
            bar Alexander Barkov made changes -
            Field Original Value New Value
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            10

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            -9

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            1
            Truncated incorrect DOUBLE value: '1-1'


            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            -11



            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            SELECT -1+1||1;
            ERROR: operator does not exist: integer || integer

            SELECT -1||0+1;
            ERROR: operator does not exist: integer || integer

            SELECT 1*1||-1;
            ERROR: operator does not exist: integer || integer

            SELECT 1||1*-1;
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            SELECT -1+1||'1'; -- (-1+1)||'1'
            01

            SELECT '-1'||0+1; -- -1||(0+1)
            -11

            SELECT 1*1||'-1'; -- (1*1)||'-1'
            1-1

            SELECT '1'||1*-1; -- '1'||(1*-1)
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            21

            SELECT '1'||1<<1; -- ('1'||1)<<1
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            01

            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            -9

            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            1-1

            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            1-1

            h2. The SQL standard (sql_mode=ANSI) and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when ANSI or DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL. In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            10

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            -9

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            1
            Truncated incorrect DOUBLE value: '1-1'


            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            -11



            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            SELECT -1+1||1;
            ERROR: operator does not exist: integer || integer

            SELECT -1||0+1;
            ERROR: operator does not exist: integer || integer

            SELECT 1*1||-1;
            ERROR: operator does not exist: integer || integer

            SELECT 1||1*-1;
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            SELECT -1+1||'1'; -- (-1+1)||'1'
            01

            SELECT '-1'||0+1; -- -1||(0+1)
            -11

            SELECT 1*1||'-1'; -- (1*1)||'-1'
            1-1

            SELECT '1'||1*-1; -- '1'||(1*-1)
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            21

            SELECT '1'||1<<1; -- ('1'||1)<<1
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            01

            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            -9

            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            1-1

            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL. In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings.
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            10

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            -9

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            1
            Truncated incorrect DOUBLE value: '1-1'


            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            -11



            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            SELECT -1+1||1;
            ERROR: operator does not exist: integer || integer

            SELECT -1||0+1;
            ERROR: operator does not exist: integer || integer

            SELECT 1*1||-1;
            ERROR: operator does not exist: integer || integer

            SELECT 1||1*-1;
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            SELECT -1+1||'1'; -- (-1+1)||'1'
            01

            SELECT '-1'||0+1; -- -1||(0+1)
            -11

            SELECT 1*1||'-1'; -- (1*1)||'-1'
            1-1

            SELECT '1'||1*-1; -- '1'||(1*-1)
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            21

            SELECT '1'||1<<1; -- ('1'||1)<<1
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            01

            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            -9

            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            1-1

            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL. In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            10

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            -9

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            1
            Truncated incorrect DOUBLE value: '1-1'


            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            -11



            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            SELECT -1+1||1;
            ERROR: operator does not exist: integer || integer

            SELECT -1||0+1;
            ERROR: operator does not exist: integer || integer

            SELECT 1*1||-1;
            ERROR: operator does not exist: integer || integer

            SELECT 1||1*-1;
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            SELECT -1+1||'1'; -- (-1+1)||'1'
            01

            SELECT '-1'||0+1; -- -1||(0+1)
            -11

            SELECT 1*1||'-1'; -- (1*1)||'-1'
            1-1

            SELECT '1'||1*-1; -- '1'||(1*-1)
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            21

            SELECT '1'||1<<1; -- ('1'||1)<<1
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            01

            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            -9

            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            1-1

            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            10

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            -9

            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            1
            Truncated incorrect DOUBLE value: '1-1'


            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            -11



            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            SELECT -1+1||1;
            ERROR: operator does not exist: integer || integer

            SELECT -1||0+1;
            ERROR: operator does not exist: integer || integer

            SELECT 1*1||-1;
            ERROR: operator does not exist: integer || integer

            SELECT 1||1*-1;
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            SELECT -1+1||'1'; -- (-1+1)||'1'
            01

            SELECT '-1'||0+1; -- -1||(0+1)
            -11

            SELECT 1*1||'-1'; -- (1*1)||'-1'
            1-1

            SELECT '1'||1*-1; -- '1'||(1*-1)
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            21

            SELECT '1'||1<<1; -- ('1'||1)<<1
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            01

            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            -9

            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            1-1

            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and *
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            This query erroneously returns a syntax error in MariaDB:

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR || 'x' AS c1;
            {code}
            {noformat}
            ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '|| 'x' AS c1' at line 1
            {noformat}

            The expected result is to return string {{'2011-01-01 10:20:30x'}}.

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            This query erroneously returns a syntax error in MariaDB:

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR || 'x' AS c1;
            {code}
            {noformat}
            ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '|| 'x' AS c1' at line 1
            {noformat}

            The expected result is to return string {{'2011-01-01 10:20:30x'}}.

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=POSTGRESQL;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            This query erroneously returns a syntax error in MariaDB:

            {code:sql}
            SET sql_mode=POSTGRESQL;
            SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR || 'x' AS c1;
            {code}
            {noformat}
            ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '|| 'x' AS c1' at line 1
            {noformat}

            The expected result is to return string {{'2011-01-01 10:20:30x'}}.

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            Labels Compatibility
            bar Alexander Barkov made changes -
            bar Alexander Barkov made changes -
            Description In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=POSTGRESQL;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            This query erroneously returns a syntax error in MariaDB:

            {code:sql}
            SET sql_mode=POSTGRESQL;
            SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR || 'x' AS c1;
            {code}
            {noformat}
            ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '|| 'x' AS c1' at line 1
            {noformat}

            The expected result is to return string {{'2011-01-01 10:20:30x'}}.

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)

            It's written in the documentation. These test queries prove.

            {code:sql}
            SELECT -1+1||1 FROM DUAL /* (-1+1)||'1' */;
            {code}
            01

            {code:sql}
            SELECT -1||0+1 FROM DUAL /* (-1||0)+1 */;
            {code}
            -9

            {code:sql}
            SELECT 1*1||-1 FROM DUAL /* (1*1)||-1 */;
            {code}
            1-1

            {code:sql}
            SELECT 1||1*-1 FROM DUAL /* 1||(1*-1) */;
            {code}
            1-1

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            In MariaDB the pipes operator {{||}} stands for boolean {{OR}} by default. For compatibility purposes {{||}} can change its meaning to concatenation when {{PIPES_AS_CONCAT}} is enabled, either as a separate flag, or as a part of these sql_mode aliases:
            - ANSI
            - ORACLE
            - MSSQL
            - POSTGRESQL
            - DB2
            - MAXDB

            However, the precedence of the concatenation operator {{||}} is not compatible with the emulated databases.


            h2. In MariaDB, concatenation has higher priority over + and * and bit shift
            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1+1||1; -- -1+(1||1)
            {code}
            10

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT -1||0+1; -- (-1||0)+1
            {code}
            -9

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1*1||-1; -- 1*(1||-1)
            {code}
            1
            Truncated incorrect DOUBLE value: '1-1'

            {code:sql}
            SET sql_mode=PIPES_AS_CONCAT;
            SELECT 1||1*-1; -- (1||1)*-1
            {code}
            -11

            {code:sql}
            SELECT 1<<1||1; -- 1<<(1||1)
            {code}
            2048

            {code:sql}
            SELECT 1||1<<-1; -- (1||1)<<-1
            {code}
            0

            h2. In PostgreSQL concatenation has the same priority with bit shift (and lower priority than + and *)

            PostgreSQL does not seem to tell explicitly in the documentation what is the priority of the concatenation operator ||, but it seems to have a lower priority than + and *, and the same priority with bit shift <<.

            In PostgreSQL at least one of the concatenation operands must be of a string type, so these queries return an error:

            {code:sql}
            SELECT -1+1||1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT -1||0+1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1*1||-1;
            {code}
            ERROR: operator does not exist: integer || integer

            {code:sql}
            SELECT 1||1*-1;
            {code}
            ERROR: operator does not exist: integer || integer


            Adding quotes reveals that concatenation has a priority lower than + and lower than *

            {code:sql}
            SELECT -1+1||'1'; -- (-1+1)||'1'
            {code}
            01

            {code:sql}
            SELECT '-1'||0+1; -- -1||(0+1)
            {code}
            -11

            {code:sql}
            SELECT 1*1||'-1'; -- (1*1)||'-1'
            {code}
            1-1

            {code:sql}
            SELECT '1'||1*-1; -- '1'||(1*-1)
            {code}
            1-1


            Further studies tell that concatenation has the same priority with bit shift:
            {code:sql}
            SELECT 1<<1||'1'; -- (1<<1)||'1'
            {code}
            21

            {code:sql}
            SELECT '1'||1<<1; -- ('1'||1)<<1
            {code}
            ERROR: operator does not exist: text << integer

            h2. PostgreSQL: mixing concatenation and INTERVAL+TIMESTAMP
            {code:sql}
            SET sql_mode=POSTGRESQL;
            SELECT INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' || 'x' AS c1;
            {code}
            {noformat}
            +---------------------+
            | c1 |
            +---------------------+
            | 2011-01-01 10:20:30 |
            +---------------------+
            1 row in set, 1 warning (0.00 sec)
            {noformat}
            Looks wrong. The expected result is {{2011-01-01 10:20:30x}}, i.e. it should do the following:
            - add 10 years to the given timestamp first
            - convert the result to string and append 'x' to the end

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            This query erroneously returns a syntax error in MariaDB:

            {code:sql}
            SET sql_mode=POSTGRESQL;
            SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR || 'x' AS c1;
            {code}
            {noformat}
            ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '|| 'x' AS c1' at line 1
            {noformat}

            The expected result is to return string {{'2011-01-01 10:20:30x'}}.

            PostgreSQL returns a correct result for the same query:
            {noformat}
                      c1
            ----------------------
             2011-01-01 10:20:30x
            {noformat}


            h2. In Oracle, concatenation has the same priority with + (and lower than *)
            This is reported as a separate issue MDEV-16186

            h2. The SQL standard and DB2 require string arguments for concatenation
            For strict compatibility, MariaDB should return an error on attempt to use concatenation over non-string data types when sql_mode=ANSI or sql_mode=DB2 is enabled.

            h2. MSSQL does not support pipes
            It's not clear why PIPES_AS_CONCAT is a part of MSSQL:
            {code:sql}
            SET sql_mode=MSSQL;
            SELECT @@sql_mode;
            {code}
            {noformat}
            +-------------------------------------------------------------------------------------------------+
            | @@sql_mode |
            +-------------------------------------------------------------------------------------------------+
            | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS |
            +-------------------------------------------------------------------------------------------------+
            {noformat}
            In SQL Server, concatenation is performed by the operator {{+}} when arguments are strings. So perhaps PIPES_AS_CONCAT should be removed from MSSQL.
            bar Alexander Barkov made changes -
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 87188 ] MariaDB v4 [ 140772 ]

            People

              bar Alexander Barkov
              bar Alexander Barkov
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.