Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OPENJPA-2932] Implements numeric JPA 3.1 JPQL functions and equivalent Criteria API #122

Merged
merged 6 commits into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,9 @@ else if (op.equals(
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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}

Original file line number Diff line number Diff line change
@@ -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;
}
}

Original file line number Diff line number Diff line change
@@ -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;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,41 @@ public Value mod(Value v1, Value v2) {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}

Original file line number Diff line number Diff line change
@@ -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;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3181,20 +3181,23 @@ public void mathFunction(SQLBuffer buf, String op, FilterValue lhs,
}

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)
appendCast(buf, lhs, type);
else
lhs.appendTo(buf);

if (mod && !supportsModOperator)
if ((mod && !supportsModOperator) || power || round)
buf.append(", ");
else
buf.append(" ").append(op).append(" ");
Expand Down
Loading