This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git


The following commit(s) were added to refs/heads/master by this push:
     new 4cc305099 [OPENJPA-2932] Implements numeric JPA 3.1 JPQL functions and 
equivalent Criteria API (#122)
4cc305099 is described below

commit 4cc3050998afbdf8d59d5e96ccc9ff0580ee07ff
Author: Paulo Cristovão de Araújo Silva Filho <pcris...@gmail.com>
AuthorDate: Sun Feb 2 11:34:55 2025 -0300

    [OPENJPA-2932] Implements numeric JPA 3.1 JPQL functions and equivalent 
Criteria API (#122)
    
    * [OPENJPA-2932] Implements numeric JPA 3.1 JPQL functions and equivalent 
Criteria API
    
    * Implements CEILING, EXP, FLOOR, SIGN, LN, POWER and ROUND JPQL functions
    * Ajusts JPQL.jjt
    * Added kernel and jdbc equivalent expressions
    * Added one test for each new expression in JPQL and Criteria API
    * Updates manual page referring new FUNCTIONS
    * Added DatabaseHelper to add necessary functions on DerbyDb (it does not 
natively support POWER and ROUND functions)
---
 .../apache/openjpa/jdbc/kernel/JDBCStoreQuery.java |   3 +
 .../apache/openjpa/jdbc/kernel/exps/Ceiling.java   |  66 +++++++++
 .../openjpa/jdbc/kernel/exps/Exponential.java      |  52 +++++++
 .../org/apache/openjpa/jdbc/kernel/exps/Floor.java |  66 +++++++++
 .../jdbc/kernel/exps/JDBCExpressionFactory.java    |  35 +++++
 .../org/apache/openjpa/jdbc/kernel/exps/Math.java  |   2 +
 .../openjpa/jdbc/kernel/exps/NaturalLogarithm.java |  52 +++++++
 .../org/apache/openjpa/jdbc/kernel/exps/Sign.java  |  57 ++++++++
 .../org/apache/openjpa/jdbc/kernel/exps/Val.java   |   5 +
 .../org/apache/openjpa/jdbc/sql/DBDictionary.java  |   9 +-
 .../java/org/apache/openjpa/kernel/Filters.java    |  43 +++++-
 .../org/apache/openjpa/kernel/exps/Ceiling.java    |  76 ++++++++++
 .../apache/openjpa/kernel/exps/Exponential.java    |  47 +++++++
 .../openjpa/kernel/exps/ExpressionFactory.java     |  35 +++++
 .../java/org/apache/openjpa/kernel/exps/Floor.java |  76 ++++++++++
 .../kernel/exps/InMemoryExpressionFactory.java     |  35 +++++
 .../openjpa/kernel/exps/NaturalLogarithm.java      |  47 +++++++
 .../java/org/apache/openjpa/kernel/exps/Power.java |  46 ++++++
 .../java/org/apache/openjpa/kernel/exps/Round.java |  45 ++++++
 .../java/org/apache/openjpa/kernel/exps/Sign.java  |  59 ++++++++
 .../openjpa/kernel/jpql/JPQLExpressionBuilder.java |  21 +++
 .../jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt |  57 +++++++-
 .../persistence/common/utils/DatabaseHelper.java   | 156 +++++++++++++++++++++
 .../persistence/criteria/TestTypesafeCriteria.java |  76 ++++++++++
 .../jpql/functions/TestEJBQLFunction.java          | 143 +++++++++++++++++++
 .../persistence/criteria/CriteriaBuilderImpl.java  |  87 ++++++------
 .../openjpa/persistence/criteria/Expressions.java  | 133 ++++++++++++++++++
 .../src/doc/manual/jpa_overview_query.xml          | 149 ++++++++++++++++++--
 28 files changed, 1613 insertions(+), 65 deletions(-)

diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
index ce69d3634..ebd107f2d 100644
--- 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
+++ 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
@@ -841,6 +841,9 @@ public class JDBCStoreQuery
             return Filters.divide(val1, c1, val2, c2);
         else if (op.equals(org.apache.openjpa.jdbc.kernel.exps.Math.MOD))
             return Filters.mod(val1, c1, val2, c2);
+        else if (op.equals(org.apache.openjpa.jdbc.kernel.exps.Math.POWER)) {
+            return Filters.power(val1, c1, val2, c2);
+        }
         throw new UnsupportedException();
     }
 
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Ceiling.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Ceiling.java
new file mode 100644
index 000000000..4cd583234
--- /dev/null
+++ 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Ceiling.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Ceiling value.
+ */
+public class Ceiling
+    extends UnaryOp {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value to operate on.
+     */
+    public Ceiling(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        Class wrap = Filters.wrap(c);
+        if (wrap == Integer.class
+            || wrap == Float.class
+            || wrap == Double.class
+            || wrap == Long.class
+            || wrap == BigDecimal.class
+            || wrap == BigInteger.class) {
+            return Filters.unwrap(c);
+        }
+        return int.class;
+    }
+
+    @Override
+    protected String getOperator() {
+        return "CEILING";
+    }
+
+    @Override
+    public int getId() {
+        return Val.CEILING_VAL;
+    }
+}
+
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Exponential.java
 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Exponential.java
new file mode 100644
index 000000000..c6fdc867e
--- /dev/null
+++ 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Exponential.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+/**
+ * Exponential value.
+ */
+public class Exponential
+    extends UnaryOp {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value to which the Euler's constant should be 
powered.
+     */
+    public Exponential(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        return double.class;
+    }
+
+    @Override
+    protected String getOperator() {
+        return "EXP";
+    }
+
+    @Override
+    public int getId() {
+        return Val.EXP_VAL;
+    }
+}
+
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Floor.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Floor.java
new file mode 100644
index 000000000..e8f7740aa
--- /dev/null
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Floor.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Floor value.
+ */
+public class Floor
+    extends UnaryOp {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value to operate on.
+     */
+    public Floor(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        Class wrap = Filters.wrap(c);
+        if (wrap == Integer.class
+            || wrap == Float.class
+            || wrap == Double.class
+            || wrap == Long.class
+            || wrap == BigDecimal.class
+            || wrap == BigInteger.class) {
+            return Filters.unwrap(c);
+        }
+        return int.class;
+    }
+
+    @Override
+    protected String getOperator() {
+        return "FLOOR";
+    }
+
+    @Override
+    public int getId() {
+        return Val.FLOOR_VAL;
+    }
+}
+
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
index fbb273270..41e6f5b30 100644
--- 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
+++ 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
@@ -448,6 +448,41 @@ public class JDBCExpressionFactory
     public Value abs(Value val) {
         return new Abs((Val) val);
     }
+    
+    @Override
+    public Value ceiling(Value val) {
+       return new Ceiling((Val) val);
+    }
+
+    @Override
+    public Value exp(Value val) {
+        return new Exponential((Val) val);
+    }
+
+    @Override
+    public Value floor(Value val) {
+        return new Floor((Val) val);
+    }
+
+    @Override
+    public Value ln(Value val) {
+        return new NaturalLogarithm((Val) val);
+    }
+
+    @Override
+    public Value sign(Value val) {
+        return new Sign((Val) val);
+    }
+
+    @Override
+    public Value power(Value base, Value exponent) {
+        return new Math((Val) base, (Val) exponent, Math.POWER);
+    }
+
+    @Override
+    public Value round(Value num, Value precision) {
+        return new Math((Val) num, (Val) precision, Math.ROUND);
+    }
 
     @Override
     public Value indexOf(Value v1, Value v2) {
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Math.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Math.java
index 744130d3d..dfbab290d 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Math.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Math.java
@@ -43,6 +43,8 @@ public class Math
     public static final String MULTIPLY = "*";
     public static final String DIVIDE = "/";
     public static final String MOD = "MOD";
+    public static final String POWER = "POWER";
+    public static final String ROUND = "ROUND";
 
     private final Val _val1;
     private final Val _val2;
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NaturalLogarithm.java
 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NaturalLogarithm.java
new file mode 100644
index 000000000..9c940a3f8
--- /dev/null
+++ 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NaturalLogarithm.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+/**
+ * Natural logarithm (base e) value.
+ */
+public class NaturalLogarithm
+    extends UnaryOp {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value from which the natural logarithm should 
be calculated.
+     */
+    public NaturalLogarithm(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        return double.class;
+    }
+
+    @Override
+    protected String getOperator() {
+        return "LN";
+    }
+
+    @Override
+    public int getId() {
+        return Val.LN_VAL;
+    }
+}
+
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sign.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sign.java
new file mode 100644
index 000000000..1079a3557
--- /dev/null
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sign.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Sign value.
+ */
+public class Sign
+    extends UnaryOp {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value whose sign will be found.
+     */
+    public Sign(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        return int.class;
+    }
+
+    @Override
+    protected String getOperator() {
+        return "SIGN";
+    }
+
+    @Override
+    public int getId() {
+        return Val.SIGN_VAL;
+    }
+}
+
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
index 049cec503..958bb024d 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
@@ -75,6 +75,11 @@ public interface Val
     int WHENSCALAR_VAL = 16;
     int COALESCE_VAL = 17;
     int NULLIF_VAL = 18;
+    int CEILING_VAL = 19;
+    int EXP_VAL = 20;
+    int FLOOR_VAL = 21;
+    int LN_VAL = 22;
+    int SIGN_VAL = 23;
 
     /**
      * Initialize the value. This method should recursively initialize any
diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
index 025306b5a..9dbba34c9 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
@@ -3181,12 +3181,15 @@ public class DBDictionary
         }
 
         boolean mod = "MOD".equals(op);
-        if (mod) {
-            if (supportsModOperator)
+        boolean power = "POWER".equals(op);
+        boolean round = "ROUND".equals(op);
+        if (mod || power || round) {
+            if (supportsModOperator && mod)
                 op = "%";
             else
                 buf.append(op);
         }
+
         buf.append("(");
 
         if (castlhs)
@@ -3194,7 +3197,7 @@ public class DBDictionary
         else
             lhs.appendTo(buf);
 
-        if (mod && !supportsModOperator)
+        if ((mod && !supportsModOperator) || power || round)
             buf.append(", ");
         else
             buf.append(" ").append(op).append(" ");
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java
index 5cc92f006..36df09254 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java
@@ -21,6 +21,7 @@ package org.apache.openjpa.kernel;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.sql.Time;
@@ -65,6 +66,8 @@ public class Filters {
     private static final int OP_MULTIPLY = 2;
     private static final int OP_DIVIDE = 3;
     private static final int OP_MOD = 4;
+    private static final int OP_POWER = 5;
+    private static final int OP_ROUND = 6;
 
     private static final Localizer _loc = Localizer.forPackage(Filters.class);
 
@@ -480,6 +483,17 @@ public class Filters {
         return op(o1, c1, o2, c2, OP_MOD);
     }
 
+    /**
+     * Power the base to the exponent
+     */
+    public static Object power(Object o1, Class<?> c1, Object o2, Class<?> c2) 
{
+        return op(o1, c1, o2, c2, OP_POWER);
+    }
+
+    public static Object round(Object o1, Class<?> c1, Object o2, Class<?> c2) 
{
+        return op(o1, c1, o2, c2, OP_ROUND);
+    }
+
     /**
      * Perform the given operation on two numbers.
      */
@@ -546,6 +560,10 @@ public class Filters {
             case OP_MOD:
                 tot = n1 % n2;
                 break;
+            case OP_POWER:
+                return Math.pow(n1, n2);
+            case OP_ROUND:
+                tot = n1;
             default:
                 throw new InternalException();
         }
@@ -573,7 +591,12 @@ public class Filters {
             case OP_MOD:
                 tot = n1 % n2;
                 break;
-            default:
+            case OP_POWER:
+                return Math.pow(n1, n2);
+            case OP_ROUND:
+                BigDecimal bg = new BigDecimal(Float.toString(n1));
+                return bg.setScale(Math.toIntExact(Math.round(n2)), 
RoundingMode.HALF_EVEN).floatValue();
+        default:
                 throw new InternalException();
         }
         return tot;
@@ -600,6 +623,12 @@ public class Filters {
             case OP_MOD:
                 tot = n1 % n2;
                 break;
+            case OP_POWER:
+                tot = Math.pow(n1, n2);
+                break;
+            case OP_ROUND:
+                BigDecimal bg = new BigDecimal(Double.toString(n1));
+                return bg.setScale(Math.toIntExact(Math.round(n2)), 
RoundingMode.HALF_EVEN).doubleValue();
             default:
                 throw new InternalException();
         }
@@ -627,6 +656,10 @@ public class Filters {
             case OP_MOD:
                 tot = n1 % n2;
                 break;
+            case OP_POWER:
+                return Math.pow(n1, n2);
+            case OP_ROUND:
+                return n1;
             default:
                 throw new InternalException();
         }
@@ -649,6 +682,10 @@ public class Filters {
                 return n1.divide(n2, scale, BigDecimal.ROUND_HALF_UP);
             case OP_MOD:
                 throw new UserException(_loc.get("mod-bigdecimal"));
+            case OP_POWER:
+                return n1.pow(n2.intValue());
+            case OP_ROUND:
+                return n1.setScale(n2.intValue(), RoundingMode.HALF_EVEN);
             default:
                 throw new InternalException();
         }
@@ -667,6 +704,10 @@ public class Filters {
                 return n1.multiply(n2);
             case OP_DIVIDE:
                 return n1.divide(n2);
+            case OP_POWER:
+                return n1.pow(n2.intValue());
+            case OP_ROUND:
+                return n1;
             default:
                 throw new InternalException();
         }
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Ceiling.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Ceiling.java
new file mode 100644
index 000000000..19123b661
--- /dev/null
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Ceiling.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Take the ceiling value of a number.
+ */
+class Ceiling
+    extends UnaryMathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the number whose ceiling value to calculate.
+     */
+    public Ceiling(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        Class wrap = Filters.wrap(c);
+        if (wrap == Integer.class
+            || wrap == Float.class
+            || wrap == Double.class
+            || wrap == Long.class
+            || wrap == BigDecimal.class
+            || wrap == BigInteger.class) {
+            return Filters.unwrap(c);
+        }
+        return int.class;
+    }
+
+    @Override
+    protected Object operate(Object o, Class c) {
+        c = Filters.wrap(c);
+        if (c == Integer.class)
+            return Math.ceil(((Number) o).intValue());
+        if (c == Float.class)
+            return Math.ceil(((Number) o).floatValue());
+        if (c == Double.class)
+            return Math.ceil(((Number) o).doubleValue());
+        if (c == Long.class)
+            return Math.ceil(((Number) o).longValue());
+        if (c == BigDecimal.class)
+            return ((BigDecimal) o).setScale(0, RoundingMode.CEILING);
+        if (c == BigInteger.class)
+            return ((BigInteger) o);
+
+        // default to int
+        return Math.ceil(((Number) o).intValue());
+    }
+}
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Exponential.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Exponential.java
new file mode 100644
index 000000000..ef34c7a78
--- /dev/null
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Exponential.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+/**
+ * Exponential value.
+ *
+ */
+class Exponential
+    extends UnaryMathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value to which the Euler's constant should be 
powered.
+     */
+    public Exponential(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        return double.class;
+    }
+
+    @Override
+    protected Object operate(Object o, Class c) {
+        return Math.exp(((Number) o).doubleValue());
+    }
+}
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
index 8c6b86cfd..38f433935 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
@@ -327,6 +327,41 @@ public interface ExpressionFactory {
      * Return a value representing the absolute value of the given one.
      */
     Value abs(Value num);
+    
+    /**
+     * Returns a value representing the ceiling value of the given one.
+     */
+    Value ceiling(Value num);
+
+    /**
+     * Returns a value representing the Euler's e constant powered to the 
given value.
+     */
+    Value exp(Value num);
+
+    /**
+     * Returns a value representing the floor of the given value.
+     */
+    Value floor(Value num);
+
+    /**
+     * Returns the natural logarithm of the given value
+     */
+    Value ln(Value num);
+
+    /**
+     * Returns the sign of the given value as a number (-1 for negative, 0 for 
zeroes and 1 for positive)
+     */
+    Value sign(Value num);
+
+    /**
+     * Returns a value representing base powered by the exponent
+     */
+    Value power(Value base, Value exponent);
+
+    /*
+     * Returns the number rounded to the given precision.
+     */
+    Value round(Value num, Value precision);
 
     /**
      * Return a value representing the indexOf (LOCATE in JPQL) function on
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Floor.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Floor.java
new file mode 100644
index 000000000..95b1ffdf3
--- /dev/null
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Floor.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Take the floor value of a number.
+ */
+class Floor
+    extends UnaryMathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the number whose floor value will be calculated.
+     */
+    public Floor(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        Class wrap = Filters.wrap(c);
+        if (wrap == Integer.class
+            || wrap == Float.class
+            || wrap == Double.class
+            || wrap == Long.class
+            || wrap == BigDecimal.class
+            || wrap == BigInteger.class) {
+            return Filters.unwrap(c);
+        }
+        return int.class;
+    }
+
+    @Override
+    protected Object operate(Object o, Class c) {
+        c = Filters.wrap(c);
+        if (c == Integer.class)
+            return Math.floor(((Number) o).intValue());
+        if (c == Float.class)
+            return Math.floor(((Number) o).floatValue());
+        if (c == Double.class)
+            return Math.floor(((Number) o).doubleValue());
+        if (c == Long.class)
+            return Math.floor(((Number) o).longValue());
+        if (c == BigDecimal.class)
+            return ((BigDecimal) o).setScale(0, RoundingMode.FLOOR);
+        if (c == BigInteger.class)
+            return ((BigInteger) o);
+
+        // default to int
+        return Math.floor(((Number) o).intValue());
+    }
+}
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
index 8e83bbe5f..00a399d8c 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
@@ -624,6 +624,41 @@ public class InMemoryExpressionFactory
     public Value abs(Value val) {
         return new Abs((Val) val);
     }
+    
+    @Override
+    public Value ceiling(Value val) {
+       return new Ceiling((Val) val);
+    }
+
+    @Override
+    public Value exp(Value val) {
+        return new Exponential((Val) val);
+    }
+
+    @Override
+    public Value floor(Value val) {
+        return new Floor((Val) val);
+    }
+
+    @Override
+    public Value ln(Value val) {
+        return new NaturalLogarithm(((Val) val));
+    }
+
+    @Override
+    public Value sign(Value val) {
+        return new Sign((Val) val);
+    }
+
+    @Override
+    public Value power(Value base, Value exponent) {
+        return new Power((Val) base, (Val) exponent);
+    }
+
+    @Override
+    public Value round(Value num, Value precision) {
+        return new Round((Val) num, (Val) precision);
+    }
 
     @Override
     public Value indexOf(Value val1, Value val2) {
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/NaturalLogarithm.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/NaturalLogarithm.java
new file mode 100644
index 000000000..38bb1e805
--- /dev/null
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/NaturalLogarithm.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+/**
+ * Natural logarithm (base e) value.
+ *
+ */
+class NaturalLogarithm
+    extends UnaryMathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value from which the natural logarithm should 
be calculated.
+     */
+    public NaturalLogarithm(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        return double.class;
+    }
+
+    @Override
+    protected Object operate(Object o, Class c) {
+        return Math.log(((Number) o).doubleValue());
+    }
+}
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Power.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Power.java
new file mode 100644
index 000000000..70c7a539f
--- /dev/null
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Power.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Value produced by one value being powered by another.
+ *
+ * @author Abe White
+ */
+class Power
+    extends MathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the values to divide.
+     */
+    public Power(Val val1, Val val2) {
+        super(val1, val2);
+    }
+
+    @Override
+    protected Object operate(Object o1, Class c1, Object o2, Class c2) {
+        return Filters.power(o1, c1, o2, c2);
+    }
+}
+
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Round.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Round.java
new file mode 100644
index 000000000..ccb6fbaf2
--- /dev/null
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Round.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Value produced by one value being rounded to the another precision.
+ *
+ */
+class Round
+    extends MathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Rounds the value to a given precision.
+     */
+    public Round(Val val1, Val val2) {
+        super(val1, val2);
+    }
+
+    @Override
+    protected Object operate(Object o1, Class c1, Object o2, Class c2) {
+        return Filters.round(o1, c1, o2, c2);
+    }
+}
+
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Sign.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Sign.java
new file mode 100644
index 000000000..0816bfc57
--- /dev/null
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Sign.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel.exps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Take the sign of a number.
+ */
+class Sign
+    extends UnaryMathVal {
+
+    
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor. Provide the value whose sign will be found.
+     */
+    public Sign(Val val) {
+        super(val);
+    }
+
+    @Override
+    protected Class getType(Class c) {
+        return int.class;
+    }
+
+    @Override
+    protected Object operate(Object o, Class c) {
+        c = Filters.wrap(c);
+        float value = 0;
+        if (c == Integer.class || c == Float.class || c == Double.class || c 
== Long.class)
+            value = ((Number) o).floatValue();
+        else if (c == BigDecimal.class)
+            value = ((BigDecimal) o).floatValue();
+        else if (c == BigInteger.class)
+            value = ((BigInteger) o).floatValue();
+        return Math.round(Math.signum(value));
+    }
+}
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
index fb7af4277..68c71456e 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
@@ -1273,6 +1273,27 @@ public class JPQLExpressionBuilder
 
             case JJTABS:
                 return factory.abs(getNumberValue(onlyChild(node)));
+                
+            case JJTCEILING:
+               return factory.ceiling(getNumberValue(onlyChild(node)));
+
+            case JJTEXP:
+                return factory.exp(getNumberValue(onlyChild(node)));
+
+            case JJTFLOOR:
+                return factory.floor(getNumberValue(onlyChild(node)));
+
+            case JJTLN:
+                return factory.ln(getNumberValue(onlyChild(node)));
+            
+            case JJTSIGN:
+                return factory.sign(getNumberValue(onlyChild(node)));
+
+            case JJTPOWER:
+                return factory.power(getNumberValue(firstChild(node)), 
getNumberValue(secondChild(node)));
+            
+            case JJTROUND:
+                return factory.round(getNumberValue(firstChild(node)), 
getNumberValue(secondChild(node)));
 
             case JJTSQRT:
                 return factory.sqrt(getNumberValue(onlyChild(node)));
diff --git 
a/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt 
b/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
index 8ee0aa099..a14aec2ea 100644
--- a/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
+++ b/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
@@ -208,6 +208,13 @@ TOKEN [ IGNORE_CASE ]: /* functions returning numerics */
        < LENGTH: "LENGTH" >
        |       < LOCATE: "LOCATE" >
        |       < ABS: "ABS" >
+       |   < CEILING: "CEILING" >
+       |       < EXP: "EXP" >
+       |   < FLOOR: "FLOOR" >
+       |   < LN: "LN" >
+       |       < SIGN: "SIGN" >
+       |       < POWER: "POWER" >
+       |       < ROUND: "ROUND" >
        |       < SQRT: "SQRT" >
        |       < MOD: "MOD" >
        |       < SIZE: "SIZE" >
@@ -1233,7 +1240,7 @@ void trim_specification() : { }
 
 void functions_returning_numerics() : { }
 {
-       length() | locate() | abs() | sqrt() | mod() | size() | index()
+       length() | locate() | abs() | ceiling() | exp() | floor() | ln() | 
sign() | power() | round() | sqrt() | mod() | size() | index()
 }
 
 
@@ -1258,6 +1265,47 @@ void abs() #ABS : { }
 
 }
 
+void ceiling() #CEILING : { }
+{
+       <CEILING> "(" arithmetic_expression() ")"
+
+}
+
+void exp() #EXP : { }
+{
+       <EXP> "(" arithmetic_expression() ")"
+
+}
+
+void floor() #FLOOR : { } 
+{
+       <FLOOR> "(" arithmetic_expression() ")"
+
+}
+
+void ln() #LN : { }
+{
+       <LN> "(" arithmetic_expression() ")"
+
+}
+
+void sign() #SIGN : { }
+{
+       <SIGN> "(" arithmetic_expression() ")"
+
+}
+
+void power() #POWER : { }
+{
+       <POWER> "(" arithmetic_expression() <COMMA> arithmetic_expression() ")"
+
+}
+
+void round() #ROUND : { }
+{
+       <ROUND> "(" arithmetic_expression() <COMMA> arithmetic_expression() ")"
+
+}
 
 void sqrt() #SQRT : { }
 {
@@ -1376,6 +1424,13 @@ void path_component() #IDENTIFICATIONVARIABLE :
        | t = <LENGTH>
        | t = <LOCATE>
        | t = <ABS>
+       | t = <CEILING>
+       | t = <EXP>
+       | t = <FLOOR>
+       | t = <LN>
+       | t = <SIGN>
+       | t = <POWER>
+       | t = <ROUND>
        | t = <SQRT>
        | t = <MOD>
        | t = <SIZE>
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/DatabaseHelper.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/DatabaseHelper.java
new file mode 100644
index 000000000..b61ce71ca
--- /dev/null
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/DatabaseHelper.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.common.utils;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.DerbyDictionary;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+import jakarta.persistence.EntityManager;
+
+/**
+ * Allows augmentation of databases, if they don't have support to some 
+ * necessary functions, such as DerbyDb's lack of POWER and ROUND
+ */
+public class DatabaseHelper {
+
+    private static final String CREATE_DERBYDB_POWER_FUNCTION_SQL = "CREATE 
FUNCTION POWER(a DOUBLE, b DOUBLE) " + 
+            "RETURNS DOUBLE PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA EXTERNAL 
NAME 'java.lang.Math.pow'";
+
+    private static final String DROP_DERBYDB_POWER_FUNCTION_SQL = "DROP 
FUNCTION POWER";
+    
+    private static final String CREATE_DERBYDB_ROUND_FUNCTION_SQL = "CREATE 
FUNCTION ROUND(a DOUBLE, b INTEGER) " + 
+            "RETURNS DOUBLE PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA " + 
+            "EXTERNAL NAME 
'org.apache.openjpa.persistence.common.utils.DatabaseHelper.roundFunction'";
+    
+    private static final String DROP_DERBYDB_ROUND_FUNCTION_SQL = "DROP 
FUNCTION ROUND";
+
+    /**
+     * Creates the POWER function on DerbyDB, ignoring exceptions if it 
already exists.
+     * 
+     */
+    public static void createPowerFunctionIfNecessary(EntityManager em, 
DBDictionary dict) {
+        if (dict instanceof DerbyDictionary) {
+            try {
+                exec(em, true, 10, CREATE_DERBYDB_POWER_FUNCTION_SQL);
+            } catch (Exception ex) {
+                // swallowing because the function probably already exists and 
any exceptions
+                // should have been ignored on exec.
+            }
+        }
+    }
+
+    /**
+     * Drops the POWER function on DerbyDB.
+     * 
+     */
+    public static void dropPowerFunction(EntityManager em, DBDictionary dict) {
+        if (dict instanceof DerbyDictionary) {
+            try {
+                exec(em, true, 10, DROP_DERBYDB_POWER_FUNCTION_SQL);
+            } catch (Exception ex) {
+                // swallowing because this is just a clean-up
+            }
+        }
+    }
+
+    /**
+     * Creates the ROUND function on DerbyDB, ignoring exceptions if it 
already exists.
+     * 
+     */
+    public static void createRoundFunctionIfNecessary(EntityManager em, 
DBDictionary dict) {
+        if (dict instanceof DerbyDictionary) {
+            try {
+                exec(em, true, 10, CREATE_DERBYDB_ROUND_FUNCTION_SQL);
+            } catch (Exception ex) {
+                // swallowing because the function probably already exists and 
any exceptions
+                // should have been ignored on exec.
+            }
+        }
+    }
+
+    public static void dropRoundFunction(EntityManager em, DBDictionary dict) {
+        if (dict instanceof DerbyDictionary) {
+            try {
+                exec(em, true, 10, DROP_DERBYDB_ROUND_FUNCTION_SQL);
+            } catch (Exception ex) {
+                // swallowing because this is just a clean-up
+            }
+        }
+
+    }
+
+    /**
+     * Rounds the number to given precision.
+     */
+    public static double roundFunction(Double num, int precision) {
+        BigDecimal db = new BigDecimal(Double.toString(num));
+        return db.setScale(precision, RoundingMode.HALF_EVEN).doubleValue();
+    }
+
+    /**
+     * Convenience method to execute SQL statements. Does not close 
EntityManager
+     * after executing.
+     * 
+     * @param em EntityManager whose connection will be extracted
+     * @param ignoreExceptions indicate if exceptions should be ignored during 
executions
+     * @param timeoutSecs timeout, in seconds, of execution
+     * @param sql SQL to be executed
+     * @throws SQLException
+     */
+    static void exec(EntityManager em, boolean ignoreExceptions, int 
timeoutSecs, String sql)
+        throws SQLException {
+        Statement s = null;
+        try {
+            assertNotNull(em);
+            Broker broker = JPAFacadeHelper.toBroker(em);
+            Connection conn = (Connection) broker.getConnection();
+            s = conn.createStatement();
+            if (timeoutSecs > 0) {
+                s.setQueryTimeout(timeoutSecs);
+            }
+            s.execute(sql);
+        } catch (SQLException sqe) {
+            if (!ignoreExceptions) {
+                // fail(sqe.toString());
+                throw sqe;
+            }
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (Exception e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+
+}
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
index 09b313327..80ddda975 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
@@ -49,6 +49,7 @@ import jakarta.persistence.metamodel.Metamodel;
 
 import org.apache.openjpa.jdbc.sql.AbstractSQLServerDictionary;
 import org.apache.openjpa.jdbc.sql.OracleDictionary;
+import org.apache.openjpa.persistence.common.utils.DatabaseHelper;
 import org.apache.openjpa.persistence.test.AllowFailure;
 
 /**
@@ -185,6 +186,80 @@ public class TestTypesafeCriteria extends CriteriaTest {
         assertEquivalence(c, jpql);
     }
 
+    public void testCeilingExpression() {
+        String jpql = "select a from Account a where ceiling(a.balance)=100";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        
c.select(account).where(cb.equal(cb.ceiling(account.get(Account_.balance)), 
100));
+        assertEquivalence(c, jpql);
+    }
+
+    public void testExponentialExpression() {
+        String jpql = "select a from Account a where exp(a.balance)=100";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        
c.select(account).where(cb.equal(cb.exp(account.get(Account_.balance)), 100));
+        assertEquivalence(c, jpql);
+    }
+
+    public void testFloorExpression() {
+        String jpql = "select a from Account a where floor(a.balance)=100";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        
c.select(account).where(cb.equal(cb.floor(account.get(Account_.balance)), 100));
+        assertEquivalence(c, jpql);
+    }
+
+    public void testLnExpression() {
+        String jpql = "select a from Account a where ln(a.balance)=100";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        c.select(account).where(cb.equal(cb.ln(account.get(Account_.balance)), 
100));
+        assertEquivalence(c, jpql);
+    }
+
+    public void testSignExpression() {
+        String jpql = "select a from Account a where sign(a.balance)=1";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        
c.select(account).where(cb.equal(cb.sign(account.get(Account_.balance)), 1));
+        assertEquivalence(c, jpql);
+    }
+
+    public void testPowerExpression() {
+        DatabaseHelper.createPowerFunctionIfNecessary(getEntityManager(), 
getDictionary());
+        String jpql = "select a from Account a where power(a.balance, 7)=1";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        
c.select(account).where(cb.equal(cb.power(account.get(Account_.balance), 7), 
1));
+        assertEquivalence(c, jpql);
+        DatabaseHelper.dropPowerFunction(getEntityManager(), getDictionary());
+    }
+
+    public void testRoundExpression() {
+        DatabaseHelper.createRoundFunctionIfNecessary(getEntityManager(), 
getDictionary());
+        String jpql = "select a from Account a where round(a.balance, 1)=1";
+
+        CriteriaQuery<Account> c = cb.createQuery(Account.class);
+        Root<Account> account = c.from(Account.class);
+
+        
c.select(account).where(cb.equal(cb.round(account.get(Account_.balance), 1), 
1));
+        assertEquivalence(c, jpql);
+        DatabaseHelper.dropRoundFunction(getEntityManager(), getDictionary());
+    }
+
     public void testAvgExpression() {
         String jpql = "select avg(a.balance) from Account a";
 
@@ -1645,4 +1720,5 @@ public class TestTypesafeCriteria extends CriteriaTest {
 
         assertEquivalence(cq, jpql);
     }
+
 }
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
index c337e0f8a..845f84276 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
@@ -18,12 +18,14 @@
  */
 package org.apache.openjpa.persistence.jpql.functions;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 import jakarta.persistence.EntityManager;
 
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.DerbyDictionary;
 import org.apache.openjpa.jdbc.sql.OracleDictionary;
 import org.apache.openjpa.jdbc.sql.SybaseDictionary;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
@@ -32,6 +34,7 @@ import org.apache.openjpa.persistence.common.apps.CompUser;
 import org.apache.openjpa.persistence.common.apps.FemaleUser;
 import org.apache.openjpa.persistence.common.apps.MaleUser;
 import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.common.utils.DatabaseHelper;
 
 public class TestEJBQLFunction extends AbstractTestCase {
 
@@ -85,11 +88,25 @@ public class TestEJBQLFunction extends AbstractTestCase {
         if(dict instanceof SybaseDictionary) {
             expectedShannonName="Shannon";
         }
+        DatabaseHelper.createPowerFunctionIfNecessary(em, dict);
+        DatabaseHelper.createRoundFunctionIfNecessary(em, dict);
 
         endTx(em);
         endEm(em);
     }
 
+    @Override
+    public void tearDown() throws Exception {
+        OpenJPAEntityManagerSPI em = (OpenJPAEntityManagerSPI) 
currentEntityManager();
+
+        DBDictionary dict = ((JDBCConfiguration) 
em.getConfiguration()).getDBDictionaryInstance();
+        DatabaseHelper.dropPowerFunction(em, dict);
+        DatabaseHelper.dropRoundFunction(em, dict);
+
+        endEm(em);
+        super.tearDown();
+    }
+
     public void testConcatSubStringFunc() {
         EntityManager em = currentEntityManager();
         startTx(em);
@@ -491,6 +508,132 @@ public class TestEJBQLFunction extends AbstractTestCase {
 
         endEm(em);
     }
+    
+    public void testCEILINGFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT CEILING(SUM(c.age) + 0.4) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(154L, ((BigDecimal) result.get(0)).longValue());
+
+        endEm(em);
+    }
+
+    public void testCEILINGFuncNegative() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT CEILING(0.4 - SUM(c.age)) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(-152L, ((BigDecimal) result.get(0)).longValue());
+
+        endEm(em);
+    }
+
+    public void testEXPFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT EXP(MIN(c.age)) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(Math.exp(10), (double) result.get(0));
+
+        endEm(em);
+    }
+
+    public void testFLOORFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT FLOOR(SUM(c.age) - 0.4) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(152L, ((BigDecimal) result.get(0)).longValue());
+
+        endEm(em);
+    }
+
+    public void testFLOORFuncNegative() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT FLOOR(10.4 - SUM(c.age)) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(-143L, ((BigDecimal) result.get(0)).longValue());
+
+        endEm(em);
+    }
+
+    public void testPOWERFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT POWER(MIN(c.age), 3) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(1000L, result.get(0));
+
+        endEm(em);
+    }
+
+    public void testROUNDFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT ROUND(SQRT(MIN(c.age)), 3) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(3.162, (double) result.get(0));
+
+        endEm(em);
+    }
+
+    public void testSIGNFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT SIGN(1 - SUM(c.age)) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(-1, ((Integer) result.get(0)).intValue());
+
+        endEm(em);
+    }
+
+    public void testLNFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT LN(MIN(c.age)) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(Math.log(10), (double) result.get(0));
+
+        endEm(em);
+    }
 
     public CompUser createUser(String name, String cName, Address add, int age,
         boolean isMale) {
diff --git 
a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
 
b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
index 7d109f25e..c9c0e2bf0 100644
--- 
a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
+++ 
b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
@@ -153,6 +153,46 @@ public class CriteriaBuilderImpl implements 
OpenJPACriteriaBuilder, ExpressionPa
     public <N extends Number> Expression<N> abs(Expression<N> x) {
         return new Expressions.Abs<>(x);
     }
+    
+    @Override
+    public <N extends Number> Expression<N> ceiling(Expression<N> x) {
+       return new Expressions.Ceiling<>(x);
+    }
+
+    @Override
+    public Expression<Double> exp(Expression<? extends Number> x) {
+        return new Expressions.Exponential(x);
+    }
+
+    @Override
+    public <N extends Number> Expression<N> floor(Expression<N> x) {
+        return new Expressions.Floor<>(x);
+    }
+
+    @Override
+    public Expression<Double> ln(Expression<? extends Number> x) {
+        return new Expressions.NaturalLogarithm(x);
+    }
+
+    @Override
+    public Expression<Integer> sign(Expression<? extends Number> x) {
+        return new Expressions.Sign(x);
+    }
+
+    @Override
+    public Expression<Double> power(Expression<? extends Number> x, Number y) {
+        return new Expressions.Power<>(x, y);
+    }
+
+    @Override
+    public Expression<Double> power(Expression<? extends Number> x, 
Expression<? extends Number> y) {
+        return new Expressions.Power<>(x, y);
+    }
+
+    @Override
+    public <T extends Number> Expression<T> round(Expression<T> x, Integer n) {
+        return new Expressions.Round<>(x, new Expressions.Constant<>(n));
+    }
 
     @Override
     public <Y> Expression<Y> all(Subquery<Y> subquery) {
@@ -988,30 +1028,6 @@ public class CriteriaBuilderImpl implements 
OpenJPACriteriaBuilder, ExpressionPa
         return new ComparisonStyle.Default();
     }
 
-    @Override
-    public <N extends Number> Expression<N> ceiling(Expression<N> x) {
-        // TODO Implement ceiling op
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Expression<Double> exp(Expression<? extends Number> x) {
-        // TODO Implement exp op
-        throw new UnsupportedAddressTypeException();
-    }
-
-    @Override
-    public <N extends Number> Expression<N> floor(Expression<N> x) {
-        // TODO Implement floor op
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Expression<Double> ln(Expression<? extends Number> x) {
-        // TODO Implement ln op
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public Expression<LocalDate> localDate() {
         // TODO Implement localDate
@@ -1030,27 +1046,4 @@ public class CriteriaBuilderImpl implements 
OpenJPACriteriaBuilder, ExpressionPa
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public Expression<Double> power(Expression<? extends Number> x, Number y) {
-        // TODO Implement power op
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Expression<Double> power(Expression<? extends Number> x, 
Expression<? extends Number> y) {
-        // TODO Implement power op
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public <T extends Number> Expression<T> round(Expression<T> x, Integer n) {
-        // TODO Implement round op
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Expression<Integer> sign(Expression<? extends Number> x) {
-        // TODO Implement sign op
-        throw new UnsupportedOperationException();
-    }
 }
diff --git 
a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
 
b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
index f7ca4633b..e8502a5b0 100644
--- 
a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
+++ 
b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
@@ -298,6 +298,139 @@ class Expressions {
         }
     }
 
+    public static class Ceiling<X> extends UnaryFunctionalExpression<X> {
+        public  Ceiling(Expression<X> x) {
+            super(x);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.ceiling(Expressions.toValue(e, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "CEILING", OPEN_BRACE, e, 
CLOSE_BRACE);
+        }
+    }
+
+    public static class Exponential extends UnaryFunctionalExpression<Double> {
+        public  Exponential(Expression<? extends Number> x) {
+            super(Double.class, x);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.exp(Expressions.toValue(e, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "EXP", OPEN_BRACE, e, CLOSE_BRACE);
+        }
+    }
+
+    public static class Floor<X> extends UnaryFunctionalExpression<X> {
+        public  Floor(Expression<X> x) {
+            super(x);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.floor(Expressions.toValue(e, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "FLOOR", OPEN_BRACE, e, CLOSE_BRACE);
+        }
+    }
+
+    public static class NaturalLogarithm extends 
UnaryFunctionalExpression<Double> {
+        public  NaturalLogarithm(Expression<? extends Number> x) {
+            super(Double.class, x);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.ln(Expressions.toValue(e, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "LN", OPEN_BRACE, e, CLOSE_BRACE);
+        }
+    }
+
+    public static class Sign extends UnaryFunctionalExpression<Integer> {
+        public  Sign(Expression<? extends Number> x) {
+            super(Integer.class, x);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.sign(Expressions.toValue(e, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "SIGN", OPEN_BRACE, e, CLOSE_BRACE);
+        }
+    }
+
+    public static class Power<X, Y extends Number> extends 
BinarayFunctionalExpression<Double> {
+        public Power(Expression<X> x, Expression<Y> y) {
+            super(double.class, x, y);
+        }
+        public Power(Expression<X> x, Y y) {
+            this(x,new Constant<>(y));
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.power(
+                Expressions.toValue(e1, factory, q),
+                Expressions.toValue(e2, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "POWER", OPEN_BRACE, e1, COMMA, e2, 
CLOSE_BRACE);
+        }
+    }
+
+    public static class Round<X> extends BinarayFunctionalExpression<X> {
+        public Round(Expression<?> x, Expression<?> y) {
+            super(((Class<X>) x.getJavaType()), x, y);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> 
q) {
+            Value value = factory.round(
+                Expressions.toValue(e1, factory, q), 
+                Expressions.toValue(e2, factory, q));
+            value.setImplicitType(getJavaType());
+            return value;
+        }
+
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "ROUND", OPEN_BRACE, e1, COMMA, e2, 
CLOSE_BRACE);
+        }
+    }
+
     public static class Count extends UnaryFunctionalExpression<Long> {
         private boolean _distinct;
         public  Count(Expression<?> x) {
diff --git a/openjpa-project/src/doc/manual/jpa_overview_query.xml 
b/openjpa-project/src/doc/manual/jpa_overview_query.xml
index c338634b6..f681f7374 100644
--- a/openjpa-project/src/doc/manual/jpa_overview_query.xml
+++ b/openjpa-project/src/doc/manual/jpa_overview_query.xml
@@ -565,6 +565,64 @@ SELECT x FROM Magazine x WHERE LOCATE('D', x.title) = 2
                     </para>
 <programlisting>
 SELECT x FROM Magazine x WHERE ABS(x.price) &gt;= 5.00
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            CEILING function
+                        </primary>
+                    </indexterm>
+
+<literal>CEILING(number)</literal>: Returns the smallest (closest to negative 
infinity)
+ value that is greater than or equal to the argument and is equal to a 
mathematical integer.
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE CEILING(x.price) &gt;= 10
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            EXP function
+                        </primary>
+                    </indexterm>
+
+<literal>EXP(number)</literal>: Returns the Euler's number 
<literal>e</literal> raised to the power of a value.
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE EXP(x.price) &gt;= 10
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            FLOOR function
+                        </primary>
+                    </indexterm>
+
+<literal>FLOOR(number)</literal>: Returns the largest (closest to positive 
infinity)
+ value that is less than or equal to the argument and is equal to a 
mathematical integer.
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE FLOOR(x.price) &gt;= 10
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            LN function
+                        </primary>
+                    </indexterm>
+
+<literal>LN(number)</literal>: Returns the natural logarithm (base 
<litera>e</literal>) of a value.
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE LN(x.price) &gt;= 10
 </programlisting>
                 </listitem>
                 <listitem>
@@ -574,6 +632,7 @@ SELECT x FROM Magazine x WHERE ABS(x.price) &gt;= 5.00
                             SQRT function
                         </primary>
                     </indexterm>
+
 <literal>SQRT(number)</literal>: Returns the square root of the argument.
                     </para>
 <programlisting>
@@ -592,6 +651,48 @@ SELECT x FROM Magazine x WHERE SQRT(x.price) &gt;= 1.00
                     </para>
 <programlisting>
 SELECT x FROM Magazine x WHERE MOD(x.price, 10) = 0
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            POWER function
+                        </primary>
+                    </indexterm>
+
+<literal>POWER(base, exponent)</literal>: Returns the value of the first 
argument raised to the power of the second argument.
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE POWER(x.price, 2) &gt;= 10
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            ROUND function
+                        </primary>
+                    </indexterm>
+
+<literal>ROUND(number, precision)</literal>: Rounds the number to given 
precision.
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE ROUND(x.price, 2) &gt;= 10
+</programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                    <indexterm>
+                        <primary>
+                            SIGN function
+                        </primary>
+                    </indexterm>
+
+<literal>SIGN(number)</literal>: Returns the sign (-1, 0, 1) of a number
+                    </para>
+<programlisting>
+SELECT x FROM Magazine x WHERE SIGN(x.price) &gt;= 0
 </programlisting>
                 </listitem>
                 <listitem>
@@ -3365,6 +3466,13 @@ that represents the string position at which the search 
is started (by default,
 the beginning of the string to be searched). The first position in a string is
 denoted by 1. If the string is not found, 0 is returned.
                      </para>
+                    <para>
+Note that not all databases support the use of a trim character other than the
+space character; use of this argument may result in queries that are not
+portable. Note that not all databases support the use of the third argument to
+<literal>LOCATE</literal>; use of this argument may result in queries that are
+not portable.
+                    </para>
                      <para>
 The <literal>LENGTH
 </literal> function returns the length of the string in characters as an
@@ -3378,33 +3486,48 @@ integer.
                     <para>
 <itemizedlist><listitem><para>functions_returning_numerics ::=
 ABS(simple_arithmetic_expression) |
+CEILING(arithmetic_expression) |
+EXP(arithmetic_expression) |
+FLOOR(arithmetic_expression) |
+LN(arithmetic_expression) |
+POWER(arithmetic_expression, arithmetic_expression) |
+ROUND(arithmetic_expression, arithmetic_expression) |
+SIGN(arithmetic_expression) |
 SQRT(simple_arithmetic_expression) |
 MOD(simple_arithmetic_expression, simple_arithmetic_expression) |
 SIZE(collection_valued_path_expression) |
-INDEX(identification_variable)
+INDEX(identification_variable) |
+extract_datetime_field
                                 </para>
                             </listitem>
                         </itemizedlist>
                     </para>
                     <para>
-The <literal>ABS</literal> function takes a numeric argument and returns a
-number (integer, float, or double) of the same type as the argument to the
-function.
+The <literal>ABS</literal>, <literal>CEILING</literal> and 
<literal>FLOOR</literal> functions 
+accept a numeric argument and return a number (integer, float, or double) of 
the same type as 
+the argument.
                     </para>
                     <para>
-The <literal>SQRT</literal> function takes a numeric argument and
-returns a double.
+The <literal>SIGN</literal> function accepts a numeric argument and
+returns an integer.
                     </para>
                     <para>
-Note that not all databases support the use of a trim character other than the
-space character; use of this argument may result in queries that are not
-portable. Note that not all databases support the use of the third argument to
-<literal>LOCATE</literal>; use of this argument may result in queries that are
-not portable.
+The <literal>SQRT</literal>, <literal>EXP</literal> and <literal>LN</literal> 
functions accept 
+a numeric argument and return a double.
                     </para>
                     <para>
-The <literal>MOD</literal> function takes two integer arguments and returns an
-integer.
+The <literal>MOD</literal> function takes two integer arguments and returns an 
integer.
+                    </para>
+                    <para>
+The <literal>ROUND</literal> function accepts a numeric argument and an 
integer argument and 
+returns a number of the same type as the first argument.
+                    </para>
+                    <para>
+The <literal>POWER<literal> function accepts two numeric arguments and returns 
a double.
+                    </para>
+                    <para>
+Numeric arguments to these functions may correspond to the numeric Java object 
types as well
+as the primitive numeric types.
                     </para>
                     <para>
 The <literal>SIZE</literal> function returns an integer value, the

Reply via email to