-
Catalin Besleaga authored
PROBLEM ======= Existing bit-wise operations: & | ^ ~ << >> BIT_COUNT BIT_AND BIT_XOR BIT_OR currently take BIGINT (64-bit integer) arguments and return BIGINT. So they are limited to 64 bits. Task is to extend them to also work on binary([VAR]BINARY/[TINY|MEDIUM|LONG]BLOB) arguments of any length for ( & | ^ ~ << >> BIT_COUNT) and limited to 511 bytes ([VAR]BINARY/TINYBLOB)for the aggregate functions BIT_AND BIT_XOR BIT_OR. Solution: ========= Implement binary operations for [VAR]BINARY(M)/[TINY|MEDIUM|LONG]BLOB(M). Depending on the types of input arguments of & | ^ ~ << >> BIT_AND BIT_XOR BIT_OR BIT_COUNT: - determine the return type (today it is INT_RESULT): a hybrid of INT_RESULT and STRING_RESULT (like '+' does); this doesn't apply to BIT_COUNT which result type will remain INT_RESULT. - call val_int() or val_str() on arguments - do calculations (for integer arguments, continue using the native C++ bit-wise operators; for binary, do that byte-by-byte). The operation's return type will be determined as follows. 1. arg1 [ & | ^] arg2 (bit-and, bit-or, bit-xor) ------------------------------------------------- Currently in 5.7: both arguments are converted to BIGINT and the result of the operation is returned as BIGINT. Solution: 1.1. when arg1 is [VAR]BINARY(m)/[TINY|MEDIUM|LONG]BLOB(m) and arg2 is [VAR]BINARY(n)/[TINY|MEDIUM|LONG]BLOB(n) and at least one of them is not a hex/bit/NULL literal 1.1.a. Determine the length of each argument: l1=LENGTH(arg 1), l2=LENGTH(arg 2). Note that l1 =< m, l2 =< n; if types are BINARY there is equality. 1.1.b If l1 <> l2, throw error (anything else would require padding to left or right, and we can't reliably decide between left and right) 1.1.c Execute the bitwise operation. Return type is VARBINARY(the length of the result is l1 i.e. l1=l2 per 1.1.b). 1.2. otherwise, convert both arguments to BIGINT, execute the operation and return BIGINT; this is the same behaviour as MySQL 5.7. 2. arg1 [ << >> ] arg2 (bit shifting) ; ~(arg1) (bit-not) ---------------------------------------------------------- Currently in 5.7: arg1 is converted to BIGINT and the result of the operation is returned as BIGINT. Solution: 2.1. when arg1 is [VAR]BINARY(m)/[TINY|MEDIUM|LONG]BLOB(m) and is not a hex/bit/NULL literal, execute the operation and return the result as [VAR]BINARY(m). For shift operators, bits may be lost without warning (as is usual for the BIGINT case: 1>>1 is 0). 2.2. otherwise convert to BIGINT execute operation and return BIGINT. This is the same behavior as MySQL 5.7. 3. BIT_COUNT ------------ always returns BIGINT(extended to work on binary data types) 4. BIT_AND, BIT_XOR, BIT_OR --------------------------- 4.1. when arg is [VAR]BINARY(m)/TINYBLOB(m) and is not a hex/bit/NULL literal 4.1.1. if arg's values have same length execute the operation and return the result as [VAR]BINARY(m) 4.1.2. if arg's values have different length throw error 4.2. when arg is [MEDIUM|LONG]BLOB(m) or [VAR]BINARY(n) with n exceeding 511 throw ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE error 4.3. when the arg is other types than those in 4.1 or 4.2 work as before => returns BIGINT *NULL values do not affect the result unless all the values are NULL, in which case the result will be the neutral element having the same length as the column definition length
Catalin Besleaga authoredPROBLEM ======= Existing bit-wise operations: & | ^ ~ << >> BIT_COUNT BIT_AND BIT_XOR BIT_OR currently take BIGINT (64-bit integer) arguments and return BIGINT. So they are limited to 64 bits. Task is to extend them to also work on binary([VAR]BINARY/[TINY|MEDIUM|LONG]BLOB) arguments of any length for ( & | ^ ~ << >> BIT_COUNT) and limited to 511 bytes ([VAR]BINARY/TINYBLOB)for the aggregate functions BIT_AND BIT_XOR BIT_OR. Solution: ========= Implement binary operations for [VAR]BINARY(M)/[TINY|MEDIUM|LONG]BLOB(M). Depending on the types of input arguments of & | ^ ~ << >> BIT_AND BIT_XOR BIT_OR BIT_COUNT: - determine the return type (today it is INT_RESULT): a hybrid of INT_RESULT and STRING_RESULT (like '+' does); this doesn't apply to BIT_COUNT which result type will remain INT_RESULT. - call val_int() or val_str() on arguments - do calculations (for integer arguments, continue using the native C++ bit-wise operators; for binary, do that byte-by-byte). The operation's return type will be determined as follows. 1. arg1 [ & | ^] arg2 (bit-and, bit-or, bit-xor) ------------------------------------------------- Currently in 5.7: both arguments are converted to BIGINT and the result of the operation is returned as BIGINT. Solution: 1.1. when arg1 is [VAR]BINARY(m)/[TINY|MEDIUM|LONG]BLOB(m) and arg2 is [VAR]BINARY(n)/[TINY|MEDIUM|LONG]BLOB(n) and at least one of them is not a hex/bit/NULL literal 1.1.a. Determine the length of each argument: l1=LENGTH(arg 1), l2=LENGTH(arg 2). Note that l1 =< m, l2 =< n; if types are BINARY there is equality. 1.1.b If l1 <> l2, throw error (anything else would require padding to left or right, and we can't reliably decide between left and right) 1.1.c Execute the bitwise operation. Return type is VARBINARY(the length of the result is l1 i.e. l1=l2 per 1.1.b). 1.2. otherwise, convert both arguments to BIGINT, execute the operation and return BIGINT; this is the same behaviour as MySQL 5.7. 2. arg1 [ << >> ] arg2 (bit shifting) ; ~(arg1) (bit-not) ---------------------------------------------------------- Currently in 5.7: arg1 is converted to BIGINT and the result of the operation is returned as BIGINT. Solution: 2.1. when arg1 is [VAR]BINARY(m)/[TINY|MEDIUM|LONG]BLOB(m) and is not a hex/bit/NULL literal, execute the operation and return the result as [VAR]BINARY(m). For shift operators, bits may be lost without warning (as is usual for the BIGINT case: 1>>1 is 0). 2.2. otherwise convert to BIGINT execute operation and return BIGINT. This is the same behavior as MySQL 5.7. 3. BIT_COUNT ------------ always returns BIGINT(extended to work on binary data types) 4. BIT_AND, BIT_XOR, BIT_OR --------------------------- 4.1. when arg is [VAR]BINARY(m)/TINYBLOB(m) and is not a hex/bit/NULL literal 4.1.1. if arg's values have same length execute the operation and return the result as [VAR]BINARY(m) 4.1.2. if arg's values have different length throw error 4.2. when arg is [MEDIUM|LONG]BLOB(m) or [VAR]BINARY(n) with n exceeding 511 throw ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE error 4.3. when the arg is other types than those in 4.1 or 4.2 work as before => returns BIGINT *NULL values do not affect the result unless all the values are NULL, in which case the result will be the neutral element having the same length as the column definition length
Loading