Incompatibilities between Db2 for z/OS and IBM Db2 Analytics Accelerator

In the list of incompatibilities, you find explanations for execution errors or different query results that Db2 for z/OS and IBM Db2 Analytics Accelerator might return for the same query.

Data types

See how IBM Db2 Analytics Accelerator handles certain Db2 data types:

FLOAT
The FLOAT data type is an approximate data type. The result can be different due to platform differences (hexadecimal floating-point numbers (HFP) versus IEEE754 floating-point numbers) or other internal handling differences. This applies to expressions that return FLOAT data and to expressions that contain a FLOAT data-type argument.

Division and multiplication of decimal values

During the division or multiplication of decimal values, Db2 for z/OS might truncate operand values if at least one of the operands is defined with a precision greater than 15. If that happens, the result of the calculation will be imprecise or wrong. IBM Db2 Analytics Accelerator does not truncate operand values internally, so the results will be more precise.
Example: Consider the following query:
CREATE TABLE TEST_TABLE(
D_DECIMAL_4_2 DECIMAL(4,2),
D_DECIMAL_17_2 DECIMAL(17,2),
D_DECIMAL_30_6 DECIMAL(30,6)
);
INSERT INTO TEST_TABLE VALUES(3.5, 3.5, 0.5);
INSERT INTO TEST_TABLE VALUES(1.5, 1.5, 1.5);

SELECT D_DECIMAL_17_2/D_DECIMAL_30_6, D_DECIMAL_17_2*D_DECIMAL_30_6
FROM TEST_TABLE;

SELECT D_DECIMAL_4_2/D_DECIMAL_30_6, D_DECIMAL_4_2*D_DECIMAL_30_6
FROM TEST_TABLE;

Db2 for z/OS returns results as follows:

  • For the first calculation in the query:
    +----------+
    | ?  | 1.5 |
    | 1  | 1.5 |
    +----------+
    
  • For the second calculation in the query:
    +------------+
    | ?   | 1.75 |
    | 1.5 | 2.25 |
    +------------+

The question mark (?) means that an overflow has occurred (division by zero) because Db2 for z/OS has internally reduced the value 0.5 to 0.

IBM Db2 Analytics Accelerator would have returned the correct results, which are the same for both calculations in the query:
+------------+
| 7   | 1.75 |
| 1   | 2.25 |
+------------+

The truncation problem is discussed in subsections of the Arithmetic with two decimal operands topic of the SQL reference in the Db2 11 for z/OS Knowledge Center. A link to this topic is provided under Related information.

Encoding issues

Consider the following points when you have to deal with Unicode SQL statements, multibyte (mixed) data in connection with parameter markers, and multibyte or double-byte EBCDIC columns.

Unicode SQL statements

Generally, when a UNICODE-encoded SQL statement contains characters or strings (as a literal, host variable, or parameter marker) that refer to a single-byte-encoded EBCDIC column, then Db2 tries to convert these strings to EBCDIC. Sometimes, such a string cannot be converted properly because it contains invalid UNICODE characters or characters that do not exist in the target EBCDIC code page. In such cases, the results of the SQL operation and the SQLCODE returned by the accelerator might be different from those returned by Db2 for z/OS with regard to the following aspects:
  • Queries might return a different number of rows.
  • SQLCODE 0 might be returned instead of the SQL warning codes +331 or +335.
  • Different substitution characters might be put into returned or inserted strings.
  • Returned or inserted strings or substitution characters might be different if multiple encoding is enabled on the accelerator.

Mixed data and parameter markers

If a Db2 subsystem is set up to contain mixed data (mixed=yes), that is, if differently encoded data is allowed to coexist, and the coded character set identifier (CCSID) is not specified for parameter markers in a query, the query might return incorrect results.

The LIKE operator in connection with binary wildcard characters

Depending on the system executing a query (Db2 for z/OS or IBM Db2 Analytics Accelerator, the query might not return any results or wrong results if the LIKE operator is used in combination with a binary wildcard character (% or _). The reason for that is that both systems expect a different binary encoding of the wildcard characters.

Db2 for z/OS
Valid binary encodings of the wildcard characters are bx'6c' for the percent sign (%) and bx'6d' for the underscore character (_).
IBM Db2 Analytics Accelerator
Valid binary encodings of the wildcard characters are X'25' for the percent sign (%) and X'5F' for the underscore character (_).

This means, for example, that if a query uses bx'6c' to refer to the percent sign as a wildcard character, Db2 for z/OS will return the expected result, but IBM Db2 Analytics Accelerator will not.

On the contrary, if an expression like SELECT COL FROM TABLE WHERE COL LIKE BINARY('A%') is encountered, IBM Db2 Analytics Accelerator will give you the expected result, but Db2 for z/OS will not.

Exception handling

When an exception, such as a buffer overflow, a division by zero, or an out-of-range value occurs, Db2 returns the value NULL combined with a +802 warning, provided that the faulty expression is in the outermost SELECT statement and affects only one row. This is also called friendly arithmetic. IBM Db2 Analytics Accelerator will always issue an error in cases like these.

Maximum row length

The maximum row length for a table on an accelerator is 1048319 bytes. If the combined length of all column fields in a Db2 table exceeds this limit, you cannot define that table on the accelerator.

Predicate evaluation

Db2 tolerates SQL errors during predicate evaluation as long as the error has no impact on the result of the evaluation. IBM Db2 Analytics Accelerator, on the contrary, always returns an error. This rule applies to predicates consisting of multiple terms (an SQL error in a predicate consisting of only one term cannot be tolerated). An SQL error in a predicate does not influence the outcome of the predicate evaluation if it does not matter whether the error makes the predicate logically true or false. For example, if the predicate is a conjunction of terms as in P1 AND P2, and the evaluation of P1 results in an SQL error, then this error does not influence the outcome if P2 evaluates to false because both, true AND P2 and false AND P2, evaluate to false. Table 1 shows all relevant permutations for two-term predicates (E = error, T = true, F = false). Values in parentheses indicate that the P2 term is not evaluated if an evaluation of P1 already yields the result of the entire predicate evaluation.
Table 1. Relevant combinations of two-term predicates
P1 P2 P1 AND P2 P1 OR P2
E E E E
E T E T
E F F E
T E E (T)
F E (F) E

The reason for choosing this evaluation method is that Db2 sometimes changes the order of term evaluation internally. The change is not announced or reported, and therefore goes unnoticed. Depending on the order of term evaluation, Db2 returns an error in one case, but not the other.

The behavior is very similar for the CASE and DECODE functions. These are basically SQL implementations of IF ... THEN ... ELSE constructs and exist in Db2 and IBM Db2 Analytics Accelerator. Db2 will ignore a wrongly defined option as long as it can select a correct one that evaluates to true. IBM Db2 Analytics Accelerator, on the other hand, will first check all available options, and return an error if one of these is not correctly defined. In the latter case, it does not matter whether selecting one of the correctly defined options would have led to a correct result.

SQL issues

In a grouping select, the HAVING clause can only reference expressions that are single-valued within a group. That is, you can only reference group fields, aggregates, or single-valued expressions that are derived from group fields or aggregates (which must include constants).

Time and date values

Time and date constructs in the dashDB® database often differ from the constructs used by Db2 for z/OS, so that values and expressions must be converted. The conversion is often accompanied by limitations.

24:00:00 conversion

This product supports the Db2 for z/OS time representation 24.00.00 for midnight (end of day) in TIME and TIMESTAMP columns or SQL expressions. There is no need to set up a conversion.

However, although the time 24:00:00 is accepted as a valid time, it is never returned by the accelerator as the result of a time addition or subtraction. This holds true even if the time added or subtracted is 0 (seconds, minutes, or hours) or 24 hours: The result will always be 00:00:00. Db2 for z/OS will return 24:00:00 in these cases.

Suppose you have a table TEST with a timestamp column C1. You insert just the following value into the column: 9999-12-01-24.00.00.000000000000. Now you run the following query, which includes a simple calculation:
SELECT C1 - 1 MONTH,C1 FROM TEST

That is, you want to retrieve the values from C1, but one month is to be deducted from each value. Since there is just one value, you will see only one record in the query results. But note the difference depending on where the query was executed:

Db2 for z/OS
9999-11-01-24.00.00.000000000000
IBM Db2 Analytics Accelerator
9999-11-02-00.00.00.000000000000

As you can see, Db2 for z/OS gives you 24:00, end of day, on the 1st of November, but IBM Db2 Analytics Accelerator gives you 00:00, beginning of the next day (2nd of November). Both values mean exactly the same, but there is a difference in the representation.

Dates in TIMESTAMP expressions

If a date is supplied as the only argument to a TIMESTAMP expression, for example TIMESTAMP(DATE('2015-12-31')), Db2 for z/OS returns a timestamp with a time portion that shows no fractional seconds, whereas IBM Db2 Analytics Accelerator returns fractional seconds with a precision of six digits:
Db2 for z/OS 2015-12-31 00:00:00
IBM Db2 Analytics Accelerator 2015-12-31 00:00:00.000000

You can circumvent this problem by supplying the date as a string value, for example TIMESTAMP('2015-12-31') because this gives the same return value in both systems, that is:

2015-12-31 00:00:00.000000

Strings as time values and their conversion

For some scalar functions, such as TIME, Db2 accepts a time value, a timestamp, and also a string representation of times and timestamps. When Db2 evaluates the scalar function, it first checks whether a value can be interpreted as a time. If this fails, it tries to interpret the value as a timestamp. The corresponding accelerator functions do not accept string values. During query conversion, the content of a string is not evaluated. Instead, it is always cast to a time value. If the string represents a valid time format on the accelerator, IBM Db2 Analytics Accelerator processes the query. Otherwise, if the string represents a timestamp, it returns an error. A workaround is to cast the string explicitly to a timestamp in the query.

Affected functions:
  • CAST (if the operation converts the string to a Db2 TIME value)
  • EXTRACT(HOUR FROM <arg>)
  • EXTRACT(MINUTE FROM <arg>)
  • HOUR
  • MIDNIGHT_SECONDS
  • MINUTE
  • SECOND
  • TIME

Trailing blanks

Trailing blanks cause incorrect results under the following conditions:

  • The result data type of an SQL expression is VARCHAR or VARGRAPHIC (as with LEFT, LTRIM, REPLACE, RIGHT, or TRIM for example).
  • The original values returned as VARCHAR or VARGRAPHIC contain trailing blanks.
  • A GROUP BY clause is used to sort the results on the VARCHAR or VARGRAPHIC column.
    Important: If you use the UNION keyword to merge the results of distinct SELECT statements, then this operation is internally realized by using GROUP BY clauses. That is, you might see incorrect results even though your query does not contain a GROUP BY clause.

Queries of this type return incorrect results because the accelerator uses column-organized tables for performance reasons. The columnar engine used for these tables removes trailing blanks from VARCHAR or VARGRAPHIC values that are sorted by a GROUP BY clause. If the original values are of varying length and contain trailing blanks, the blanks are removed when the rewritten query is executed. Hence the grouped values in the column-organized table do not contain trailing blanks, and the length calculation will inevitably lead to deviating results.

GROUP BY example

SELECT <varchar_col> || 'a' FROM <table> GROUP BY <varchar_field>

In the first part of the query, the letter a is added to each value of a VARCHAR column at the end. The result data type is also VARCHAR. If the original values contain trailing blanks, and the first part of the query is run on its own, you see the following, different outputs depending on where the query is run:

Db2 for z/OS:
<varchar_value> a

That is, the trailing blanks are preserved for each value in the column.

IBM Db2 Analytics Accelerator:
<varchar_value>a

The trailing blanks are removed by the accelerator.

The second part of the query adds a GROUP BY clause to the first part. The outputs of the entire query differ as follows:

Db2 for z/OS:
  • <varchar_value> a
  • <varchar_value>a

Db2 for z/OS returns both possibilities for each grouped value.

IBM Db2 Analytics Accelerator:
<varchar_value>a

IBM Db2 Analytics Accelerator returns just the values without the trailing blanks.

UNION example

((SELECT "ACC001"."COL1","ACC001"."COL2","ACC001"."COL3"  
  FROM "DWAXXYYZ"."TB12345-0136008" ACC001  
   WHERE "ACC001"."COL1"<2)
UNION
(SELECT "ACC002"."COL1","ACC002"."COL2","ACC002"."COL3"  
 FROM "DWAXXYYZZ"."TB12345-0136008" ACC002  
  WHERE "ACC002"."COL1"<2)) WITH UR

In this example, the UNION keyword is used to merge the results of two SELECT queries, each of these against a copy of the same table. The copies exist on different accelerators. One of these accelerators is an IBM Db2 Analytics Accelerator for z/OS Version 5.1.x accelerator, the other a version 7.1.x accelerator.

The version 5.1.x accelerator returns column values with the same number of trailing blanks as Db2 for z/OS. However, the version 7.1.0 accelerator returns column values with fewer or no trailing blanks.

Remember: In general, queries are internally rewritten, so that they might contain a GROUP BY clause even though no such clause was given in the original query. In this case, the number of trailing blanks extracted from VARCHAR or VARGRAPHIC columns can be different depending on where the query is run.