/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2018, 2021 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     Markus Karg - allow arguments to be specified multiple times in argumentIndices
//     05/07/2009-1.1.1 Dave Brosius
//       - 263904: [PATCH] ExpressionOperator doesn't compare arrays correctly
//     01/23/2018-2.7 Will Dazey
//       - 530214: trim operation should not bind parameters
package org.eclipse.persistence.expressions;

import java.io.IOException;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.internal.expressions.ArgumentListFunctionExpression;
import org.eclipse.persistence.internal.expressions.ExpressionJavaPrinter;
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.LogicalExpression;
import org.eclipse.persistence.internal.expressions.ObjectExpression;
import org.eclipse.persistence.internal.expressions.RelationExpression;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.JavaPlatform;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;

/**
 * <p>
 * <b>Purpose</b>: ADVANCED: The expression operator is used internally to define SQL operations and functions.
 * It is possible for an advanced user to define their own operators.
 */
public class ExpressionOperator implements Serializable {

    /** Required for serialization compatibility. */
    static final long serialVersionUID = -7066100204792043980L;
    protected int selector;
    protected String name;
    protected String[] databaseStrings;
    protected boolean isPrefix = false;
    protected boolean isRepeating = false;
    protected Class nodeClass;
    protected int type;
    protected int[] argumentIndices = null;
    protected static Map<Integer, ExpressionOperator> allOperators = initializeOperators();
    protected static final Map<String, Integer> platformOperatorSelectors = initializePlatformOperatorSelectors();
    protected static final Map<Integer, String> platformOperatorNames = initializePlatformOperatorNames();
    protected String[] javaStrings;
    /** Allow operator to disable binding. */
    protected boolean isBindingSupported = true;

    /** Operator types */
    public static final int LogicalOperator = 1;
    public static final int ComparisonOperator = 2;
    public static final int AggregateOperator = 3;
    public static final int OrderOperator = 4;
    public static final int FunctionOperator = 5;

    /** Logical operators */
    public static final int And = 1;
    public static final int Or = 2;
    public static final int Not = 3;

    /** Comparison operators */
    public static final int Equal = 4;
    public static final int NotEqual = 5;
    public static final int EqualOuterJoin = 6;
    public static final int LessThan = 7;
    public static final int LessThanEqual = 8;
    public static final int GreaterThan = 9;
    public static final int GreaterThanEqual = 10;
    public static final int Like = 11;
    public static final int NotLike = 12;
    public static final int In = 13;
    public static final int InSubQuery = 129;
    public static final int NotIn = 14;
    public static final int NotInSubQuery = 130;
    public static final int Between = 15;
    public static final int NotBetween = 16;
    public static final int IsNull = 17;
    public static final int NotNull = 18;
    public static final int Exists = 86;
    public static final int NotExists = 88;
    public static final int LikeEscape = 89;
    public static final int NotLikeEscape = 134;
    public static final int Decode = 105;
    public static final int Case = 117;
    public static final int NullIf = 131;
    public static final int Coalesce = 132;
    public static final int CaseCondition = 136;
    public static final int Regexp = 141;

    /** Aggregate operators */
    public static final int Count = 19;
    public static final int Sum = 20;
    public static final int Average = 21;
    public static final int Maximum = 22;
    public static final int Minimum = 23;
    public static final int StandardDeviation = 24;
    public static final int Variance = 25;
    public static final int Distinct = 87;

    public static final int As = 148;

    /** Union operators */
    public static final int Union = 142;
    public static final int UnionAll = 143;
    public static final int Intersect = 144;
    public static final int IntersectAll = 145;
    public static final int Except = 146;
    public static final int ExceptAll = 147;

    /** Ordering operators */
    public static final int Ascending = 26;
    public static final int Descending = 27;
    public static final int NullsFirst = 139;
    public static final int NullsLast = 140;

    /** Function operators */

    // General
    public static final int ToUpperCase = 28;
    public static final int ToLowerCase = 29;
    public static final int Chr = 30;
    public static final int Concat = 31;
    public static final int HexToRaw = 32;
    public static final int Initcap = 33;
    public static final int Instring = 34;
    public static final int Soundex = 35;
    public static final int LeftPad = 36;
    public static final int LeftTrim = 37;
    public static final int Replace = 38;
    public static final int RightPad = 39;
    public static final int RightTrim = 40;
    public static final int Substring = 41;
    public static final int ToNumber = 42;
    public static final int Translate = 43;
    public static final int Trim = 44;
    public static final int Ascii = 45;
    public static final int Length = 46;
    public static final int CharIndex = 96;
    public static final int CharLength = 97;
    public static final int Difference = 98;
    public static final int Reverse = 99;
    public static final int Replicate = 100;
    public static final int Right = 101;
    public static final int Locate = 112;
    public static final int Locate2 = 113;
    public static final int ToChar = 114;
    public static final int ToCharWithFormat = 115;
    public static final int RightTrim2 = 116;
    public static final int Any = 118;
    public static final int Some = 119;
    public static final int All = 120;
    public static final int Trim2 = 121;
    public static final int LeftTrim2 = 122;
    public static final int SubstringSingleArg = 133;
    public static final int Cast = 137;
    public static final int Extract = 138;

    // Date
    public static final int AddMonths = 47;
    public static final int DateToString = 48;
    public static final int LastDay = 49;
    public static final int MonthsBetween = 50;
    public static final int NextDay = 51;
    public static final int RoundDate = 52;
    public static final int ToDate = 53;
    /**
     * Function to obtain the current timestamp on the database including date
     * and time components. This corresponds to the JPQL function
     * current_timestamp.
     */
    public static final int Today = 54;
    public static final int AddDate = 90;
    public static final int DateName = 92;
    public static final int DatePart = 93;
    public static final int DateDifference = 94;
    public static final int TruncateDate = 102;
    public static final int NewTime = 103;
    public static final int Nvl = 104;
    /**
     * Function to obtain the current date on the database with date components
     * only but without time components. This corresponds to the JPQL function
     * current_date.
     */
    public static final int CurrentDate = 123;
    /**
     * Function to obtain the current time on the database with time components
     * only but without date components. This corresponds to the JPQL function
     * current_time.
     */
    public static final int CurrentTime = 128;

    // Math
    public static final int Ceil = 55;
    public static final int Cos = 56;
    public static final int Cosh = 57;
    public static final int Abs = 58;
    public static final int Acos = 59;
    public static final int Asin = 60;
    public static final int Atan = 61;
    public static final int Exp = 62;
    public static final int Sqrt = 63;
    public static final int Floor = 64;
    public static final int Ln = 65;
    public static final int Log = 66;
    public static final int Mod = 67;
    public static final int Power = 68;
    public static final int Round = 69;
    public static final int Sign = 70;
    public static final int Sin = 71;
    public static final int Sinh = 72;
    public static final int Tan = 73;
    public static final int Tanh = 74;
    public static final int Trunc = 75;
    public static final int Greatest = 76;
    public static final int Least = 77;
    public static final int Add = 78;
    public static final int Subtract = 79;
    public static final int Divide = 80;
    public static final int Multiply = 81;
    public static final int Atan2 = 91;
    public static final int Cot = 95;
    public static final int Negate = 135;

    // Object-relational
    public static final int Deref = 82;
    public static final int Ref = 83;
    public static final int RefToHex = 84;
    public static final int Value = 85;

    //XML Specific
    public static final int ExtractXml = 106;
    public static final int ExtractValue = 107;
    public static final int ExistsNode = 108;
    public static final int GetStringVal = 109;
    public static final int GetNumberVal = 110;
    public static final int IsFragment = 111;

    // Spatial
    public static final int SDO_WITHIN_DISTANCE = 124;
    public static final int SDO_RELATE = 125;
    public static final int SDO_FILTER = 126;
    public static final int SDO_NN = 127;

    /**
     * ADVANCED:
     * Create a new operator.
     */
    public ExpressionOperator() {
        this.type = FunctionOperator;
        // For bug 2780072 provide default behavior to make this class more useable.
        setNodeClass(ClassConstants.FunctionExpression_Class);
    }

    /**
     * ADVANCED:
     * Create a new operator with the given name(s) and strings to print.
     */
    public ExpressionOperator(int selector, List<String> newDatabaseStrings) {
        this.type = FunctionOperator;
        // For bug 2780072 provide default behavior to make this class more useable.
        setNodeClass(ClassConstants.FunctionExpression_Class);
        this.selector = selector;
        this.printsAs(newDatabaseStrings);
    }

    /**
     * PUBLIC:
     * Return if binding is compatible with this operator.
     */
    public boolean isBindingSupported() {
        return isBindingSupported;
    }

    /**
     * PUBLIC:
     * Set if binding is compatible with this operator.
     * Some databases do not allow binding, or require casting with certain operators.
     */
    public void setIsBindingSupported(boolean isBindingSupported) {
        this.isBindingSupported = isBindingSupported;
    }

    /**
     * INTERNAL:
     * Return if the operator is equal to the other.
     */
    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if ((object == null) || (getClass() != object.getClass())) {
            return false;
        }
        ExpressionOperator operator = (ExpressionOperator) object;
        if (getSelector() == 0) {
            return Arrays.equals(getDatabaseStrings(), operator.getDatabaseStrings());
        } else {
            return getSelector() == operator.getSelector();
        }
    }

    /**
     * INTERNAL:
     * Return the hash-code based on the unique selector.
     */
    @Override
    public int hashCode() {
        return getSelector();
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator abs() {
        return simpleFunction(Abs, "ABS");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator acos() {
        return simpleFunction(Acos, "ACOS");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator addDate() {
        ExpressionOperator exOperator = simpleThreeArgumentFunction(AddDate, "DATEADD");
        int[] indices = new int[3];
        indices[0] = 1;
        indices[1] = 2;
        indices[2] = 0;

        exOperator.setArgumentIndices(indices);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator addMonths() {
        return simpleTwoArgumentFunction(AddMonths, "ADD_MONTHS");
    }

    /**
     * ADVANCED:
     * Add an operator to the global list of operators.
     */
    public static void addOperator(ExpressionOperator exOperator) {
        allOperators.put(Integer.valueOf(exOperator.getSelector()), exOperator);
    }

    /**
     * ADVANCED:
     * Define a name for a user defined operator.
     */
    public static void registerOperator(int selector, String name) {
        platformOperatorNames.put(selector, name);
        platformOperatorSelectors.put(name, selector);
    }

    /**
     * INTERNAL:
     * Create the AND operator.
     */
    public static ExpressionOperator and() {
        return simpleLogical(And, "AND", "and");
    }

    /**
     * INTERNAL:
     * Apply this to an object in memory.
     * Throw an error if the function is not supported.
     */
    public Object applyFunction(Object source, List arguments) {
        if (source instanceof String) {
            if (this.selector == ToUpperCase) {
                return ((String)source).toUpperCase();
            } else if (this.selector == ToLowerCase) {
                return ((String)source).toLowerCase();
            } else if ((this.selector == Concat) && (arguments.size() == 1) && (arguments.get(0) instanceof String)) {
                return ((String)source).concat((String)arguments.get(0));
            } else if ((this.selector == Substring) && (arguments.size() == 2) && (arguments.get(0) instanceof Number) && (arguments.get(1) instanceof Number)) {
                // assume the first parameter to be 1-based first index of the substring, the second - substring length.
                int beginIndexInclusive = ((Number)arguments.get(0)).intValue() - 1;
                int endIndexExclusive = beginIndexInclusive +  ((Number)arguments.get(1)).intValue();
                return ((String)source).substring(beginIndexInclusive, endIndexExclusive);
            } else if ((this.selector == SubstringSingleArg) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                int beginIndexInclusive = ((Number)arguments.get(0)).intValue() - 1;
                int endIndexExclusive = ((String)source).length();
                return ((String)source).substring(beginIndexInclusive, endIndexExclusive);
            } else if (this.selector == ToNumber) {
                return new java.math.BigDecimal((String)source);
            } else if (this.selector == Trim) {
                return ((String)source).trim();
            } else if (this.selector == Length) {
                return Integer.valueOf(((String)source).length());
            }
        } else if (source instanceof Number) {
            if (this.selector == Ceil) {
                return Double.valueOf(Math.ceil(((Number)source).doubleValue()));
            } else if (this.selector == Cos) {
                return Double.valueOf(Math.cos(((Number)source).doubleValue()));
            } else if (this.selector == Abs) {
                return Double.valueOf(Math.abs(((Number)source).doubleValue()));
            } else if (this.selector == Acos) {
                return Double.valueOf(Math.acos(((Number)source).doubleValue()));
            } else if (this.selector == Asin) {
                return Double.valueOf(Math.asin(((Number)source).doubleValue()));
            } else if (this.selector == Atan) {
                return Double.valueOf(Math.atan(((Number)source).doubleValue()));
            } else if (this.selector == Exp) {
                return Double.valueOf(Math.exp(((Number)source).doubleValue()));
            } else if (this.selector == Sqrt) {
                return Double.valueOf(Math.sqrt(((Number)source).doubleValue()));
            } else if (this.selector == Floor) {
                return Double.valueOf(Math.floor(((Number)source).doubleValue()));
            } else if (this.selector == Log) {
                return Double.valueOf(Math.log(((Number)source).doubleValue()));
            } else if ((this.selector == Power) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(Math.pow(((Number)source).doubleValue(), (((Number)arguments.get(0)).doubleValue())));
            } else if (this.selector == Round) {
                return Double.valueOf(Math.round(((Number)source).doubleValue()));
            } else if (this.selector == Sin) {
                return Double.valueOf(Math.sin(((Number)source).doubleValue()));
            } else if (this.selector == Tan) {
                return Double.valueOf(Math.tan(((Number)source).doubleValue()));
            } else if ((this.selector == Greatest) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(Math.max(((Number)source).doubleValue(), (((Number)arguments.get(0)).doubleValue())));
            } else if ((this.selector == Least) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(Math.min(((Number)source).doubleValue(), (((Number)arguments.get(0)).doubleValue())));
            } else if ((this.selector == Add) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(((Number)source).doubleValue() + (((Number)arguments.get(0)).doubleValue()));
            } else if ((this.selector == Subtract) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(((Number)source).doubleValue() - (((Number)arguments.get(0)).doubleValue()));
            } else if ((this.selector == Divide) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(((Number)source).doubleValue() / (((Number)arguments.get(0)).doubleValue()));
            } else if ((this.selector == Multiply) && (arguments.size() == 1) && (arguments.get(0) instanceof Number)) {
                return Double.valueOf(((Number)source).doubleValue() * (((Number)arguments.get(0)).doubleValue()));
            }
        }

        throw QueryException.cannotConformExpression();
    }

    /**
     * INTERNAL:
     * Create the ASCENDING operator.
     */
    public static ExpressionOperator ascending() {
        return simpleOrdering(Ascending, "ASC", "ascending");
    }

    /**
     * INTERNAL:
     * Create the AS operator.
     */
    public static ExpressionOperator as() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(As);
        exOperator.printsAs(" AS ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the NULLS FIRST ordering operator.
     */
    public static ExpressionOperator nullsFirst() {
        return simpleOrdering(NullsFirst, "NULLS FIRST", "nullsFirst");
    }

    /**
     * INTERNAL:
     * Create the NULLS LAST ordering operator.
     */
    public static ExpressionOperator nullsLast() {
        return simpleOrdering(NullsLast, "NULLS LAST", "nullsLast");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator ascii() {
        return simpleFunction(Ascii, "ASCII");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator asin() {
        return simpleFunction(Asin, "ASIN");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator atan() {
        return simpleFunction(Atan, "ATAN");
    }

    /**
     * INTERNAL:
     * Create the AVERAGE operator.
     */
    public static ExpressionOperator average() {
        return simpleAggregate(Average, "AVG", "average");
    }

    /**
     * ADVANCED:
     * Tell the operator to be postfix, i.e. its strings start printing after
     * those of its first argument.
     */
    public void bePostfix() {
        isPrefix = false;
    }

    /**
     * ADVANCED:
     * Tell the operator to be pretfix, i.e. its strings start printing before
     * those of its first argument.
     */
    public void bePrefix() {
        isPrefix = true;
    }

    /**
     * INTERNAL:
     * Make this a repeating argument. Currently unused.
     */
    public void beRepeating() {
        isRepeating = true;
    }

    /**
     * INTERNAL:
     * Create the BETWEEN Operator
     */
    public static ExpressionOperator between() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(Between);
        result.setType(ComparisonOperator);
        List<String> v = new ArrayList<>();
        v.add("(");
        v.add(" BETWEEN ");
        v.add(" AND ");
        v.add(")");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Build operator.
     * Note: This operator works differently from other operators.
     * @see Expression#caseStatement(Map, Object)
     */
    public static ExpressionOperator caseStatement() {
        ListExpressionOperator exOperator = new ListExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Case);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.ArgumentListFunctionExpression_Class);
        exOperator.setIsBindingSupported(false);
        exOperator.setStartString("CASE ");
        exOperator.setSeparators(new String[]{" WHEN ", " THEN "});
        exOperator.setTerminationStrings(new String[]{" ELSE ", " END"});
        return exOperator;
    }


    /**
     * INTERNAL:
     * Build operator.
     * Note: This operator works differently from other operators.
     * @see Expression#caseStatement(Map, Object)
     */
    public static ExpressionOperator caseConditionStatement() {
        ListExpressionOperator exOperator = new ListExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(CaseCondition);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.ArgumentListFunctionExpression_Class);
        exOperator.setIsBindingSupported(false);
        exOperator.setStartStrings(new String[]{"CASE WHEN ", " THEN "});
        exOperator.setSeparators(new String[]{" WHEN ", " THEN "});
        exOperator.setTerminationStrings(new String[]{" ELSE ", " END "});
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator ceil() {
        return simpleFunction(Ceil, "CEIL");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator charIndex() {
        return simpleTwoArgumentFunction(CharIndex, "CHARINDEX");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator charLength() {
        return simpleFunction(CharLength, "CHAR_LENGTH");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator chr() {
        return simpleFunction(Chr, "CHR");
    }

    /**
     * INTERNAL:
     * Build operator.
     * Note: This operator works differently from other operators.
     * @see Expression#caseStatement(Map, Object)
     */
    public static ExpressionOperator coalesce() {
        ListExpressionOperator exOperator = new ListExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Coalesce);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.ArgumentListFunctionExpression_Class);
        exOperator.setStartString("COALESCE(");
        exOperator.setSeparator(", ");
        exOperator.setTerminationString(")");
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator concat() {
        ExpressionOperator operator = simpleMath(Concat, "+");
        operator.setIsBindingSupported(false);
        return operator;
    }

    /**
     * INTERNAL:
     * Compare between in memory.
     */
    public boolean conformBetween(Object left, Object right) {
        Object start = ((Vector)right).elementAt(0);
        Object end = ((Vector)right).elementAt(1);
        if ((left == null) || (start == null) || (end == null)) {
            return false;
        }
        if ((left instanceof Number) && (start instanceof Number) && (end instanceof Number)) {
            return ((((Number)left).doubleValue()) >= (((Number)start).doubleValue())) && ((((Number)left).doubleValue()) <= (((Number)end).doubleValue()));
        } else if ((left instanceof String) && (start instanceof String) && (end instanceof String)) {
            return ((((String)left).compareTo(((String)start)) > 0) || (((String)left).compareTo(((String)start)) == 0)) && ((((String)left).compareTo(((String)end)) < 0) || (((String)left).compareTo(((String)end)) == 0));
        } else if ((left instanceof java.util.Date) && (start instanceof java.util.Date) && (end instanceof java.util.Date)) {
            return (((java.util.Date)left).after(((java.util.Date)start)) || ((java.util.Date)left).equals((start))) && (((java.util.Date)left).before(((java.util.Date)end)) || ((java.util.Date)left).equals((end)));
        } else if ((left instanceof java.util.Calendar) && (start instanceof java.util.Calendar) && (end instanceof java.util.Calendar)) {
            return (((java.util.Calendar)left).after(start) || ((java.util.Calendar)left).equals((start))) && (((java.util.Calendar)left).before(end) || ((java.util.Calendar)left).equals((end)));
        }

        throw QueryException.cannotConformExpression();
    }

    /**
     * INTERNAL:
     * Compare like in memory.
     * This only works for % not _.
     * @author Christian Weeks aka ChristianLink
     */
    public boolean conformLike(Object left, Object right) {
        if ((right == null) && (left == null)) {
            return true;
        }
        if (!(right instanceof String) || !(left instanceof String)) {
            throw QueryException.cannotConformExpression();
        }
        String likeString = (String)right;
        if (likeString.indexOf('_') != -1) {
            throw QueryException.cannotConformExpression();
        }
        String value = (String)left;
        if (likeString.indexOf('%') == -1) {
            // No % symbols
            return left.equals(right);
        }
        boolean strictStart = !likeString.startsWith("%");
        boolean strictEnd = !likeString.endsWith("%");
        StringTokenizer tokens = new StringTokenizer(likeString, "%");
        int lastPosition = 0;
        String lastToken = null;
        if (strictStart) {
            lastToken = tokens.nextToken();
            if (!value.startsWith(lastToken)) {
                return false;
            }
        }
        while (tokens.hasMoreTokens()) {
            lastToken = tokens.nextToken();
            lastPosition = value.indexOf(lastToken, lastPosition);
            if (lastPosition < 0) {
                return false;
            }
        }
        if (strictEnd) {
            return value.endsWith(lastToken);
        }
        return true;
    }

    public void copyTo(ExpressionOperator operator){
        operator.selector = selector;
        operator.isPrefix = isPrefix;
        operator.isRepeating = isRepeating;
        operator.nodeClass = nodeClass;
        operator.type = type;
        operator.databaseStrings = databaseStrings == null ? null : Helper.copyStringArray(databaseStrings);
        operator.argumentIndices = argumentIndices == null ? null : Helper.copyIntArray(argumentIndices);
        operator.javaStrings = javaStrings == null ? null : Helper.copyStringArray(javaStrings);
        operator.isBindingSupported = isBindingSupported;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator cos() {
        return simpleFunction(Cos, "COS");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator cosh() {
        return simpleFunction(Cosh, "COSH");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator cot() {
        return simpleFunction(Cot, "COT");
    }

    /**
     * INTERNAL:
     * Create the COUNT operator.
     */
    public static ExpressionOperator count() {
        return simpleAggregate(Count, "COUNT", "count");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator dateDifference() {
        return simpleThreeArgumentFunction(DateDifference, "DATEDIFF");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator dateName() {
        return simpleTwoArgumentFunction(DateName, "DATENAME");
    }

    /**
     * INTERNAL:
     * Oracle equivalent to DATENAME is TO_CHAR.
     */
    public static ExpressionOperator oracleDateName() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(DateName);
        List<String> v = new ArrayList<>(3);
        v.add("TO_CHAR(");
        v.add(", '");
        v.add("')");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        int[] indices = { 1, 0 };
        exOperator.setArgumentIndices(indices);
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator datePart() {
        return simpleTwoArgumentFunction(DatePart, "DATEPART");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator dateToString() {
        return simpleFunction(DateToString, "TO_CHAR");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator toChar() {
        return simpleFunction(ToChar, "TO_CHAR");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator toCharWithFormat() {
        return simpleTwoArgumentFunction(ToCharWithFormat, "TO_CHAR");
    }

    /**
     * INTERNAL:
     * Build operator.
     * Note: This operator works differently from other operators.
     * @see Expression#decode(Map, String)
     */
    public static ExpressionOperator decode() {
        ExpressionOperator exOperator = new ExpressionOperator();

        exOperator.setSelector(Decode);

        exOperator.setNodeClass(FunctionExpression.class);
        exOperator.setType(FunctionOperator);
        exOperator.bePrefix();
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator deref() {
        return simpleFunction(Deref, "DEREF");
    }

    /**
     * INTERNAL:
     * Create the DESCENDING operator.
     */
    public static ExpressionOperator descending() {
        return simpleOrdering(Descending, "DESC", "descending");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator difference() {
        return simpleTwoArgumentFunction(Difference, "DIFFERENCE");
    }

    /**
     * INTERNAL:
     * Create the DISTINCT operator.
     */
    public static ExpressionOperator distinct() {
        return simpleFunction(Distinct, "DISTINCT", "distinct");
    }

    /**
     * INTERNAL:
     * Compare the values in memory.
     * Used for in-memory querying, all operators are not support.
     */
    public boolean doesRelationConform(Object left, Object right) {
        // Big ugly case statement follows.
        // Java is really verbose, the Smalltalk equivalent to this... left perform: self selector with: right
        // Note, compareTo for String returns a number <= -1 if the String is less than.  We assumed that
        // it would return -1.  The same thing for strings that are greater than (ie it returns >= 1). PWK
        // Equals

        if (this.selector == Equal || this.selector == NotEqual) {
            if ((left == null) && (right == null)) {
                return  this.selector == Equal;
            } else if ((left == null) || (right == null)) {
                return this.selector == NotEqual;
            }
            if (left instanceof Number && left instanceof Comparable && right instanceof Comparable
                && left.getClass().equals (right.getClass())) {
                return (((Comparable) left).compareTo( right) == 0) == (this.selector == Equal);
            }
            if (((left instanceof Number) && (right instanceof Number)) && (left.getClass() != right.getClass())) {
                double leftDouble = ((Number)left).doubleValue();
                double rightDouble = ((Number)right).doubleValue();
                if (Double.isNaN(leftDouble) && Double.isNaN(rightDouble)){
                    return this.selector == Equal;
                }
                return (leftDouble == rightDouble) == (this.selector == Equal);
            }
            return left.equals( right) == (this.selector == Equal);
        } else if (this.selector == IsNull) {
            return (left == null);
        }
        if (this.selector == NotNull) {
            return (left != null);
        }
        // Less thans, greater thans
        else if (this.selector == LessThan) {// You have got to love polymorphism in Java, NOT!!!
            if ((left == null) || (right == null)) {
                return false;
            }
            if ((left instanceof Number) && (right instanceof Number)) {
                return (((Number)left).doubleValue()) < (((Number)right).doubleValue());
            } else if ((left instanceof String) && (right instanceof String)) {
                return ((String)left).compareTo(((String)right)) < 0;
            } else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) {
                return ((java.util.Date)left).before(((java.util.Date)right));
            } else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) {
                return ((java.util.Calendar)left).before(right);
            }
        } else if (this.selector == LessThanEqual) {
            if ((left == null) && (right == null)) {
                return true;
            } else if ((left == null) || (right == null)) {
                return false;
            }
            if ((left instanceof Number) && (right instanceof Number)) {
                return (((Number)left).doubleValue()) <= (((Number)right).doubleValue());
            } else if ((left instanceof String) && (right instanceof String)) {
                int compareValue = ((String)left).compareTo(((String)right));
                return (compareValue < 0) || (compareValue == 0);
            } else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) {
                return ((java.util.Date)left).equals((right)) || ((java.util.Date)left).before(((java.util.Date)right));
            } else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) {
                return ((java.util.Calendar)left).equals((right)) || ((java.util.Calendar)left).before(right);
            }
        } else if (this.selector == GreaterThan) {
            if ((left == null) || (right == null)) {
                return false;
            }
            if ((left instanceof Number) && (right instanceof Number)) {
                return (((Number)left).doubleValue()) > (((Number)right).doubleValue());
            } else if ((left instanceof String) && (right instanceof String)) {
                int compareValue = ((String)left).compareTo(((String)right));
                return (compareValue > 0);
            } else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) {
                return ((java.util.Date)left).after(((java.util.Date)right));
            } else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) {
                return ((java.util.Calendar)left).after(right);
            }
        } else if (this.selector == GreaterThanEqual) {
            if ((left == null) && (right == null)) {
                return true;
            } else if ((left == null) || (right == null)) {
                return false;
            }
            if ((left instanceof Number) && (right instanceof Number)) {
                return (((Number)left).doubleValue()) >= (((Number)right).doubleValue());
            } else if ((left instanceof String) && (right instanceof String)) {
                int compareValue = ((String)left).compareTo(((String)right));
                return (compareValue > 0) || (compareValue == 0);
            } else if ((left instanceof java.util.Date) && (right instanceof java.util.Date)) {
                return ((java.util.Date)left).equals((right)) || ((java.util.Date)left).after(((java.util.Date)right));
            } else if ((left instanceof java.util.Calendar) && (right instanceof java.util.Calendar)) {
                return ((java.util.Calendar)left).equals((right)) || ((java.util.Calendar)left).after(right);
            }
        }
        // Between
        else if ((this.selector == Between) && (right instanceof Vector) && (((Vector)right).size() == 2)) {
            return conformBetween(left, right);
        } else if ((this.selector == NotBetween) && (right instanceof Vector) && (((Vector)right).size() == 2)) {
            return !conformBetween(left, right);
        }
        // In
        else if ((this.selector == In) && (right instanceof Collection)) {
            return ((Collection)right).contains(left);
        } else if ((this.selector == NotIn) && (right instanceof Collection)) {
            return !((Collection)right).contains(left);
        }
        // Like
        //conformLike(left, right);
        else if (((this.selector == Like) || (this.selector == NotLike)) && (right instanceof Vector) && (((Vector)right).size() == 1)) {
            Boolean doesLikeConform = JavaPlatform.conformLike(left, ((Vector)right).get(0));
            if (doesLikeConform != null) {
                if (doesLikeConform.booleanValue()) {
                    return this.selector == Like;// Negate for NotLike
                } else {
                    return this.selector != Like;// Negate for NotLike
                }
            }
        }
        // Regexp
        else if ((this.selector == Regexp) && (right instanceof Vector) && (((Vector)right).size() == 1)) {
            Boolean doesConform = JavaPlatform.conformRegexp(left, ((Vector)right).get(0));
            if (doesConform != null) {
                return doesConform.booleanValue();
            }
        }

        throw QueryException.cannotConformExpression();
    }

    /**
     * INTERNAL:
     * Initialize the outer join operator
     * Note: This is merely a shell which is incomplete, and
     * so will be replaced by the platform's operator when we
     * go to print. We need to create this here so that the expression
     * class is correct, normally it assumes functions for unknown operators.
     */
    public static ExpressionOperator equalOuterJoin() {
        return simpleRelation(EqualOuterJoin, "=*");
    }

    /**
     * INTERNAL:
     * Create the EXISTS operator.
     */
    public static ExpressionOperator exists() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Exists);
        List<String> v = new ArrayList<>(2);
        v.add("EXISTS" + " ");
        v.add(" ");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator exp() {
        return simpleFunction(Exp, "EXP");
    }

    /**
     * INTERNAL:
     * Create an expression for this operator, using the given base.
     */
    public Expression expressionFor(Expression base) {
        return expressionForArguments(base, new ArrayList<>(0));
    }

    /**
     * INTERNAL:
     * Create an expression for this operator, using the given base and a single argument.
     */
    public Expression expressionFor(Expression base, Object value) {
        return newExpressionForArgument(base, value);
    }

    /**
     * INTERNAL:
     * Create an expression for this operator, using the given base and a single argument.
     * Base is used last in the expression
     */
    public Expression expressionForWithBaseLast(Expression base, Object value) {
        return newExpressionForArgumentWithBaseLast(base, value);
    }

    /**
     * INTERNAL:
     * Create an expression for this operator, using the given base and arguments.
     */
    public Expression expressionForArguments(Expression base, List arguments) {
        return newExpressionForArguments(base, arguments);
    }

    /**
     * INTERNAL:
     * Create the extract expression operator
     */
    public static ExpressionOperator extractXml() {
        ExpressionOperator result = new ExpressionOperator();
        List<String> v = new ArrayList<>();
        v.add("extract(");
        v.add(",");
        v.add(")");
        result.printsAs(v);
        result.bePrefix();
        result.setSelector(ExtractXml);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Create the extractValue expression operator
     */
    public static ExpressionOperator extractValue() {
        ExpressionOperator result = new ExpressionOperator();
        List<String> v = new ArrayList<>();
        v.add("extractValue(");
        v.add(",");
        v.add(")");
        result.printsAs(v);
        result.bePrefix();
        result.setSelector(ExtractValue);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Create the existsNode expression operator
     */
    public static ExpressionOperator existsNode() {
        ExpressionOperator result = new ExpressionOperator();
        List<String> v = new ArrayList<>();
        v.add("existsNode(");
        v.add(",");
        v.add(")");
        result.printsAs(v);
        result.bePrefix();
        result.setSelector(ExistsNode);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    public static ExpressionOperator getStringVal() {
        ExpressionOperator result = new ExpressionOperator();
        List<String> v = new ArrayList<>();
        v.add(".getStringVal()");
        result.printsAs(v);
        result.bePostfix();
        result.setSelector(GetStringVal);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    public static ExpressionOperator getNumberVal() {
        ExpressionOperator result = new ExpressionOperator();
        List<String> v = new ArrayList<>();
        v.add(".getNumberVal()");
        result.printsAs(v);
        result.bePostfix();
        result.setSelector(GetNumberVal);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    public static ExpressionOperator isFragment() {
        ExpressionOperator result = new ExpressionOperator();
        List<String> v = new ArrayList<>();
        v.add(".isFragment()");
        result.printsAs(v);
        result.bePostfix();
        result.setSelector(IsFragment);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator floor() {
        return simpleFunction(Floor, "FLOOR");
    }

    /**
     * ADVANCED:
     * Return the map of all operators.
     */
    public static Map<Integer, ExpressionOperator> getAllOperators() {
        return allOperators;
    }

    public static Map<String, Integer> getPlatformOperatorSelectors() {
        return platformOperatorSelectors;
    }

    /**
     * INTERNAL:
     */
    public String[] getDatabaseStrings() {
        return databaseStrings;
    }

    /**
     * INTERNAL:
     */
    public String[] getJavaStrings() {
        return javaStrings;
    }

    /**
     * INTERNAL:
     */
    public Class getNodeClass() {
        return nodeClass;
    }

    /**
     * INTERNAL:
     * Lookup the operator with the given id.
     */
    public static ExpressionOperator getOperator(Integer selector) {
        return getAllOperators().get(selector);
    }

    /**
     * INTERNAL:
     * Return the selector id.
     */
    public int getSelector() {
        return selector;
    }

    /**
     * INTERNAL:
     * Return the name.
     */
    public String getName() {
        return name;
    }

    /**
     * INTERNAL:
     * Set the name.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * ADVANCED:
     * Return the type of function.
     * This must be one of the static function types defined in this class.
     */
    public int getType() {
        return this.type;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator greatest() {
        return simpleTwoArgumentFunction(Greatest, "GREATEST");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator hexToRaw() {
        return simpleFunction(HexToRaw, "HEXTORAW");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator ifNull() {
        return simpleTwoArgumentFunction(Nvl, "NVL");
    }

    /**
     * INTERNAL:
     * Create the IN operator.
     */
    public static ExpressionOperator in() {
        return simpleRelation(In, "IN");
    }

    /**
     * INTERNAL:
     * Create the IN operator taking a subquery.
     * Note, the subquery itself comes with parenethesis, so the IN operator
     * should not add any parenethesis.
     */
    public static ExpressionOperator inSubQuery() {
        ExpressionOperator result = new ExpressionOperator();
        result.setType(ExpressionOperator.FunctionOperator);
        result.setSelector(InSubQuery);
        List<String> v = new ArrayList<>(1);
        v.add(" IN ");
        result.printsAs(v);
        result.bePostfix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator initcap() {
        return simpleFunction(Initcap, "INITCAP");
    }

    /**
     * INTERNAL:
     */
    protected static void initializeAggregateFunctionOperators() {
        addOperator(count());
        addOperator(sum());
        addOperator(average());
        addOperator(minimum());
        addOperator(maximum());
        addOperator(distinct());
    }

    /**
     * INTERNAL:
     */
    protected static void initializeFunctionOperators() {
        addOperator(notOperator());
        addOperator(ascending());
        addOperator(descending());
        addOperator(as());
        addOperator(nullsFirst());
        addOperator(nullsLast());
        addOperator(any());
        addOperator(some());
        addOperator(all());
        addOperator(in());
        addOperator(inSubQuery());
        addOperator(notIn());
        addOperator(notInSubQuery());
        addOperator(coalesce());
        addOperator(caseStatement());
        addOperator(caseConditionStatement());
    }

    /**
     * INTERNAL:
     */
    protected static void initializeLogicalOperators() {
        addOperator(and());
        addOperator(or());
        addOperator(isNull());
        addOperator(notNull());

    }

    /**
     * INTERNAL:
     */
    public static Map initializeOperators() {
        resetOperators();
        initializeFunctionOperators();
        initializeRelationOperators();
        initializeLogicalOperators();
        initializeAggregateFunctionOperators();
        return allOperators;
    }

    /**
     * INTERNAL:
     * Initialize a mapping to the platform operator names for usage with exceptions.
     */
    public static String getPlatformOperatorName(int operator) {
        String name = (String)getPlatformOperatorNames().get(Integer.valueOf(operator));
        if (name == null) {
            name = String.valueOf(operator);
        }
        return name;
    }

    /**
     * INTERNAL:
     * Initialize a mapping to the platform operator names for usage with exceptions.
     */
    public static Map getPlatformOperatorNames() {
        return platformOperatorNames;
    }

    /**
     * INTERNAL:
     * Initialize a mapping to the platform operator names for usage with exceptions.
     */
    public static Map<Integer, String> initializePlatformOperatorNames() {
        Map<Integer, String> platformOperatorNames = new HashMap<>();
        platformOperatorNames.put(Integer.valueOf(ToUpperCase), "ToUpperCase");
        platformOperatorNames.put(Integer.valueOf(ToLowerCase), "ToLowerCase");
        platformOperatorNames.put(Integer.valueOf(Chr), "Chr");
        platformOperatorNames.put(Integer.valueOf(Concat), "Concat");
        platformOperatorNames.put(Integer.valueOf(Coalesce), "Coalesce");
        platformOperatorNames.put(Integer.valueOf(Case), "Case");
        platformOperatorNames.put(Integer.valueOf(CaseCondition), "Case(codition)");
        platformOperatorNames.put(Integer.valueOf(HexToRaw), "HexToRaw");
        platformOperatorNames.put(Integer.valueOf(Initcap), "Initcap");
        platformOperatorNames.put(Integer.valueOf(Instring), "Instring");
        platformOperatorNames.put(Integer.valueOf(Soundex), "Soundex");
        platformOperatorNames.put(Integer.valueOf(LeftPad), "LeftPad");
        platformOperatorNames.put(Integer.valueOf(LeftTrim), "LeftTrim");
        platformOperatorNames.put(Integer.valueOf(RightPad), "RightPad");
        platformOperatorNames.put(Integer.valueOf(RightTrim), "RightTrim");
        platformOperatorNames.put(Integer.valueOf(Substring), "Substring");
        platformOperatorNames.put(Integer.valueOf(SubstringSingleArg), "Substring");
        platformOperatorNames.put(Integer.valueOf(Translate), "Translate");
        platformOperatorNames.put(Integer.valueOf(Ascii), "Ascii");
        platformOperatorNames.put(Integer.valueOf(Length), "Length");
        platformOperatorNames.put(Integer.valueOf(CharIndex), "CharIndex");
        platformOperatorNames.put(Integer.valueOf(CharLength), "CharLength");
        platformOperatorNames.put(Integer.valueOf(Difference), "Difference");
        platformOperatorNames.put(Integer.valueOf(Reverse), "Reverse");
        platformOperatorNames.put(Integer.valueOf(Replicate), "Replicate");
        platformOperatorNames.put(Integer.valueOf(Right), "Right");
        platformOperatorNames.put(Integer.valueOf(Locate), "Locate");
        platformOperatorNames.put(Integer.valueOf(Locate2), "Locate");
        platformOperatorNames.put(Integer.valueOf(ToNumber), "ToNumber");
        platformOperatorNames.put(Integer.valueOf(ToChar), "ToChar");
        platformOperatorNames.put(Integer.valueOf(ToCharWithFormat), "ToChar");
        platformOperatorNames.put(Integer.valueOf(AddMonths), "AddMonths");
        platformOperatorNames.put(Integer.valueOf(DateToString), "DateToString");
        platformOperatorNames.put(Integer.valueOf(MonthsBetween), "MonthsBetween");
        platformOperatorNames.put(Integer.valueOf(NextDay), "NextDay");
        platformOperatorNames.put(Integer.valueOf(RoundDate), "RoundDate");
        platformOperatorNames.put(Integer.valueOf(AddDate), "AddDate");
        platformOperatorNames.put(Integer.valueOf(DateName), "DateName");
        platformOperatorNames.put(Integer.valueOf(DatePart), "DatePart");
        platformOperatorNames.put(Integer.valueOf(DateDifference), "DateDifference");
        platformOperatorNames.put(Integer.valueOf(TruncateDate), "TruncateDate");
        platformOperatorNames.put(Integer.valueOf(Extract), "Extract");
        platformOperatorNames.put(Integer.valueOf(Cast), "Cast");
        platformOperatorNames.put(Integer.valueOf(NewTime), "NewTime");
        platformOperatorNames.put(Integer.valueOf(Nvl), "Nvl");
        platformOperatorNames.put(Integer.valueOf(NewTime), "NewTime");
        platformOperatorNames.put(Integer.valueOf(Ceil), "Ceil");
        platformOperatorNames.put(Integer.valueOf(Cos), "Cos");
        platformOperatorNames.put(Integer.valueOf(Cosh), "Cosh");
        platformOperatorNames.put(Integer.valueOf(Abs), "Abs");
        platformOperatorNames.put(Integer.valueOf(Acos), "Acos");
        platformOperatorNames.put(Integer.valueOf(Asin), "Asin");
        platformOperatorNames.put(Integer.valueOf(Atan), "Atan");
        platformOperatorNames.put(Integer.valueOf(Exp), "Exp");
        platformOperatorNames.put(Integer.valueOf(Sqrt), "Sqrt");
        platformOperatorNames.put(Integer.valueOf(Floor), "Floor");
        platformOperatorNames.put(Integer.valueOf(Ln), "Ln");
        platformOperatorNames.put(Integer.valueOf(Log), "Log");
        platformOperatorNames.put(Integer.valueOf(Mod), "Mod");
        platformOperatorNames.put(Integer.valueOf(Power), "Power");
        platformOperatorNames.put(Integer.valueOf(Round), "Round");
        platformOperatorNames.put(Integer.valueOf(Sign), "Sign");
        platformOperatorNames.put(Integer.valueOf(Sin), "Sin");
        platformOperatorNames.put(Integer.valueOf(Sinh), "Sinh");
        platformOperatorNames.put(Integer.valueOf(Tan), "Tan");
        platformOperatorNames.put(Integer.valueOf(Tanh), "Tanh");
        platformOperatorNames.put(Integer.valueOf(Trunc), "Trunc");
        platformOperatorNames.put(Integer.valueOf(Greatest), "Greatest");
        platformOperatorNames.put(Integer.valueOf(Least), "Least");
        platformOperatorNames.put(Integer.valueOf(Add), "Add");
        platformOperatorNames.put(Integer.valueOf(Subtract), "Subtract");
        platformOperatorNames.put(Integer.valueOf(Divide), "Divide");
        platformOperatorNames.put(Integer.valueOf(Multiply), "Multiply");
        platformOperatorNames.put(Integer.valueOf(Atan2), "Atan2");
        platformOperatorNames.put(Integer.valueOf(Cot), "Cot");
        platformOperatorNames.put(Integer.valueOf(Deref), "Deref");
        platformOperatorNames.put(Integer.valueOf(Ref), "Ref");
        platformOperatorNames.put(Integer.valueOf(RefToHex), "RefToHex");
        platformOperatorNames.put(Integer.valueOf(Value), "Value");
        platformOperatorNames.put(Integer.valueOf(ExtractXml), "ExtractXml");
        platformOperatorNames.put(Integer.valueOf(ExtractValue), "ExtractValue");
        platformOperatorNames.put(Integer.valueOf(ExistsNode), "ExistsNode");
        platformOperatorNames.put(Integer.valueOf(GetStringVal), "GetStringVal");
        platformOperatorNames.put(Integer.valueOf(GetNumberVal), "GetNumberVal");
        platformOperatorNames.put(Integer.valueOf(IsFragment), "IsFragment");
        platformOperatorNames.put(Integer.valueOf(SDO_WITHIN_DISTANCE), "MDSYS.SDO_WITHIN_DISTANCE");
        platformOperatorNames.put(Integer.valueOf(SDO_RELATE), "MDSYS.SDO_RELATE");
        platformOperatorNames.put(Integer.valueOf(SDO_FILTER), "MDSYS.SDO_FILTER");
        platformOperatorNames.put(Integer.valueOf(SDO_NN), "MDSYS.SDO_NN");
        platformOperatorNames.put(Integer.valueOf(NullIf), "NullIf");
        platformOperatorNames.put(Integer.valueOf(Regexp), "REGEXP");
        platformOperatorNames.put(Integer.valueOf(Union), "UNION");
        platformOperatorNames.put(Integer.valueOf(UnionAll), "UNION ALL");
        platformOperatorNames.put(Integer.valueOf(Intersect), "INTERSECT");
        platformOperatorNames.put(Integer.valueOf(IntersectAll), "INTERSECT ALL");
        platformOperatorNames.put(Integer.valueOf(Except), "EXCEPT");
        platformOperatorNames.put(Integer.valueOf(ExceptAll), "EXCEPT ALL");
        return platformOperatorNames;
    }

    /**
     * INTERNAL:
     * Initialize a mapping to the platform operator names for usage with exceptions.
     */
    public static Map<String, Integer> initializePlatformOperatorSelectors() {
        Map<String, Integer> platformOperatorNames = new HashMap<>();
        platformOperatorNames.put("ToUpperCase", Integer.valueOf(ToUpperCase));
        platformOperatorNames.put("ToLowerCase", Integer.valueOf(ToLowerCase));
        platformOperatorNames.put("Chr", Integer.valueOf(Chr));
        platformOperatorNames.put("Concat", Integer.valueOf(Concat));
        platformOperatorNames.put("Coalesce", Integer.valueOf(Coalesce));
        platformOperatorNames.put("Case", Integer.valueOf(Case));
        platformOperatorNames.put("HexToRaw", Integer.valueOf(HexToRaw));
        platformOperatorNames.put("Initcap", Integer.valueOf(Initcap));
        platformOperatorNames.put("Instring", Integer.valueOf(Instring));
        platformOperatorNames.put("Soundex", Integer.valueOf(Soundex));
        platformOperatorNames.put("LeftPad", Integer.valueOf(LeftPad));
        platformOperatorNames.put("LeftTrim", Integer.valueOf(LeftTrim));
        platformOperatorNames.put("RightPad", Integer.valueOf(RightPad));
        platformOperatorNames.put("RightTrim", Integer.valueOf(RightTrim));
        platformOperatorNames.put("Substring", Integer.valueOf(Substring));
        platformOperatorNames.put("Translate", Integer.valueOf(Translate));
        platformOperatorNames.put("Ascii", Integer.valueOf(Ascii));
        platformOperatorNames.put("Length", Integer.valueOf(Length));
        platformOperatorNames.put("CharIndex", Integer.valueOf(CharIndex));
        platformOperatorNames.put("CharLength", Integer.valueOf(CharLength));
        platformOperatorNames.put("Difference", Integer.valueOf(Difference));
        platformOperatorNames.put("Reverse", Integer.valueOf(Reverse));
        platformOperatorNames.put("Replicate", Integer.valueOf(Replicate));
        platformOperatorNames.put("Right", Integer.valueOf(Right));
        platformOperatorNames.put("Locate", Integer.valueOf(Locate));
        platformOperatorNames.put("ToNumber", Integer.valueOf(ToNumber));
        platformOperatorNames.put("ToChar", Integer.valueOf(ToChar));
        platformOperatorNames.put("AddMonths", Integer.valueOf(AddMonths));
        platformOperatorNames.put("DateToString", Integer.valueOf(DateToString));
        platformOperatorNames.put("MonthsBetween", Integer.valueOf(MonthsBetween));
        platformOperatorNames.put("NextDay", Integer.valueOf(NextDay));
        platformOperatorNames.put("RoundDate", Integer.valueOf(RoundDate));
        platformOperatorNames.put("AddDate", Integer.valueOf(AddDate));
        platformOperatorNames.put("DateName", Integer.valueOf(DateName));
        platformOperatorNames.put("DatePart", Integer.valueOf(DatePart));
        platformOperatorNames.put("DateDifference", Integer.valueOf(DateDifference));
        platformOperatorNames.put("TruncateDate", Integer.valueOf(TruncateDate));
        platformOperatorNames.put("NewTime", Integer.valueOf(NewTime));
        platformOperatorNames.put("Nvl", Integer.valueOf(Nvl));
        platformOperatorNames.put("NewTime", Integer.valueOf(NewTime));
        platformOperatorNames.put("Ceil", Integer.valueOf(Ceil));
        platformOperatorNames.put("Cos", Integer.valueOf(Cos));
        platformOperatorNames.put("Cosh", Integer.valueOf(Cosh));
        platformOperatorNames.put("Abs", Integer.valueOf(Abs));
        platformOperatorNames.put("Acos", Integer.valueOf(Acos));
        platformOperatorNames.put("Asin", Integer.valueOf(Asin));
        platformOperatorNames.put("Atan", Integer.valueOf(Atan));
        platformOperatorNames.put("Exp", Integer.valueOf(Exp));
        platformOperatorNames.put("Sqrt", Integer.valueOf(Sqrt));
        platformOperatorNames.put("Floor", Integer.valueOf(Floor));
        platformOperatorNames.put("Ln", Integer.valueOf(Ln));
        platformOperatorNames.put("Log", Integer.valueOf(Log));
        platformOperatorNames.put("Mod", Integer.valueOf(Mod));
        platformOperatorNames.put("Power", Integer.valueOf(Power));
        platformOperatorNames.put("Round", Integer.valueOf(Round));
        platformOperatorNames.put("Sign", Integer.valueOf(Sign));
        platformOperatorNames.put("Sin", Integer.valueOf(Sin));
        platformOperatorNames.put("Sinh", Integer.valueOf(Sinh));
        platformOperatorNames.put("Tan", Integer.valueOf(Tan));
        platformOperatorNames.put("Tanh", Integer.valueOf(Tanh));
        platformOperatorNames.put("Trunc", Integer.valueOf(Trunc));
        platformOperatorNames.put("Greatest", Integer.valueOf(Greatest));
        platformOperatorNames.put("Least", Integer.valueOf(Least));
        platformOperatorNames.put("Add", Integer.valueOf(Add));
        platformOperatorNames.put("Subtract", Integer.valueOf(Subtract));
        platformOperatorNames.put("Divide", Integer.valueOf(Divide));
        platformOperatorNames.put("Multiply", Integer.valueOf(Multiply));
        platformOperatorNames.put("Atan2", Integer.valueOf(Atan2));
        platformOperatorNames.put("Cot", Integer.valueOf(Cot));
        platformOperatorNames.put("Deref", Integer.valueOf(Deref));
        platformOperatorNames.put("Ref", Integer.valueOf(Ref));
        platformOperatorNames.put("RefToHex", Integer.valueOf(RefToHex));
        platformOperatorNames.put("Value", Integer.valueOf(Value));
        platformOperatorNames.put("Cast", Integer.valueOf(Cast));
        platformOperatorNames.put("Extract", Integer.valueOf(Extract));
        platformOperatorNames.put("ExtractXml", Integer.valueOf(ExtractXml));
        platformOperatorNames.put("ExtractValue", Integer.valueOf(ExtractValue));
        platformOperatorNames.put("ExistsNode", Integer.valueOf(ExistsNode));
        platformOperatorNames.put("GetStringVal", Integer.valueOf(GetStringVal));
        platformOperatorNames.put("GetNumberVal", Integer.valueOf(GetNumberVal));
        platformOperatorNames.put("IsFragment", Integer.valueOf(IsFragment));
        platformOperatorNames.put("SDO_WITHIN_DISTANCE", Integer.valueOf(SDO_WITHIN_DISTANCE));
        platformOperatorNames.put("SDO_RELATE", Integer.valueOf(SDO_RELATE));
        platformOperatorNames.put("SDO_FILTER", Integer.valueOf(SDO_FILTER));
        platformOperatorNames.put("SDO_NN", Integer.valueOf(SDO_NN));
        platformOperatorNames.put("NullIf", Integer.valueOf(NullIf));
        return platformOperatorNames;
    }

    /**
     * INTERNAL:
     */
    protected static void initializeRelationOperators() {
        addOperator(simpleRelation(Equal, "=", "equal"));
        addOperator(simpleRelation(NotEqual, "<>", "notEqual"));
        addOperator(simpleRelation(LessThan, "<", "lessThan"));
        addOperator(simpleRelation(LessThanEqual, "<=", "lessThanEqual"));
        addOperator(simpleRelation(GreaterThan, ">", "greaterThan"));
        addOperator(simpleRelation(GreaterThanEqual, ">=", "greaterThanEqual"));

        addOperator(like());
        addOperator(likeEscape());
        addOperator(notLike());
        addOperator(notLikeEscape());
        addOperator(between());

        addOperator(exists());
        addOperator(notExists());
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator instring() {
        return simpleTwoArgumentFunction(Instring, "INSTR");
    }

    /**
     * Aggregate functions are function in the select such as COUNT.
     */
    public boolean isAggregateOperator() {
        return getType() == AggregateOperator;
    }

    /**
     * Comparison functions are functions such as = and {@literal >}.
     */
    public boolean isComparisonOperator() {
        return getType() == ComparisonOperator;
    }

    /**
     * INTERNAL:
     * If we have all the required information, this operator is complete
     * and can be used as is. Otherwise we will need to look up a platform-
     * specific operator.
     */
    public boolean isComplete() {
        return (databaseStrings != null) && (databaseStrings.length != 0);
    }

    /**
     * General functions are any normal function such as UPPER.
     */
    public boolean isFunctionOperator() {
        return getType() == FunctionOperator;
    }

    /**
     * Logical functions are functions such as and and or.
     */
    public boolean isLogicalOperator() {
        return getType() == LogicalOperator;
    }

    /**
     * INTERNAL:
     * Create the ISNULL operator.
     */
    public static ExpressionOperator isNull() {
        ExpressionOperator result = new ExpressionOperator();
        result.setType(ComparisonOperator);
        result.setSelector(IsNull);
        List<String> v = new ArrayList<>();
        v.add("(");
        v.add(" IS NULL)");
        result.printsAs(v);
        result.bePrefix();
        result.printsJavaAs(".isNull()");
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * Order functions are used in the order by such as ASC.
     */
    public boolean isOrderOperator() {
        return getType() == OrderOperator;
    }

    /**
     * ADVANCED:
     * Return true if this is a prefix operator.
     */
    public boolean isPrefix() {
        return isPrefix;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator lastDay() {
        return simpleFunction(LastDay, "LAST_DAY");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator least() {
        return simpleTwoArgumentFunction(Least, "LEAST");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator leftPad() {
        return simpleThreeArgumentFunction(LeftPad, "LPAD");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator leftTrim() {
        return simpleFunction(LeftTrim, "LTRIM");
    }

    /**
     * INTERNAL:
     * Build leftTrim operator that takes one parameter.
     */
    public static ExpressionOperator leftTrim2() {
        ExpressionOperator operator = simpleTwoArgumentFunction(LeftTrim2, "LTRIM");
        return operator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator length() {
        return simpleFunction(Length, "LENGTH");
    }

    /**
     * INTERNAL:
     * Create the LIKE operator.
     */
    public static ExpressionOperator like() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(Like);
        result.setType(FunctionOperator);
        List<String> v = new ArrayList<>(3);
        v.add("");
        v.add(" LIKE ");
        v.add("");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        v = new ArrayList<>(2);
        v.add(".like(");
        v.add(")");
        result.printsJavaAs(v);
        return result;
    }

    /**
     * INTERNAL:
     * Create the REGEXP operator.
     * REGEXP allows for comparison through regular expression,
     * this is supported by many databases and with be part of the next SQL standard.
     */
    public static ExpressionOperator regexp() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(Regexp);
        result.setType(FunctionOperator);
        List<String> v = new ArrayList<>(3);
        v.add("");
        v.add(" REGEXP ");
        v.add("");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        v = new ArrayList<>(2);
        v.add(".regexp(");
        v.add(")");
        result.printsJavaAs(v);
        return result;
    }

    /**
     * INTERNAL:
     * Create the LIKE operator with ESCAPE.
     */
    public static ExpressionOperator likeEscape() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(LikeEscape);
        result.setType(FunctionOperator);
        List<String> v = new ArrayList<>();
        v.add("");
        v.add(" LIKE ");
        v.add(" ESCAPE ");
        v.add("");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        result.setIsBindingSupported(false);
        return result;
    }
    /**
     * INTERNAL:
     * Create the LIKE operator with ESCAPE.
     */
    public static ExpressionOperator notLikeEscape() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(NotLikeEscape);
        result.setType(FunctionOperator);
        List<String> v = new ArrayList<>();
        v.add("");
        v.add(" NOT LIKE ");
        v.add(" ESCAPE ");
        v.add("");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        result.setIsBindingSupported(false);
        return result;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator ln() {
        return simpleFunction(Ln, "LN");
    }

    /**
     * INTERNAL:
     * Build locate operator i.e. LOCATE("ob", t0.F_NAME)
     */
    public static ExpressionOperator locate() {
        ExpressionOperator expOperator = simpleTwoArgumentFunction(Locate, "LOCATE");
        int[] argumentIndices = new int[2];
        argumentIndices[0] = 1;
        argumentIndices[1] = 0;
        expOperator.setArgumentIndices(argumentIndices);
        expOperator.setIsBindingSupported(false);
        return expOperator;
    }

    /**
     * INTERNAL:
     * Build locate operator with 3 params i.e. LOCATE("coffee", t0.DESCRIP, 4).
     * Last parameter is a start at.
     */
    public static ExpressionOperator locate2() {
        ExpressionOperator expOperator = simpleThreeArgumentFunction(Locate2, "LOCATE");
        int[] argumentIndices = new int[3];
        argumentIndices[0] = 1;
        argumentIndices[1] = 0;
        argumentIndices[2] = 2;
        expOperator.setArgumentIndices(argumentIndices);
        expOperator.setIsBindingSupported(false);
        return expOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator log() {
        return simpleFunction(Log, "LOG");
    }

    /**
     * INTERNAL:
     * Create the MAXIMUM operator.
     */
    public static ExpressionOperator maximum() {
        return simpleAggregate(Maximum, "MAX", "maximum");
    }

    /**
     * INTERNAL:
     * Create the MINIMUM operator.
     */
    public static ExpressionOperator minimum() {
        return simpleAggregate(Minimum, "MIN", "minimum");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator mod() {
        ExpressionOperator operator = simpleTwoArgumentFunction(Mod, "MOD");
        operator.setIsBindingSupported(false);
        return operator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator monthsBetween() {
        return simpleTwoArgumentFunction(MonthsBetween, "MONTHS_BETWEEN");
    }

    /**
     * INTERNAL:
     * Create a new expression. Optimized for the single argument case.
     */
    public Expression newExpressionForArgument(Expression base, Object singleArgument) {
        if (singleArgument == null) {
            if (this.selector == Equal) {
                return base.isNull();
            } else if (this.selector == NotEqual) {
                return base.notNull();
            }
        }
        Expression node = createNode();
        node.create(base, singleArgument, this);
        return node;
    }

    /**
     * INTERNAL:
     * Instantiate an instance of the operator's node class.
     */
    protected Expression createNode() {
        // PERF: Avoid reflection for common cases.
        if (this.nodeClass == ClassConstants.ArgumentListFunctionExpression_Class){
            return new ArgumentListFunctionExpression();
        } else if (this.nodeClass == ClassConstants.FunctionExpression_Class) {
            return new FunctionExpression();

        } else if (this.nodeClass == ClassConstants.RelationExpression_Class) {
            return new RelationExpression();
        } else if (this.nodeClass == ClassConstants.LogicalExpression_Class) {
            return new LogicalExpression();
        }
        try {
            Expression node = null;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    node = (Expression)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(getNodeClass()));
                } catch (PrivilegedActionException exception) {
                    return null;
                }
            } else {
                node = (Expression)PrivilegedAccessHelper.newInstanceFromClass(getNodeClass());
            }
            return node;
        } catch (InstantiationException exception) {
            throw new InternalError(exception.toString());
        } catch (IllegalAccessException exception) {
            throw new InternalError(exception.toString());
        }
    }

    /**
     * INTERNAL:
     * Create a new expression. Optimized for the single argument case with base last
     */
    public Expression newExpressionForArgumentWithBaseLast(Expression base, Object singleArgument) {
        if (singleArgument == null) {
            if (this.selector == Equal) {
                return base.isNull();
            } else if (this.selector == NotEqual) {
                return base.notNull();
            }
        }
        Expression node = createNode();
        node.createWithBaseLast(base, singleArgument, this);
        return node;
    }

    /**
     * INTERNAL:
     * The general case.
     */
    public Expression newExpressionForArguments(Expression base, List arguments) {
        if ((arguments.size() == 1) && (arguments.get(0) == null)) {
            if (this.selector == Equal) {
                return base.isNull();
            } else if (this.selector == NotEqual) {
                return base.notNull();
            }
        }
        Expression node = createNode();
        node.create(base, arguments, this);
        return node;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator negate() {
        return simpleFunction(Negate, "-");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator newTime() {
        return simpleThreeArgumentFunction(NewTime, "NEW_TIME");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator nextDay() {
        return simpleTwoArgumentFunction(NextDay, "NEXT_DAY");
    }

    /**
     * INTERNAL:
     * Create the NOT EXISTS operator.
     */
    public static ExpressionOperator notExists() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(NotExists);
        List<String> v = new ArrayList<>(2);
        v.add("NOT EXISTS" + " ");
        v.add(" ");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the NOTIN operator.
     */
    public static ExpressionOperator notIn() {
        return simpleRelation(NotIn, "NOT IN");
    }

    /**
     * INTERNAL:
     * Create the NOTIN operator taking a subQuery.
     * Note, the subquery itself comes with parenethesis, so the IN operator
     * should not add any parenethesis.
     */
    public static ExpressionOperator notInSubQuery() {
        ExpressionOperator result = new ExpressionOperator();
        result.setType(ExpressionOperator.FunctionOperator);
        result.setSelector(NotInSubQuery);
        List<String> v = new ArrayList<>(1);
        v.add(" NOT IN ");
        result.printsAs(v);
        result.bePostfix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Create the NOTLIKE operator.
     */
    public static ExpressionOperator notLike() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(NotLike);
        result.setType(FunctionOperator);
        List<String> v = new ArrayList<>();
        v.add("");
        v.add(" NOT LIKE ");
        v.add("");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        v = new ArrayList<>(2);
        v.add(".notLike(");
        v.add(")");
        result.printsJavaAs(v);
        return result;
    }

    /**
     * INTERNAL:
     * Create the NOTNULL operator.
     */
    public static ExpressionOperator notNull() {
        ExpressionOperator result = new ExpressionOperator();
        result.setType(ComparisonOperator);
        result.setSelector(NotNull);
        List<String> v = new ArrayList<>();
        v.add("(");
        v.add(" IS NOT NULL)");
        result.printsAs(v);
        result.bePrefix();
        result.printsJavaAs(".notNull()");
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Create the NOT operator.
     */
    public static ExpressionOperator notOperator() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(Not);
        List<String> v = new ArrayList<>();
        v.add("NOT (");
        v.add(")");
        result.printsAs(v);
        result.bePrefix();
        result.printsJavaAs(".not()");
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator nullIf() {
        return simpleTwoArgumentFunction(NullIf, "NULLIF");
    }

    /**
     * INTERNAL:
     * Create the OR operator.
     */
    public static ExpressionOperator or() {
        return simpleLogical(Or, "OR", "or");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator power() {
        return simpleTwoArgumentFunction(Power, "POWER");
    }

    /**
     * INTERNAL: Print the collection onto the SQL stream.
     */
    public void printCollection(List items, ExpressionSQLPrinter printer) {
        // Certain functions don't allow binding on some platforms.
        if (printer.getPlatform().isDynamicSQLRequiredForFunctions() && !isBindingSupported()) {
            printer.getCall().setUsesBinding(false);
        }
        int dbStringIndex = 0;
        try {
            if (isPrefix()) {
                printer.getWriter().write(getDatabaseStrings()[0]);
                dbStringIndex = 1;
            } else {
                dbStringIndex = 0;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (argumentIndices == null) {
            argumentIndices = new int[items.size()];
            for (int i = 0; i < argumentIndices.length; i++){
                argumentIndices[i] = i;
            }
        }

        for (final int index : argumentIndices) {
            Expression item = (Expression)items.get(index);
            if ((this.selector == Ref) || ((this.selector == Deref) && (item.isObjectExpression()))) {
                DatabaseTable alias = ((ObjectExpression)item).aliasForTable(((ObjectExpression)item).getDescriptor().getTables().firstElement());
                printer.printString(alias.getNameDelimited(printer.getPlatform()));
            } else if ((this.selector == Count) && (item.isExpressionBuilder())) {
                printer.printString("*");
            } else {
                item.printSQL(printer);
            }
            if (dbStringIndex < getDatabaseStrings().length) {
                printer.printString(getDatabaseStrings()[dbStringIndex++]);
            }
        }
    }

    /**
     * INTERNAL: Print the collection onto the SQL stream.
     */
    public void printJavaCollection(List items, ExpressionJavaPrinter printer) {
        int javaStringIndex = 0;

        for (int i = 0; i < items.size(); i++) {
            Expression item = (Expression)items.get(i);
            item.printJava(printer);
            if (javaStringIndex < getJavaStrings().length) {
                printer.printString(getJavaStrings()[javaStringIndex++]);
            }
        }
    }

    /**
     * INTERNAL:
     * For performance, special case printing two children, since it's by far the most common
     */
    public void printDuo(Expression first, Expression second, ExpressionSQLPrinter printer) {
        // Certain functions don't allow binding on some platforms.
        if (printer.getPlatform().isDynamicSQLRequiredForFunctions() && !isBindingSupported()) {
            printer.getCall().setUsesBinding(false);
        }
        int dbStringIndex;
        if (isPrefix()) {
            printer.printString(getDatabaseStrings()[0]);
            dbStringIndex = 1;
        } else {
            dbStringIndex = 0;
        }

        first.printSQL(printer);
        if (dbStringIndex < getDatabaseStrings().length) {
            printer.printString(getDatabaseStrings()[dbStringIndex++]);
        }
        if (second != null) {
            second.printSQL(printer);
            if (dbStringIndex < getDatabaseStrings().length) {
                printer.printString(getDatabaseStrings()[dbStringIndex++]);
            }
        }
    }

    /**
     * INTERNAL:
     * For performance, special case printing two children, since it's by far the most common
     */
    public void printJavaDuo(Expression first, Expression second, ExpressionJavaPrinter printer) {
        int javaStringIndex = 0;

        first.printJava(printer);
        if (javaStringIndex < getJavaStrings().length) {
            printer.printString(getJavaStrings()[javaStringIndex++]);
        }
        if (second != null) {
            second.printJava(printer);
            if (javaStringIndex < getJavaStrings().length) {
                printer.printString(getJavaStrings()[javaStringIndex]);
            }
        }
    }

    /**
     * ADVANCED:
     * Set the single string for this operator.
     */
    public void printsAs(String s) {
        List<String> v = new ArrayList<>(1);
        v.add(s);
        printsAs(v);
    }

    /**
     * ADVANCED:
     * Set the strings for this operator.
     */
    public void printsAs(List<String> dbStrings) {
        this.databaseStrings = new String[dbStrings.size()];
        for (int i = 0; i < dbStrings.size(); i++) {
            getDatabaseStrings()[i] = dbStrings.get(i);
        }
    }

    /**
     * ADVANCED:
     * Set the single string for this operator.
     */
    public void printsJavaAs(String s) {
        List<String> v = new ArrayList<>(1);
        v.add(s);
        printsJavaAs(v);
    }

    /**
     * ADVANCED:
     * Set the strings for this operator.
     */
    public void printsJavaAs(List<String> dbStrings) {
        this.javaStrings = new String[dbStrings.size()];
        for (int i = 0; i < dbStrings.size(); i++) {
            getJavaStrings()[i] = dbStrings.get(i);
        }
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator ref() {
        return simpleFunction(Ref, "REF");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator refToHex() {
        return simpleFunction(RefToHex, "REFTOHEX");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator replace() {
        ExpressionOperator operator = simpleThreeArgumentFunction(Replace, "REPLACE");
        operator.setIsBindingSupported(false);
        return operator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator replicate() {
        return simpleTwoArgumentFunction(Replicate, "REPLICATE");
    }

    /**
     * INTERNAL:
     * Reset all the operators.
     */
    public static void resetOperators() {
        allOperators = new HashMap();
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator reverse() {
        return simpleFunction(Reverse, "REVERSE");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator right() {
        return simpleTwoArgumentFunction(Right, "RIGHT");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator rightPad() {
        return simpleThreeArgumentFunction(RightPad, "RPAD");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator rightTrim() {
        return simpleFunction(RightTrim, "RTRIM");
    }

    /**
     * INTERNAL:
     * Build rightTrim operator that takes one parameter.
     */
    public static ExpressionOperator rightTrim2() {
        // bug 2916893 rightTrim(substring) broken
        ExpressionOperator operator = simpleTwoArgumentFunction(RightTrim2, "RTRIM");
        return operator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator round() {
        return simpleTwoArgumentFunction(Round, "ROUND");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator roundDate() {
        return simpleTwoArgumentFunction(RoundDate, "ROUND");
    }

    /**
     * ADVANCED: Set the array of indexes to use when building the SQL function.
     *
     * The index of the array is the position in the printout, from left to right, starting with zero.
     * The value of the array entry is the number of the argument to print at that particular output position.
     * So each argument can be used zero, one or many times.
     */
    public void setArgumentIndices(int[] indices) {
        argumentIndices = indices;
    }

    /**
     * ADVANCED:
     * Set the node class for this operator. For user-defined functions this is
     * set automatically but can be changed.
     * <p>A list of Operator types, an example, and the node class used follows.
     * <p>LogicalOperator     AND           LogicalExpression
     * <p>ComparisonOperator  {@literal <>} RelationExpression
     * <p>AggregateOperator   COUNT         FunctionExpression
     * <p>OrderOperator       ASCENDING             "
     * <p>FunctionOperator    RTRIM                 "
     * <p>Node classes given belong to org.eclipse.persistence.internal.expressions.
     */
    public void setNodeClass(Class nodeClass) {
        this.nodeClass = nodeClass;
    }

    /**
     * INTERNAL:
     * Set the selector id.
     */
    public void setSelector(int selector) {
        this.selector = selector;
    }

    /**
     * ADVANCED:
     * Set the type of function.
     * This must be one of the static function types defined in this class.
     */
    public void setType(int type) {
        this.type = type;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator sign() {
        return simpleFunction(Sign, "SIGN");
    }

    /**
     * INTERNAL:
     * Create an operator for a simple aggregate given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleAggregate(int selector, String databaseName, String javaName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(AggregateOperator);
        exOperator.setSelector(selector);
        List<String> v = new ArrayList<>(2);
        v.add(databaseName + "(");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.printsJavaAs("." + javaName + "()");
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple function given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleFunction(int selector, String databaseName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(selector);
        exOperator.setName(databaseName);
        List<String> v = new ArrayList<>(2);
        v.add(databaseName + "(");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple function call without parentheses
     */
    public static ExpressionOperator simpleFunctionNoParentheses(int selector, String databaseName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(selector);
        List<String> v = new ArrayList<>(1);
        v.add(databaseName);
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }


    /**
     * INTERNAL:
     * Create an operator for a simple function given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleFunction(int selector, String databaseName, String javaName) {
        ExpressionOperator exOperator = simpleFunction(selector, databaseName);
        exOperator.printsJavaAs("." + javaName + "()");
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple logical given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleLogical(int selector, String databaseName, String javaName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(LogicalOperator);
        exOperator.setSelector(selector);
        exOperator.printsAs(" " + databaseName + " ");
        exOperator.bePostfix();
        List<String> v = new ArrayList<>(2);
        v.add("." + javaName + "(");
        v.add(")");
        exOperator.printsJavaAs(v);
        exOperator.setNodeClass(ClassConstants.LogicalExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple math operatin, i.e. +, -, *, /
     */
    public static ExpressionOperator simpleMath(int selector, String databaseName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setIsBindingSupported(false);
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(selector);
        List<String> v = new ArrayList<>(3);
        v.add("(");
        v.add(" " + databaseName + " ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple ordering given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleOrdering(int selector, String databaseName, String javaName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(OrderOperator);
        exOperator.setSelector(selector);
        exOperator.printsAs(" " + databaseName);
        exOperator.bePostfix();
        exOperator.printsJavaAs("." + javaName + "()");
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple relation given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleRelation(int selector, String databaseName) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(ComparisonOperator);
        exOperator.setSelector(selector);
        exOperator.printsAs(" " + databaseName + " ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.RelationExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create an operator for a simple relation given a Java name and a single
     * String for the database (parentheses will be added automatically).
     */
    public static ExpressionOperator simpleRelation(int selector, String databaseName, String javaName) {
        ExpressionOperator exOperator = simpleRelation(selector, databaseName);
        List<String> v = new ArrayList<>(2);
        v.add("." + javaName + "(");
        v.add(")");
        exOperator.printsJavaAs(v);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator simpleThreeArgumentFunction(int selector, String dbString) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(selector);
        exOperator.setName(dbString);
        List<String> v = new ArrayList<>(4);
        v.add(dbString + "(");
        v.add(", ");
        v.add(", ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator simpleTwoArgumentFunction(int selector, String dbString) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(selector);
        exOperator.setName(dbString);
        List<String> v = new ArrayList<>(5);
        v.add(dbString + "(");
        v.add(", ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * e.g.: ... "Bob" CONCAT "Smith" ...
     * Parentheses will not be addded. [RMB - March 5 2000]
     */
    public static ExpressionOperator simpleLogicalNoParens(int selector, String dbString) {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(selector);
        List<String> v = new ArrayList<>(5);
        v.add("");
        v.add(" " + dbString + " ");
        v.add("");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator sin() {
        return simpleFunction(Sin, "SIN");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator sinh() {
        return simpleFunction(Sinh, "SINH");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator soundex() {
        return simpleFunction(Soundex, "SOUNDEX");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator sqrt() {
        return simpleFunction(Sqrt, "SQRT");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator standardDeviation() {
        return simpleAggregate(StandardDeviation, "STDDEV", "standardDeviation");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator substring() {
        ExpressionOperator operator = simpleThreeArgumentFunction(Substring, "SUBSTR");
        operator.setIsBindingSupported(false);
        return operator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator substringSingleArg() {
        return simpleTwoArgumentFunction(SubstringSingleArg, "SUBSTR");
    }

    /**
     * INTERNAL:
     * Create the SUM operator.
     */
    public static ExpressionOperator sum() {
        return simpleAggregate(Sum, "SUM", "sum");
    }

    /**
     * INTERNAL:
     * Function, to add months to a date.
     */
    public static ExpressionOperator sybaseAddMonthsOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(AddMonths);
        List<String> v = new ArrayList<>(3);
        v.add("DATEADD(month, ");
        v.add(", ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        int[] indices = { 1, 0 };
        exOperator.setArgumentIndices(indices);
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;

    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator sybaseAtan2Operator() {
        return ExpressionOperator.simpleTwoArgumentFunction(Atan2, "ATN2");
    }

    /**
     * INTERNAL:
     * Build instring operator
     */
    public static ExpressionOperator sybaseInStringOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Instring);
        List<String> v = new ArrayList<>(3);
        v.add("CHARINDEX(");
        v.add(", ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        int[] indices = { 1, 0 };
        exOperator.setArgumentIndices(indices);
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;

    }

    /**
     * INTERNAL:
     * Build Sybase equivalent to TO_NUMBER.
     */
    public static ExpressionOperator sybaseToNumberOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(ToNumber);
        List<String> v = new ArrayList<>(2);
        v.add("CONVERT(NUMERIC, ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build Sybase equivalent to TO_CHAR.
     */
    public static ExpressionOperator sybaseToDateToStringOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(DateToString);
        List<String> v = new ArrayList<>(2);
        v.add("CONVERT(CHAR, ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build Sybase equivalent to TO_DATE.
     */
    public static ExpressionOperator sybaseToDateOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(ToDate);
        List<String> v = new ArrayList<>(2);
        v.add("CONVERT(DATETIME, ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build Sybase equivalent to TO_CHAR.
     */
    public static ExpressionOperator sybaseToCharOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(ToChar);
        List<String> v = new ArrayList<>(2);
        v.add("CONVERT(CHAR, ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build Sybase equivalent to TO_CHAR.
     */
    public static ExpressionOperator sybaseToCharWithFormatOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(ToCharWithFormat);
        List<String> v = new ArrayList<>(3);
        v.add("CONVERT(CHAR, ");
        v.add(",");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build the Sybase equivalent to Locate
     */
    public static ExpressionOperator sybaseLocateOperator() {
        ExpressionOperator result = simpleTwoArgumentFunction(ExpressionOperator.Locate, "CHARINDEX");
        int[] argumentIndices = new int[2];
        argumentIndices[0] = 1;
        argumentIndices[1] = 0;
        result.setArgumentIndices(argumentIndices);
        return result;
    }

    /**
     * INTERNAL:
     * Build the Sybase equivalent to Locate with a start index.
     * Sybase does not define this, so this gets a little complex...
     */
    public static ExpressionOperator sybaseLocate2Operator() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(ExpressionOperator.Locate2);
        result.setType(ExpressionOperator.FunctionOperator);
        List<String> v = new ArrayList<>();
        v.add("CASE (CHARINDEX(");
        v.add(", SUBSTRING(");
        v.add(",");
        v.add(", CHAR_LENGTH(");
        v.add(")))) WHEN 0 THEN 0 ELSE (CHARINDEX(");
        v.add(", SUBSTRING(");
        v.add(",");
        v.add(", CHAR_LENGTH(");
        v.add("))) + ");
        v.add(" - 1) END");
        result.printsAs(v);
        int[] indices = new int[9];
        indices[0] = 1;
        indices[1] = 0;
        indices[2] = 2;
        indices[3] = 0;
        indices[4] = 1;
        indices[5] = 0;
        indices[6] = 2;
        indices[7] = 0;
        indices[8] = 2;

        result.setArgumentIndices(indices);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        result.bePrefix();
        return result;
    }


    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator tan() {
        return simpleFunction(Tan, "TAN");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator tanh() {
        return simpleFunction(Tanh, "TANH");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator toDate() {
        return simpleFunction(ToDate, "TO_DATE");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator today() {
        return currentTimeStamp();
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator currentTimeStamp() {
        return simpleFunctionNoParentheses(Today,  "CURRENT_TIMESTAMP");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator currentDate() {
        return simpleFunctionNoParentheses(CurrentDate,  "CURRENT_DATE");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator currentTime() {
        return simpleFunctionNoParentheses(CurrentTime, "CURRENT_TIME");
    }

    /**
     * INTERNAL:
     * Create the toLowerCase operator.
     */
    public static ExpressionOperator toLowerCase() {
        return simpleFunction(ToLowerCase, "LOWER", "toLowerCase");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator toNumber() {
        return simpleFunction(ToNumber, "TO_NUMBER");
    }

    /**
     * Print a debug representation of this operator.
     */
    @Override
    public String toString() {
        if ((getDatabaseStrings() == null) || (getDatabaseStrings().length == 0)) {
            //CR#... Print a useful name for the missing platform operator.
            return "platform operator - " + getPlatformOperatorName(this.selector);
        } else {
            return "operator " + Arrays.asList(getDatabaseStrings());
        }
    }

    /**
     * INTERNAL:
     * Create the TOUPPERCASE operator.
     */
    public static ExpressionOperator toUpperCase() {
        return simpleFunction(ToUpperCase, "UPPER", "toUpperCase");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator translate() {
        ExpressionOperator operator = simpleThreeArgumentFunction(Translate, "TRANSLATE");
        operator.setIsBindingSupported(false);
        return operator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator trim() {
        return simpleFunction(Trim, "TRIM");
    }

    /**
     * INTERNAL:
     * Build Trim operator.
     */
    public static ExpressionOperator trim2() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Trim2);
        List<String> v = new ArrayList<>(5);
        v.add("TRIM(");
        v.add(" FROM ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        // Bug 573094
        int[] indices = { 1, 0 };
        exOperator.setArgumentIndices(indices);
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        exOperator.setIsBindingSupported(false);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator trunc() {
        return simpleTwoArgumentFunction(Trunc, "TRUNC");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator truncateDate() {
        return simpleTwoArgumentFunction(TruncateDate, "TRUNC");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator cast() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Cast);
        exOperator.setName("CAST");
        List<String> v = new ArrayList<>(5);
        v.add("CAST(");
        v.add(" AS ");
        v.add(")");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator extract() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Extract);
        exOperator.setName("EXTRACT");
        List<String> v = new ArrayList<>(5);
        v.add("EXTRACT(");
        v.add(" FROM ");
        v.add(")");
        exOperator.printsAs(v);
        int[] indices = new int[2];
        indices[0] = 1;
        indices[1] = 0;
        exOperator.setArgumentIndices(indices);
        exOperator.bePrefix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator value() {
        return simpleFunction(Value, "VALUE");
    }

    /**
     * INTERNAL:
     * Build operator.
     */
    public static ExpressionOperator variance() {
        return simpleAggregate(Variance, "VARIANCE", "variance");
    }

    /**
     * INTERNAL:
     * Create the ANY operator.
     */
    public static ExpressionOperator any() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Any);
        exOperator.printsAs("ANY");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the SOME operator.
     */
    public static ExpressionOperator some() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Some);
        exOperator.printsAs("SOME");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the ALL operator.
     */
    public static ExpressionOperator all() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(All);
        exOperator.printsAs("ALL");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the UNION operator.
     */
    public static ExpressionOperator union() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Union);
        exOperator.printsAs("UNION ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the UNION ALL operator.
     */
    public static ExpressionOperator unionAll() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(UnionAll);
        exOperator.printsAs("UNION ALL ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the INTERSECT operator.
     */
    public static ExpressionOperator intersect() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Intersect);
        exOperator.printsAs("INTERSECT ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the INTERSECT ALL operator.
     */
    public static ExpressionOperator intersectAll() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(IntersectAll);
        exOperator.printsAs("INTERSECT ALL ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the EXCEPT operator.
     */
    public static ExpressionOperator except() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(Except);
        exOperator.printsAs("EXCEPT ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Create the EXCEPT ALL operator.
     */
    public static ExpressionOperator exceptAll() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(FunctionOperator);
        exOperator.setSelector(ExceptAll);
        exOperator.printsAs("EXCEPT ALL ");
        exOperator.bePostfix();
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    /**
     * INTERNAL:
     * Indicates whether operator has selector Any or Some
     */
    public boolean isAny() {
        return  selector == ExpressionOperator.Any ||
                selector == ExpressionOperator.Some;
    }
    /**
     * INTERNAL:
     * Indicates whether operator has selector All
     */
    public boolean isAll() {
        return  selector == ExpressionOperator.All;
    }
    /**
     * INTERNAL:
     * Indicates whether operator has selector Any, Some or All
     */
    public boolean isAnyOrAll() {
        return  isAny() || isAll();
    }
}
