org.eclipse.persistence.internal.expressions.ExtractOperator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* 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
*/
// Contributors:
// 07/29/2022-4.0.0 Tomas Kraus - 1573: Fixed types returned by JPQL EXTRACT()
package org.eclipse.persistence.internal.expressions;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.helper.ClassConstants;
/**
* Expression operator customization for {@code EXTRACT( FROM )}.
* Contains support for platform specific native SQL override for individual {@code }
* values.
*/
public class ExtractOperator extends ExpressionOperator {
// Default native database Strings to be printed for EXTRACT expression
private static List defaultDbStrings() {
final List dbStrings = new ArrayList<>(5);
dbStrings.add("EXTRACT(");
dbStrings.add(" FROM ");
dbStrings.add(")");
return dbStrings;
}
/**
* Creates an instance of {@link ExtractOperator} expression.
* Default native database Strings are set for EXTRACT expression.
*/
public ExtractOperator() {
this(defaultDbStrings());
}
/**
* Creates an instance of {@link ExtractOperator} expression.
* Custom native database Strings are set for EXTRACT expression.
*
* @param dbStrings native database Strings
*/
protected ExtractOperator(List dbStrings) {
this.setType(ExpressionOperator.FunctionOperator);
this.setSelector(ExpressionOperator.Extract);
this.setName("EXTRACT");
this.printsAs(dbStrings);
this.setArgumentIndices(new int[] {1, 0});
this.bePrefix();
this.setNodeClass(ClassConstants.FunctionExpression_Class);
}
/**
* Default SQL printer for {@code EXTRACT( FROM )}.
* It expects 2 arguments (first, second), argument indices array of size 2
* and 3 database Strings (prefix, arguments separator and suffix).
* Indices swap first and second expression order by default.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
private void printPartSql(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
if (printer.getPlatform().isDynamicSQLRequiredForFunctions() && Boolean.FALSE.equals(isBindingSupported())) {
printer.getCall().setUsesBinding(false);
}
final int[] indices = getArgumentIndices(2);
final String[] dbString = getDatabaseStrings();
int dbStringPos = 0;
// Print 1st database String (prefix) if defined
if (isPrefix() && dbString.length > dbStringPos) {
printer.printString(dbString[dbStringPos++]);
}
// Print first or second argument depending on indices
if (indices[0] == 0) {
first.printSQL(printer);
}
if (indices[0] == 1) {
second.printSQL(printer);
}
// Print 2nd database String (arguments separator) if defined
if (dbString.length > dbStringPos) {
printer.printString(dbString[dbStringPos++]);
}
// Print first or second argument depending on indices
if (indices[1] == 0) {
first.printSQL(printer);
}
if (indices[1] == 1) {
second.printSQL(printer);
}
// Print 3rd database String (suffix) if defined
if (dbString.length > dbStringPos) {
printer.printString(dbString[dbStringPos]);
}
}
/**
* Printer for YEAR ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printYearSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for QUARTER ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printQuarterSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for MONTH ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printMonthSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for WEEK ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printWeekSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for DAY ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printDaySQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for HOUR ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printHourSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for MINUTE ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printMinuteSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
/**
* Printer for SECOND ({@code } argument.
* This method shall be overriden to implement platform specific SQL printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printSecondSQL(final Expression first, Expression second, final ExpressionSQLPrinter printer) {
printPartSql(first, second, printer);
}
@Override
public void printDuo(Expression first, Expression second, ExpressionSQLPrinter printer) {
if (second instanceof LiteralExpression) {
switch (((LiteralExpression) second).getValue().toUpperCase()) {
case "YEAR":
printYearSQL(first, second, printer);
return;
case "QUARTER":
printQuarterSQL(first, second, printer);
return;
case "MONTH":
printMonthSQL(first, second, printer);
return;
case "WEEK":
printWeekSQL(first, second, printer);
return;
case "DAY":
printDaySQL(first, second, printer);
return;
case "HOUR":
printHourSQL(first, second, printer);
return;
case "MINUTE":
printMinuteSQL(first, second, printer);
return;
case "SECOND":
printSecondSQL(first, second, printer);
return;
default:
throw new IllegalArgumentException("Unknown EXTRACT function datetime_field: "
+ ((LiteralExpression) second).getValue().toUpperCase());
}
}
super.printDuo(first, second, printer);
}
@Override
public void printCollection(List items, ExpressionSQLPrinter printer) {
if (items.size() == 2) {
final Expression second = items.get(1);
if (second instanceof LiteralExpression) {
switch (((LiteralExpression) second).getValue().toUpperCase()) {
case "YEAR":
printYearSQL(items.get(0), second, printer);
return;
case "QUARTER":
printQuarterSQL(items.get(0), second, printer);
return;
case "MONTH":
printMonthSQL(items.get(0), second, printer);
return;
case "WEEK":
printWeekSQL(items.get(0), second, printer);
return;
case "DAY":
printDaySQL(items.get(0), second, printer);
return;
case "HOUR":
printHourSQL(items.get(0), second, printer);
return;
case "MINUTE":
printMinuteSQL(items.get(0), second, printer);
return;
case "SECOND":
printSecondSQL(items.get(0), second, printer);
return;
default:
throw new IllegalArgumentException("Unknown EXTRACT function datetime_field: "
+ ((LiteralExpression) second).getValue().toUpperCase());
}
}
}
super.printCollection(items, printer);
}
/**
* Default Java printer for {@code EXTRACT( FROM )}.
* It expects 2 arguments (first, second), argument indices array of size 2
* and 3 database Strings (prefix, arguments separator and suffix).
* Indices swap first and second expression order by default.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
private void printPartJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
final int[] indices = getArgumentIndices(2);
final String[] dbString = getDatabaseStrings();
// Print prefix from database Strings
if (isPrefix()) {
printer.printString(dbString[0]);
}
// Print first or second argument depending on indices
if (indices[0] == 0) {
first.printJava(printer);
}
if (indices[0] == 1) {
second.printJava(printer);
}
// Print 2nd database String if defined
if (dbString.length > 1) {
printer.printString(dbString[1]);
}
// Print first or second argument depending on indices
if (indices[1] == 0) {
first.printJava(printer);
}
if (indices[1] == 1) {
second.printJava(printer);
}
// Print 3rd database String if defined
if (dbString.length > 2) {
printer.printString(dbString[2]);
}
}
/**
* Printer for YEAR ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printYearJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for QUARTER ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printQuarterJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for MONTH ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printMonthJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for WEEK ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printWeekJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for DAY ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printDayJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for HOUR ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printHourJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for MINUTE ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printMinuteJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
/**
* Printer for SECOND ({@code } argument.
* This method shall be overriden to implement platform specific Java printer.
*
* @param first first expression ({@code } argument)
* @param second second expression ({@code } argument)
* @param printer target printer
*/
protected void printSecondJava(final Expression first, Expression second, final ExpressionJavaPrinter printer) {
printPartJava(first, second, printer);
}
@Override
public void printJavaDuo(Expression first, Expression second, ExpressionJavaPrinter printer) {
if (second instanceof LiteralExpression) {
switch (((LiteralExpression) second).getValue().toUpperCase()) {
case "YEAR":
printYearJava(first, second, printer);
return;
case "QUARTER":
printQuarterJava(first, second, printer);
return;
case "MONTH":
printMonthJava(first, second, printer);
return;
case "WEEK":
printWeekJava(first, second, printer);
return;
case "DAY":
printDayJava(first, second, printer);
return;
case "HOUR":
printHourJava(first, second, printer);
return;
case "MINUTE":
printMinuteJava(first, second, printer);
return;
case "SECOND":
printSecondJava(first, second, printer);
return;
default:
throw new IllegalArgumentException("Unknown EXTRACT function datetime_field: "
+ ((LiteralExpression) second).getValue().toUpperCase());
}
}
super.printJavaDuo(first, second, printer);
}
@Override
public void printJavaCollection(List items, ExpressionJavaPrinter printer) {
if (items.size() == 2) {
final Expression second = items.get(1);
if (second instanceof LiteralExpression) {
switch (((LiteralExpression) second).getValue().toUpperCase()) {
case "YEAR":
printYearJava(items.get(0), second, printer);
return;
case "QUARTER":
printQuarterJava(items.get(0), second, printer);
return;
case "MONTH":
printMonthJava(items.get(0), second, printer);
return;
case "WEEK":
printWeekJava(items.get(0), second, printer);
return;
case "DAY":
printDayJava(items.get(0), second, printer);
return;
case "HOUR":
printHourJava(items.get(0), second, printer);
return;
case "MINUTE":
printMinuteJava(items.get(0), second, printer);
return;
case "SECOND":
printSecondJava(items.get(0), second, printer);
return;
default:
throw new IllegalArgumentException("Unknown EXTRACT function datetime_field: "
+ ((LiteralExpression) second).getValue().toUpperCase());
}
}
}
super.printJavaCollection(items, printer);
}
}