0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
0005: *
0006: *
0007: * The contents of this file are subject to the terms of either the GNU
0008: * General Public License Version 2 only ("GPL") or the Common Development
0009: * and Distribution License("CDDL") (collectively, the "License"). You
0010: * may not use this file except in compliance with the License. You can obtain
0011: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
0012: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
0013: * language governing permissions and limitations under the License.
0014: *
0015: * When distributing the software, include this License Header Notice in each
0016: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
0017: * Sun designates this particular file as subject to the "Classpath" exception
0018: * as provided by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the License
0020: * Header, with the fields enclosed by brackets [] replaced by your own
0021: * identifying information: "Portions Copyrighted [year]
0022: * [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * If you wish your version of this file to be governed by only the CDDL or
0027: * only the GPL Version 2, indicate your decision by adding "[Contributor]
0028: * elects to include this software in this distribution under the [CDDL or GPL
0029: * Version 2] license." If you don't indicate a single choice of license, a
0030: * recipient has the option to distribute your version of this file under
0031: * either the CDDL, the GPL Version 2 or to extend the choice of license to
0032: * its licensees as provided above. However, if you add GPL Version 2 code
0033: * and therefore, elected the GPL Version 2 license, then the option applies
0034: * only if the new code is made subject to such option by the copyright
0035: * holder.
0036: */
0037: package oracle.toplink.essentials.expressions;
0038:
0039: import java.security.AccessController;
0040: import java.security.PrivilegedActionException;
0041: import java.util.*;
0042: import java.io.*;
0043: import oracle.toplink.essentials.internal.expressions.*;
0044: import oracle.toplink.essentials.internal.helper.*;
0045: import oracle.toplink.essentials.exceptions.*;
0046: import oracle.toplink.essentials.internal.helper.ClassConstants;
0047: import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper;
0048: import oracle.toplink.essentials.internal.security.PrivilegedNewInstanceFromClass;
0049:
0050: /**
0051: * <p>
0052: * <b>Purpose</b>: ADVANCED: The expression operator is used internally to define SQL operations and functions.
0053: * It is possible for an advanced user to define their own operators.
0054: */
0055: public class ExpressionOperator implements Serializable {
0056:
0057: /** Required for serialization compatibility. */
0058: static final long serialVersionUID = -7066100204792043980L;
0059: protected int selector;
0060: protected String[] databaseStrings;
0061: protected boolean isPrefix = false;
0062: protected boolean isRepeating = false;
0063: protected Class nodeClass;
0064: protected int type;
0065: protected int[] argumentIndices = null;
0066: protected static Hashtable allOperators;
0067: protected static Hashtable platformOperatorNames;
0068: protected String[] javaStrings;
0069:
0070: /** Operator types */
0071: public static final int LogicalOperator = 1;
0072: public static final int ComparisonOperator = 2;
0073: public static final int AggregateOperator = 3;
0074: public static final int OrderOperator = 4;
0075: public static final int FunctionOperator = 5;
0076:
0077: /** Logical operators */
0078: public static final int And = 1;
0079: public static final int Or = 2;
0080: public static final int Not = 3;
0081:
0082: /** Comparison operators */
0083: public static final int Equal = 4;
0084: public static final int NotEqual = 5;
0085: public static final int EqualOuterJoin = 6;
0086: public static final int LessThan = 7;
0087: public static final int LessThanEqual = 8;
0088: public static final int GreaterThan = 9;
0089: public static final int GreaterThanEqual = 10;
0090: public static final int Like = 11;
0091: public static final int NotLike = 12;
0092: public static final int In = 13;
0093: public static final int InSubQuery = 125;
0094: public static final int NotIn = 14;
0095: public static final int NotInSubQuery = 126;
0096: public static final int Between = 15;
0097: public static final int NotBetween = 16;
0098: public static final int IsNull = 17;
0099: public static final int NotNull = 18;
0100: public static final int Exists = 86;
0101: public static final int NotExists = 88;
0102: public static final int LikeEscape = 89;
0103: public static final int Decode = 105;
0104: public static final int Case = 117;
0105:
0106: /** Aggregate operators */
0107: public static final int Count = 19;
0108: public static final int Sum = 20;
0109: public static final int Average = 21;
0110: public static final int Maximum = 22;
0111: public static final int Minimum = 23;
0112: public static final int StandardDeviation = 24;
0113: public static final int Variance = 25;
0114: public static final int Distinct = 87;
0115:
0116: /** Ordering operators */
0117: public static final int Ascending = 26;
0118: public static final int Descending = 27;
0119:
0120: /** Function operators */
0121:
0122: // General
0123: public static final int ToUpperCase = 28;
0124: public static final int ToLowerCase = 29;
0125: public static final int Chr = 30;
0126: public static final int Concat = 31;
0127: public static final int HexToRaw = 32;
0128: public static final int Initcap = 33;
0129: public static final int Instring = 34;
0130: public static final int Soundex = 35;
0131: public static final int LeftPad = 36;
0132: public static final int LeftTrim = 37;
0133: public static final int Replace = 38;
0134: public static final int RightPad = 39;
0135: public static final int RightTrim = 40;
0136: public static final int Substring = 41;
0137: public static final int ToNumber = 42;
0138: public static final int Translate = 43;
0139: public static final int Trim = 44;
0140: public static final int Ascii = 45;
0141: public static final int Length = 46;
0142: public static final int CharIndex = 96;
0143: public static final int CharLength = 97;
0144: public static final int Difference = 98;
0145: public static final int Reverse = 99;
0146: public static final int Replicate = 100;
0147: public static final int Right = 101;
0148: public static final int Locate = 112;
0149: public static final int Locate2 = 113;
0150: public static final int ToChar = 114;
0151: public static final int ToCharWithFormat = 115;
0152: public static final int RightTrim2 = 116;
0153: public static final int Any = 118;
0154: public static final int Some = 119;
0155: public static final int All = 120;
0156: public static final int Trim2 = 121;
0157: public static final int LeftTrim2 = 122;
0158:
0159: // Date
0160: public static final int AddMonths = 47;
0161: public static final int DateToString = 48;
0162: public static final int LastDay = 49;
0163: public static final int MonthsBetween = 50;
0164: public static final int NextDay = 51;
0165: public static final int RoundDate = 52;
0166: public static final int ToDate = 53;
0167: public static final int Today = 54;
0168: public static final int AddDate = 90;
0169: public static final int DateName = 92;
0170: public static final int DatePart = 93;
0171: public static final int DateDifference = 94;
0172: public static final int TruncateDate = 102;
0173: public static final int NewTime = 103;
0174: public static final int Nvl = 104;
0175: public static final int CurrentDate = 123;
0176: public static final int CurrentTime = 124;
0177:
0178: // Math
0179: public static final int Ceil = 55;
0180: public static final int Cos = 56;
0181: public static final int Cosh = 57;
0182: public static final int Abs = 58;
0183: public static final int Acos = 59;
0184: public static final int Asin = 60;
0185: public static final int Atan = 61;
0186: public static final int Exp = 62;
0187: public static final int Sqrt = 63;
0188: public static final int Floor = 64;
0189: public static final int Ln = 65;
0190: public static final int Log = 66;
0191: public static final int Mod = 67;
0192: public static final int Power = 68;
0193: public static final int Round = 69;
0194: public static final int Sign = 70;
0195: public static final int Sin = 71;
0196: public static final int Sinh = 72;
0197: public static final int Tan = 73;
0198: public static final int Tanh = 74;
0199: public static final int Trunc = 75;
0200: public static final int Greatest = 76;
0201: public static final int Least = 77;
0202: public static final int Add = 78;
0203: public static final int Subtract = 79;
0204: public static final int Divide = 80;
0205: public static final int Multiply = 81;
0206: public static final int Atan2 = 91;
0207: public static final int Cot = 95;
0208:
0209: // Object-relational
0210: public static final int Deref = 82;
0211: public static final int Ref = 83;
0212: public static final int RefToHex = 84;
0213: public static final int Value = 85;
0214:
0215: //XML Specific
0216: public static final int Extract = 106;
0217: public static final int ExtractValue = 107;
0218: public static final int ExistsNode = 108;
0219: public static final int GetStringVal = 109;
0220: public static final int GetNumberVal = 110;
0221: public static final int IsFragment = 111;
0222:
0223: /**
0224: * ADVANCED:
0225: * Create a new operator.
0226: */
0227: public ExpressionOperator() {
0228: this .type = FunctionOperator;
0229: // For bug 2780072 provide default behavior to make this class more useable.
0230: setNodeClass(ClassConstants.FunctionExpression_Class);
0231: }
0232:
0233: /**
0234: * ADVANCED:
0235: * Create a new operator with the given name(s) and strings to print.
0236: */
0237: public ExpressionOperator(int selector, Vector newDatabaseStrings) {
0238: this .type = FunctionOperator;
0239: // For bug 2780072 provide default behavior to make this class more useable.
0240: setNodeClass(ClassConstants.FunctionExpression_Class);
0241: this .selector = selector;
0242: this .printsAs(newDatabaseStrings);
0243: }
0244:
0245: /**
0246: * INTERNAL:
0247: * Build operator.
0248: */
0249: public static ExpressionOperator abs() {
0250: return simpleFunction(Abs, "ABS");
0251: }
0252:
0253: /**
0254: * INTERNAL:
0255: * Build operator.
0256: */
0257: public static ExpressionOperator acos() {
0258: return simpleFunction(Acos, "ACOS");
0259: }
0260:
0261: /**
0262: * INTERNAL:
0263: * Build operator.
0264: */
0265: public static ExpressionOperator addDate() {
0266: ExpressionOperator exOperator = simpleThreeArgumentFunction(
0267: AddDate, "DATEADD");
0268: int[] indices = new int[3];
0269: indices[0] = 1;
0270: indices[1] = 2;
0271: indices[2] = 0;
0272:
0273: exOperator.setArgumentIndices(indices);
0274: return exOperator;
0275: }
0276:
0277: /**
0278: * INTERNAL:
0279: * Build operator.
0280: */
0281: public static ExpressionOperator addMonths() {
0282: return simpleTwoArgumentFunction(AddMonths, "ADD_MONTHS");
0283: }
0284:
0285: /**
0286: * ADVANCED:
0287: * Add an operator to the global list of operators.
0288: */
0289: public static void addOperator(ExpressionOperator exOperator) {
0290: allOperators.put(new Integer(exOperator.getSelector()),
0291: exOperator);
0292: }
0293:
0294: /**
0295: * INTERNAL:
0296: * Create the AND operator.
0297: */
0298: public static ExpressionOperator and() {
0299: return simpleLogical(And, "AND", "and");
0300: }
0301:
0302: /**
0303: * INTERNAL:
0304: * Apply this to an object in memory.
0305: * Throw an error if the function is not supported.
0306: */
0307: public Object applyFunction(Object source, Vector arguments) {
0308: if (source instanceof String) {
0309: if (getSelector() == ToUpperCase) {
0310: return ((String) source).toUpperCase();
0311: } else if (getSelector() == ToLowerCase) {
0312: return ((String) source).toLowerCase();
0313: } else if ((getSelector() == Concat)
0314: && (arguments.size() == 1)
0315: && (arguments.elementAt(0) instanceof String)) {
0316: return ((String) source).concat((String) arguments
0317: .elementAt(0));
0318: } else if ((getSelector() == Substring)
0319: && (arguments.size() == 2)
0320: && (arguments.elementAt(0) instanceof Number)
0321: && (arguments.elementAt(1) instanceof Number)) {
0322: // assume the first parameter to be 1-based first index of the substring, the second - substring length.
0323: int beginIndexInclusive = ((Number) arguments
0324: .elementAt(0)).intValue() - 1;
0325: int endIndexExclusive = beginIndexInclusive
0326: + ((Number) arguments.elementAt(1)).intValue();
0327: return ((String) source).substring(beginIndexInclusive,
0328: endIndexExclusive);
0329: } else if (getSelector() == ToNumber) {
0330: return new java.math.BigDecimal((String) source);
0331: } else if (getSelector() == Trim) {
0332: return ((String) source).trim();
0333: } else if (getSelector() == Length) {
0334: return new Integer(((String) source).length());
0335: }
0336: } else if (source instanceof Number) {
0337: if (getSelector() == Ceil) {
0338: return new Double(Math.ceil(((Number) source)
0339: .doubleValue()));
0340: } else if (getSelector() == Cos) {
0341: return new Double(Math.cos(((Number) source)
0342: .doubleValue()));
0343: } else if (getSelector() == Abs) {
0344: return new Double(Math.abs(((Number) source)
0345: .doubleValue()));
0346: } else if (getSelector() == Acos) {
0347: return new Double(Math.acos(((Number) source)
0348: .doubleValue()));
0349: } else if (getSelector() == Asin) {
0350: return new Double(Math.asin(((Number) source)
0351: .doubleValue()));
0352: } else if (getSelector() == Atan) {
0353: return new Double(Math.atan(((Number) source)
0354: .doubleValue()));
0355: } else if (getSelector() == Exp) {
0356: return new Double(Math.exp(((Number) source)
0357: .doubleValue()));
0358: } else if (getSelector() == Sqrt) {
0359: return new Double(Math.sqrt(((Number) source)
0360: .doubleValue()));
0361: } else if (getSelector() == Floor) {
0362: return new Double(Math.floor(((Number) source)
0363: .doubleValue()));
0364: } else if (getSelector() == Log) {
0365: return new Double(Math.log(((Number) source)
0366: .doubleValue()));
0367: } else if ((getSelector() == Power)
0368: && (arguments.size() == 1)
0369: && (arguments.elementAt(0) instanceof Number)) {
0370: return new Double(Math.pow(((Number) source)
0371: .doubleValue(), (((Number) arguments
0372: .elementAt(0)).doubleValue())));
0373: } else if (getSelector() == Round) {
0374: return new Double(Math.round(((Number) source)
0375: .doubleValue()));
0376: } else if (getSelector() == Sin) {
0377: return new Double(Math.sin(((Number) source)
0378: .doubleValue()));
0379: } else if (getSelector() == Tan) {
0380: return new Double(Math.tan(((Number) source)
0381: .doubleValue()));
0382: } else if ((getSelector() == Greatest)
0383: && (arguments.size() == 1)
0384: && (arguments.elementAt(0) instanceof Number)) {
0385: return new Double(Math.max(((Number) source)
0386: .doubleValue(), (((Number) arguments
0387: .elementAt(0)).doubleValue())));
0388: } else if ((getSelector() == Least)
0389: && (arguments.size() == 1)
0390: && (arguments.elementAt(0) instanceof Number)) {
0391: return new Double(Math.min(((Number) source)
0392: .doubleValue(), (((Number) arguments
0393: .elementAt(0)).doubleValue())));
0394: } else if ((getSelector() == Add)
0395: && (arguments.size() == 1)
0396: && (arguments.elementAt(0) instanceof Number)) {
0397: return new Double(((Number) source).doubleValue()
0398: + (((Number) arguments.elementAt(0))
0399: .doubleValue()));
0400: } else if ((getSelector() == Subtract)
0401: && (arguments.size() == 1)
0402: && (arguments.elementAt(0) instanceof Number)) {
0403: return new Double(((Number) source).doubleValue()
0404: - (((Number) arguments.elementAt(0))
0405: .doubleValue()));
0406: } else if ((getSelector() == Divide)
0407: && (arguments.size() == 1)
0408: && (arguments.elementAt(0) instanceof Number)) {
0409: return new Double(((Number) source).doubleValue()
0410: / (((Number) arguments.elementAt(0))
0411: .doubleValue()));
0412: } else if ((getSelector() == Multiply)
0413: && (arguments.size() == 1)
0414: && (arguments.elementAt(0) instanceof Number)) {
0415: return new Double(((Number) source).doubleValue()
0416: * (((Number) arguments.elementAt(0))
0417: .doubleValue()));
0418: }
0419: }
0420:
0421: throw QueryException.cannotConformExpression();
0422: }
0423:
0424: /**
0425: * INTERNAL:
0426: * Create the ASCENDING operator.
0427: */
0428: public static ExpressionOperator ascending() {
0429: return simpleOrdering(Ascending, "ASC", "ascending");
0430: }
0431:
0432: /**
0433: * INTERNAL:
0434: * Build operator.
0435: */
0436: public static ExpressionOperator ascii() {
0437: return simpleFunction(Ascii, "ASCII");
0438: }
0439:
0440: /**
0441: * INTERNAL:
0442: * Build operator.
0443: */
0444: public static ExpressionOperator asin() {
0445: return simpleFunction(Asin, "ASIN");
0446: }
0447:
0448: /**
0449: * INTERNAL:
0450: * Build operator.
0451: */
0452: public static ExpressionOperator atan() {
0453: return simpleFunction(Atan, "ATAN");
0454: }
0455:
0456: /**
0457: * INTERNAL:
0458: * Create the AVERAGE operator.
0459: */
0460: public static ExpressionOperator average() {
0461: return simpleAggregate(Average, "AVG", "average");
0462: }
0463:
0464: /**
0465: * ADVANCED:
0466: * Tell the operator to be postfix, i.e. its strings start printing after
0467: * those of its first argument.
0468: */
0469: public void bePostfix() {
0470: isPrefix = false;
0471: }
0472:
0473: /**
0474: * ADVANCED:
0475: * Tell the operator to be pretfix, i.e. its strings start printing before
0476: * those of its first argument.
0477: */
0478: public void bePrefix() {
0479: isPrefix = true;
0480: }
0481:
0482: /**
0483: * INTERNAL:
0484: * Make this a repeating argument. Currently unused.
0485: */
0486: public void beRepeating() {
0487: isRepeating = true;
0488: }
0489:
0490: /**
0491: * INTERNAL:
0492: * Create the BETWEEN Operator
0493: */
0494: public static ExpressionOperator between() {
0495: ExpressionOperator result = new ExpressionOperator();
0496: result.setSelector(Between);
0497: result.setType(ComparisonOperator);
0498: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
0499: .newInstance();
0500: v.addElement("(");
0501: v.addElement(" BETWEEN ");
0502: v.addElement(" AND ");
0503: v.addElement(")");
0504: result.printsAs(v);
0505: result.bePrefix();
0506: result.setNodeClass(ClassConstants.FunctionExpression_Class);
0507: return result;
0508: }
0509:
0510: /**
0511: * INTERNAL:
0512: * Build operator.
0513: * Note: This operator works differently from other operators.
0514: * @see Expression#caseStatement(Hashtable, String)
0515: */
0516: public static ExpressionOperator caseStatement() {
0517: ExpressionOperator exOperator = new ExpressionOperator();
0518: exOperator.setType(FunctionOperator);
0519: exOperator.setSelector(Case);
0520: exOperator.bePrefix();
0521: exOperator.setNodeClass(FunctionExpression.class);
0522: return exOperator;
0523: }
0524:
0525: /**
0526: * INTERNAL:
0527: * Build operator.
0528: */
0529: public static ExpressionOperator ceil() {
0530: return simpleFunction(Ceil, "CEIL");
0531: }
0532:
0533: /**
0534: * INTERNAL:
0535: * Build operator.
0536: */
0537: public static ExpressionOperator charIndex() {
0538: return simpleTwoArgumentFunction(CharIndex, "CHARINDEX");
0539: }
0540:
0541: /**
0542: * INTERNAL:
0543: * Build operator.
0544: */
0545: public static ExpressionOperator charLength() {
0546: return simpleFunction(CharLength, "CHAR_LENGTH");
0547: }
0548:
0549: /**
0550: * INTERNAL:
0551: * Build operator.
0552: */
0553: public static ExpressionOperator chr() {
0554: return simpleFunction(Chr, "CHR");
0555: }
0556:
0557: /**
0558: * INTERNAL:
0559: * Build operator.
0560: */
0561: public static ExpressionOperator concat() {
0562: return simpleMath(Concat, "+");
0563: }
0564:
0565: /**
0566: * INTERNAL:
0567: * Compare bewteen in memory.
0568: */
0569: public boolean conformBetween(Object left, Object right) {
0570: Object start = ((Vector) right).elementAt(0);
0571: Object end = ((Vector) right).elementAt(1);
0572: if ((left == null) || (start == null) || (end == null)) {
0573: return false;
0574: }
0575: if ((left instanceof Number) && (start instanceof Number)
0576: && (end instanceof Number)) {
0577: return ((((Number) left).doubleValue()) >= (((Number) start)
0578: .doubleValue()))
0579: && ((((Number) left).doubleValue()) <= (((Number) end)
0580: .doubleValue()));
0581: } else if ((left instanceof String)
0582: && (start instanceof String) && (end instanceof String)) {
0583: return ((((String) left).compareTo(((String) start)) > 0) || (((String) left)
0584: .compareTo(((String) start)) == 0))
0585: && ((((String) left).compareTo(((String) end)) < 0) || (((String) left)
0586: .compareTo(((String) end)) == 0));
0587: } else if ((left instanceof java.util.Date)
0588: && (start instanceof java.util.Date)
0589: && (end instanceof java.util.Date)) {
0590: return (((java.util.Date) left)
0591: .after(((java.util.Date) start)) || ((java.util.Date) left)
0592: .equals(((java.util.Date) start)))
0593: && (((java.util.Date) left)
0594: .before(((java.util.Date) end)) || ((java.util.Date) left)
0595: .equals(((java.util.Date) end)));
0596: }
0597:
0598: throw QueryException.cannotConformExpression();
0599: }
0600:
0601: /**
0602: * INTERNAL:
0603: * Compare like in memory.
0604: * This only works for % not _.
0605: * @author Christian Weeks aka ChristianLink
0606: */
0607: public boolean conformLike(Object left, Object right) {
0608: if ((right == null) && (left == null)) {
0609: return true;
0610: }
0611: if (!(right instanceof String) || !(left instanceof String)) {
0612: throw QueryException.cannotConformExpression();
0613: }
0614: String likeString = (String) right;
0615: if (likeString.indexOf("_") != -1) {
0616: throw QueryException.cannotConformExpression();
0617: }
0618: String value = (String) left;
0619: if (likeString.indexOf("%") == -1) {
0620: // No % symbols
0621: return left.equals(right);
0622: }
0623: boolean strictStart = !likeString.startsWith("%");
0624: boolean strictEnd = !likeString.endsWith("%");
0625: StringTokenizer tokens = new StringTokenizer(likeString, "%");
0626: int lastPosition = 0;
0627: String lastToken = null;
0628: if (strictStart) {
0629: lastToken = tokens.nextToken();
0630: if (!value.startsWith(lastToken)) {
0631: return false;
0632: }
0633: }
0634: while (tokens.hasMoreTokens()) {
0635: lastToken = tokens.nextToken();
0636: lastPosition = value.indexOf(lastToken, lastPosition);
0637: if (lastPosition < 0) {
0638: return false;
0639: }
0640: }
0641: if (strictEnd) {
0642: return value.endsWith(lastToken);
0643: }
0644: return true;
0645: }
0646:
0647: /**
0648: * INTERNAL:
0649: * Build operator.
0650: */
0651: public static ExpressionOperator cos() {
0652: return simpleFunction(Cos, "COS");
0653: }
0654:
0655: /**
0656: * INTERNAL:
0657: * Build operator.
0658: */
0659: public static ExpressionOperator cosh() {
0660: return simpleFunction(Cosh, "COSH");
0661: }
0662:
0663: /**
0664: * INTERNAL:
0665: * Build operator.
0666: */
0667: public static ExpressionOperator cot() {
0668: return simpleFunction(Cot, "COT");
0669: }
0670:
0671: /**
0672: * INTERNAL:
0673: * Create the COUNT operator.
0674: */
0675: public static ExpressionOperator count() {
0676: return simpleAggregate(Count, "COUNT", "count");
0677: }
0678:
0679: /**
0680: * INTERNAL:
0681: * Build operator.
0682: */
0683: public static ExpressionOperator dateDifference() {
0684: return simpleThreeArgumentFunction(DateDifference, "DATEDIFF");
0685: }
0686:
0687: /**
0688: * INTERNAL:
0689: * Build operator.
0690: */
0691: public static ExpressionOperator dateName() {
0692: return simpleTwoArgumentFunction(DateName, "DATENAME");
0693: }
0694:
0695: /**
0696: * INTERNAL:
0697: * Oracle equivalent to DATENAME is TO_CHAR.
0698: */
0699: public static ExpressionOperator oracleDateName() {
0700: ExpressionOperator exOperator = new ExpressionOperator();
0701: exOperator.setType(FunctionOperator);
0702: exOperator.setSelector(DateName);
0703: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
0704: .newInstance(3);
0705: v.addElement("TO_CHAR(");
0706: v.addElement(", '");
0707: v.addElement("')");
0708: exOperator.printsAs(v);
0709: exOperator.bePrefix();
0710: int[] indices = { 1, 0 };
0711: exOperator.setArgumentIndices(indices);
0712: exOperator
0713: .setNodeClass(ClassConstants.FunctionExpression_Class);
0714: return exOperator;
0715: }
0716:
0717: /**
0718: * INTERNAL:
0719: * Build operator.
0720: */
0721: public static ExpressionOperator datePart() {
0722: return simpleTwoArgumentFunction(DatePart, "DATEPART");
0723: }
0724:
0725: /**
0726: * INTERNAL:
0727: * Build operator.
0728: */
0729: public static ExpressionOperator dateToString() {
0730: return simpleFunction(DateToString, "TO_CHAR");
0731: }
0732:
0733: /**
0734: * INTERNAL:
0735: * Build operator.
0736: */
0737: public static ExpressionOperator toChar() {
0738: return simpleFunction(ToChar, "TO_CHAR");
0739: }
0740:
0741: /**
0742: * INTERNAL:
0743: * Build operator.
0744: */
0745: public static ExpressionOperator toCharWithFormat() {
0746: return simpleTwoArgumentFunction(ToCharWithFormat, "TO_CHAR");
0747: }
0748:
0749: /**
0750: * INTERNAL:
0751: * Build operator.
0752: * Note: This operator works differently from other operators.
0753: * @see Expression#decode(Hashtable, String)
0754: */
0755: public static ExpressionOperator decode() {
0756: ExpressionOperator exOperator = new ExpressionOperator();
0757:
0758: exOperator.setSelector(Decode);
0759:
0760: exOperator.setNodeClass(FunctionExpression.class);
0761: exOperator.setType(FunctionOperator);
0762: exOperator.bePrefix();
0763: return exOperator;
0764: }
0765:
0766: /**
0767: * INTERNAL:
0768: * Build operator.
0769: */
0770: public static ExpressionOperator deref() {
0771: return simpleFunction(Deref, "DEREF");
0772: }
0773:
0774: /**
0775: * INTERNAL:
0776: * Create the DESCENDING operator.
0777: */
0778: public static ExpressionOperator descending() {
0779: return simpleOrdering(Descending, "DESC", "descending");
0780: }
0781:
0782: /**
0783: * INTERNAL:
0784: * Build operator.
0785: */
0786: public static ExpressionOperator difference() {
0787: return simpleTwoArgumentFunction(Difference, "DIFFERENCE");
0788: }
0789:
0790: /**
0791: * INTERNAL:
0792: * Create the DISTINCT operator.
0793: */
0794: public static ExpressionOperator distinct() {
0795: return simpleFunction(Distinct, "DISTINCT", "distinct");
0796: }
0797:
0798: /**
0799: * INTERNAL:
0800: * Compare the values in memory.
0801: * Used for in-memory querying, all operators are not support.
0802: */
0803: public boolean doesRelationConform(Object left, Object right) {
0804: // Big case statement follows.
0805: // Note, compareTo for String returns a number <= -1 if the String is less than. We assumed that
0806: // it would return -1. The same thing for strings that are greater than (ie it returns >= 1). PWK
0807: // Equals
0808: if (getSelector() == Equal) {
0809: if ((left == null) && (right == null)) {
0810: return true;
0811: } else if ((left == null) || (right == null)) {
0812: return false;
0813: }
0814: if (((left instanceof Number) && (right instanceof Number))
0815: && (left.getClass() != right.getClass())) {
0816: return ((Number) left).doubleValue() == ((Number) right)
0817: .doubleValue();
0818: }
0819: return left.equals(right);
0820: } else if (getSelector() == NotEqual) {
0821: if ((left == null) && (right == null)) {
0822: return false;
0823: } else if ((left == null) || (right == null)) {
0824: return true;
0825: }
0826: return !left.equals(right);
0827: } else if (getSelector() == IsNull) {
0828: return (left == null);
0829: }
0830: if (getSelector() == NotNull) {
0831: return (left != null);
0832: }
0833: // Less thans, greater thans
0834: else if (getSelector() == LessThan) {// You have gottan love polymorphism in Java, NOT!!!
0835: if ((left == null) || (right == null)) {
0836: return false;
0837: }
0838: if ((left instanceof Number) && (right instanceof Number)) {
0839: return (((Number) left).doubleValue()) < (((Number) right)
0840: .doubleValue());
0841: } else if ((left instanceof String)
0842: && (right instanceof String)) {
0843: return ((String) left).compareTo(((String) right)) < 0;
0844: } else if ((left instanceof java.util.Date)
0845: && (right instanceof java.util.Date)) {
0846: return ((java.util.Date) left)
0847: .before(((java.util.Date) right));
0848: }
0849: } else if (getSelector() == LessThanEqual) {
0850: if ((left == null) && (right == null)) {
0851: return true;
0852: } else if ((left == null) || (right == null)) {
0853: return false;
0854: }
0855: if ((left instanceof Number) && (right instanceof Number)) {
0856: return (((Number) left).doubleValue()) <= (((Number) right)
0857: .doubleValue());
0858: } else if ((left instanceof String)
0859: && (right instanceof String)) {
0860: int compareValue = ((String) left)
0861: .compareTo(((String) right));
0862: return (compareValue < 0) || (compareValue == 0);
0863: } else if ((left instanceof java.util.Date)
0864: && (right instanceof java.util.Date)) {
0865: return ((java.util.Date) left)
0866: .equals(((java.util.Date) right))
0867: || ((java.util.Date) left)
0868: .before(((java.util.Date) right));
0869: }
0870: } else if (getSelector() == GreaterThan) {
0871: if ((left == null) || (right == null)) {
0872: return false;
0873: }
0874: if ((left instanceof Number) && (right instanceof Number)) {
0875: return (((Number) left).doubleValue()) > (((Number) right)
0876: .doubleValue());
0877: } else if ((left instanceof String)
0878: && (right instanceof String)) {
0879: int compareValue = ((String) left)
0880: .compareTo(((String) right));
0881: return (compareValue > 0);
0882: } else if ((left instanceof java.util.Date)
0883: && (right instanceof java.util.Date)) {
0884: return ((java.util.Date) left)
0885: .after(((java.util.Date) right));
0886: }
0887: } else if (getSelector() == GreaterThanEqual) {
0888: if ((left == null) && (right == null)) {
0889: return true;
0890: } else if ((left == null) || (right == null)) {
0891: return false;
0892: }
0893: if ((left instanceof Number) && (right instanceof Number)) {
0894: return (((Number) left).doubleValue()) >= (((Number) right)
0895: .doubleValue());
0896: } else if ((left instanceof String)
0897: && (right instanceof String)) {
0898: int compareValue = ((String) left)
0899: .compareTo(((String) right));
0900: return (compareValue > 0) || (compareValue == 0);
0901: } else if ((left instanceof java.util.Date)
0902: && (right instanceof java.util.Date)) {
0903: return ((java.util.Date) left)
0904: .equals(((java.util.Date) right))
0905: || ((java.util.Date) left)
0906: .after(((java.util.Date) right));
0907: }
0908: }
0909: // Between
0910: else if ((getSelector() == Between)
0911: && (right instanceof Vector)
0912: && (((Vector) right).size() == 2)) {
0913: return conformBetween(left, right);
0914: } else if ((getSelector() == NotBetween)
0915: && (right instanceof Vector)
0916: && (((Vector) right).size() == 2)) {
0917: return !conformBetween(left, right);
0918: }
0919: // In
0920: else if ((getSelector() == In) && (right instanceof Vector)) {
0921: return ((Vector) right).contains(left);
0922: } else if ((getSelector() == NotIn)
0923: && (right instanceof Vector)) {
0924: return !((Vector) right).contains(left);
0925: }
0926: // Like
0927: //conformLike(left, right);
0928: else if ((getSelector() == Like) || (getSelector() == NotLike)) {
0929: // the regular expression framework we use to conform like is only supported in
0930: // JDK 1.4 and later. We will ask our JavaPlatform to do this for us.
0931: int doesLikeConform = JavaPlatform.conformLike(left, right);
0932: if (doesLikeConform == JavaPlatform.TRUE) {
0933: return getSelector() == Like;// Negate for NotLike
0934: } else if (doesLikeConform == JavaPlatform.FALSE) {
0935: return getSelector() != Like;// Negate for NotLike
0936: }
0937: }
0938:
0939: throw QueryException.cannotConformExpression();
0940: }
0941:
0942: /**
0943: * INTERNAL:
0944: * Initialize the outer join operator
0945: * Note: This is merely a shell which is incomplete, and
0946: * so will be replaced by the platform's operator when we
0947: * go to print. We need to create this here so that the expression
0948: * class is correct, normally it assumes functions for unknown operators.
0949: */
0950: public static ExpressionOperator equalOuterJoin() {
0951: return simpleRelation(EqualOuterJoin, "=*");
0952: }
0953:
0954: /**
0955: * PUBLIC:
0956: * Test for equality
0957: */
0958: public boolean equals(Object object) {
0959: if (!(object instanceof ExpressionOperator)) {
0960: return false;
0961: }
0962: return getSelector() == ((ExpressionOperator) object)
0963: .getSelector();
0964: }
0965:
0966: /**
0967: * PUBLIC:
0968: * Return the hash-code based on the unique selector.
0969: */
0970: public int hashCode() {
0971: return getSelector();
0972: }
0973:
0974: /**
0975: * INTERNAL:
0976: * Create the EXISTS operator.
0977: */
0978: public static ExpressionOperator exists() {
0979: ExpressionOperator exOperator = new ExpressionOperator();
0980: exOperator.setType(FunctionOperator);
0981: exOperator.setSelector(Exists);
0982: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
0983: .newInstance(2);
0984: v.addElement("EXISTS" + " ");
0985: v.addElement(" ");
0986: exOperator.printsAs(v);
0987: exOperator.bePrefix();
0988: exOperator
0989: .setNodeClass(ClassConstants.FunctionExpression_Class);
0990: return exOperator;
0991: }
0992:
0993: /**
0994: * INTERNAL:
0995: * Build operator.
0996: */
0997: public static ExpressionOperator exp() {
0998: return simpleFunction(Exp, "EXP");
0999: }
1000:
1001: /**
1002: * INTERNAL:
1003: * Create an expression for this operator, using the given base.
1004: */
1005: public Expression expressionFor(Expression base) {
1006: return expressionForArguments(
1007: base,
1008: oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1009: .newInstance(0));
1010: }
1011:
1012: /**
1013: * INTERNAL:
1014: * Create an expression for this operator, using the given base and a single argument.
1015: */
1016: public Expression expressionFor(Expression base, Object value) {
1017: return newExpressionForArgument(base, value);
1018: }
1019:
1020: /**
1021: * INTERNAL:
1022: * Create an expression for this operator, using the given base and a single argument.
1023: * Base is used last in the expression
1024: */
1025: public Expression expressionForWithBaseLast(Expression base,
1026: Object value) {
1027: return newExpressionForArgumentWithBaseLast(base, value);
1028: }
1029:
1030: /**
1031: * INTERNAL:
1032: * Create an expression for this operator, using the given base and arguments.
1033: */
1034: public Expression expressionForArguments(Expression base,
1035: Vector arguments) {
1036: return newExpressionForArguments(base, arguments);
1037: }
1038:
1039: /**
1040: * INTERNAL:
1041: * Create the extract expression operator
1042: */
1043: public static ExpressionOperator extract() {
1044: ExpressionOperator result = new ExpressionOperator();
1045: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1046: .newInstance();
1047: v.addElement("extract(");
1048: v.addElement(",");
1049: v.addElement(")");
1050: result.printsAs(v);
1051: result.bePrefix();
1052: result.setSelector(Extract);
1053: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1054: return result;
1055: }
1056:
1057: /**
1058: * INTERNAL:
1059: * Create the extractValue expression operator
1060: */
1061: public static ExpressionOperator extractValue() {
1062: ExpressionOperator result = new ExpressionOperator();
1063: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1064: .newInstance();
1065: v.addElement("extractValue(");
1066: v.addElement(",");
1067: v.addElement(")");
1068: result.printsAs(v);
1069: result.bePrefix();
1070: result.setSelector(ExtractValue);
1071: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1072: return result;
1073: }
1074:
1075: /**
1076: * INTERNAL:
1077: * Create the existsNode expression operator
1078: */
1079: public static ExpressionOperator existsNode() {
1080: ExpressionOperator result = new ExpressionOperator();
1081: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1082: .newInstance();
1083: v.addElement("existsNode(");
1084: v.addElement(",");
1085: v.addElement(")");
1086: result.printsAs(v);
1087: result.bePrefix();
1088: result.setSelector(ExistsNode);
1089: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1090: return result;
1091: }
1092:
1093: public static ExpressionOperator getStringVal() {
1094: ExpressionOperator result = new ExpressionOperator();
1095: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1096: .newInstance();
1097: v.addElement(".getStringVal()");
1098: result.printsAs(v);
1099: result.bePostfix();
1100: result.setSelector(GetStringVal);
1101: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1102: return result;
1103: }
1104:
1105: public static ExpressionOperator getNumberVal() {
1106: ExpressionOperator result = new ExpressionOperator();
1107: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1108: .newInstance();
1109: v.addElement(".getNumberVal()");
1110: result.printsAs(v);
1111: result.bePostfix();
1112: result.setSelector(GetNumberVal);
1113: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1114: return result;
1115: }
1116:
1117: public static ExpressionOperator isFragment() {
1118: ExpressionOperator result = new ExpressionOperator();
1119: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1120: .newInstance();
1121: v.addElement(".isFragment()");
1122: result.printsAs(v);
1123: result.bePostfix();
1124: result.setSelector(IsFragment);
1125: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1126: return result;
1127: }
1128:
1129: /**
1130: * INTERNAL:
1131: * Build operator.
1132: */
1133: public static ExpressionOperator floor() {
1134: return simpleFunction(Floor, "FLOOR");
1135: }
1136:
1137: /**
1138: * ADVANCED:
1139: * Return the hashtable of all operators.
1140: */
1141: public static synchronized Hashtable getAllOperators() {
1142: if (allOperators == null) {
1143: initializeOperators();
1144: }
1145: return allOperators;
1146: }
1147:
1148: /**
1149: * INTERNAL:
1150: */
1151: public String[] getDatabaseStrings() {
1152: return databaseStrings;
1153: }
1154:
1155: /**
1156: * INTERNAL:
1157: */
1158: public String[] getJavaStrings() {
1159: return javaStrings;
1160: }
1161:
1162: /**
1163: * INTERNAL:
1164: */
1165: public Class getNodeClass() {
1166: return nodeClass;
1167: }
1168:
1169: /**
1170: * INTERNAL:
1171: * Lookup the operator with the given name.
1172: */
1173: public static ExpressionOperator getOperator(Integer selector) {
1174: return (ExpressionOperator) getAllOperators().get(selector);
1175: }
1176:
1177: /**
1178: * INTERNAL:
1179: * Return the selector id.
1180: */
1181: public int getSelector() {
1182: return selector;
1183: }
1184:
1185: /**
1186: * ADVANCED:
1187: * Return the type of function.
1188: * This must be one of the static function types defined in this class.
1189: */
1190: public int getType() {
1191: return this .type;
1192: }
1193:
1194: /**
1195: * INTERNAL:
1196: * Build operator.
1197: */
1198: public static ExpressionOperator greatest() {
1199: return simpleTwoArgumentFunction(Greatest, "GREATEST");
1200: }
1201:
1202: /**
1203: * INTERNAL:
1204: * Build operator.
1205: */
1206: public static ExpressionOperator hexToRaw() {
1207: return simpleFunction(HexToRaw, "HEXTORAW");
1208: }
1209:
1210: /**
1211: * INTERNAL:
1212: * Build operator.
1213: */
1214: public static ExpressionOperator ifNull() {
1215: return simpleTwoArgumentFunction(Nvl, "NVL");
1216: }
1217:
1218: /**
1219: * INTERNAL:
1220: * Create the IN operator.
1221: */
1222: public static ExpressionOperator in() {
1223: ExpressionOperator result = new ExpressionOperator();
1224: result.setType(ExpressionOperator.FunctionOperator);
1225: result.setSelector(In);
1226: Vector v = new Vector(2);
1227: v.addElement(" IN (");
1228: v.addElement(")");
1229: result.printsAs(v);
1230: result.bePostfix();
1231: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1232: return result;
1233: }
1234:
1235: /**
1236: * INTERNAL:
1237: * Create the IN operator taking a subquery.
1238: * Note, the subquery itself comes with parenethesis, so the IN operator
1239: * should not add any parenethesis.
1240: */
1241: public static ExpressionOperator inSubQuery() {
1242: ExpressionOperator result = new ExpressionOperator();
1243: result.setType(ExpressionOperator.FunctionOperator);
1244: result.setSelector(InSubQuery);
1245: Vector v = new Vector(1);
1246: v.addElement(" IN ");
1247: result.printsAs(v);
1248: result.bePostfix();
1249: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1250: return result;
1251: }
1252:
1253: /**
1254: * INTERNAL:
1255: * Build operator.
1256: */
1257: public static ExpressionOperator initcap() {
1258: return simpleFunction(Initcap, "INITCAP");
1259: }
1260:
1261: /**
1262: * INTERNAL:
1263: */
1264: protected static void initializeAggregateFunctionOperators() {
1265: addOperator(count());
1266: addOperator(sum());
1267: addOperator(average());
1268: addOperator(minimum());
1269: addOperator(maximum());
1270: addOperator(variance());
1271: addOperator(standardDeviation());
1272: addOperator(distinct());
1273: }
1274:
1275: /**
1276: * INTERNAL:
1277: */
1278: protected static void initializeFunctionOperators() {
1279: addOperator(notOperator());
1280: addOperator(ascending());
1281: addOperator(descending());
1282: addOperator(any());
1283: addOperator(some());
1284: addOperator(all());
1285: addOperator(in());
1286: addOperator(inSubQuery());
1287: addOperator(notIn());
1288: addOperator(notInSubQuery());
1289: }
1290:
1291: /**
1292: * INTERNAL:
1293: */
1294: protected static void initializeLogicalOperators() {
1295: addOperator(and());
1296: addOperator(or());
1297: addOperator(isNull());
1298: addOperator(notNull());
1299:
1300: }
1301:
1302: /**
1303: * INTERNAL:
1304: */
1305: public static Hashtable initializeOperators() {
1306: resetOperators();
1307: initializeFunctionOperators();
1308: initializeRelationOperators();
1309: initializeLogicalOperators();
1310: initializeAggregateFunctionOperators();
1311: return allOperators;
1312: }
1313:
1314: /**
1315: * INTERNAL:
1316: * Initialize a mapping to the platform operator names for usage with exceptions.
1317: */
1318: public static String getPlatformOperatorName(int operator) {
1319: String name = (String) getPlatformOperatorNames().get(
1320: new Integer(operator));
1321: if (name == null) {
1322: name = String.valueOf(operator);
1323: }
1324: return name;
1325: }
1326:
1327: /**
1328: * INTERNAL:
1329: * Initialize a mapping to the platform operator names for usage with exceptions.
1330: */
1331: public static synchronized Hashtable getPlatformOperatorNames() {
1332: if (platformOperatorNames == null) {
1333: platformOperatorNames = new Hashtable();
1334: platformOperatorNames.put(new Integer(ToUpperCase),
1335: "ToUpperCase");
1336: platformOperatorNames.put(new Integer(ToLowerCase),
1337: "ToLowerCase");
1338: platformOperatorNames.put(new Integer(Chr), "Chr");
1339: platformOperatorNames.put(new Integer(Concat), "Concat");
1340: platformOperatorNames
1341: .put(new Integer(HexToRaw), "HexToRaw");
1342: platformOperatorNames.put(new Integer(Initcap), "Initcap");
1343: platformOperatorNames
1344: .put(new Integer(Instring), "Instring");
1345: platformOperatorNames.put(new Integer(Soundex), "Soundex");
1346: platformOperatorNames.put(new Integer(LeftPad), "LeftPad");
1347: platformOperatorNames
1348: .put(new Integer(LeftTrim), "LeftTrim");
1349: platformOperatorNames
1350: .put(new Integer(RightPad), "RightPad");
1351: platformOperatorNames.put(new Integer(RightTrim),
1352: "RightTrim");
1353: platformOperatorNames.put(new Integer(Substring),
1354: "Substring");
1355: platformOperatorNames.put(new Integer(Translate),
1356: "Translate");
1357: platformOperatorNames.put(new Integer(Ascii), "Ascii");
1358: platformOperatorNames.put(new Integer(Length), "Length");
1359: platformOperatorNames.put(new Integer(CharIndex),
1360: "CharIndex");
1361: platformOperatorNames.put(new Integer(CharLength),
1362: "CharLength");
1363: platformOperatorNames.put(new Integer(Difference),
1364: "Difference");
1365: platformOperatorNames.put(new Integer(Reverse), "Reverse");
1366: platformOperatorNames.put(new Integer(Replicate),
1367: "Replicate");
1368: platformOperatorNames.put(new Integer(Right), "Right");
1369: platformOperatorNames.put(new Integer(Locate), "Locate");
1370: platformOperatorNames.put(new Integer(Locate2), "Locate");
1371: platformOperatorNames
1372: .put(new Integer(ToNumber), "ToNumber");
1373: platformOperatorNames.put(new Integer(ToChar), "ToChar");
1374: platformOperatorNames.put(new Integer(ToCharWithFormat),
1375: "ToChar");
1376: platformOperatorNames.put(new Integer(AddMonths),
1377: "AddMonths");
1378: platformOperatorNames.put(new Integer(DateToString),
1379: "DateToString");
1380: platformOperatorNames.put(new Integer(MonthsBetween),
1381: "MonthsBetween");
1382: platformOperatorNames.put(new Integer(NextDay), "NextDay");
1383: platformOperatorNames.put(new Integer(RoundDate),
1384: "RoundDate");
1385: platformOperatorNames.put(new Integer(AddDate), "AddDate");
1386: platformOperatorNames
1387: .put(new Integer(DateName), "DateName");
1388: platformOperatorNames
1389: .put(new Integer(DatePart), "DatePart");
1390: platformOperatorNames.put(new Integer(DateDifference),
1391: "DateDifference");
1392: platformOperatorNames.put(new Integer(TruncateDate),
1393: "TruncateDate");
1394: platformOperatorNames.put(new Integer(NewTime), "NewTime");
1395: platformOperatorNames.put(new Integer(Nvl), "Nvl");
1396: platformOperatorNames.put(new Integer(NewTime), "NewTime");
1397: platformOperatorNames.put(new Integer(Ceil), "Ceil");
1398: platformOperatorNames.put(new Integer(Cos), "Cos");
1399: platformOperatorNames.put(new Integer(Cosh), "Cosh");
1400: platformOperatorNames.put(new Integer(Abs), "Abs");
1401: platformOperatorNames.put(new Integer(Acos), "Acos");
1402: platformOperatorNames.put(new Integer(Asin), "Asin");
1403: platformOperatorNames.put(new Integer(Atan), "Atan");
1404: platformOperatorNames.put(new Integer(Exp), "Exp");
1405: platformOperatorNames.put(new Integer(Sqrt), "Sqrt");
1406: platformOperatorNames.put(new Integer(Floor), "Floor");
1407: platformOperatorNames.put(new Integer(Ln), "Ln");
1408: platformOperatorNames.put(new Integer(Log), "Log");
1409: platformOperatorNames.put(new Integer(Mod), "Mod");
1410: platformOperatorNames.put(new Integer(Power), "Power");
1411: platformOperatorNames.put(new Integer(Round), "Round");
1412: platformOperatorNames.put(new Integer(Sign), "Sign");
1413: platformOperatorNames.put(new Integer(Sin), "Sin");
1414: platformOperatorNames.put(new Integer(Sinh), "Sinh");
1415: platformOperatorNames.put(new Integer(Tan), "Tan");
1416: platformOperatorNames.put(new Integer(Tanh), "Tanh");
1417: platformOperatorNames.put(new Integer(Trunc), "Trunc");
1418: platformOperatorNames
1419: .put(new Integer(Greatest), "Greatest");
1420: platformOperatorNames.put(new Integer(Least), "Least");
1421: platformOperatorNames.put(new Integer(Add), "Add");
1422: platformOperatorNames
1423: .put(new Integer(Subtract), "Subtract");
1424: platformOperatorNames.put(new Integer(Divide), "Divide");
1425: platformOperatorNames
1426: .put(new Integer(Multiply), "Multiply");
1427: platformOperatorNames.put(new Integer(Atan2), "Atan2");
1428: platformOperatorNames.put(new Integer(Cot), "Cot");
1429: platformOperatorNames.put(new Integer(Deref), "Deref");
1430: platformOperatorNames.put(new Integer(Ref), "Ref");
1431: platformOperatorNames
1432: .put(new Integer(RefToHex), "RefToHex");
1433: platformOperatorNames.put(new Integer(Value), "Value");
1434: platformOperatorNames.put(new Integer(Extract), "Extract");
1435: platformOperatorNames.put(new Integer(ExtractValue),
1436: "ExtractValue");
1437: platformOperatorNames.put(new Integer(ExistsNode),
1438: "ExistsNode");
1439: platformOperatorNames.put(new Integer(GetStringVal),
1440: "GetStringVal");
1441: platformOperatorNames.put(new Integer(GetNumberVal),
1442: "GetNumberVal");
1443: platformOperatorNames.put(new Integer(IsFragment),
1444: "IsFragment");
1445: }
1446: return platformOperatorNames;
1447: }
1448:
1449: /**
1450: * INTERNAL:
1451: */
1452: protected static void initializeRelationOperators() {
1453: addOperator(simpleRelation(Equal, "=", "equal"));
1454: addOperator(simpleRelation(NotEqual, "<>", "notEqual"));
1455: addOperator(simpleRelation(LessThan, "<", "lessThan"));
1456: addOperator(simpleRelation(LessThanEqual, "<=", "lessThanEqual"));
1457: addOperator(simpleRelation(GreaterThan, ">", "greaterThan"));
1458: addOperator(simpleRelation(GreaterThanEqual, ">=",
1459: "greaterThanEqual"));
1460:
1461: addOperator(like());
1462: addOperator(likeEscape());
1463: addOperator(notLike());
1464: addOperator(between());
1465:
1466: addOperator(exists());
1467: addOperator(notExists());
1468: }
1469:
1470: /**
1471: * INTERNAL:
1472: * Build operator.
1473: */
1474: public static ExpressionOperator instring() {
1475: return simpleTwoArgumentFunction(Instring, "INSTR");
1476: }
1477:
1478: /**
1479: * Aggregate functions are function in the select such as COUNT.
1480: */
1481: public boolean isAggregateOperator() {
1482: return getType() == AggregateOperator;
1483: }
1484:
1485: /**
1486: * Comparison functions are functions such as = and >.
1487: */
1488: public boolean isComparisonOperator() {
1489: return getType() == ComparisonOperator;
1490: }
1491:
1492: /**
1493: * INTERNAL:
1494: * If we have all the required information, this operator is complete
1495: * and can be used as is. Otherwise we will need to look up a platform-
1496: * specific operator.
1497: */
1498: public boolean isComplete() {
1499: return (databaseStrings != null)
1500: && (databaseStrings.length != 0);
1501: }
1502:
1503: /**
1504: * General functions are any normal function such as UPPER.
1505: */
1506: public boolean isFunctionOperator() {
1507: return getType() == FunctionOperator;
1508: }
1509:
1510: /**
1511: * Logical functions are functions such as and and or.
1512: */
1513: public boolean isLogicalOperator() {
1514: return getType() == LogicalOperator;
1515: }
1516:
1517: /**
1518: * INTERNAL:
1519: * Create the ISNULL operator.
1520: */
1521: public static ExpressionOperator isNull() {
1522: ExpressionOperator result = new ExpressionOperator();
1523: result.setType(ComparisonOperator);
1524: result.setSelector(IsNull);
1525: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1526: .newInstance();
1527: v.addElement("(");
1528: v.addElement(" IS NULL)");
1529: result.printsAs(v);
1530: result.bePrefix();
1531: result.printsJavaAs(".isNull()");
1532: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1533: return result;
1534: }
1535:
1536: /**
1537: * Order functions are used in the order by such as ASC.
1538: */
1539: public boolean isOrderOperator() {
1540: return getType() == OrderOperator;
1541: }
1542:
1543: /**
1544: * ADVANCED:
1545: * Return true if this is a prefix operator.
1546: */
1547: public boolean isPrefix() {
1548: return isPrefix;
1549: }
1550:
1551: /**
1552: * INTERNAL:
1553: * Build operator.
1554: */
1555: public static ExpressionOperator lastDay() {
1556: return simpleFunction(LastDay, "LAST_DAY");
1557: }
1558:
1559: /**
1560: * INTERNAL:
1561: * Build operator.
1562: */
1563: public static ExpressionOperator least() {
1564: return simpleTwoArgumentFunction(Least, "LEAST");
1565: }
1566:
1567: /**
1568: * INTERNAL:
1569: * Build operator.
1570: */
1571: public static ExpressionOperator leftPad() {
1572: return simpleThreeArgumentFunction(LeftPad, "LPAD");
1573: }
1574:
1575: /**
1576: * INTERNAL:
1577: * Build operator.
1578: */
1579: public static ExpressionOperator leftTrim() {
1580: return simpleFunction(LeftTrim, "LTRIM");
1581: }
1582:
1583: /**
1584: * INTERNAL:
1585: * Build leftTrim operator that takes one parameter.
1586: */
1587: public static ExpressionOperator leftTrim2() {
1588: return simpleTwoArgumentFunction(LeftTrim2, "LTRIM");
1589: }
1590:
1591: /**
1592: * INTERNAL:
1593: * Build operator.
1594: */
1595: public static ExpressionOperator length() {
1596: return simpleFunction(Length, "LENGTH");
1597: }
1598:
1599: /**
1600: * INTERNAL:
1601: * Create the LIKE operator.
1602: */
1603: public static ExpressionOperator like() {
1604: return simpleRelation(Like, "LIKE", "like");
1605: }
1606:
1607: /**
1608: * INTERNAL:
1609: * Create the LIKE operator.
1610: */
1611: public static ExpressionOperator likeEscape() {
1612: ExpressionOperator result = new ExpressionOperator();
1613: result.setSelector(LikeEscape);
1614: result.setType(ComparisonOperator);
1615: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1616: .newInstance();
1617: v.addElement("(");
1618: v.addElement(" LIKE ");
1619: v.addElement(" ESCAPE ");
1620: v.addElement(")");
1621: result.printsAs(v);
1622: result.bePrefix();
1623: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1624: return result;
1625: }
1626:
1627: /**
1628: * INTERNAL:
1629: * Build operator.
1630: */
1631: public static ExpressionOperator ln() {
1632: return simpleFunction(Ln, "LN");
1633: }
1634:
1635: /**
1636: * INTERNAL:
1637: * Build locate operator i.e. LOCATE("ob", t0.F_NAME)
1638: */
1639: public static ExpressionOperator locate() {
1640: ExpressionOperator expOperator = simpleTwoArgumentFunction(
1641: Locate, "LOCATE");
1642: int[] argumentIndices = new int[2];
1643: argumentIndices[0] = 1;
1644: argumentIndices[1] = 0;
1645: expOperator.setArgumentIndices(argumentIndices);
1646: return expOperator;
1647: }
1648:
1649: /**
1650: * INTERNAL:
1651: * Build locate operator with 3 params i.e. LOCATE("coffee", t0.DESCRIP, 4).
1652: * Last parameter is a start at.
1653: */
1654: public static ExpressionOperator locate2() {
1655: ExpressionOperator expOperator = simpleThreeArgumentFunction(
1656: Locate2, "LOCATE");
1657: int[] argumentIndices = new int[3];
1658: argumentIndices[0] = 1;
1659: argumentIndices[1] = 0;
1660: argumentIndices[2] = 2;
1661: expOperator.setArgumentIndices(argumentIndices);
1662: return expOperator;
1663: }
1664:
1665: /**
1666: * INTERNAL:
1667: * Build operator.
1668: */
1669: public static ExpressionOperator log() {
1670: return simpleFunction(Log, "LOG");
1671: }
1672:
1673: /**
1674: * INTERNAL:
1675: * Create the MAXIMUM operator.
1676: */
1677: public static ExpressionOperator maximum() {
1678: return simpleAggregate(Maximum, "MAX", "maximum");
1679: }
1680:
1681: /**
1682: * INTERNAL:
1683: * Create the MINIMUM operator.
1684: */
1685: public static ExpressionOperator minimum() {
1686: return simpleAggregate(Minimum, "MIN", "minimum");
1687: }
1688:
1689: /**
1690: * INTERNAL:
1691: * Build operator.
1692: */
1693: public static ExpressionOperator mod() {
1694: return simpleTwoArgumentFunction(Mod, "MOD");
1695: }
1696:
1697: /**
1698: * INTERNAL:
1699: * Build operator.
1700: */
1701: public static ExpressionOperator monthsBetween() {
1702: return simpleTwoArgumentFunction(MonthsBetween,
1703: "MONTHS_BETWEEN");
1704: }
1705:
1706: /**
1707: * INTERNAL:
1708: * Create a new expression. Optimized for the single argument case.
1709: */
1710: public Expression newExpressionForArgument(Expression base,
1711: Object singleArgument) {
1712: if (representsEqualToNull(singleArgument)) {
1713: return base.isNull();
1714: }
1715: if (representsNotEqualToNull(singleArgument)) {
1716: return base.notNull();
1717: }
1718:
1719: try {
1720: Expression exp = null;
1721: if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
1722: try {
1723: exp = (Expression) AccessController
1724: .doPrivileged(new PrivilegedNewInstanceFromClass(
1725: getNodeClass()));
1726: } catch (PrivilegedActionException exception) {
1727: return null;
1728: }
1729: } else {
1730: exp = (Expression) PrivilegedAccessHelper
1731: .newInstanceFromClass(getNodeClass());
1732: }
1733: exp.create(base, singleArgument, this );
1734: return exp;
1735: } catch (InstantiationException e) {
1736: return null;
1737: } catch (IllegalAccessException f) {
1738: return null;
1739: }
1740: }
1741:
1742: /**
1743: * INTERNAL:
1744: * Create a new expression. Optimized for the single argument case with base last
1745: */
1746: public Expression newExpressionForArgumentWithBaseLast(
1747: Expression base, Object singleArgument) {
1748: if (representsEqualToNull(singleArgument)) {
1749: return base.isNull();
1750: }
1751: if (representsNotEqualToNull(singleArgument)) {
1752: return base.notNull();
1753: }
1754:
1755: try {
1756: Expression exp = null;
1757: if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
1758: try {
1759: exp = (Expression) AccessController
1760: .doPrivileged(new PrivilegedNewInstanceFromClass(
1761: getNodeClass()));
1762: } catch (PrivilegedActionException exception) {
1763: return null;
1764: }
1765: } else {
1766: exp = (Expression) PrivilegedAccessHelper
1767: .newInstanceFromClass(getNodeClass());
1768: }
1769: exp.createWithBaseLast(base, singleArgument, this );
1770: return exp;
1771: } catch (InstantiationException e) {
1772: return null;
1773: } catch (IllegalAccessException f) {
1774: return null;
1775: }
1776: }
1777:
1778: /**
1779: * INTERNAL:
1780: * The general case.
1781: */
1782: public Expression newExpressionForArguments(Expression base,
1783: Vector arguments) {
1784: if (representsEqualToNull(arguments)) {
1785: return base.isNull();
1786: }
1787: if (representsNotEqualToNull(arguments)) {
1788: return base.notNull();
1789: }
1790:
1791: try {
1792: Expression exp = null;
1793: if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
1794: try {
1795: exp = (Expression) AccessController
1796: .doPrivileged(new PrivilegedNewInstanceFromClass(
1797: getNodeClass()));
1798: } catch (PrivilegedActionException exception) {
1799: return null;
1800: }
1801: } else {
1802: exp = (Expression) PrivilegedAccessHelper
1803: .newInstanceFromClass(getNodeClass());
1804: }
1805: exp.create(base, arguments, this );
1806: return exp;
1807: } catch (InstantiationException e) {
1808: return null;
1809: } catch (IllegalAccessException f) {
1810: return null;
1811: }
1812: }
1813:
1814: /**
1815: * INTERNAL:
1816: * Build operator.
1817: */
1818: public static ExpressionOperator newTime() {
1819: return simpleThreeArgumentFunction(NewTime, "NEW_TIME");
1820: }
1821:
1822: /**
1823: * INTERNAL:
1824: * Build operator.
1825: */
1826: public static ExpressionOperator nextDay() {
1827: return simpleTwoArgumentFunction(NextDay, "NEXT_DAY");
1828: }
1829:
1830: /**
1831: * INTERNAL:
1832: * Create the NOT EXISTS operator.
1833: */
1834: public static ExpressionOperator notExists() {
1835: ExpressionOperator exOperator = new ExpressionOperator();
1836: exOperator.setType(FunctionOperator);
1837: exOperator.setSelector(NotExists);
1838: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1839: .newInstance(2);
1840: v.addElement("NOT EXISTS" + " ");
1841: v.addElement(" ");
1842: exOperator.printsAs(v);
1843: exOperator.bePrefix();
1844: exOperator
1845: .setNodeClass(ClassConstants.FunctionExpression_Class);
1846: return exOperator;
1847: }
1848:
1849: /**
1850: * INTERNAL:
1851: * Create the NOTIN operator.
1852: */
1853: public static ExpressionOperator notIn() {
1854: ExpressionOperator result = new ExpressionOperator();
1855: result.setType(ExpressionOperator.FunctionOperator);
1856: result.setSelector(NotIn);
1857: Vector v = new Vector(2);
1858: v.addElement(" NOT IN (");
1859: v.addElement(")");
1860: result.printsAs(v);
1861: result.bePostfix();
1862: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1863: return result;
1864: }
1865:
1866: /**
1867: * INTERNAL:
1868: * Create the NOTIN operator taking a subQuery.
1869: * Note, the subquery itself comes with parenethesis, so the IN operator
1870: * should not add any parenethesis.
1871: */
1872: public static ExpressionOperator notInSubQuery() {
1873: ExpressionOperator result = new ExpressionOperator();
1874: result.setType(ExpressionOperator.FunctionOperator);
1875: result.setSelector(NotInSubQuery);
1876: Vector v = new Vector(1);
1877: v.addElement(" NOT IN ");
1878: result.printsAs(v);
1879: result.bePostfix();
1880: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1881: return result;
1882: }
1883:
1884: /**
1885: * INTERNAL:
1886: * Create the NOTLIKE operator.
1887: */
1888: public static ExpressionOperator notLike() {
1889: return simpleRelation(NotLike, "NOT LIKE", "notLike");
1890: }
1891:
1892: /**
1893: * INTERNAL:
1894: * Create the NOTNULL operator.
1895: */
1896: public static ExpressionOperator notNull() {
1897: ExpressionOperator result = new ExpressionOperator();
1898: result.setType(ComparisonOperator);
1899: result.setSelector(NotNull);
1900: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1901: .newInstance();
1902: v.addElement("(");
1903: v.addElement(" IS NOT NULL)");
1904: result.printsAs(v);
1905: result.bePrefix();
1906: result.printsJavaAs(".notNull()");
1907: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1908: return result;
1909: }
1910:
1911: /**
1912: * INTERNAL:
1913: * Create the NOT operator.
1914: */
1915: public static ExpressionOperator notOperator() {
1916: ExpressionOperator result = new ExpressionOperator();
1917: result.setSelector(Not);
1918: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
1919: .newInstance();
1920: v.addElement("NOT (");
1921: v.addElement(")");
1922: result.printsAs(v);
1923: result.bePrefix();
1924: result.printsJavaAs(".not()");
1925: result.setNodeClass(ClassConstants.FunctionExpression_Class);
1926: return result;
1927: }
1928:
1929: /**
1930: * INTERNAL:
1931: * Create the OR operator.
1932: */
1933: public static ExpressionOperator or() {
1934: return simpleLogical(Or, "OR", "or");
1935: }
1936:
1937: /**
1938: * INTERNAL:
1939: * Build operator.
1940: */
1941: public static ExpressionOperator power() {
1942: return simpleTwoArgumentFunction(Power, "POWER");
1943: }
1944:
1945: /**
1946: * INTERNAL: Print the collection onto the SQL stream.
1947: */
1948: public void printCollection(Vector items,
1949: ExpressionSQLPrinter printer) {
1950: int dbStringIndex = 0;
1951: try {
1952: if (isPrefix()) {
1953: printer.getWriter().write(getDatabaseStrings()[0]);
1954: dbStringIndex = 1;
1955: } else {
1956: dbStringIndex = 0;
1957: }
1958: } catch (IOException e) {
1959: e.printStackTrace();
1960: }
1961:
1962: for (int i = 0; i < items.size(); i++) {
1963: int index = 0;
1964: if (argumentIndices == null) {
1965: index = i;
1966: } else {
1967: index = argumentIndices[i];
1968: }
1969: ;
1970: Expression item = (Expression) items.elementAt(index);
1971: if ((getSelector() == Ref)
1972: || ((getSelector() == Deref) && (item
1973: .isObjectExpression()))) {
1974: DatabaseTable alias = ((ObjectExpression) item)
1975: .aliasForTable((DatabaseTable) ((ObjectExpression) item)
1976: .getDescriptor().getTables()
1977: .firstElement());
1978: printer.printString(alias.getName());
1979: } else if ((getSelector() == Count)
1980: && (item.isExpressionBuilder())) {
1981: printer.printString("*");
1982: } else if (getType() == FunctionOperator) {
1983: item.printSQLWithoutConversion(printer);
1984: } else {
1985: item.printSQL(printer);
1986: }
1987: if (dbStringIndex < getDatabaseStrings().length) {
1988: printer
1989: .printString(getDatabaseStrings()[dbStringIndex++]);
1990: }
1991: }
1992: }
1993:
1994: /**
1995: * INTERNAL: Print the collection onto the SQL stream.
1996: */
1997: public void printJavaCollection(Vector items,
1998: ExpressionJavaPrinter printer) {
1999: int javaStringIndex = 0;
2000:
2001: for (int i = 0; i < items.size(); i++) {
2002: Expression item = (Expression) items.elementAt(i);
2003: item.printJava(printer);
2004: if (javaStringIndex < getJavaStrings().length) {
2005: printer
2006: .printString(getJavaStrings()[javaStringIndex++]);
2007: }
2008: }
2009: }
2010:
2011: /**
2012: * INTERNAL:
2013: * For performance, special case printing two children, since it's by far the most common
2014: */
2015: public void printDuo(Expression first, Expression second,
2016: ExpressionSQLPrinter printer) {
2017: int dbStringIndex;
2018: if (isPrefix()) {
2019: printer.printString(getDatabaseStrings()[0]);
2020: dbStringIndex = 1;
2021: } else {
2022: dbStringIndex = 0;
2023: }
2024:
2025: first.printSQL(printer);
2026: if (dbStringIndex < getDatabaseStrings().length) {
2027: printer.printString(getDatabaseStrings()[dbStringIndex++]);
2028: }
2029: if (second != null) {
2030: second.printSQL(printer);
2031: if (dbStringIndex < getDatabaseStrings().length) {
2032: printer
2033: .printString(getDatabaseStrings()[dbStringIndex++]);
2034: }
2035: }
2036: }
2037:
2038: /**
2039: * INTERNAL:
2040: * For performance, special case printing two children, since it's by far the most common
2041: */
2042: public void printJavaDuo(Expression first, Expression second,
2043: ExpressionJavaPrinter printer) {
2044: int javaStringIndex = 0;
2045:
2046: first.printJava(printer);
2047: if (javaStringIndex < getJavaStrings().length) {
2048: printer.printString(getJavaStrings()[javaStringIndex++]);
2049: }
2050: if (second != null) {
2051: second.printJava(printer);
2052: if (javaStringIndex < getJavaStrings().length) {
2053: printer.printString(getJavaStrings()[javaStringIndex]);
2054: }
2055: }
2056: }
2057:
2058: /**
2059: * ADVANCED:
2060: * Set the single string for this operator.
2061: */
2062: public void printsAs(String s) {
2063: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2064: .newInstance(1);
2065: v.addElement(s);
2066: printsAs(v);
2067: }
2068:
2069: /**
2070: * ADVANCED:
2071: * Set the strings for this operator.
2072: */
2073: public void printsAs(Vector dbStrings) {
2074: this .databaseStrings = new String[dbStrings.size()];
2075: for (int i = 0; i < dbStrings.size(); i++) {
2076: getDatabaseStrings()[i] = (String) dbStrings.elementAt(i);
2077: }
2078: }
2079:
2080: /**
2081: * ADVANCED:
2082: * Set the single string for this operator.
2083: */
2084: public void printsJavaAs(String s) {
2085: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2086: .newInstance(1);
2087: v.addElement(s);
2088: printsJavaAs(v);
2089: }
2090:
2091: /**
2092: * ADVANCED:
2093: * Set the strings for this operator.
2094: */
2095: public void printsJavaAs(Vector dbStrings) {
2096: this .javaStrings = new String[dbStrings.size()];
2097: for (int i = 0; i < dbStrings.size(); i++) {
2098: getJavaStrings()[i] = (String) dbStrings.elementAt(i);
2099: }
2100: }
2101:
2102: /**
2103: * INTERNAL:
2104: * Build operator.
2105: */
2106: public static ExpressionOperator ref() {
2107: return simpleFunction(Ref, "REF");
2108: }
2109:
2110: /**
2111: * INTERNAL:
2112: * Build operator.
2113: */
2114: public static ExpressionOperator refToHex() {
2115: return simpleFunction(RefToHex, "REFTOHEX");
2116: }
2117:
2118: /**
2119: * INTERNAL:
2120: * Build operator.
2121: */
2122: public static ExpressionOperator replace() {
2123: return simpleThreeArgumentFunction(Replace, "REPLACE");
2124: }
2125:
2126: /**
2127: * INTERNAL:
2128: * Build operator.
2129: */
2130: public static ExpressionOperator replicate() {
2131: return simpleTwoArgumentFunction(Replicate, "REPLICATE");
2132: }
2133:
2134: /**
2135: * INTERNAL:
2136: * Test if this operator instance represents a comparison to null, which
2137: * we have to print specially. Also special-cased for performance.
2138: */
2139: public boolean representsEqualToNull(Object singleArgument) {
2140: if (singleArgument instanceof Vector) {
2141: return representsEqualToNull((Vector) singleArgument);
2142: }
2143: return (getSelector() == Equal) && (singleArgument == null);
2144: }
2145:
2146: /**
2147: * INTERNAL:
2148: * Test if this operator instance represents a comparison to null, which
2149: * we have to print specially.
2150: */
2151: public boolean representsEqualToNull(Vector arguments) {
2152: return (getSelector() == Equal) && (arguments.size() == 1)
2153: && (arguments.elementAt(0) == null);
2154: }
2155:
2156: /**
2157: * INTERNAL:
2158: * Test if this operator instance represents a comparison to null, which
2159: * we have to print specially. Also special-cased for performance.
2160: */
2161: public boolean representsNotEqualToNull(Object singleArgument) {
2162: if (singleArgument instanceof Vector) {
2163: return representsNotEqualToNull((Vector) singleArgument);
2164: }
2165: return (getSelector() == NotEqual) && (singleArgument == null);
2166: }
2167:
2168: /**
2169: * INTERNAL:
2170: * Test if this operator instance represents a comparison to null, which
2171: * we have to print specially.
2172: */
2173: public boolean representsNotEqualToNull(Vector arguments) {
2174: return (getSelector() == NotEqual) && (arguments.size() == 1)
2175: && (arguments.elementAt(0) == null);
2176: }
2177:
2178: /**
2179: * INTERNAL:
2180: * Reset all the operators.
2181: */
2182: public static void resetOperators() {
2183: allOperators = new Hashtable();
2184: }
2185:
2186: /**
2187: * INTERNAL:
2188: * Build operator.
2189: */
2190: public static ExpressionOperator reverse() {
2191: return simpleFunction(Reverse, "REVERSE");
2192: }
2193:
2194: /**
2195: * INTERNAL:
2196: * Build operator.
2197: */
2198: public static ExpressionOperator right() {
2199: return simpleTwoArgumentFunction(Right, "RIGHT");
2200: }
2201:
2202: /**
2203: * INTERNAL:
2204: * Build operator.
2205: */
2206: public static ExpressionOperator rightPad() {
2207: return simpleThreeArgumentFunction(RightPad, "RPAD");
2208: }
2209:
2210: /**
2211: * INTERNAL:
2212: * Build operator.
2213: */
2214: public static ExpressionOperator rightTrim() {
2215: return simpleFunction(RightTrim, "RTRIM");
2216: }
2217:
2218: /**
2219: * INTERNAL:
2220: * Build rightTrim operator that takes one parameter.
2221: * @bug 2916893 rightTrim(substring) broken.
2222: */
2223: public static ExpressionOperator rightTrim2() {
2224: return simpleTwoArgumentFunction(RightTrim2, "RTRIM");
2225: }
2226:
2227: /**
2228: * INTERNAL:
2229: * Build operator.
2230: */
2231: public static ExpressionOperator round() {
2232: return simpleTwoArgumentFunction(Round, "ROUND");
2233: }
2234:
2235: /**
2236: * INTERNAL:
2237: * Build operator.
2238: */
2239: public static ExpressionOperator roundDate() {
2240: return simpleTwoArgumentFunction(RoundDate, "ROUND");
2241: }
2242:
2243: /**
2244: * ADVANCED:
2245: * Set the array of indexes to use when building the SQL function.
2246: */
2247: public void setArgumentIndices(int[] indices) {
2248: argumentIndices = indices;
2249: }
2250:
2251: /**
2252: * ADVANCED:
2253: * Set the node class for this operator. For user-defined functions this is
2254: * set automatically but can be changed.
2255: * <p>A list of Operator types, an example, and the node class used follows.
2256: * <p>LogicalOperator AND LogicalExpression
2257: * <p>ComparisonOperator <> RelationExpression
2258: * <p>AggregateOperator COUNT FunctionExpression
2259: * <p>OrderOperator ASCENDING "
2260: * <p>FunctionOperator RTRIM "
2261: * <p>Node classes given belong to oracle.toplink.essentials.internal.expressions.
2262: */
2263: public void setNodeClass(Class nodeClass) {
2264: this .nodeClass = nodeClass;
2265: }
2266:
2267: /**
2268: * INTERNAL:
2269: * Set the selector id.
2270: */
2271: public void setSelector(int selector) {
2272: this .selector = selector;
2273: }
2274:
2275: /**
2276: * ADVANCED:
2277: * Set the type of function.
2278: * This must be one of the static function types defined in this class.
2279: */
2280: public void setType(int type) {
2281: this .type = type;
2282: }
2283:
2284: /**
2285: * INTERNAL:
2286: * Build operator.
2287: */
2288: public static ExpressionOperator sign() {
2289: return simpleFunction(Sign, "SIGN");
2290: }
2291:
2292: /**
2293: * INTERNAL:
2294: * Create an operator for a simple aggregate given a Java name and a single
2295: * String for the database (parentheses will be added automatically).
2296: */
2297: public static ExpressionOperator simpleAggregate(int selector,
2298: String databaseName, String javaName) {
2299: ExpressionOperator exOperator = new ExpressionOperator();
2300: exOperator.setType(AggregateOperator);
2301: exOperator.setSelector(selector);
2302: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2303: .newInstance(2);
2304: v.addElement(databaseName + "(");
2305: v.addElement(")");
2306: exOperator.printsAs(v);
2307: exOperator.bePrefix();
2308: exOperator.printsJavaAs("." + javaName + "()");
2309: exOperator
2310: .setNodeClass(ClassConstants.FunctionExpression_Class);
2311: return exOperator;
2312: }
2313:
2314: /**
2315: * INTERNAL:
2316: * Create an operator for a simple function given a Java name and a single
2317: * String for the database (parentheses will be added automatically).
2318: */
2319: public static ExpressionOperator simpleFunction(int selector,
2320: String databaseName) {
2321: ExpressionOperator exOperator = new ExpressionOperator();
2322: exOperator.setType(FunctionOperator);
2323: exOperator.setSelector(selector);
2324: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2325: .newInstance(2);
2326: v.addElement(databaseName + "(");
2327: v.addElement(")");
2328: exOperator.printsAs(v);
2329: exOperator.bePrefix();
2330: exOperator
2331: .setNodeClass(ClassConstants.FunctionExpression_Class);
2332: return exOperator;
2333: }
2334:
2335: /**
2336: * INTERNAL:
2337: * Create an operator for a simple function call without parentheses
2338: */
2339: public static ExpressionOperator simpleFunctionNoParentheses(
2340: int selector, String databaseName) {
2341: ExpressionOperator exOperator = new ExpressionOperator();
2342: exOperator.setType(FunctionOperator);
2343: exOperator.setSelector(selector);
2344: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2345: .newInstance(1);
2346: v.addElement(databaseName);
2347: exOperator.printsAs(v);
2348: exOperator.bePrefix();
2349: exOperator
2350: .setNodeClass(ClassConstants.FunctionExpression_Class);
2351: return exOperator;
2352: }
2353:
2354: /**
2355: * INTERNAL:
2356: * Create an operator for a simple function given a Java name and a single
2357: * String for the database (parentheses will be added automatically).
2358: */
2359: public static ExpressionOperator simpleFunction(int selector,
2360: String databaseName, String javaName) {
2361: ExpressionOperator exOperator = simpleFunction(selector,
2362: databaseName);
2363: exOperator.printsJavaAs("." + javaName + "()");
2364: return exOperator;
2365: }
2366:
2367: /**
2368: * INTERNAL:
2369: * Create an operator for a simple logical given a Java name and a single
2370: * String for the database (parentheses will be added automatically).
2371: */
2372: public static ExpressionOperator simpleLogical(int selector,
2373: String databaseName, String javaName) {
2374: ExpressionOperator exOperator = new ExpressionOperator();
2375: exOperator.setType(LogicalOperator);
2376: exOperator.setSelector(selector);
2377: exOperator.printsAs(" " + databaseName + " ");
2378: exOperator.bePostfix();
2379: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2380: .newInstance(2);
2381: v.addElement("." + javaName + "(");
2382: v.addElement(")");
2383: exOperator.printsJavaAs(v);
2384: exOperator.setNodeClass(ClassConstants.LogicalExpression_Class);
2385: return exOperator;
2386: }
2387:
2388: /**
2389: * INTERNAL:
2390: * Create an operator for a simple math operatin, i.e. +, -, *, /
2391: */
2392: public static ExpressionOperator simpleMath(int selector,
2393: String databaseName) {
2394: ExpressionOperator exOperator = new ExpressionOperator();
2395: exOperator.setType(FunctionOperator);
2396: exOperator.setSelector(selector);
2397: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2398: .newInstance(3);
2399: v.addElement("(");
2400: v.addElement(" " + databaseName + " ");
2401: v.addElement(")");
2402: exOperator.printsAs(v);
2403: exOperator.bePrefix();
2404: exOperator
2405: .setNodeClass(ClassConstants.FunctionExpression_Class);
2406: return exOperator;
2407: }
2408:
2409: /**
2410: * INTERNAL:
2411: * Create an operator for a simple ordering given a Java name and a single
2412: * String for the database (parentheses will be added automatically).
2413: */
2414: public static ExpressionOperator simpleOrdering(int selector,
2415: String databaseName, String javaName) {
2416: ExpressionOperator exOperator = new ExpressionOperator();
2417: exOperator.setType(OrderOperator);
2418: exOperator.setSelector(selector);
2419: exOperator.printsAs(" " + databaseName);
2420: exOperator.bePostfix();
2421: exOperator.printsJavaAs("." + javaName + "()");
2422: exOperator
2423: .setNodeClass(ClassConstants.FunctionExpression_Class);
2424: return exOperator;
2425: }
2426:
2427: /**
2428: * INTERNAL:
2429: * Create an operator for a simple relation given a Java name and a single
2430: * String for the database (parentheses will be added automatically).
2431: */
2432: public static ExpressionOperator simpleRelation(int selector,
2433: String databaseName) {
2434: ExpressionOperator exOperator = new ExpressionOperator();
2435: exOperator.setType(ComparisonOperator);
2436: exOperator.setSelector(selector);
2437: exOperator.printsAs(" " + databaseName + " ");
2438: exOperator.bePostfix();
2439: exOperator
2440: .setNodeClass(ClassConstants.RelationExpression_Class);
2441: return exOperator;
2442: }
2443:
2444: /**
2445: * INTERNAL:
2446: * Create an operator for a simple relation given a Java name and a single
2447: * String for the database (parentheses will be added automatically).
2448: */
2449: public static ExpressionOperator simpleRelation(int selector,
2450: String databaseName, String javaName) {
2451: ExpressionOperator exOperator = simpleRelation(selector,
2452: databaseName);
2453: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2454: .newInstance(2);
2455: v.addElement("." + javaName + "(");
2456: v.addElement(")");
2457: exOperator.printsJavaAs(v);
2458: return exOperator;
2459: }
2460:
2461: /**
2462: * INTERNAL:
2463: * Build operator.
2464: */
2465: public static ExpressionOperator simpleThreeArgumentFunction(
2466: int selector, String dbString) {
2467: ExpressionOperator exOperator = new ExpressionOperator();
2468: exOperator.setType(FunctionOperator);
2469: exOperator.setSelector(selector);
2470: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2471: .newInstance(4);
2472: v.addElement(dbString + "(");
2473: v.addElement(", ");
2474: v.addElement(", ");
2475: v.addElement(")");
2476: exOperator.printsAs(v);
2477: exOperator.bePrefix();
2478: exOperator
2479: .setNodeClass(ClassConstants.FunctionExpression_Class);
2480: return exOperator;
2481: }
2482:
2483: /**
2484: * INTERNAL:
2485: * Build operator.
2486: */
2487: public static ExpressionOperator simpleTwoArgumentFunction(
2488: int selector, String dbString) {
2489: ExpressionOperator exOperator = new ExpressionOperator();
2490: exOperator.setType(FunctionOperator);
2491: exOperator.setSelector(selector);
2492: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2493: .newInstance(5);
2494: v.addElement(dbString + "(");
2495: v.addElement(", ");
2496: v.addElement(")");
2497: exOperator.printsAs(v);
2498: exOperator.bePrefix();
2499: exOperator
2500: .setNodeClass(ClassConstants.FunctionExpression_Class);
2501: return exOperator;
2502: }
2503:
2504: /**
2505: * INTERNAL:
2506: * e.g.: ... "Bob" CONCAT "Smith" ...
2507: * Parentheses will not be addded. [RMB - March 5 2000]
2508: */
2509: public static ExpressionOperator simpleLogicalNoParens(
2510: int selector, String dbString) {
2511: ExpressionOperator exOperator = new ExpressionOperator();
2512: exOperator.setType(FunctionOperator);
2513: exOperator.setSelector(selector);
2514: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2515: .newInstance(5);
2516: v.addElement("");
2517: v.addElement(" " + dbString + " ");
2518: v.addElement("");
2519: exOperator.printsAs(v);
2520: exOperator.bePrefix();
2521: exOperator
2522: .setNodeClass(ClassConstants.FunctionExpression_Class);
2523: return exOperator;
2524: }
2525:
2526: /**
2527: * INTERNAL:
2528: * Build operator.
2529: */
2530: public static ExpressionOperator sin() {
2531: return simpleFunction(Sin, "SIN");
2532: }
2533:
2534: /**
2535: * INTERNAL:
2536: * Build operator.
2537: */
2538: public static ExpressionOperator sinh() {
2539: return simpleFunction(Sinh, "SINH");
2540: }
2541:
2542: /**
2543: * INTERNAL:
2544: * Build operator.
2545: */
2546: public static ExpressionOperator soundex() {
2547: return simpleFunction(Soundex, "SOUNDEX");
2548: }
2549:
2550: /**
2551: * INTERNAL:
2552: * Build operator.
2553: */
2554: public static ExpressionOperator sqrt() {
2555: return simpleFunction(Sqrt, "SQRT");
2556: }
2557:
2558: /**
2559: * INTERNAL:
2560: * Build operator.
2561: */
2562: public static ExpressionOperator standardDeviation() {
2563: return simpleAggregate(StandardDeviation, "STDDEV",
2564: "standardDeviation");
2565: }
2566:
2567: /**
2568: * INTERNAL:
2569: * Build operator.
2570: */
2571: public static ExpressionOperator substring() {
2572: return simpleThreeArgumentFunction(Substring, "SUBSTR");
2573: }
2574:
2575: /**
2576: * INTERNAL:
2577: * Create the SUM operator.
2578: */
2579: public static ExpressionOperator sum() {
2580: return simpleAggregate(Sum, "SUM", "sum");
2581: }
2582:
2583: /**
2584: * INTERNAL:
2585: * Function, to add months to a date.
2586: */
2587: public static ExpressionOperator sybaseAddMonthsOperator() {
2588: ExpressionOperator exOperator = new ExpressionOperator();
2589: exOperator.setType(FunctionOperator);
2590: exOperator.setSelector(AddMonths);
2591: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2592: .newInstance(3);
2593: v.addElement("DATEADD(month, ");
2594: v.addElement(", ");
2595: v.addElement(")");
2596: exOperator.printsAs(v);
2597: exOperator.bePrefix();
2598: int[] indices = { 1, 0 };
2599: exOperator.setArgumentIndices(indices);
2600: exOperator
2601: .setNodeClass(ClassConstants.FunctionExpression_Class);
2602: return exOperator;
2603:
2604: }
2605:
2606: /**
2607: * INTERNAL:
2608: * Build operator.
2609: */
2610: public static ExpressionOperator sybaseAtan2Operator() {
2611: return ExpressionOperator.simpleTwoArgumentFunction(Atan2,
2612: "ATN2");
2613: }
2614:
2615: /**
2616: * INTERNAL:
2617: * Build instring operator
2618: */
2619: public static ExpressionOperator sybaseInStringOperator() {
2620: ExpressionOperator exOperator = new ExpressionOperator();
2621: exOperator.setType(FunctionOperator);
2622: exOperator.setSelector(Instring);
2623: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2624: .newInstance(3);
2625: v.addElement("CHARINDEX(");
2626: v.addElement(", ");
2627: v.addElement(")");
2628: exOperator.printsAs(v);
2629: exOperator.bePrefix();
2630: int[] indices = { 1, 0 };
2631: exOperator.setArgumentIndices(indices);
2632: exOperator
2633: .setNodeClass(ClassConstants.FunctionExpression_Class);
2634: return exOperator;
2635:
2636: }
2637:
2638: /**
2639: * INTERNAL:
2640: * Build Sybase equivalent to TO_NUMBER.
2641: */
2642: public static ExpressionOperator sybaseToNumberOperator() {
2643: ExpressionOperator exOperator = new ExpressionOperator();
2644: exOperator.setType(FunctionOperator);
2645: exOperator.setSelector(ToNumber);
2646: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2647: .newInstance(2);
2648: v.addElement("CONVERT(NUMERIC, ");
2649: v.addElement(")");
2650: exOperator.printsAs(v);
2651: exOperator.bePrefix();
2652: exOperator
2653: .setNodeClass(ClassConstants.FunctionExpression_Class);
2654: return exOperator;
2655: }
2656:
2657: /**
2658: * INTERNAL:
2659: * Build Sybase equivalent to TO_CHAR.
2660: */
2661: public static ExpressionOperator sybaseToDateToStringOperator() {
2662: ExpressionOperator exOperator = new ExpressionOperator();
2663: exOperator.setType(FunctionOperator);
2664: exOperator.setSelector(DateToString);
2665: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2666: .newInstance(2);
2667: v.addElement("CONVERT(CHAR, ");
2668: v.addElement(")");
2669: exOperator.printsAs(v);
2670: exOperator.bePrefix();
2671: exOperator
2672: .setNodeClass(ClassConstants.FunctionExpression_Class);
2673: return exOperator;
2674: }
2675:
2676: /**
2677: * INTERNAL:
2678: * Build Sybase equivalent to TO_DATE.
2679: */
2680: public static ExpressionOperator sybaseToDateOperator() {
2681: ExpressionOperator exOperator = new ExpressionOperator();
2682: exOperator.setType(FunctionOperator);
2683: exOperator.setSelector(ToDate);
2684: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2685: .newInstance(2);
2686: v.addElement("CONVERT(DATETIME, ");
2687: v.addElement(")");
2688: exOperator.printsAs(v);
2689: exOperator.bePrefix();
2690: exOperator
2691: .setNodeClass(ClassConstants.FunctionExpression_Class);
2692: return exOperator;
2693: }
2694:
2695: /**
2696: * INTERNAL:
2697: * Build Sybase equivalent to TO_CHAR.
2698: */
2699: public static ExpressionOperator sybaseToCharOperator() {
2700: ExpressionOperator exOperator = new ExpressionOperator();
2701: exOperator.setType(FunctionOperator);
2702: exOperator.setSelector(ToChar);
2703: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2704: .newInstance(2);
2705: v.addElement("CONVERT(CHAR, ");
2706: v.addElement(")");
2707: exOperator.printsAs(v);
2708: exOperator.bePrefix();
2709: exOperator
2710: .setNodeClass(ClassConstants.FunctionExpression_Class);
2711: return exOperator;
2712: }
2713:
2714: /**
2715: * INTERNAL:
2716: * Build Sybase equivalent to TO_CHAR.
2717: */
2718: public static ExpressionOperator sybaseToCharWithFormatOperator() {
2719: ExpressionOperator exOperator = new ExpressionOperator();
2720: exOperator.setType(FunctionOperator);
2721: exOperator.setSelector(ToCharWithFormat);
2722: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2723: .newInstance(3);
2724: v.addElement("CONVERT(CHAR, ");
2725: v.addElement(",");
2726: v.addElement(")");
2727: exOperator.printsAs(v);
2728: exOperator.bePrefix();
2729: exOperator
2730: .setNodeClass(ClassConstants.FunctionExpression_Class);
2731: return exOperator;
2732: }
2733:
2734: /**
2735: * INTERNAL:
2736: * Build the Sybase equivalent to Locate
2737: */
2738: public static ExpressionOperator sybaseLocateOperator() {
2739: ExpressionOperator result = simpleTwoArgumentFunction(
2740: ExpressionOperator.Locate, "CHARINDEX");
2741: int[] argumentIndices = new int[2];
2742: argumentIndices[0] = 1;
2743: argumentIndices[1] = 0;
2744: result.setArgumentIndices(argumentIndices);
2745: return result;
2746: }
2747:
2748: /**
2749: * INTERNAL:
2750: * Build operator.
2751: */
2752: public static ExpressionOperator tan() {
2753: return simpleFunction(Tan, "TAN");
2754: }
2755:
2756: /**
2757: * INTERNAL:
2758: * Build operator.
2759: */
2760: public static ExpressionOperator tanh() {
2761: return simpleFunction(Tanh, "TANH");
2762: }
2763:
2764: /**
2765: * INTERNAL:
2766: * Build operator.
2767: */
2768: public static ExpressionOperator toDate() {
2769: return simpleFunction(ToDate, "TO_DATE");
2770: }
2771:
2772: /**
2773: * INTERNAL:
2774: * Build operator.
2775: */
2776: public static ExpressionOperator today() {
2777: return currentTimeStamp();
2778: }
2779:
2780: /**
2781: * INTERNAL:
2782: * Build operator.
2783: */
2784: public static ExpressionOperator currentTimeStamp() {
2785: return simpleFunctionNoParentheses(Today, "CURRENT_TIMESTAMP");
2786: }
2787:
2788: /**
2789: * INTERNAL:
2790: * Build operator.
2791: */
2792: public static ExpressionOperator currentDate() {
2793: return simpleFunctionNoParentheses(CurrentDate, "CURRENT_DATE");
2794: }
2795:
2796: /**
2797: * INTERNAL:
2798: * Build operator.
2799: */
2800: public static ExpressionOperator currentTime() {
2801: return simpleFunctionNoParentheses(CurrentTime, "CURRENT_TIME");
2802: }
2803:
2804: /**
2805: * INTERNAL:
2806: * Create the toLowerCase operator.
2807: */
2808: public static ExpressionOperator toLowerCase() {
2809: return simpleFunction(ToLowerCase, "LOWER", "toLowerCase");
2810: }
2811:
2812: /**
2813: * INTERNAL:
2814: * Build operator.
2815: */
2816: public static ExpressionOperator toNumber() {
2817: return simpleFunction(ToNumber, "TO_NUMBER");
2818: }
2819:
2820: /**
2821: * Print a debug representation of this operator.
2822: */
2823: public String toString() {
2824: if ((getDatabaseStrings() == null)
2825: || (getDatabaseStrings().length == 0)) {
2826: //CR#... Print a useful name for the missing plaftorm operator.
2827: return "platform operator - "
2828: + getPlatformOperatorName(getSelector());
2829: } else {
2830: return "operator " + getDatabaseStrings()[0];
2831: }
2832: }
2833:
2834: /**
2835: * INTERNAL:
2836: * Create the TOUPPERCASE operator.
2837: */
2838: public static ExpressionOperator toUpperCase() {
2839: return simpleFunction(ToUpperCase, "UPPER", "toUpperCase");
2840: }
2841:
2842: /**
2843: * INTERNAL:
2844: * Build operator.
2845: */
2846: public static ExpressionOperator translate() {
2847: return simpleThreeArgumentFunction(Translate, "TRANSLATE");
2848: }
2849:
2850: /**
2851: * INTERNAL:
2852: * Build operator.
2853: */
2854: public static ExpressionOperator trim() {
2855: return simpleFunction(Trim, "TRIM");
2856: }
2857:
2858: /**
2859: * INTERNAL:
2860: * Build Trim operator.
2861: */
2862: public static ExpressionOperator trim2() {
2863: ExpressionOperator exOperator = new ExpressionOperator();
2864: exOperator.setType(FunctionOperator);
2865: exOperator.setSelector(Trim2);
2866: Vector v = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
2867: .newInstance(5);
2868: v.addElement("TRIM(");
2869: v.addElement(" FROM ");
2870: v.addElement(")");
2871: exOperator.printsAs(v);
2872: exOperator.bePrefix();
2873: exOperator
2874: .setNodeClass(ClassConstants.FunctionExpression_Class);
2875: return exOperator;
2876: }
2877:
2878: /**
2879: * INTERNAL:
2880: * Build operator.
2881: */
2882: public static ExpressionOperator trunc() {
2883: return simpleTwoArgumentFunction(Trunc, "TRUNC");
2884: }
2885:
2886: /**
2887: * INTERNAL:
2888: * Build operator.
2889: */
2890: public static ExpressionOperator truncateDate() {
2891: return simpleTwoArgumentFunction(TruncateDate, "TRUNC");
2892: }
2893:
2894: /**
2895: * INTERNAL:
2896: * Build operator.
2897: */
2898: public static ExpressionOperator value() {
2899: return simpleFunction(Value, "VALUE");
2900: }
2901:
2902: /**
2903: * INTERNAL:
2904: * Build operator.
2905: */
2906: public static ExpressionOperator variance() {
2907: return simpleAggregate(Variance, "VARIANCE", "variance");
2908: }
2909:
2910: /**
2911: * INTERNAL:
2912: * Create the ANY operator.
2913: */
2914: public static ExpressionOperator any() {
2915: ExpressionOperator exOperator = new ExpressionOperator();
2916: exOperator.setType(FunctionOperator);
2917: exOperator.setSelector(Any);
2918: exOperator.printsAs("ANY");
2919: exOperator.bePostfix();
2920: exOperator
2921: .setNodeClass(ClassConstants.FunctionExpression_Class);
2922: return exOperator;
2923: }
2924:
2925: /**
2926: * INTERNAL:
2927: * Create the SOME operator.
2928: */
2929: public static ExpressionOperator some() {
2930: ExpressionOperator exOperator = new ExpressionOperator();
2931: exOperator.setType(FunctionOperator);
2932: exOperator.setSelector(Some);
2933: exOperator.printsAs("SOME");
2934: exOperator.bePostfix();
2935: exOperator
2936: .setNodeClass(ClassConstants.FunctionExpression_Class);
2937: return exOperator;
2938: }
2939:
2940: /**
2941: * INTERNAL:
2942: * Create the ALL operator.
2943: */
2944: public static ExpressionOperator all() {
2945: ExpressionOperator exOperator = new ExpressionOperator();
2946: exOperator.setType(FunctionOperator);
2947: exOperator.setSelector(All);
2948: exOperator.printsAs("ALL");
2949: exOperator.bePostfix();
2950: exOperator
2951: .setNodeClass(ClassConstants.FunctionExpression_Class);
2952: return exOperator;
2953: }
2954:
2955: /**
2956: * INTERNAL:
2957: * Indicates whether operator has selector Any or Some
2958: */
2959: public boolean isAny() {
2960: return selector == ExpressionOperator.Any
2961: || selector == ExpressionOperator.Some;
2962: }
2963:
2964: /**
2965: * INTERNAL:
2966: * Indicates whether operator has selector All
2967: */
2968: public boolean isAll() {
2969: return selector == ExpressionOperator.All;
2970: }
2971:
2972: /**
2973: * INTERNAL:
2974: * Indicates whether operator has selector Any, Some or All
2975: */
2976: public boolean isAnyOrAll() {
2977: return isAny() || isAll();
2978: }
2979: }
|