Skip to content

Commit

Permalink
Add DB2 support for JPA31 ROUND (#1742)
Browse files Browse the repository at this point in the history
Add DB2 support for ROUND operator
and DB2 test profile

Signed-off-by: William Dazey <wadazey@us.ibm.com>
  • Loading branch information
dazey3 committed Nov 29, 2022
1 parent 54f8273 commit 2a0f3b2
Show file tree
Hide file tree
Showing 6 changed files with 1,317 additions and 21 deletions.
22 changes: 22 additions & 0 deletions etc/el-test.db2.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0,
# or the Eclipse Distribution License v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#

# DB Connection properties
db.driver=com.ibm.db2.jcc.DB2Driver
db.url=jdbc:db2://localhost:50000/TestDB
db.user=root
db.pwd=root
db.platform=org.eclipse.persistence.platform.database.DB2Platform
datasource.type=java.sql.Driver

# Logging option for debugging
logging.level=info
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,8 @@ protected void initializePlatformOperators() {
addOperator(lengthOperator());
addOperator(nullifOperator());
addOperator(coalesceOperator());

addOperator(roundOperator());
}

/**
Expand Down Expand Up @@ -1497,6 +1499,19 @@ public void printJavaCollection(List<Expression> items, ExpressionJavaPrinter pr
return operator;
}

/**
* DB2 requires that at least one argument be a known type
* <p>
* With binding enabled, DB2 will throw an error:
* <pre>Db2 cannot determine how to implicitly cast the arguments between string and
* numeric data types. DB2 SQL Error: SQLCODE=-245, SQLSTATE=428F5</pre>
*/
protected ExpressionOperator roundOperator() {
ExpressionOperator operator = disableAtLeast1BindingExpression();
ExpressionOperator.round().copyTo(operator);
return operator;
}

@Override
public boolean isDB2() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,21 @@ public void printJavaDuo(Expression first, Expression second, ExpressionJavaPrin
return operator;
}

/**
* Disable binding support.
* <p>
* With binding enabled, DB2 z/OS will throw an error:
* <pre>The data type, the length, or the value of an argument of a scalar function
* is incorrect. DB2 SQL Error: SQLCODE=-171, SQLSTATE=42815</pre>
*/
@Override
protected ExpressionOperator roundOperator() {
ExpressionOperator operatorS = super.roundOperator();
ExpressionOperator operator = disableAllBindingExpression();
operatorS.copyTo(operator);
return operator;
}

@Override
public boolean isDB2Z() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,6 @@ protected void initializePlatformOperators() {
addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.ToNumber, "DOUBLE"));
addOperator(derbyExtractOperator());
addOperator(derbyPowerOperator());
addOperator(derbyRoundOperator());

addOperator(avgOperator());
addOperator(sumOperator());
Expand Down Expand Up @@ -487,26 +486,6 @@ private static ExpressionOperator derbyPowerOperator() {
return operator;
}

// Emulate ROUND as FLOOR((:x)*1e:n+0.5)/1e:n
private static ExpressionOperator derbyRoundOperator() {
ExpressionOperator operator = disableAllBindingExpression();
ExpressionOperator.round().copyTo(operator);

List<String> v = new ArrayList<>(4);
v.add("FLOOR((");
v.add(")*1e");
v.add("+0.5)/1e");
v.add("");
operator.printsAs(v);
int[] argumentIndices = new int[3];
argumentIndices[0] = 0;
argumentIndices[1] = 1;
argumentIndices[2] = 1;
operator.setArgumentIndices(argumentIndices);
operator.setIsBindingSupported(false);
return operator;
}

// Derby does not suport native EXTRACT at all. There are specific functions for most of the date/time parts.
// QUARTER part needs to be calculated from MONTH value.
// SECOND does not return fraction part and there is no fraction specific function available.
Expand Down Expand Up @@ -830,6 +809,29 @@ public void printJavaDuo(Expression first, Expression second, ExpressionJavaPrin
return operator;
}

/**
* Emulate ROUND as FLOOR((:x)*1e:n+0.5)/1e:n
*/
@Override
protected ExpressionOperator roundOperator() {
ExpressionOperator operator = disableAllBindingExpression();
ExpressionOperator.round().copyTo(operator);

List<String> v = new ArrayList<>(4);
v.add("FLOOR((");
v.add(")*1e");
v.add("+0.5)/1e");
v.add("");
operator.printsAs(v);
int[] argumentIndices = new int[3];
argumentIndices[0] = 0;
argumentIndices[1] = 1;
argumentIndices[2] = 1;
operator.setArgumentIndices(argumentIndices);
operator.setIsBindingSupported(false);
return operator;
}

/**
* INTERNAL
* Derby has some issues with using parameters on certain functions and relations.
Expand Down

0 comments on commit 2a0f3b2

Please sign in to comment.