/******************************************************************************* | |
* Copyright (c) 1998, 2018 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
* Markus Karg - allow arguments to be specified multiple times in argumentIndices | |
* 05/07/2009-1.1.1 Dave Brosius | |
* - 263904: [PATCH] ExpressionOperator doesn't compare arrays correctly | |
* 01/23/2018-2.6 Will Dazey | |
* - 530214: trim operation should not bind parameters | |
******************************************************************************/ | |
package org.eclipse.persistence.expressions; | |
import java.security.AccessController; | |
import java.security.PrivilegedActionException; | |
import java.util.*; | |
import java.io.*; | |
import org.eclipse.persistence.internal.expressions.*; | |
import org.eclipse.persistence.internal.helper.*; | |
import org.eclipse.persistence.exceptions.*; | |
import org.eclipse.persistence.internal.helper.ClassConstants; | |
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; | |
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass; | |
/** | |
* <p> | |
* <b>Purpose</b>: ADVANCED: The expression operator is used internally to define SQL operations and functions. | |
* It is possible for an advanced user to define their own operators. | |
*/ | |
public class ExpressionOperator implements Serializable { | |
/** Required for serialization compatibility. */ | |
static final long serialVersionUID = -7066100204792043980L; | |
protected int selector; | |
protected String name; | |
protected String[] databaseStrings; | |
protected boolean isPrefix = false; | |
protected boolean isRepeating = false; | |
protected Class nodeClass; | |
protected int type; | |
protected int[] argumentIndices = null; | |
protected static Map<Integer, ExpressionOperator> allOperators = initializeOperators(); | |
protected static Map<String, Integer> platformOperatorSelectors = initializePlatformOperatorSelectors(); | |
protected static Map<Integer, String> platformOperatorNames = initializePlatformOperatorNames(); | |
protected String[] javaStrings; | |
/** Allow operator to disable binding. */ | |
protected boolean isBindingSupported = true; | |
/** Operator types */ | |
public static final int LogicalOperator = 1; | |
public static final int ComparisonOperator = 2; | |
public static final int AggregateOperator = 3; | |
public static final int OrderOperator = 4; | |
public static final int FunctionOperator = 5; | |
/** Logical operators */ | |
public static final int And = 1; | |
public static final int Or = 2; | |
public static final int Not = 3; | |
/** Comparison operators */ | |
public static final int Equal = 4; | |
public static final int NotEqual = 5; | |
public static final int EqualOuterJoin = 6; | |
public static final int LessThan = 7; | |
public static final int LessThanEqual = 8; | |
public static final int GreaterThan = 9; | |
public static final int GreaterThanEqual = 10; | |
public static final int Like = 11; | |
public static final int NotLike = 12; | |
public static final int In = 13; | |
public static final int InSubQuery = 129; | |
public static final int NotIn = 14; | |
public static final int NotInSubQuery = 130; | |
public static final int Between = 15; | |
public static final int NotBetween = 16; | |
public static final int IsNull = 17; | |
public static final int NotNull = 18; | |
public static final int Exists = 86; | |
public static final int NotExists = 88; | |
public static final int LikeEscape = 89; | |
public static final int NotLikeEscape = 134; | |
public static final int Decode = 105; | |
public static final int Case = 117; | |
public static final int NullIf = 131; | |
public static final int Coalesce = 132; | |
public static final int CaseCondition = 136; | |
public static final int Regexp = 141; | |
/** Aggregate operators */ | |
public static final int Count = 19; | |
public static final int Sum = 20; | |
public static final int Average = 21; | |
public static final int Maximum = 22; | |
public static final int Minimum = 23; | |
public static final int StandardDeviation = 24; | |
public static final int Variance = 25; | |
public static final int Distinct = 87; | |
public static final int As = 148; | |
/** Union operators */ | |
public static final int Union = 142; | |
public static final int UnionAll = 143; | |
public static final int Intersect = 144; | |
public static final int IntersectAll = 145; | |
public static final int Except = 146; | |
public static final int ExceptAll = 147; | |
/** Ordering operators */ | |
public static final int Ascending = 26; | |
public static final int Descending = 27; | |
public static final int NullsFirst = 139; | |
public static final int NullsLast = 140; | |
/** Function operators */ | |
// General | |
public static final int ToUpperCase = 28; | |
public static final int ToLowerCase = 29; | |
public static final int Chr = 30; | |
public static final int Concat = 31; | |
public static final int HexToRaw = 32; | |
public static final int Initcap = 33; | |
public static final int Instring = 34; | |
public static final int Soundex = 35; | |
public static final int LeftPad = 36; | |
public static final int LeftTrim = 37; | |
public static final int Replace = 38; | |
public static final int RightPad = 39; | |
public static final int RightTrim = 40; | |
public static final int Substring = 41; | |
public static final int ToNumber = 42; | |
public static final int Translate = 43; | |
public static final int Trim = 44; | |
public static final int Ascii = 45; | |
public static final int Length = 46; | |
public static final int CharIndex = 96; | |
public static final int CharLength = 97; | |
public static final int Difference = 98; | |
public static final int Reverse = 99; | |
public static final int Replicate = 100; | |
public static final int Right = 101; | |
public static final int Locate = 112; | |
public static final int Locate2 = 113; | |
public static final int ToChar = 114; | |
public static final int ToCharWithFormat = 115; | |
public static final int RightTrim2 = 116; | |
public static final int Any = 118; | |
public static final int Some = 119; | |
public static final int All = 120; | |
public static final int Trim2 = 121; | |
public static final int LeftTrim2 = 122; | |
public static final int SubstringSingleArg = 133; | |
public static final int Cast = 137; | |
public static final int Extract = 138; | |
// Date | |
public static final int AddMonths = 47; | |
public static final int DateToString = 48; | |
public static final int LastDay = 49; | |
public static final int MonthsBetween = 50; | |
public static final int NextDay = 51; | |
public static final int RoundDate = 52; | |
public static final int ToDate = 53; | |
/** | |
* Function to obtain the current timestamp on the database including date | |
* and time components. This corresponds to the JPQL function | |
* current_timestamp. | |
*/ | |
public static final int Today = 54; | |
public static final int AddDate = 90; | |
public static final int DateName = 92; | |
public static final int DatePart = 93; | |
public static final int DateDifference = 94; | |
public static final int TruncateDate = 102; | |
public static final int NewTime = 103; | |
public static final int Nvl = 104; | |
/** | |
* Function to obtain the current date on the database with date components | |
* only but without time components. This corresponds to the JPQL function | |
* current_date. | |
*/ | |
public static final int CurrentDate = 123; | |
/** | |
* Function to obtain the current time on the database with time components | |
* only but without date components. This corresponds to the JPQL function | |
* current_time. | |
*/ | |
public static final int CurrentTime = 128; | |
// Math | |
public static final int Ceil = 55; | |
public static final int Cos = 56; | |
public static final int Cosh = 57; | |
public static final int Abs = 58; | |
public static final int Acos = 59; | |
public static final int Asin = 60; | |
public static final int Atan = 61; | |
public static final int Exp = 62; | |
public static final int Sqrt = 63; | |
public static final int Floor = 64; | |
public static final int Ln = 65; | |
public static final int Log = 66; | |
public static final int Mod = 67; | |
public static final int Power = 68; | |
public static final int Round = 69; | |
public static final int Sign = 70; | |
public static final int Sin = 71; | |
public static final int Sinh = 72; | |
public static final int Tan = 73; | |
public static final int Tanh = 74; | |
public static final int Trunc = 75; | |
public static final int Greatest = 76; | |
public static final int Least = 77; | |
public static final int Add = 78; | |
public static final int Subtract = 79; | |
public static final int Divide = 80; | |
public static final int Multiply = 81; | |
public static final int Atan2 = 91; | |
public static final int Cot = 95; | |
public static final int Negate = 135; | |
// Object-relational | |
public static final int Deref = 82; | |
public static final int Ref = 83; | |
public static final int RefToHex = 84; | |
public static final int Value = 85; | |
//XML Specific | |
public static final int ExtractXml = 106; | |
public static final int ExtractValue = 107; | |
public static final int ExistsNode = 108; | |
public static final int GetStringVal = 109; | |
public static final int GetNumberVal = 110; | |
public static final int IsFragment = 111; | |
// Spatial | |
public static final int SDO_WITHIN_DISTANCE = 124; | |
public static final int SDO_RELATE = 125; | |
public static final int SDO_FILTER = 126; | |
public static final int SDO_NN = 127; | |
/** | |
* ADVANCED: | |
* Create a new operator. | |
*/ | |
public ExpressionOperator() { | |
this.type = FunctionOperator; | |
// For bug 2780072 provide default behavior to make this class more useable. | |
setNodeClass(ClassConstants.FunctionExpression_Class); | |
} | |
/** | |
* ADVANCED: | |
* Create a new operator with the given name(s) and strings to print. | |
*/ | |
public ExpressionOperator(int selector, Vector newDatabaseStrings) { | |
this.type = FunctionOperator; | |
// For bug 2780072 provide default behavior to make this class more useable. | |
setNodeClass(ClassConstants.FunctionExpression_Class); | |
this.selector = selector; | |
this.printsAs(newDatabaseStrings); | |
} | |
/** | |
* PUBLIC: | |
* Return if binding is compatible with this operator. | |
*/ | |
public boolean isBindingSupported() { | |
return isBindingSupported; | |
} | |
/** | |
* PUBLIC: | |
* Set if binding is compatible with this operator. | |
* Some databases do not allow binding, or require casting with certain operators. | |
*/ | |
public void setIsBindingSupported(boolean isBindingSupported) { | |
this.isBindingSupported = isBindingSupported; | |
} | |
/** | |
* INTERNAL: | |
* Return if the operator is equal to the other. | |
*/ | |
public boolean equals(Object object) { | |
if (this == object) { | |
return true; | |
} | |
if ((object == null) || (getClass() != object.getClass())) { | |
return false; | |
} | |
ExpressionOperator operator = (ExpressionOperator) object; | |
if (getSelector() == 0) { | |
return Arrays.equals(getDatabaseStrings(), operator.getDatabaseStrings()); | |
} else { | |
return getSelector() == operator.getSelector(); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Return the hash-code based on the unique selector. | |
*/ | |
public int hashCode() { | |
return getSelector(); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator abs() { | |
return simpleFunction(Abs, "ABS"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator acos() { | |
return simpleFunction(Acos, "ACOS"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator addDate() { | |
ExpressionOperator exOperator = simpleThreeArgumentFunction(AddDate, "DATEADD"); | |
int[] indices = new int[3]; | |
indices[0] = 1; | |
indices[1] = 2; | |
indices[2] = 0; | |
exOperator.setArgumentIndices(indices); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator addMonths() { | |
return simpleTwoArgumentFunction(AddMonths, "ADD_MONTHS"); | |
} | |
/** | |
* ADVANCED: | |
* Add an operator to the global list of operators. | |
*/ | |
public static void addOperator(ExpressionOperator exOperator) { | |
allOperators.put(Integer.valueOf(exOperator.getSelector()), exOperator); | |
} | |
/** | |
* ADVANCED: | |
* Define a name for a user defined operator. | |
*/ | |
public static void registerOperator(int selector, String name) { | |
platformOperatorNames.put(selector, name); | |
platformOperatorSelectors.put(name, selector); | |
} | |
/** | |
* INTERNAL: | |
* Create the AND operator. | |
*/ | |
public static ExpressionOperator and() { | |
return simpleLogical(And, "AND", "and"); | |
} | |
/** | |
* INTERNAL: | |
* Apply this to an object in memory. | |
* Throw an error if the function is not supported. | |
*/ | |
public Object applyFunction(Object source, Vector arguments) { | |
if (source instanceof String) { | |
if (this.selector == ToUpperCase) { | |
return ((String)source).toUpperCase(); | |
} else if (this.selector == ToLowerCase) { | |
return ((String)source).toLowerCase(); | |
} else if ((this.selector == Concat) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof String)) { | |
return ((String)source).concat((String)arguments.elementAt(0)); | |
} else if ((this.selector == Substring) && (arguments.size() == 2) && (arguments.elementAt(0) instanceof Number) && (arguments.elementAt(1) instanceof Number)) { | |
// assume the first parameter to be 1-based first index of the substring, the second - substring length. | |
int beginIndexInclusive = ((Number)arguments.elementAt(0)).intValue() - 1; | |
int endIndexExclusive = beginIndexInclusive + ((Number)arguments.elementAt(1)).intValue(); | |
return ((String)source).substring(beginIndexInclusive, endIndexExclusive); | |
} else if ((this.selector == SubstringSingleArg) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
int beginIndexInclusive = ((Number)arguments.elementAt(0)).intValue() - 1; | |
int endIndexExclusive = ((String)source).length(); | |
return ((String)source).substring(beginIndexInclusive, endIndexExclusive); | |
} else if (this.selector == ToNumber) { | |
return new java.math.BigDecimal((String)source); | |
} else if (this.selector == Trim) { | |
return ((String)source).trim(); | |
} else if (this.selector == Length) { | |
return Integer.valueOf(((String)source).length()); | |
} | |
} else if (source instanceof Number) { | |
if (this.selector == Ceil) { | |
return Double.valueOf(Math.ceil(((Number)source).doubleValue())); | |
} else if (this.selector == Cos) { | |
return Double.valueOf(Math.cos(((Number)source).doubleValue())); | |
} else if (this.selector == Abs) { | |
return Double.valueOf(Math.abs(((Number)source).doubleValue())); | |
} else if (this.selector == Acos) { | |
return Double.valueOf(Math.acos(((Number)source).doubleValue())); | |
} else if (this.selector == Asin) { | |
return Double.valueOf(Math.asin(((Number)source).doubleValue())); | |
} else if (this.selector == Atan) { | |
return Double.valueOf(Math.atan(((Number)source).doubleValue())); | |
} else if (this.selector == Exp) { | |
return Double.valueOf(Math.exp(((Number)source).doubleValue())); | |
} else if (this.selector == Sqrt) { | |
return Double.valueOf(Math.sqrt(((Number)source).doubleValue())); | |
} else if (this.selector == Floor) { | |
return Double.valueOf(Math.floor(((Number)source).doubleValue())); | |
} else if (this.selector == Log) { | |
return Double.valueOf(Math.log(((Number)source).doubleValue())); | |
} else if ((this.selector == Power) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(Math.pow(((Number)source).doubleValue(), (((Number)arguments.elementAt(0)).doubleValue()))); | |
} else if (this.selector == Round) { | |
return Double.valueOf(Math.round(((Number)source).doubleValue())); | |
} else if (this.selector == Sin) { | |
return Double.valueOf(Math.sin(((Number)source).doubleValue())); | |
} else if (this.selector == Tan) { | |
return Double.valueOf(Math.tan(((Number)source).doubleValue())); | |
} else if ((this.selector == Greatest) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(Math.max(((Number)source).doubleValue(), (((Number)arguments.elementAt(0)).doubleValue()))); | |
} else if ((this.selector == Least) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(Math.min(((Number)source).doubleValue(), (((Number)arguments.elementAt(0)).doubleValue()))); | |
} else if ((this.selector == Add) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(((Number)source).doubleValue() + (((Number)arguments.elementAt(0)).doubleValue())); | |
} else if ((this.selector == Subtract) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(((Number)source).doubleValue() - (((Number)arguments.elementAt(0)).doubleValue())); | |
} else if ((this.selector == Divide) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(((Number)source).doubleValue() / (((Number)arguments.elementAt(0)).doubleValue())); | |
} else if ((this.selector == Multiply) && (arguments.size() == 1) && (arguments.elementAt(0) instanceof Number)) { | |
return Double.valueOf(((Number)source).doubleValue() * (((Number)arguments.elementAt(0)).doubleValue())); | |
} | |
} | |
throw QueryException.cannotConformExpression(); | |
} | |
/** | |
* INTERNAL: | |
* Create the ASCENDING operator. | |
*/ | |
public static ExpressionOperator ascending() { | |
return simpleOrdering(Ascending, "ASC", "ascending"); | |
} | |
/** | |
* INTERNAL: | |
* Create the AS operator. | |
*/ | |
public static ExpressionOperator as() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(As); | |
exOperator.printsAs(" AS "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the NULLS FIRST ordering operator. | |
*/ | |
public static ExpressionOperator nullsFirst() { | |
return simpleOrdering(NullsFirst, "NULLS FIRST", "nullsFirst"); | |
} | |
/** | |
* INTERNAL: | |
* Create the NULLS LAST ordering operator. | |
*/ | |
public static ExpressionOperator nullsLast() { | |
return simpleOrdering(NullsLast, "NULLS LAST", "nullsLast"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator ascii() { | |
return simpleFunction(Ascii, "ASCII"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator asin() { | |
return simpleFunction(Asin, "ASIN"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator atan() { | |
return simpleFunction(Atan, "ATAN"); | |
} | |
/** | |
* INTERNAL: | |
* Create the AVERAGE operator. | |
*/ | |
public static ExpressionOperator average() { | |
return simpleAggregate(Average, "AVG", "average"); | |
} | |
/** | |
* ADVANCED: | |
* Tell the operator to be postfix, i.e. its strings start printing after | |
* those of its first argument. | |
*/ | |
public void bePostfix() { | |
isPrefix = false; | |
} | |
/** | |
* ADVANCED: | |
* Tell the operator to be pretfix, i.e. its strings start printing before | |
* those of its first argument. | |
*/ | |
public void bePrefix() { | |
isPrefix = true; | |
} | |
/** | |
* INTERNAL: | |
* Make this a repeating argument. Currently unused. | |
*/ | |
public void beRepeating() { | |
isRepeating = true; | |
} | |
/** | |
* INTERNAL: | |
* Create the BETWEEN Operator | |
*/ | |
public static ExpressionOperator between() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(Between); | |
result.setType(ComparisonOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("("); | |
v.add(" BETWEEN "); | |
v.add(" AND "); | |
v.add(")"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
* Note: This operator works differently from other operators. | |
* @see Expression#caseStatement(Map, Object) | |
*/ | |
public static ExpressionOperator caseStatement() { | |
ListExpressionOperator exOperator = new ListExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Case); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.ArgumentListFunctionExpression_Class); | |
exOperator.setIsBindingSupported(false); | |
exOperator.setStartString("CASE "); | |
exOperator.setSeparators(new String[]{" WHEN ", " THEN "}); | |
exOperator.setTerminationStrings(new String[]{" ELSE ", " END"}); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
* Note: This operator works differently from other operators. | |
* @see Expression#caseStatement(Map, Object) | |
*/ | |
public static ExpressionOperator caseConditionStatement() { | |
ListExpressionOperator exOperator = new ListExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(CaseCondition); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.ArgumentListFunctionExpression_Class); | |
exOperator.setIsBindingSupported(false); | |
exOperator.setStartStrings(new String[]{"CASE WHEN ", " THEN "}); | |
exOperator.setSeparators(new String[]{" WHEN ", " THEN "}); | |
exOperator.setTerminationStrings(new String[]{" ELSE ", " END "}); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator ceil() { | |
return simpleFunction(Ceil, "CEIL"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator charIndex() { | |
return simpleTwoArgumentFunction(CharIndex, "CHARINDEX"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator charLength() { | |
return simpleFunction(CharLength, "CHAR_LENGTH"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator chr() { | |
return simpleFunction(Chr, "CHR"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
* Note: This operator works differently from other operators. | |
* @see Expression#caseStatement(Map, Object) | |
*/ | |
public static ExpressionOperator coalesce() { | |
ListExpressionOperator exOperator = new ListExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Coalesce); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.ArgumentListFunctionExpression_Class); | |
exOperator.setStartString("COALESCE("); | |
exOperator.setSeparator(","); | |
exOperator.setTerminationString(" )"); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator concat() { | |
ExpressionOperator operator = simpleMath(Concat, "+"); | |
operator.setIsBindingSupported(false); | |
return operator; | |
} | |
/** | |
* INTERNAL: | |
* Compare between in memory. | |
*/ | |
public boolean conformBetween(Object left, Object right) { | |
Object start = ((Vector)right).elementAt(0); | |
Object end = ((Vector)right).elementAt(1); | |
if ((left == null) || (start == null) || (end == null)) { | |
return false; | |
} | |
if ((left instanceof Number) && (start instanceof Number) && (end instanceof Number)) { | |
return ((((Number)left).doubleValue()) >= (((Number)start).doubleValue())) && ((((Number)left).doubleValue()) <= (((Number)end).doubleValue())); | |
} else if ((left instanceof String) && (start instanceof String) && (end instanceof String)) { | |
return ((((String)left).compareTo(((String)start)) > 0) || (((String)left).compareTo(((String)start)) == 0)) && ((((String)left).compareTo(((String)end)) < 0) || (((String)left).compareTo(((String)end)) == 0)); | |
} else if ((left instanceof java.util.Date) && (start instanceof java.util.Date) && (end instanceof java.util.Date)) { | |
return (((java.util.Date)left).after(((java.util.Date)start)) || ((java.util.Date)left).equals((start))) && (((java.util.Date)left).before(((java.util.Date)end)) || ((java.util.Date)left).equals((end))); | |
} else if ((left instanceof java.util.Calendar) && (start instanceof java.util.Calendar) && (end instanceof java.util.Calendar)) { | |
return (((java.util.Calendar)left).after(start) || ((java.util.Calendar)left).equals((start))) && (((java.util.Calendar)left).before(end) || ((java.util.Calendar)left).equals((end))); | |
} | |
throw QueryException.cannotConformExpression(); | |
} | |
/** | |
* INTERNAL: | |
* Compare like in memory. | |
* This only works for % not _. | |
* @author Christian Weeks aka ChristianLink | |
*/ | |
public boolean conformLike(Object left, Object right) { | |
if ((right == null) && (left == null)) { | |
return true; | |
} | |
if (!(right instanceof String) || !(left instanceof String)) { | |
throw QueryException.cannotConformExpression(); | |
} | |
String likeString = (String)right; | |
if (likeString.indexOf("_") != -1) { | |
throw QueryException.cannotConformExpression(); | |
} | |
String value = (String)left; | |
if (likeString.indexOf("%") == -1) { | |
// No % symbols | |
return left.equals(right); | |
} | |
boolean strictStart = !likeString.startsWith("%"); | |
boolean strictEnd = !likeString.endsWith("%"); | |
StringTokenizer tokens = new StringTokenizer(likeString, "%"); | |
int lastPosition = 0; | |
String lastToken = null; | |
if (strictStart) { | |
lastToken = tokens.nextToken(); | |
if (!value.startsWith(lastToken)) { | |
return false; | |
} | |
} | |
while (tokens.hasMoreTokens()) { | |
lastToken = tokens.nextToken(); | |
lastPosition = value.indexOf(lastToken, lastPosition); | |
if (lastPosition < 0) { | |
return false; | |
} | |
} | |
if (strictEnd) { | |
return value.endsWith(lastToken); | |
} | |
return true; | |
} | |
public void copyTo(ExpressionOperator operator){ | |
operator.selector = selector; | |
operator.isPrefix = isPrefix; | |
operator.isRepeating = isRepeating; | |
operator.nodeClass = nodeClass; | |
operator.type = type; | |
operator.databaseStrings = databaseStrings == null ? null : Helper.copyStringArray(databaseStrings); | |
operator.argumentIndices = argumentIndices == null ? null : Helper.copyIntArray(argumentIndices); | |
operator.javaStrings = javaStrings == null ? null : Helper.copyStringArray(javaStrings); | |
operator.isBindingSupported = isBindingSupported; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator cos() { | |
return simpleFunction(Cos, "COS"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator cosh() { | |
return simpleFunction(Cosh, "COSH"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator cot() { | |
return simpleFunction(Cot, "COT"); | |
} | |
/** | |
* INTERNAL: | |
* Create the COUNT operator. | |
*/ | |
public static ExpressionOperator count() { | |
return simpleAggregate(Count, "COUNT", "count"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator dateDifference() { | |
return simpleThreeArgumentFunction(DateDifference, "DATEDIFF"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator dateName() { | |
return simpleTwoArgumentFunction(DateName, "DATENAME"); | |
} | |
/** | |
* INTERNAL: | |
* Oracle equivalent to DATENAME is TO_CHAR. | |
*/ | |
public static ExpressionOperator oracleDateName() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(DateName); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(3); | |
v.add("TO_CHAR("); | |
v.add(", '"); | |
v.add("')"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
int[] indices = { 1, 0 }; | |
exOperator.setArgumentIndices(indices); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator datePart() { | |
return simpleTwoArgumentFunction(DatePart, "DATEPART"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator dateToString() { | |
return simpleFunction(DateToString, "TO_CHAR"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator toChar() { | |
return simpleFunction(ToChar, "TO_CHAR"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator toCharWithFormat() { | |
return simpleTwoArgumentFunction(ToCharWithFormat, "TO_CHAR"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
* Note: This operator works differently from other operators. | |
* @see Expression#decode(Map, String) | |
*/ | |
public static ExpressionOperator decode() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setSelector(Decode); | |
exOperator.setNodeClass(FunctionExpression.class); | |
exOperator.setType(FunctionOperator); | |
exOperator.bePrefix(); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator deref() { | |
return simpleFunction(Deref, "DEREF"); | |
} | |
/** | |
* INTERNAL: | |
* Create the DESCENDING operator. | |
*/ | |
public static ExpressionOperator descending() { | |
return simpleOrdering(Descending, "DESC", "descending"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator difference() { | |
return simpleTwoArgumentFunction(Difference, "DIFFERENCE"); | |
} | |
/** | |
* INTERNAL: | |
* Create the DISTINCT operator. | |
*/ | |
public static ExpressionOperator distinct() { | |
return simpleFunction(Distinct, "DISTINCT", "distinct"); | |
} | |
/** | |
* INTERNAL: | |
* Compare the values in memory. | |
* Used for in-memory querying, all operators are not support. | |
*/ | |
public boolean doesRelationConform(Object left, Object right) { | |
// Big ugly case statement follows. | |
// Java is really verbose, the Smalltalk equivalent to this... left perform: self selector with: right | |
// Note, compareTo for String returns a number <= -1 if the String is less than. We assumed that | |
// it would return -1. The same thing for strings that are greater than (ie it returns >= 1). PWK | |
// Equals | |
if (this.selector == Equal || this.selector == NotEqual) { | |
if ((left == null) && (right == null)) { | |
return this.selector == Equal; | |
} else if ((left == null) || (right == null)) { | |
return this.selector == NotEqual; | |
} | |
if (left instanceof Number && left instanceof Comparable && right instanceof Comparable | |
&& left.getClass().equals (right.getClass())) { | |
return (((Comparable) left).compareTo( (Comparable) right) == 0) == (this.selector == Equal); | |
} | |
if (((left instanceof Number) && (right instanceof Number)) && (left.getClass() != right.getClass())) { | |
double leftDouble = ((Number)left).doubleValue(); | |
double rightDouble = ((Number)right).doubleValue(); | |
if (Double.isNaN(leftDouble) && Double.isNaN(rightDouble)){ | |
return this.selector == Equal; | |
} | |
return (leftDouble == rightDouble) == (this.selector == Equal); | |
} | |
return left.equals( right) == (this.selector == Equal); | |
} else if (this.selector == IsNull) { | |
return (left == null); | |
} | |
if (this.selector == NotNull) { | |
return (left != null); | |
} | |
// Less thans, greater thans | |
else if (this.selector == LessThan) {// You have got to love polymorphism in Java, NOT!!! | |
if ((left == null) || (right == null)) { | |
return false; | |
} | |
if ((left instanceof Number) && (right instanceof Number)) { | |
return (((Number)left).doubleValue()) < (((Number)right).doubleValue()); | |
} else if ((left instanceof String) && (right instanceof String)) { | |
return ((String)left).compareTo(((String)right)) < 0; | |
} else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) { | |
return ((java.util.Date)left).before(((java.util.Date)right)); | |
} else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) { | |
return ((java.util.Calendar)left).before(right); | |
} | |
} else if (this.selector == LessThanEqual) { | |
if ((left == null) && (right == null)) { | |
return true; | |
} else if ((left == null) || (right == null)) { | |
return false; | |
} | |
if ((left instanceof Number) && (right instanceof Number)) { | |
return (((Number)left).doubleValue()) <= (((Number)right).doubleValue()); | |
} else if ((left instanceof String) && (right instanceof String)) { | |
int compareValue = ((String)left).compareTo(((String)right)); | |
return (compareValue < 0) || (compareValue == 0); | |
} else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) { | |
return ((java.util.Date)left).equals((right)) || ((java.util.Date)left).before(((java.util.Date)right)); | |
} else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) { | |
return ((java.util.Calendar)left).equals((right)) || ((java.util.Calendar)left).before(right); | |
} | |
} else if (this.selector == GreaterThan) { | |
if ((left == null) || (right == null)) { | |
return false; | |
} | |
if ((left instanceof Number) && (right instanceof Number)) { | |
return (((Number)left).doubleValue()) > (((Number)right).doubleValue()); | |
} else if ((left instanceof String) && (right instanceof String)) { | |
int compareValue = ((String)left).compareTo(((String)right)); | |
return (compareValue > 0); | |
} else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) { | |
return ((java.util.Date)left).after(((java.util.Date)right)); | |
} else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) { | |
return ((java.util.Calendar)left).after(right); | |
} | |
} else if (this.selector == GreaterThanEqual) { | |
if ((left == null) && (right == null)) { | |
return true; | |
} else if ((left == null) || (right == null)) { | |
return false; | |
} | |
if ((left instanceof Number) && (right instanceof Number)) { | |
return (((Number)left).doubleValue()) >= (((Number)right).doubleValue()); | |
} else if ((left instanceof String) && (right instanceof String)) { | |
int compareValue = ((String)left).compareTo(((String)right)); | |
return (compareValue > 0) || (compareValue == 0); | |
} else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) { | |
return ((java.util.Date)left).equals((right)) || ((java.util.Date)left).after(((java.util.Date)right)); | |
} else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) { | |
return ((java.util.Calendar)left).equals((right)) || ((java.util.Calendar)left).after(right); | |
} | |
} | |
// Between | |
else if ((this.selector == Between) && (right instanceof Vector) && (((Vector)right).size() == 2)) { | |
return conformBetween(left, right); | |
} else if ((this.selector == NotBetween) && (right instanceof Vector) && (((Vector)right).size() == 2)) { | |
return !conformBetween(left, right); | |
} | |
// In | |
else if ((this.selector == In) && (right instanceof Collection)) { | |
return ((Collection)right).contains(left); | |
} else if ((this.selector == NotIn) && (right instanceof Collection)) { | |
return !((Collection)right).contains(left); | |
} | |
// Like | |
//conformLike(left, right); | |
else if (((this.selector == Like) || (this.selector == NotLike)) && (right instanceof Vector) && (((Vector)right).size() == 1)) { | |
Boolean doesLikeConform = JavaPlatform.conformLike(left, ((Vector)right).get(0)); | |
if (doesLikeConform != null) { | |
if (doesLikeConform.booleanValue()) { | |
return this.selector == Like;// Negate for NotLike | |
} else { | |
return this.selector != Like;// Negate for NotLike | |
} | |
} | |
} | |
// Regexp | |
else if ((this.selector == Regexp) && (right instanceof Vector) && (((Vector)right).size() == 1)) { | |
Boolean doesConform = JavaPlatform.conformRegexp(left, ((Vector)right).get(0)); | |
if (doesConform != null) { | |
return doesConform.booleanValue(); | |
} | |
} | |
throw QueryException.cannotConformExpression(); | |
} | |
/** | |
* INTERNAL: | |
* Initialize the outer join operator | |
* Note: This is merely a shell which is incomplete, and | |
* so will be replaced by the platform's operator when we | |
* go to print. We need to create this here so that the expression | |
* class is correct, normally it assumes functions for unknown operators. | |
*/ | |
public static ExpressionOperator equalOuterJoin() { | |
return simpleRelation(EqualOuterJoin, "=*"); | |
} | |
/** | |
* INTERNAL: | |
* Create the EXISTS operator. | |
*/ | |
public static ExpressionOperator exists() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Exists); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("EXISTS" + " "); | |
v.add(" "); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator exp() { | |
return simpleFunction(Exp, "EXP"); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression for this operator, using the given base. | |
*/ | |
public Expression expressionFor(Expression base) { | |
return expressionForArguments(base, org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(0)); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression for this operator, using the given base and a single argument. | |
*/ | |
public Expression expressionFor(Expression base, Object value) { | |
return newExpressionForArgument(base, value); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression for this operator, using the given base and a single argument. | |
* Base is used last in the expression | |
*/ | |
public Expression expressionForWithBaseLast(Expression base, Object value) { | |
return newExpressionForArgumentWithBaseLast(base, value); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression for this operator, using the given base and arguments. | |
*/ | |
@Deprecated | |
public Expression expressionForArguments(Expression base, Vector arguments) { | |
return newExpressionForArguments(base, arguments); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression for this operator, using the given base and arguments. | |
*/ | |
public Expression expressionForArguments(Expression base, List arguments) { | |
return newExpressionForArguments(base, arguments); | |
} | |
/** | |
* INTERNAL: | |
* Create the extract expression operator | |
*/ | |
public static ExpressionOperator extractXml() { | |
ExpressionOperator result = new ExpressionOperator(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("extract("); | |
v.add(","); | |
v.add(")"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setSelector(ExtractXml); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the extractValue expression operator | |
*/ | |
public static ExpressionOperator extractValue() { | |
ExpressionOperator result = new ExpressionOperator(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("extractValue("); | |
v.add(","); | |
v.add(")"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setSelector(ExtractValue); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the existsNode expression operator | |
*/ | |
public static ExpressionOperator existsNode() { | |
ExpressionOperator result = new ExpressionOperator(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("existsNode("); | |
v.add(","); | |
v.add(")"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setSelector(ExistsNode); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
public static ExpressionOperator getStringVal() { | |
ExpressionOperator result = new ExpressionOperator(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add(".getStringVal()"); | |
result.printsAs(v); | |
result.bePostfix(); | |
result.setSelector(GetStringVal); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
public static ExpressionOperator getNumberVal() { | |
ExpressionOperator result = new ExpressionOperator(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add(".getNumberVal()"); | |
result.printsAs(v); | |
result.bePostfix(); | |
result.setSelector(GetNumberVal); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
public static ExpressionOperator isFragment() { | |
ExpressionOperator result = new ExpressionOperator(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add(".isFragment()"); | |
result.printsAs(v); | |
result.bePostfix(); | |
result.setSelector(IsFragment); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator floor() { | |
return simpleFunction(Floor, "FLOOR"); | |
} | |
/** | |
* ADVANCED: | |
* Return the map of all operators. | |
*/ | |
public static Map<Integer, ExpressionOperator> getAllOperators() { | |
return allOperators; | |
} | |
public static Map<String, Integer> getPlatformOperatorSelectors() { | |
return platformOperatorSelectors; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public String[] getDatabaseStrings() { | |
return databaseStrings; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public String[] getJavaStrings() { | |
return javaStrings; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Class getNodeClass() { | |
return nodeClass; | |
} | |
/** | |
* INTERNAL: | |
* Lookup the operator with the given id. | |
*/ | |
public static ExpressionOperator getOperator(Integer selector) { | |
return getAllOperators().get(selector); | |
} | |
/** | |
* INTERNAL: | |
* Return the selector id. | |
*/ | |
public int getSelector() { | |
return selector; | |
} | |
/** | |
* INTERNAL: | |
* Return the name. | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* INTERNAL: | |
* Set the name. | |
*/ | |
public void setName(String name) { | |
this.name = name; | |
} | |
/** | |
* ADVANCED: | |
* Return the type of function. | |
* This must be one of the static function types defined in this class. | |
*/ | |
public int getType() { | |
return this.type; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator greatest() { | |
return simpleTwoArgumentFunction(Greatest, "GREATEST"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator hexToRaw() { | |
return simpleFunction(HexToRaw, "HEXTORAW"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator ifNull() { | |
return simpleTwoArgumentFunction(Nvl, "NVL"); | |
} | |
/** | |
* INTERNAL: | |
* Create the IN operator. | |
*/ | |
public static ExpressionOperator in() { | |
return simpleRelation(In, "IN"); | |
} | |
/** | |
* INTERNAL: | |
* Create the IN operator taking a subquery. | |
* Note, the subquery itself comes with parenethesis, so the IN operator | |
* should not add any parenethesis. | |
*/ | |
public static ExpressionOperator inSubQuery() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setType(ExpressionOperator.FunctionOperator); | |
result.setSelector(InSubQuery); | |
Vector v = new Vector(1); | |
v.add(" IN "); | |
result.printsAs(v); | |
result.bePostfix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator initcap() { | |
return simpleFunction(Initcap, "INITCAP"); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
protected static void initializeAggregateFunctionOperators() { | |
addOperator(count()); | |
addOperator(sum()); | |
addOperator(average()); | |
addOperator(minimum()); | |
addOperator(maximum()); | |
addOperator(distinct()); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
protected static void initializeFunctionOperators() { | |
addOperator(notOperator()); | |
addOperator(ascending()); | |
addOperator(descending()); | |
addOperator(as()); | |
addOperator(nullsFirst()); | |
addOperator(nullsLast()); | |
addOperator(any()); | |
addOperator(some()); | |
addOperator(all()); | |
addOperator(in()); | |
addOperator(inSubQuery()); | |
addOperator(notIn()); | |
addOperator(notInSubQuery()); | |
addOperator(coalesce()); | |
addOperator(caseStatement()); | |
addOperator(caseConditionStatement()); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
protected static void initializeLogicalOperators() { | |
addOperator(and()); | |
addOperator(or()); | |
addOperator(isNull()); | |
addOperator(notNull()); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public static Map initializeOperators() { | |
resetOperators(); | |
initializeFunctionOperators(); | |
initializeRelationOperators(); | |
initializeLogicalOperators(); | |
initializeAggregateFunctionOperators(); | |
return allOperators; | |
} | |
/** | |
* INTERNAL: | |
* Initialize a mapping to the platform operator names for usage with exceptions. | |
*/ | |
public static String getPlatformOperatorName(int operator) { | |
String name = (String)getPlatformOperatorNames().get(Integer.valueOf(operator)); | |
if (name == null) { | |
name = String.valueOf(operator); | |
} | |
return name; | |
} | |
/** | |
* INTERNAL: | |
* Initialize a mapping to the platform operator names for usage with exceptions. | |
*/ | |
public static Map getPlatformOperatorNames() { | |
return platformOperatorNames; | |
} | |
/** | |
* INTERNAL: | |
* Initialize a mapping to the platform operator names for usage with exceptions. | |
*/ | |
public static Map<Integer, String> initializePlatformOperatorNames() { | |
Map<Integer, String> platformOperatorNames = new HashMap<Integer, String>(); | |
platformOperatorNames.put(Integer.valueOf(ToUpperCase), "ToUpperCase"); | |
platformOperatorNames.put(Integer.valueOf(ToLowerCase), "ToLowerCase"); | |
platformOperatorNames.put(Integer.valueOf(Chr), "Chr"); | |
platformOperatorNames.put(Integer.valueOf(Concat), "Concat"); | |
platformOperatorNames.put(Integer.valueOf(Coalesce), "Coalesce"); | |
platformOperatorNames.put(Integer.valueOf(Case), "Case"); | |
platformOperatorNames.put(Integer.valueOf(CaseCondition), "Case(codition)"); | |
platformOperatorNames.put(Integer.valueOf(HexToRaw), "HexToRaw"); | |
platformOperatorNames.put(Integer.valueOf(Initcap), "Initcap"); | |
platformOperatorNames.put(Integer.valueOf(Instring), "Instring"); | |
platformOperatorNames.put(Integer.valueOf(Soundex), "Soundex"); | |
platformOperatorNames.put(Integer.valueOf(LeftPad), "LeftPad"); | |
platformOperatorNames.put(Integer.valueOf(LeftTrim), "LeftTrim"); | |
platformOperatorNames.put(Integer.valueOf(RightPad), "RightPad"); | |
platformOperatorNames.put(Integer.valueOf(RightTrim), "RightTrim"); | |
platformOperatorNames.put(Integer.valueOf(Substring), "Substring"); | |
platformOperatorNames.put(Integer.valueOf(SubstringSingleArg), "Substring"); | |
platformOperatorNames.put(Integer.valueOf(Translate), "Translate"); | |
platformOperatorNames.put(Integer.valueOf(Ascii), "Ascii"); | |
platformOperatorNames.put(Integer.valueOf(Length), "Length"); | |
platformOperatorNames.put(Integer.valueOf(CharIndex), "CharIndex"); | |
platformOperatorNames.put(Integer.valueOf(CharLength), "CharLength"); | |
platformOperatorNames.put(Integer.valueOf(Difference), "Difference"); | |
platformOperatorNames.put(Integer.valueOf(Reverse), "Reverse"); | |
platformOperatorNames.put(Integer.valueOf(Replicate), "Replicate"); | |
platformOperatorNames.put(Integer.valueOf(Right), "Right"); | |
platformOperatorNames.put(Integer.valueOf(Locate), "Locate"); | |
platformOperatorNames.put(Integer.valueOf(Locate2), "Locate"); | |
platformOperatorNames.put(Integer.valueOf(ToNumber), "ToNumber"); | |
platformOperatorNames.put(Integer.valueOf(ToChar), "ToChar"); | |
platformOperatorNames.put(Integer.valueOf(ToCharWithFormat), "ToChar"); | |
platformOperatorNames.put(Integer.valueOf(AddMonths), "AddMonths"); | |
platformOperatorNames.put(Integer.valueOf(DateToString), "DateToString"); | |
platformOperatorNames.put(Integer.valueOf(MonthsBetween), "MonthsBetween"); | |
platformOperatorNames.put(Integer.valueOf(NextDay), "NextDay"); | |
platformOperatorNames.put(Integer.valueOf(RoundDate), "RoundDate"); | |
platformOperatorNames.put(Integer.valueOf(AddDate), "AddDate"); | |
platformOperatorNames.put(Integer.valueOf(DateName), "DateName"); | |
platformOperatorNames.put(Integer.valueOf(DatePart), "DatePart"); | |
platformOperatorNames.put(Integer.valueOf(DateDifference), "DateDifference"); | |
platformOperatorNames.put(Integer.valueOf(TruncateDate), "TruncateDate"); | |
platformOperatorNames.put(Integer.valueOf(Extract), "Extract"); | |
platformOperatorNames.put(Integer.valueOf(Cast), "Cast"); | |
platformOperatorNames.put(Integer.valueOf(NewTime), "NewTime"); | |
platformOperatorNames.put(Integer.valueOf(Nvl), "Nvl"); | |
platformOperatorNames.put(Integer.valueOf(NewTime), "NewTime"); | |
platformOperatorNames.put(Integer.valueOf(Ceil), "Ceil"); | |
platformOperatorNames.put(Integer.valueOf(Cos), "Cos"); | |
platformOperatorNames.put(Integer.valueOf(Cosh), "Cosh"); | |
platformOperatorNames.put(Integer.valueOf(Abs), "Abs"); | |
platformOperatorNames.put(Integer.valueOf(Acos), "Acos"); | |
platformOperatorNames.put(Integer.valueOf(Asin), "Asin"); | |
platformOperatorNames.put(Integer.valueOf(Atan), "Atan"); | |
platformOperatorNames.put(Integer.valueOf(Exp), "Exp"); | |
platformOperatorNames.put(Integer.valueOf(Sqrt), "Sqrt"); | |
platformOperatorNames.put(Integer.valueOf(Floor), "Floor"); | |
platformOperatorNames.put(Integer.valueOf(Ln), "Ln"); | |
platformOperatorNames.put(Integer.valueOf(Log), "Log"); | |
platformOperatorNames.put(Integer.valueOf(Mod), "Mod"); | |
platformOperatorNames.put(Integer.valueOf(Power), "Power"); | |
platformOperatorNames.put(Integer.valueOf(Round), "Round"); | |
platformOperatorNames.put(Integer.valueOf(Sign), "Sign"); | |
platformOperatorNames.put(Integer.valueOf(Sin), "Sin"); | |
platformOperatorNames.put(Integer.valueOf(Sinh), "Sinh"); | |
platformOperatorNames.put(Integer.valueOf(Tan), "Tan"); | |
platformOperatorNames.put(Integer.valueOf(Tanh), "Tanh"); | |
platformOperatorNames.put(Integer.valueOf(Trunc), "Trunc"); | |
platformOperatorNames.put(Integer.valueOf(Greatest), "Greatest"); | |
platformOperatorNames.put(Integer.valueOf(Least), "Least"); | |
platformOperatorNames.put(Integer.valueOf(Add), "Add"); | |
platformOperatorNames.put(Integer.valueOf(Subtract), "Subtract"); | |
platformOperatorNames.put(Integer.valueOf(Divide), "Divide"); | |
platformOperatorNames.put(Integer.valueOf(Multiply), "Multiply"); | |
platformOperatorNames.put(Integer.valueOf(Atan2), "Atan2"); | |
platformOperatorNames.put(Integer.valueOf(Cot), "Cot"); | |
platformOperatorNames.put(Integer.valueOf(Deref), "Deref"); | |
platformOperatorNames.put(Integer.valueOf(Ref), "Ref"); | |
platformOperatorNames.put(Integer.valueOf(RefToHex), "RefToHex"); | |
platformOperatorNames.put(Integer.valueOf(Value), "Value"); | |
platformOperatorNames.put(Integer.valueOf(ExtractXml), "ExtractXml"); | |
platformOperatorNames.put(Integer.valueOf(ExtractValue), "ExtractValue"); | |
platformOperatorNames.put(Integer.valueOf(ExistsNode), "ExistsNode"); | |
platformOperatorNames.put(Integer.valueOf(GetStringVal), "GetStringVal"); | |
platformOperatorNames.put(Integer.valueOf(GetNumberVal), "GetNumberVal"); | |
platformOperatorNames.put(Integer.valueOf(IsFragment), "IsFragment"); | |
platformOperatorNames.put(Integer.valueOf(SDO_WITHIN_DISTANCE), "MDSYS.SDO_WITHIN_DISTANCE"); | |
platformOperatorNames.put(Integer.valueOf(SDO_RELATE), "MDSYS.SDO_RELATE"); | |
platformOperatorNames.put(Integer.valueOf(SDO_FILTER), "MDSYS.SDO_FILTER"); | |
platformOperatorNames.put(Integer.valueOf(SDO_NN), "MDSYS.SDO_NN"); | |
platformOperatorNames.put(Integer.valueOf(NullIf), "NullIf"); | |
platformOperatorNames.put(Integer.valueOf(Regexp), "REGEXP"); | |
platformOperatorNames.put(Integer.valueOf(Union), "UNION"); | |
platformOperatorNames.put(Integer.valueOf(UnionAll), "UNION ALL"); | |
platformOperatorNames.put(Integer.valueOf(Intersect), "INTERSECT"); | |
platformOperatorNames.put(Integer.valueOf(IntersectAll), "INTERSECT ALL"); | |
platformOperatorNames.put(Integer.valueOf(Except), "EXCEPT"); | |
platformOperatorNames.put(Integer.valueOf(ExceptAll), "EXCEPT ALL"); | |
return platformOperatorNames; | |
} | |
/** | |
* INTERNAL: | |
* Initialize a mapping to the platform operator names for usage with exceptions. | |
*/ | |
public static Map<String, Integer> initializePlatformOperatorSelectors() { | |
Map<String, Integer> platformOperatorNames = new HashMap<String, Integer>(); | |
platformOperatorNames.put("ToUpperCase", Integer.valueOf(ToUpperCase)); | |
platformOperatorNames.put("ToLowerCase", Integer.valueOf(ToLowerCase)); | |
platformOperatorNames.put("Chr", Integer.valueOf(Chr)); | |
platformOperatorNames.put("Concat", Integer.valueOf(Concat)); | |
platformOperatorNames.put("Coalesce", Integer.valueOf(Coalesce)); | |
platformOperatorNames.put("Case", Integer.valueOf(Case)); | |
platformOperatorNames.put("HexToRaw", Integer.valueOf(HexToRaw)); | |
platformOperatorNames.put("Initcap", Integer.valueOf(Initcap)); | |
platformOperatorNames.put("Instring", Integer.valueOf(Instring)); | |
platformOperatorNames.put("Soundex", Integer.valueOf(Soundex)); | |
platformOperatorNames.put("LeftPad", Integer.valueOf(LeftPad)); | |
platformOperatorNames.put("LeftTrim", Integer.valueOf(LeftTrim)); | |
platformOperatorNames.put("RightPad", Integer.valueOf(RightPad)); | |
platformOperatorNames.put("RightTrim", Integer.valueOf(RightTrim)); | |
platformOperatorNames.put("Substring", Integer.valueOf(Substring)); | |
platformOperatorNames.put("Translate", Integer.valueOf(Translate)); | |
platformOperatorNames.put("Ascii", Integer.valueOf(Ascii)); | |
platformOperatorNames.put("Length", Integer.valueOf(Length)); | |
platformOperatorNames.put("CharIndex", Integer.valueOf(CharIndex)); | |
platformOperatorNames.put("CharLength", Integer.valueOf(CharLength)); | |
platformOperatorNames.put("Difference", Integer.valueOf(Difference)); | |
platformOperatorNames.put("Reverse", Integer.valueOf(Reverse)); | |
platformOperatorNames.put("Replicate", Integer.valueOf(Replicate)); | |
platformOperatorNames.put("Right", Integer.valueOf(Right)); | |
platformOperatorNames.put("Locate", Integer.valueOf(Locate)); | |
platformOperatorNames.put("ToNumber", Integer.valueOf(ToNumber)); | |
platformOperatorNames.put("ToChar", Integer.valueOf(ToChar)); | |
platformOperatorNames.put("AddMonths", Integer.valueOf(AddMonths)); | |
platformOperatorNames.put("DateToString", Integer.valueOf(DateToString)); | |
platformOperatorNames.put("MonthsBetween", Integer.valueOf(MonthsBetween)); | |
platformOperatorNames.put("NextDay", Integer.valueOf(NextDay)); | |
platformOperatorNames.put("RoundDate", Integer.valueOf(RoundDate)); | |
platformOperatorNames.put("AddDate", Integer.valueOf(AddDate)); | |
platformOperatorNames.put("DateName", Integer.valueOf(DateName)); | |
platformOperatorNames.put("DatePart", Integer.valueOf(DatePart)); | |
platformOperatorNames.put("DateDifference", Integer.valueOf(DateDifference)); | |
platformOperatorNames.put("TruncateDate", Integer.valueOf(TruncateDate)); | |
platformOperatorNames.put("NewTime", Integer.valueOf(NewTime)); | |
platformOperatorNames.put("Nvl", Integer.valueOf(Nvl)); | |
platformOperatorNames.put("NewTime", Integer.valueOf(NewTime)); | |
platformOperatorNames.put("Ceil", Integer.valueOf(Ceil)); | |
platformOperatorNames.put("Cos", Integer.valueOf(Cos)); | |
platformOperatorNames.put("Cosh", Integer.valueOf(Cosh)); | |
platformOperatorNames.put("Abs", Integer.valueOf(Abs)); | |
platformOperatorNames.put("Acos", Integer.valueOf(Acos)); | |
platformOperatorNames.put("Asin", Integer.valueOf(Asin)); | |
platformOperatorNames.put("Atan", Integer.valueOf(Atan)); | |
platformOperatorNames.put("Exp", Integer.valueOf(Exp)); | |
platformOperatorNames.put("Sqrt", Integer.valueOf(Sqrt)); | |
platformOperatorNames.put("Floor", Integer.valueOf(Floor)); | |
platformOperatorNames.put("Ln", Integer.valueOf(Ln)); | |
platformOperatorNames.put("Log", Integer.valueOf(Log)); | |
platformOperatorNames.put("Mod", Integer.valueOf(Mod)); | |
platformOperatorNames.put("Power", Integer.valueOf(Power)); | |
platformOperatorNames.put("Round", Integer.valueOf(Round)); | |
platformOperatorNames.put("Sign", Integer.valueOf(Sign)); | |
platformOperatorNames.put("Sin", Integer.valueOf(Sin)); | |
platformOperatorNames.put("Sinh", Integer.valueOf(Sinh)); | |
platformOperatorNames.put("Tan", Integer.valueOf(Tan)); | |
platformOperatorNames.put("Tanh", Integer.valueOf(Tanh)); | |
platformOperatorNames.put("Trunc", Integer.valueOf(Trunc)); | |
platformOperatorNames.put("Greatest", Integer.valueOf(Greatest)); | |
platformOperatorNames.put("Least", Integer.valueOf(Least)); | |
platformOperatorNames.put("Add", Integer.valueOf(Add)); | |
platformOperatorNames.put("Subtract", Integer.valueOf(Subtract)); | |
platformOperatorNames.put("Divide", Integer.valueOf(Divide)); | |
platformOperatorNames.put("Multiply", Integer.valueOf(Multiply)); | |
platformOperatorNames.put("Atan2", Integer.valueOf(Atan2)); | |
platformOperatorNames.put("Cot", Integer.valueOf(Cot)); | |
platformOperatorNames.put("Deref", Integer.valueOf(Deref)); | |
platformOperatorNames.put("Ref", Integer.valueOf(Ref)); | |
platformOperatorNames.put("RefToHex", Integer.valueOf(RefToHex)); | |
platformOperatorNames.put("Value", Integer.valueOf(Value)); | |
platformOperatorNames.put("Cast", Integer.valueOf(Cast)); | |
platformOperatorNames.put("Extract", Integer.valueOf(Extract)); | |
platformOperatorNames.put("ExtractXml", Integer.valueOf(ExtractXml)); | |
platformOperatorNames.put("ExtractValue", Integer.valueOf(ExtractValue)); | |
platformOperatorNames.put("ExistsNode", Integer.valueOf(ExistsNode)); | |
platformOperatorNames.put("GetStringVal", Integer.valueOf(GetStringVal)); | |
platformOperatorNames.put("GetNumberVal", Integer.valueOf(GetNumberVal)); | |
platformOperatorNames.put("IsFragment", Integer.valueOf(IsFragment)); | |
platformOperatorNames.put("SDO_WITHIN_DISTANCE", Integer.valueOf(SDO_WITHIN_DISTANCE)); | |
platformOperatorNames.put("SDO_RELATE", Integer.valueOf(SDO_RELATE)); | |
platformOperatorNames.put("SDO_FILTER", Integer.valueOf(SDO_FILTER)); | |
platformOperatorNames.put("SDO_NN", Integer.valueOf(SDO_NN)); | |
platformOperatorNames.put("NullIf", Integer.valueOf(NullIf)); | |
return platformOperatorNames; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
protected static void initializeRelationOperators() { | |
addOperator(simpleRelation(Equal, "=", "equal")); | |
addOperator(simpleRelation(NotEqual, "<>", "notEqual")); | |
addOperator(simpleRelation(LessThan, "<", "lessThan")); | |
addOperator(simpleRelation(LessThanEqual, "<=", "lessThanEqual")); | |
addOperator(simpleRelation(GreaterThan, ">", "greaterThan")); | |
addOperator(simpleRelation(GreaterThanEqual, ">=", "greaterThanEqual")); | |
addOperator(like()); | |
addOperator(likeEscape()); | |
addOperator(notLike()); | |
addOperator(notLikeEscape()); | |
addOperator(between()); | |
addOperator(exists()); | |
addOperator(notExists()); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator instring() { | |
return simpleTwoArgumentFunction(Instring, "INSTR"); | |
} | |
/** | |
* Aggregate functions are function in the select such as COUNT. | |
*/ | |
public boolean isAggregateOperator() { | |
return getType() == AggregateOperator; | |
} | |
/** | |
* Comparison functions are functions such as = and {@literal >}. | |
*/ | |
public boolean isComparisonOperator() { | |
return getType() == ComparisonOperator; | |
} | |
/** | |
* INTERNAL: | |
* If we have all the required information, this operator is complete | |
* and can be used as is. Otherwise we will need to look up a platform- | |
* specific operator. | |
*/ | |
public boolean isComplete() { | |
return (databaseStrings != null) && (databaseStrings.length != 0); | |
} | |
/** | |
* General functions are any normal function such as UPPER. | |
*/ | |
public boolean isFunctionOperator() { | |
return getType() == FunctionOperator; | |
} | |
/** | |
* Logical functions are functions such as and and or. | |
*/ | |
public boolean isLogicalOperator() { | |
return getType() == LogicalOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the ISNULL operator. | |
*/ | |
public static ExpressionOperator isNull() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setType(ComparisonOperator); | |
result.setSelector(IsNull); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("("); | |
v.add(" IS NULL)"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.printsJavaAs(".isNull()"); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* Order functions are used in the order by such as ASC. | |
*/ | |
public boolean isOrderOperator() { | |
return getType() == OrderOperator; | |
} | |
/** | |
* ADVANCED: | |
* Return true if this is a prefix operator. | |
*/ | |
public boolean isPrefix() { | |
return isPrefix; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator lastDay() { | |
return simpleFunction(LastDay, "LAST_DAY"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator least() { | |
return simpleTwoArgumentFunction(Least, "LEAST"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator leftPad() { | |
return simpleThreeArgumentFunction(LeftPad, "LPAD"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator leftTrim() { | |
return simpleFunction(LeftTrim, "LTRIM"); | |
} | |
/** | |
* INTERNAL: | |
* Build leftTrim operator that takes one parameter. | |
*/ | |
public static ExpressionOperator leftTrim2() { | |
return simpleTwoArgumentFunction(LeftTrim2, "LTRIM"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator length() { | |
return simpleFunction(Length, "LENGTH"); | |
} | |
/** | |
* INTERNAL: | |
* Create the LIKE operator. | |
*/ | |
public static ExpressionOperator like() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(Like); | |
result.setType(FunctionOperator); | |
Vector v = NonSynchronizedVector.newInstance(3); | |
v.add(""); | |
v.add(" LIKE "); | |
v.add(""); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
v = NonSynchronizedVector.newInstance(2); | |
v.add(".like("); | |
v.add(")"); | |
result.printsJavaAs(v); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the REGEXP operator. | |
* REGEXP allows for comparison through regular expression, | |
* this is supported by many databases and with be part of the next SQL standard. | |
*/ | |
public static ExpressionOperator regexp() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(Regexp); | |
result.setType(FunctionOperator); | |
Vector v = NonSynchronizedVector.newInstance(3); | |
v.add(""); | |
v.add(" REGEXP "); | |
v.add(""); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
v = NonSynchronizedVector.newInstance(2); | |
v.add(".regexp("); | |
v.add(")"); | |
result.printsJavaAs(v); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the LIKE operator with ESCAPE. | |
*/ | |
public static ExpressionOperator likeEscape() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(LikeEscape); | |
result.setType(FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add(""); | |
v.add(" LIKE "); | |
v.add(" ESCAPE "); | |
v.add(""); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
result.setIsBindingSupported(false); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the LIKE operator with ESCAPE. | |
*/ | |
public static ExpressionOperator notLikeEscape() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(NotLikeEscape); | |
result.setType(FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add(""); | |
v.add(" NOT LIKE "); | |
v.add(" ESCAPE "); | |
v.add(""); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
result.setIsBindingSupported(false); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator ln() { | |
return simpleFunction(Ln, "LN"); | |
} | |
/** | |
* INTERNAL: | |
* Build locate operator i.e. LOCATE("ob", t0.F_NAME) | |
*/ | |
public static ExpressionOperator locate() { | |
ExpressionOperator expOperator = simpleTwoArgumentFunction(Locate, "LOCATE"); | |
int[] argumentIndices = new int[2]; | |
argumentIndices[0] = 1; | |
argumentIndices[1] = 0; | |
expOperator.setArgumentIndices(argumentIndices); | |
expOperator.setIsBindingSupported(false); | |
return expOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build locate operator with 3 params i.e. LOCATE("coffee", t0.DESCRIP, 4). | |
* Last parameter is a start at. | |
*/ | |
public static ExpressionOperator locate2() { | |
ExpressionOperator expOperator = simpleThreeArgumentFunction(Locate2, "LOCATE"); | |
int[] argumentIndices = new int[3]; | |
argumentIndices[0] = 1; | |
argumentIndices[1] = 0; | |
argumentIndices[2] = 2; | |
expOperator.setArgumentIndices(argumentIndices); | |
expOperator.setIsBindingSupported(false); | |
return expOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator log() { | |
return simpleFunction(Log, "LOG"); | |
} | |
/** | |
* INTERNAL: | |
* Create the MAXIMUM operator. | |
*/ | |
public static ExpressionOperator maximum() { | |
return simpleAggregate(Maximum, "MAX", "maximum"); | |
} | |
/** | |
* INTERNAL: | |
* Create the MINIMUM operator. | |
*/ | |
public static ExpressionOperator minimum() { | |
return simpleAggregate(Minimum, "MIN", "minimum"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator mod() { | |
ExpressionOperator operator = simpleTwoArgumentFunction(Mod, "MOD"); | |
operator.setIsBindingSupported(false); | |
return operator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator monthsBetween() { | |
return simpleTwoArgumentFunction(MonthsBetween, "MONTHS_BETWEEN"); | |
} | |
/** | |
* INTERNAL: | |
* Create a new expression. Optimized for the single argument case. | |
*/ | |
public Expression newExpressionForArgument(Expression base, Object singleArgument) { | |
if (singleArgument == null) { | |
if (this.selector == Equal) { | |
return base.isNull(); | |
} else if (this.selector == NotEqual) { | |
return base.notNull(); | |
} | |
} | |
Expression node = createNode(); | |
node.create(base, singleArgument, this); | |
return node; | |
} | |
/** | |
* INTERNAL: | |
* Instantiate an instance of the operator's node class. | |
*/ | |
protected Expression createNode() { | |
// PERF: Avoid reflection for common cases. | |
if (this.nodeClass == ClassConstants.ArgumentListFunctionExpression_Class){ | |
return new ArgumentListFunctionExpression(); | |
} else if (this.nodeClass == ClassConstants.FunctionExpression_Class) { | |
return new FunctionExpression(); | |
} else if (this.nodeClass == ClassConstants.RelationExpression_Class) { | |
return new RelationExpression(); | |
} else if (this.nodeClass == ClassConstants.LogicalExpression_Class) { | |
return new LogicalExpression(); | |
} | |
try { | |
Expression node = null; | |
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ | |
try { | |
node = (Expression)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(getNodeClass())); | |
} catch (PrivilegedActionException exception) { | |
return null; | |
} | |
} else { | |
node = (Expression)PrivilegedAccessHelper.newInstanceFromClass(getNodeClass()); | |
} | |
return node; | |
} catch (InstantiationException exception) { | |
throw new InternalError(exception.toString()); | |
} catch (IllegalAccessException exception) { | |
throw new InternalError(exception.toString()); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Create a new expression. Optimized for the single argument case with base last | |
*/ | |
public Expression newExpressionForArgumentWithBaseLast(Expression base, Object singleArgument) { | |
if (singleArgument == null) { | |
if (this.selector == Equal) { | |
return base.isNull(); | |
} else if (this.selector == NotEqual) { | |
return base.notNull(); | |
} | |
} | |
Expression node = createNode(); | |
node.createWithBaseLast(base, singleArgument, this); | |
return node; | |
} | |
/** | |
* INTERNAL: | |
* The general case. | |
*/ | |
public Expression newExpressionForArguments(Expression base, List arguments) { | |
if ((arguments.size() == 1) && (arguments.get(0) == null)) { | |
if (this.selector == Equal) { | |
return base.isNull(); | |
} else if (this.selector == NotEqual) { | |
return base.notNull(); | |
} | |
} | |
Expression node = createNode(); | |
node.create(base, arguments, this); | |
return node; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator negate() { | |
return simpleFunction(Negate, "-"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator newTime() { | |
return simpleThreeArgumentFunction(NewTime, "NEW_TIME"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator nextDay() { | |
return simpleTwoArgumentFunction(NextDay, "NEXT_DAY"); | |
} | |
/** | |
* INTERNAL: | |
* Create the NOT EXISTS operator. | |
*/ | |
public static ExpressionOperator notExists() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(NotExists); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("NOT EXISTS" + " "); | |
v.add(" "); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the NOTIN operator. | |
*/ | |
public static ExpressionOperator notIn() { | |
return simpleRelation(NotIn, "NOT IN"); | |
} | |
/** | |
* INTERNAL: | |
* Create the NOTIN operator taking a subQuery. | |
* Note, the subquery itself comes with parenethesis, so the IN operator | |
* should not add any parenethesis. | |
*/ | |
public static ExpressionOperator notInSubQuery() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setType(ExpressionOperator.FunctionOperator); | |
result.setSelector(NotInSubQuery); | |
Vector v = new Vector(1); | |
v.add(" NOT IN "); | |
result.printsAs(v); | |
result.bePostfix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the NOTLIKE operator. | |
*/ | |
public static ExpressionOperator notLike() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(NotLike); | |
result.setType(FunctionOperator); | |
Vector v = NonSynchronizedVector.newInstance(); | |
v.add(""); | |
v.add(" NOT LIKE "); | |
v.add(""); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
v = NonSynchronizedVector.newInstance(2); | |
v.add(".notLike("); | |
v.add(")"); | |
result.printsJavaAs(v); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the NOTNULL operator. | |
*/ | |
public static ExpressionOperator notNull() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setType(ComparisonOperator); | |
result.setSelector(NotNull); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("("); | |
v.add(" IS NOT NULL)"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.printsJavaAs(".notNull()"); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Create the NOT operator. | |
*/ | |
public static ExpressionOperator notOperator() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(Not); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("NOT ("); | |
v.add(")"); | |
result.printsAs(v); | |
result.bePrefix(); | |
result.printsJavaAs(".not()"); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator nullIf() { | |
return simpleTwoArgumentFunction(NullIf, "NULLIF"); | |
} | |
/** | |
* INTERNAL: | |
* Create the OR operator. | |
*/ | |
public static ExpressionOperator or() { | |
return simpleLogical(Or, "OR", "or"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator power() { | |
return simpleTwoArgumentFunction(Power, "POWER"); | |
} | |
/** | |
* INTERNAL: Print the collection onto the SQL stream. | |
*/ | |
public void printCollection(Vector items, ExpressionSQLPrinter printer) { | |
// Certain functions don't allow binding on some platforms. | |
if (printer.getPlatform().isDynamicSQLRequiredForFunctions() && !isBindingSupported()) { | |
printer.getCall().setUsesBinding(false); | |
} | |
int dbStringIndex = 0; | |
try { | |
if (isPrefix()) { | |
printer.getWriter().write(getDatabaseStrings()[0]); | |
dbStringIndex = 1; | |
} else { | |
dbStringIndex = 0; | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
if (argumentIndices == null) { | |
argumentIndices = new int[items.size()]; | |
for (int i = 0; i < argumentIndices.length; i++){ | |
argumentIndices[i] = i; | |
} | |
} | |
for (final int index : argumentIndices) { | |
Expression item = (Expression)items.elementAt(index); | |
if ((this.selector == Ref) || ((this.selector == Deref) && (item.isObjectExpression()))) { | |
DatabaseTable alias = ((ObjectExpression)item).aliasForTable(((ObjectExpression)item).getDescriptor().getTables().firstElement()); | |
printer.printString(alias.getNameDelimited(printer.getPlatform())); | |
} else if ((this.selector == Count) && (item.isExpressionBuilder())) { | |
printer.printString("*"); | |
} else { | |
item.printSQL(printer); | |
} | |
if (dbStringIndex < getDatabaseStrings().length) { | |
printer.printString(getDatabaseStrings()[dbStringIndex++]); | |
} | |
} | |
} | |
/** | |
* INTERNAL: Print the collection onto the SQL stream. | |
*/ | |
public void printJavaCollection(Vector items, ExpressionJavaPrinter printer) { | |
int javaStringIndex = 0; | |
for (int i = 0; i < items.size(); i++) { | |
Expression item = (Expression)items.elementAt(i); | |
item.printJava(printer); | |
if (javaStringIndex < getJavaStrings().length) { | |
printer.printString(getJavaStrings()[javaStringIndex++]); | |
} | |
} | |
} | |
/** | |
* INTERNAL: | |
* For performance, special case printing two children, since it's by far the most common | |
*/ | |
public void printDuo(Expression first, Expression second, ExpressionSQLPrinter printer) { | |
// Certain functions don't allow binding on some platforms. | |
if (printer.getPlatform().isDynamicSQLRequiredForFunctions() && !isBindingSupported()) { | |
printer.getCall().setUsesBinding(false); | |
} | |
int dbStringIndex; | |
if (isPrefix()) { | |
printer.printString(getDatabaseStrings()[0]); | |
dbStringIndex = 1; | |
} else { | |
dbStringIndex = 0; | |
} | |
first.printSQL(printer); | |
if (dbStringIndex < getDatabaseStrings().length) { | |
printer.printString(getDatabaseStrings()[dbStringIndex++]); | |
} | |
if (second != null) { | |
second.printSQL(printer); | |
if (dbStringIndex < getDatabaseStrings().length) { | |
printer.printString(getDatabaseStrings()[dbStringIndex++]); | |
} | |
} | |
} | |
/** | |
* INTERNAL: | |
* For performance, special case printing two children, since it's by far the most common | |
*/ | |
public void printJavaDuo(Expression first, Expression second, ExpressionJavaPrinter printer) { | |
int javaStringIndex = 0; | |
first.printJava(printer); | |
if (javaStringIndex < getJavaStrings().length) { | |
printer.printString(getJavaStrings()[javaStringIndex++]); | |
} | |
if (second != null) { | |
second.printJava(printer); | |
if (javaStringIndex < getJavaStrings().length) { | |
printer.printString(getJavaStrings()[javaStringIndex]); | |
} | |
} | |
} | |
/** | |
* ADVANCED: | |
* Set the single string for this operator. | |
*/ | |
public void printsAs(String s) { | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1); | |
v.add(s); | |
printsAs(v); | |
} | |
/** | |
* ADVANCED: | |
* Set the strings for this operator. | |
*/ | |
public void printsAs(Vector dbStrings) { | |
this.databaseStrings = new String[dbStrings.size()]; | |
for (int i = 0; i < dbStrings.size(); i++) { | |
getDatabaseStrings()[i] = (String)dbStrings.elementAt(i); | |
} | |
} | |
/** | |
* ADVANCED: | |
* Set the single string for this operator. | |
*/ | |
public void printsJavaAs(String s) { | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1); | |
v.add(s); | |
printsJavaAs(v); | |
} | |
/** | |
* ADVANCED: | |
* Set the strings for this operator. | |
*/ | |
public void printsJavaAs(Vector dbStrings) { | |
this.javaStrings = new String[dbStrings.size()]; | |
for (int i = 0; i < dbStrings.size(); i++) { | |
getJavaStrings()[i] = (String)dbStrings.elementAt(i); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator ref() { | |
return simpleFunction(Ref, "REF"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator refToHex() { | |
return simpleFunction(RefToHex, "REFTOHEX"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator replace() { | |
ExpressionOperator operator = simpleThreeArgumentFunction(Replace, "REPLACE"); | |
operator.setIsBindingSupported(false); | |
return operator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator replicate() { | |
return simpleTwoArgumentFunction(Replicate, "REPLICATE"); | |
} | |
/** | |
* INTERNAL: | |
* Reset all the operators. | |
*/ | |
public static void resetOperators() { | |
allOperators = new HashMap(); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator reverse() { | |
return simpleFunction(Reverse, "REVERSE"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator right() { | |
return simpleTwoArgumentFunction(Right, "RIGHT"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator rightPad() { | |
return simpleThreeArgumentFunction(RightPad, "RPAD"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator rightTrim() { | |
return simpleFunction(RightTrim, "RTRIM"); | |
} | |
/** | |
* INTERNAL: | |
* Build rightTrim operator that takes one parameter. | |
* @bug 2916893 rightTrim(substring) broken. | |
*/ | |
public static ExpressionOperator rightTrim2() { | |
return simpleTwoArgumentFunction(RightTrim2, "RTRIM"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator round() { | |
return simpleTwoArgumentFunction(Round, "ROUND"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator roundDate() { | |
return simpleTwoArgumentFunction(RoundDate, "ROUND"); | |
} | |
/** | |
* ADVANCED: Set the array of indexes to use when building the SQL function. | |
* | |
* The index of the array is the position in the printout, from left to right, starting with zero. | |
* The value of the array entry is the number of the argument to print at that particular output position. | |
* So each argument can be used zero, one or many times. | |
*/ | |
public void setArgumentIndices(int[] indices) { | |
argumentIndices = indices; | |
} | |
/** | |
* ADVANCED: | |
* Set the node class for this operator. For user-defined functions this is | |
* set automatically but can be changed. | |
* <p>A list of Operator types, an example, and the node class used follows. | |
* <p>LogicalOperator AND LogicalExpression | |
* <p>ComparisonOperator {@literal <>} RelationExpression | |
* <p>AggregateOperator COUNT FunctionExpression | |
* <p>OrderOperator ASCENDING " | |
* <p>FunctionOperator RTRIM " | |
* <p>Node classes given belong to org.eclipse.persistence.internal.expressions. | |
*/ | |
public void setNodeClass(Class nodeClass) { | |
this.nodeClass = nodeClass; | |
} | |
/** | |
* INTERNAL: | |
* Set the selector id. | |
*/ | |
public void setSelector(int selector) { | |
this.selector = selector; | |
} | |
/** | |
* ADVANCED: | |
* Set the type of function. | |
* This must be one of the static function types defined in this class. | |
*/ | |
public void setType(int type) { | |
this.type = type; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator sign() { | |
return simpleFunction(Sign, "SIGN"); | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple aggregate given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleAggregate(int selector, String databaseName, String javaName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(AggregateOperator); | |
exOperator.setSelector(selector); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add(databaseName + "("); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.printsJavaAs("." + javaName + "()"); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple function given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleFunction(int selector, String databaseName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(selector); | |
exOperator.setName(databaseName); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add(databaseName + "("); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple function call without parentheses | |
*/ | |
public static ExpressionOperator simpleFunctionNoParentheses(int selector, String databaseName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(selector); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1); | |
v.add(databaseName); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple function given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleFunction(int selector, String databaseName, String javaName) { | |
ExpressionOperator exOperator = simpleFunction(selector, databaseName); | |
exOperator.printsJavaAs("." + javaName + "()"); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple logical given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleLogical(int selector, String databaseName, String javaName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(LogicalOperator); | |
exOperator.setSelector(selector); | |
exOperator.printsAs(" " + databaseName + " "); | |
exOperator.bePostfix(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("." + javaName + "("); | |
v.add(")"); | |
exOperator.printsJavaAs(v); | |
exOperator.setNodeClass(ClassConstants.LogicalExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple math operatin, i.e. +, -, *, / | |
*/ | |
public static ExpressionOperator simpleMath(int selector, String databaseName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setIsBindingSupported(false); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(selector); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(3); | |
v.add("("); | |
v.add(" " + databaseName + " "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple ordering given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleOrdering(int selector, String databaseName, String javaName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(OrderOperator); | |
exOperator.setSelector(selector); | |
exOperator.printsAs(" " + databaseName); | |
exOperator.bePostfix(); | |
exOperator.printsJavaAs("." + javaName + "()"); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple relation given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleRelation(int selector, String databaseName) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(ComparisonOperator); | |
exOperator.setSelector(selector); | |
exOperator.printsAs(" " + databaseName + " "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.RelationExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create an operator for a simple relation given a Java name and a single | |
* String for the database (parentheses will be added automatically). | |
*/ | |
public static ExpressionOperator simpleRelation(int selector, String databaseName, String javaName) { | |
ExpressionOperator exOperator = simpleRelation(selector, databaseName); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("." + javaName + "("); | |
v.add(")"); | |
exOperator.printsJavaAs(v); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator simpleThreeArgumentFunction(int selector, String dbString) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(selector); | |
exOperator.setName(dbString); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(4); | |
v.add(dbString + "("); | |
v.add(", "); | |
v.add(", "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator simpleTwoArgumentFunction(int selector, String dbString) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(selector); | |
exOperator.setName(dbString); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(5); | |
v.add(dbString + "("); | |
v.add(", "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* e.g.: ... "Bob" CONCAT "Smith" ... | |
* Parentheses will not be addded. [RMB - March 5 2000] | |
*/ | |
public static ExpressionOperator simpleLogicalNoParens(int selector, String dbString) { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(selector); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(5); | |
v.add(""); | |
v.add(" " + dbString + " "); | |
v.add(""); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator sin() { | |
return simpleFunction(Sin, "SIN"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator sinh() { | |
return simpleFunction(Sinh, "SINH"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator soundex() { | |
return simpleFunction(Soundex, "SOUNDEX"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator sqrt() { | |
return simpleFunction(Sqrt, "SQRT"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator standardDeviation() { | |
return simpleAggregate(StandardDeviation, "STDDEV", "standardDeviation"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator substring() { | |
ExpressionOperator operator = simpleThreeArgumentFunction(Substring, "SUBSTR"); | |
operator.setIsBindingSupported(false); | |
return operator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator substringSingleArg() { | |
return simpleTwoArgumentFunction(SubstringSingleArg, "SUBSTR"); | |
} | |
/** | |
* INTERNAL: | |
* Create the SUM operator. | |
*/ | |
public static ExpressionOperator sum() { | |
return simpleAggregate(Sum, "SUM", "sum"); | |
} | |
/** | |
* INTERNAL: | |
* Function, to add months to a date. | |
*/ | |
public static ExpressionOperator sybaseAddMonthsOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(AddMonths); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(3); | |
v.add("DATEADD(month, "); | |
v.add(", "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
int[] indices = { 1, 0 }; | |
exOperator.setArgumentIndices(indices); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator sybaseAtan2Operator() { | |
return ExpressionOperator.simpleTwoArgumentFunction(Atan2, "ATN2"); | |
} | |
/** | |
* INTERNAL: | |
* Build instring operator | |
*/ | |
public static ExpressionOperator sybaseInStringOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Instring); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(3); | |
v.add("CHARINDEX("); | |
v.add(", "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
int[] indices = { 1, 0 }; | |
exOperator.setArgumentIndices(indices); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build Sybase equivalent to TO_NUMBER. | |
*/ | |
public static ExpressionOperator sybaseToNumberOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(ToNumber); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("CONVERT(NUMERIC, "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build Sybase equivalent to TO_CHAR. | |
*/ | |
public static ExpressionOperator sybaseToDateToStringOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(DateToString); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("CONVERT(CHAR, "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build Sybase equivalent to TO_DATE. | |
*/ | |
public static ExpressionOperator sybaseToDateOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(ToDate); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("CONVERT(DATETIME, "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build Sybase equivalent to TO_CHAR. | |
*/ | |
public static ExpressionOperator sybaseToCharOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(ToChar); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); | |
v.add("CONVERT(CHAR, "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build Sybase equivalent to TO_CHAR. | |
*/ | |
public static ExpressionOperator sybaseToCharWithFormatOperator() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(ToCharWithFormat); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(3); | |
v.add("CONVERT(CHAR, "); | |
v.add(","); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build the Sybase equivalent to Locate | |
*/ | |
public static ExpressionOperator sybaseLocateOperator() { | |
ExpressionOperator result = simpleTwoArgumentFunction(ExpressionOperator.Locate, "CHARINDEX"); | |
int[] argumentIndices = new int[2]; | |
argumentIndices[0] = 1; | |
argumentIndices[1] = 0; | |
result.setArgumentIndices(argumentIndices); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build the Sybase equivalent to Locate with a start index. | |
* Sybase does not define this, so this gets a little complex... | |
*/ | |
public static ExpressionOperator sybaseLocate2Operator() { | |
ExpressionOperator result = new ExpressionOperator(); | |
result.setSelector(ExpressionOperator.Locate2); | |
result.setType(ExpressionOperator.FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); | |
v.add("CASE (CHARINDEX("); | |
v.add(", SUBSTRING("); | |
v.add(","); | |
v.add(", CHAR_LENGTH("); | |
v.add(")))) WHEN 0 THEN 0 ELSE (CHARINDEX("); | |
v.add(", SUBSTRING("); | |
v.add(","); | |
v.add(", CHAR_LENGTH("); | |
v.add("))) + "); | |
v.add(" - 1) END"); | |
result.printsAs(v); | |
int[] indices = new int[9]; | |
indices[0] = 1; | |
indices[1] = 0; | |
indices[2] = 2; | |
indices[3] = 0; | |
indices[4] = 1; | |
indices[5] = 0; | |
indices[6] = 2; | |
indices[7] = 0; | |
indices[8] = 2; | |
result.setArgumentIndices(indices); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
result.bePrefix(); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator tan() { | |
return simpleFunction(Tan, "TAN"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator tanh() { | |
return simpleFunction(Tanh, "TANH"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator toDate() { | |
return simpleFunction(ToDate, "TO_DATE"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator today() { | |
return currentTimeStamp(); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator currentTimeStamp() { | |
return simpleFunctionNoParentheses(Today, "CURRENT_TIMESTAMP"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator currentDate() { | |
return simpleFunctionNoParentheses(CurrentDate, "CURRENT_DATE"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator currentTime() { | |
return simpleFunctionNoParentheses(CurrentTime, "CURRENT_TIME"); | |
} | |
/** | |
* INTERNAL: | |
* Create the toLowerCase operator. | |
*/ | |
public static ExpressionOperator toLowerCase() { | |
return simpleFunction(ToLowerCase, "LOWER", "toLowerCase"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator toNumber() { | |
return simpleFunction(ToNumber, "TO_NUMBER"); | |
} | |
/** | |
* Print a debug representation of this operator. | |
*/ | |
public String toString() { | |
if ((getDatabaseStrings() == null) || (getDatabaseStrings().length == 0)) { | |
//CR#... Print a useful name for the missing platform operator. | |
return "platform operator - " + getPlatformOperatorName(this.selector); | |
} else { | |
return "operator " + Arrays.asList(getDatabaseStrings()); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Create the TOUPPERCASE operator. | |
*/ | |
public static ExpressionOperator toUpperCase() { | |
return simpleFunction(ToUpperCase, "UPPER", "toUpperCase"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator translate() { | |
ExpressionOperator operator = simpleThreeArgumentFunction(Translate, "TRANSLATE"); | |
operator.setIsBindingSupported(false); | |
return operator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator trim() { | |
return simpleFunction(Trim, "TRIM"); | |
} | |
/** | |
* INTERNAL: | |
* Build Trim operator. | |
*/ | |
public static ExpressionOperator trim2() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Trim2); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(5); | |
v.add("TRIM("); | |
v.add(" FROM "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
exOperator.setIsBindingSupported(false); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator trunc() { | |
return simpleTwoArgumentFunction(Trunc, "TRUNC"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator truncateDate() { | |
return simpleTwoArgumentFunction(TruncateDate, "TRUNC"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator cast() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Cast); | |
exOperator.setName("CAST"); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(5); | |
v.add("CAST("); | |
v.add(" AS "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator extract() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Extract); | |
exOperator.setName("EXTRACT"); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(5); | |
v.add("EXTRACT("); | |
v.add(" FROM "); | |
v.add(")"); | |
exOperator.printsAs(v); | |
int[] indices = new int[2]; | |
indices[0] = 1; | |
indices[1] = 0; | |
exOperator.setArgumentIndices(indices); | |
exOperator.bePrefix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator value() { | |
return simpleFunction(Value, "VALUE"); | |
} | |
/** | |
* INTERNAL: | |
* Build operator. | |
*/ | |
public static ExpressionOperator variance() { | |
return simpleAggregate(Variance, "VARIANCE", "variance"); | |
} | |
/** | |
* INTERNAL: | |
* Create the ANY operator. | |
*/ | |
public static ExpressionOperator any() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Any); | |
exOperator.printsAs("ANY"); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the SOME operator. | |
*/ | |
public static ExpressionOperator some() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Some); | |
exOperator.printsAs("SOME"); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the ALL operator. | |
*/ | |
public static ExpressionOperator all() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(All); | |
exOperator.printsAs("ALL"); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the UNION operator. | |
*/ | |
public static ExpressionOperator union() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Union); | |
exOperator.printsAs("UNION "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the UNION ALL operator. | |
*/ | |
public static ExpressionOperator unionAll() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(UnionAll); | |
exOperator.printsAs("UNION ALL "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the INTERSECT operator. | |
*/ | |
public static ExpressionOperator intersect() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Intersect); | |
exOperator.printsAs("INTERSECT "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the INTERSECT ALL operator. | |
*/ | |
public static ExpressionOperator intersectAll() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(IntersectAll); | |
exOperator.printsAs("INTERSECT ALL "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the EXCEPT operator. | |
*/ | |
public static ExpressionOperator except() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(Except); | |
exOperator.printsAs("EXCEPT "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Create the EXCEPT ALL operator. | |
*/ | |
public static ExpressionOperator exceptAll() { | |
ExpressionOperator exOperator = new ExpressionOperator(); | |
exOperator.setType(FunctionOperator); | |
exOperator.setSelector(ExceptAll); | |
exOperator.printsAs("EXCEPT ALL "); | |
exOperator.bePostfix(); | |
exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return exOperator; | |
} | |
/** | |
* INTERNAL: | |
* Indicates whether operator has selector Any or Some | |
*/ | |
public boolean isAny() { | |
return selector == ExpressionOperator.Any || | |
selector == ExpressionOperator.Some; | |
} | |
/** | |
* INTERNAL: | |
* Indicates whether operator has selector All | |
*/ | |
public boolean isAll() { | |
return selector == ExpressionOperator.All; | |
} | |
/** | |
* INTERNAL: | |
* Indicates whether operator has selector Any, Some or All | |
*/ | |
public boolean isAnyOrAll() { | |
return isAny() || isAll(); | |
} | |
} |