@Override public FSM parseToFSM() { boolean first = true; FSM tmp = null; boolean isSimple = true; for (Expression e : this.disj) { if (first) { tmp = e.parseToFSM(); first = false; if (e.getType() != RegularExpressionParser.Literal) isSimple = false; } else if (e.getType() == RegularExpressionParser.Literal && isSimple) { IntDomain dom = tmp.initState.transitions.iterator().next().domain; int val = Integer.parseInt(((Literal) e).lit); tmp.initState.transitions.iterator().next().domain = dom.union(val); } else { tmp = tmp.union(e.parseToFSM()); isSimple = false; } } return tmp; }
private Rvalue compileImpl(IntermediateCompiler ic, Scope scope, CType leftType, CType rightType) throws SyntaxException { // Compile operands. Rvalue rhs = right.compileWithConversion(ic, scope, rightType); Lvalue lhs = left.compileAsLvalue(ic, scope, false); // Load LHS to register. Rvalue lhsVal = new Rvalue(new VirtualRegister()); ic.emit("load", lhsVal.getRegister(), "0", lhs.getRegister()); lhsVal = left.getType(scope).compileConversion(ic, scope, lhsVal, leftType); // Compile the binary operator. String binOp = operator.binaryOperator; Rvalue retVal; if (leftType.isPointer()) { // Scale integer operand if necessary. int leftIncrSize = left.getType(scope).decay().getIncrementSize(); if (leftIncrSize > 1) ic.emit("mul", rhs.getRegister(), "=" + leftIncrSize); ic.emit(operator.mnemonic, lhsVal.getRegister(), rhs.getRegister()); retVal = lhsVal; } else if (operator.type == BinaryExpression.Type.BITWISE) retVal = leftType.compileBinaryBitwiseOperator(ic, scope, lhsVal, rhs, binOp); else if (operator.type == BinaryExpression.Type.SHIFT) retVal = leftType.compileBinaryShiftOperator(ic, scope, lhsVal, rhs, binOp); else // if (operator.type == BinaryExpression.Type.ARITHMETIC) retVal = leftType.compileBinaryArithmeticOperator(ic, scope, lhsVal, rhs, binOp); // Convert to the original type of the left operand. retVal = leftType.compileConversion(ic, scope, retVal, left.getType(scope)); // Assign result back to lvalue. ic.emit("store", retVal.getRegister(), "0", lhs.getRegister()); return retVal; }
/** * Create an Evaluator for the given query sources and projection * * @param <T> * @param metadata query metadata * @param sources sources of the query * @param projection projection of the query * @return evaluator */ public <T> Evaluator<T> create( QueryMetadata metadata, List<? extends Expression<?>> sources, Expression<T> projection) { final CollQuerySerializer serializer = new CollQuerySerializer(templates); serializer.append("return "); if (projection instanceof FactoryExpression<?>) { serializer.append("("); serializer.append(ClassUtils.getName(projection.getType())); serializer.append(")("); serializer.handle(projection); serializer.append(")"); } else { serializer.handle(projection); } serializer.append(";"); Map<Object, String> constantToLabel = serializer.getConstantToLabel(); Map<String, Object> constants = getConstants(metadata, constantToLabel); Class<?>[] types = new Class<?>[sources.size()]; String[] names = new String[sources.size()]; for (int i = 0; i < sources.size(); i++) { types[i] = sources.get(i).getType(); names[i] = sources.get(i).toString(); } // normalize types for (int i = 0; i < types.length; i++) { if (Primitives.isWrapperType(types[i])) { types[i] = Primitives.unwrap(types[i]); } } return factory.createEvaluator( serializer.toString(), projection.getType(), names, types, constants); }
/** * Create an Evaluator for the given source and filter * * @param <T> * @param source source of the query * @param filter filter of the query * @return evaluator */ @SuppressWarnings("unchecked") public <T> Evaluator<List<T>> createEvaluator( QueryMetadata metadata, Expression<? extends T> source, Predicate filter) { String typeName = ClassUtils.getName(source.getType()); CollQuerySerializer ser = new CollQuerySerializer(templates); ser.append( "java.util.List<" + typeName + "> rv = new java.util.ArrayList<" + typeName + ">();\n"); ser.append("for (" + typeName + " " + source + " : " + source + "_) {\n"); ser.append(" try {\n"); ser.append(" if (").handle(filter).append(") {\n"); ser.append(" rv.add(" + source + ");\n"); ser.append(" }\n"); ser.append(" } catch (NullPointerException npe) { }\n"); ser.append("}\n"); ser.append("return rv;"); Map<Object, String> constantToLabel = ser.getConstantToLabel(); Map<String, Object> constants = getConstants(metadata, constantToLabel); Type sourceType = new ClassType(TypeCategory.SIMPLE, source.getType()); ClassType sourceListType = new ClassType(TypeCategory.SIMPLE, Iterable.class, sourceType); return factory.createEvaluator( ser.toString(), sourceListType, new String[] {source + "_"}, new Type[] {sourceListType}, new Class[] {Iterable.class}, constants); }
protected Query range( Path<?> leftHandSide, String field, @Nullable Expression<?> min, @Nullable Expression<?> max, boolean minInc, boolean maxInc, QueryMetadata metadata) { if (min != null && Number.class.isAssignableFrom(min.getType()) || max != null && Number.class.isAssignableFrom(max.getType())) { @SuppressWarnings("unchecked") // guarded by previous check Constant<? extends Number> minConstant = (Constant<? extends Number>) min; @SuppressWarnings("unchecked") // guarded by previous check Constant<? extends Number> maxConstant = (Constant<? extends Number>) max; Class<? extends Number> numType = minConstant != null ? minConstant.getType() : maxConstant.getType(); // this is not necessarily safe, but compile time checking // on the user side mandates these types to be interchangeable @SuppressWarnings("unchecked") Class<Number> unboundedNumType = (Class<Number>) numType; return numericRange( unboundedNumType, field, minConstant == null ? null : minConstant.getConstant(), maxConstant == null ? null : maxConstant.getConstant(), minInc, maxInc); } return stringRange(leftHandSide, field, min, max, minInc, maxInc, metadata); }
private void jitStringConcat(Expression left, Expression right) { invokeConstructor(StringBuilder.class); jitExpression(left, String.class); invokeVirtual(StringBuilder.class, "append", StringBuilder.class, left.getType()); jitExpression(right, String.class); invokeVirtual(StringBuilder.class, "append", StringBuilder.class, right.getType()); invokeVirtual(StringBuilder.class, "toString", String.class); }
public BinaryRelationalExp(int o, Expression l, Expression r) throws TypeClashException { operator = o; left = l; right = r; type = parser.operators.check(this.operator, this.left.getType(), this.right.getType()); if ((l.getType().getType() instanceof IntType) && (r.getType().getType() instanceof FloatType)) left = new CastedExp(new FloatType(), l); else if ((l.getType().getType() instanceof FloatType) && (r.getType().getType() instanceof IntType)) right = new CastedExp(new FloatType(), r); }
private void jitInstanceof(SingleCondition singleCondition) { Class<?> value = (Class<?>) ((FixedExpression) singleCondition.getRight()).getValue(); String internalClassName = internalName(value); Expression left = singleCondition.getLeft(); Class<?> leftType = isDeclarationExpression(left) ? convertFromPrimitiveType(left.getType()) : left.getType(); jitExpression(left, leftType); mv.visitTypeInsn(INSTANCEOF, internalClassName); }
private ConstantValue evaluateBinaryExpr( Expression lhs, Expression rhs, Type resultType, ArithmeticBinaryOperation operation) { // Evaluate subexpressions ConstantValue valueLhs = lhs.accept(this, null); ConstantValue valueRhs = rhs.accept(this, null); // Convert to type implied by usual arithmetic conversions final ArithmeticType commonType = TypeUtils.doUsualArithmeticConversions( (ArithmeticType) lhs.getType().get(), (ArithmeticType) rhs.getType().get()); final ConstantType commonConstantType = typeFactory.newConstantType(commonType); final ConstantType resultConstantType = typeFactory.newConstantType(resultType); valueLhs = valueLhs.castTo(commonConstantType); valueRhs = valueRhs.castTo(commonConstantType); // Perform the operation switch (operation) { case ADDITION: return valueLhs.add(valueRhs); case SUBTRACTION: return valueLhs.subtract(valueRhs); case MULTIPLICATION: return valueLhs.multiply(valueRhs); case DIVISION: return valueLhs.divide(valueRhs); case REMAINDER: return valueLhs.remainder(valueRhs); case BITWISE_AND: return valueLhs.bitwiseAnd(valueRhs); case BITWISE_OR: return valueLhs.bitwiseOr(valueRhs); case BITWISE_XOR: return valueLhs.bitwiseXor(valueRhs); case LESS: return valueLhs.less(valueRhs).castTo(resultConstantType); case LESS_OR_EQUAL: return valueLhs.lessOrEqual(valueRhs).castTo(resultConstantType); case GREATER: return valueLhs.greater(valueRhs).castTo(resultConstantType); case GREATER_OR_EQUAL: return valueLhs.greaterOrEqual(valueRhs).castTo(resultConstantType); case EQUAL: return valueLhs.equalTo(valueRhs).castTo(resultConstantType); case NOT_EQUAL: return valueLhs.notEqualTo(valueRhs).castTo(resultConstantType); default: throw new RuntimeException("unexpected arithmetic binary operation '" + operation + "'"); } }
/** * @param e condition * @param index Index object * @param isJoin whether a join or not */ void addIndexCondition(Expression e, Index index, boolean isJoin) { rangeIndex = index; isJoinIndex = isJoin; switch (e.getType()) { case OpTypes.NOT: indexCondition = e; break; case OpTypes.IS_NULL: indexEndCondition = e; break; case OpTypes.EQUAL: indexCondition = e; indexEndCondition = indexCondition; break; case OpTypes.GREATER: case OpTypes.GREATER_EQUAL: indexCondition = e; break; case OpTypes.SMALLER: case OpTypes.SMALLER_EQUAL: indexEndCondition = e; break; default: Error.runtimeError(ErrorCode.U_S0500, "Expression"); } }
public void translateDesynthesized(ClassGenerator classGen, MethodGenerator methodGen) { final Type tleft = _left.getType(); final InstructionList il = methodGen.getInstructionList(); if (tleft instanceof BooleanType) { _left.translate(classGen, methodGen); _right.translate(classGen, methodGen); _falseList.add( il.append( _op == Operators.EQ ? (BranchInstruction) new IF_ICMPNE(null) : (BranchInstruction) new IF_ICMPEQ(null))); } else if (tleft instanceof NumberType) { _left.translate(classGen, methodGen); _right.translate(classGen, methodGen); if (tleft instanceof RealType) { il.append(DCMPG); _falseList.add( il.append( _op == Operators.EQ ? (BranchInstruction) new IFNE(null) : (BranchInstruction) new IFEQ(null))); } else { _falseList.add( il.append( _op == Operators.EQ ? (BranchInstruction) new IF_ICMPNE(null) : (BranchInstruction) new IF_ICMPEQ(null))); } } else { translate(classGen, methodGen); desynthesize(classGen, methodGen); } }
void prepareCheckConstraint(Session session, Table table, boolean checkValues) { // to ensure no subselects etc. are in condition check.checkValidCheckConstraint(); if (table == null) { check.resolveTypes(session, null); } else { QuerySpecification s = Expression.getCheckSelect(session, table, check); Result r = s.getResult(session, 1); if (r.getNavigator().getSize() != 0) { String[] info = new String[] {table.getName().name, ""}; throw Error.error(ErrorCode.X_23504, ErrorCode.CONSTRAINT, info); } rangeVariable = s.rangeVariables[0]; // removes reference to the Index object in range variable rangeVariable.setForCheckConstraint(); } if (check.getType() == OpTypes.NOT && check.getLeftNode().getType() == OpTypes.IS_NULL && check.getLeftNode().getLeftNode().getType() == OpTypes.COLUMN) { notNullColumnIndex = check.getLeftNode().getLeftNode().getColumnIndex(); isNotNull = true; } }
/** @see jaskell.compiler.JaskellVisitor#visit(QualifiedVariable) */ public Object visit(QualifiedVariable a) { Module mod = null; Iterator it = a.getPath().iterator(); while (it.hasNext()) { String mname = (String) it.next(); if (mod != null) mod = (Module) mod.lookup(mname); else mod = (Module) Module.getToplevels().get(mname); } /* module found */ if (mod != null) { Expression def = mod.lookup(a.getName()); if (def == null) throw new CompilerException("Unknown variable " + a.getName()); Type t = def.getType(); if (t == null) t = (Type) def.visit(this); /* as it is the case for variable, we assume * that a defined symbol may be overloaded (only for primitive types) * so we return a type variable and defers choice of * symbol to a later stage */ a.setType(t); return t; } throw new CompilerException("Unable to find module needed for variable " + a.getName()); }
private Rvalue compileSimpleAssignment(IntermediateCompiler ic, Scope scope) throws SyntaxException { Rvalue rhs = right.compileWithConversion(ic, scope, left.getType(scope).decay()); Lvalue lhs = left.compileAsLvalue(ic, scope, false); ic.emit("store", rhs.getRegister(), "0", lhs.getRegister()); return rhs; }
/** * @param scalar * @return true if the scalar is defines as $GLOBALS call */ private static boolean checkGLOBALS(Scalar scalar) { final String stringValue = scalar.getStringValue(); if (scalar.getScalarType() != Scalar.TYPE_STRING || stringValue.length() < 3) { return false; } final char charAtZero = stringValue.charAt(0); final char charAtEnd = stringValue.charAt(stringValue.length() - 1); if (!detectString(charAtZero) || !detectString(charAtEnd)) { return false; } if (scalar.getParent().getType() == ASTNode.ARRAY_ACCESS) { ArrayAccess arrayAccess = (ArrayAccess) scalar.getParent(); final Expression variableName = arrayAccess.getName(); if (variableName.getType() == ASTNode.VARIABLE) { Variable var = (Variable) variableName; if (var.isDollared() && var.getName() instanceof Identifier) { final Identifier id = (Identifier) var.getName(); return id.getName().equals("_GLOBALS") // $NON-NLS-1$ || id.getName().equals("GLOBALS"); // $NON-NLS-1$ } } } return false; }
/** * Type check a call to a standard function. Insert CastExprs when needed. If as a result of the * insertion of a CastExpr a type check error is thrown, then catch it and re-throw it with a new * "this". */ public Type typeCheckStandard(SymbolTable stable) throws TypeCheckError { _fname.clearNamespace(); // HACK!!! final int n = _arguments.size(); final Vector argsType = typeCheckArgs(stable); final MethodType args = new MethodType(Type.Void, argsType); final MethodType ptype = lookupPrimop(stable, _fname.getLocalPart(), args); if (ptype != null) { for (int i = 0; i < n; i++) { final Type argType = (Type) ptype.argsType().elementAt(i); final Expression exp = (Expression) _arguments.elementAt(i); if (!argType.identicalTo(exp.getType())) { try { _arguments.setElementAt(new CastExpr(exp, argType), i); } catch (TypeCheckError e) { throw new TypeCheckError(this); // invalid conversion } } } _chosenMethodType = ptype; return _type = ptype.resultType(); } throw new TypeCheckError(this); }
/** Typing rules: see XSLT Reference by M. Kay page 345. */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { final Type tleft = _left.typeCheck(stable); final Type tright = _right.typeCheck(stable); if (tleft.isSimple() && tright.isSimple()) { if (tleft != tright) { if (tleft instanceof BooleanType) { _right = new CastExpr(_right, Type.Boolean); } else if (tright instanceof BooleanType) { _left = new CastExpr(_left, Type.Boolean); } else if (tleft instanceof NumberType || tright instanceof NumberType) { _left = new CastExpr(_left, Type.Real); _right = new CastExpr(_right, Type.Real); } else { // both compared as strings _left = new CastExpr(_left, Type.String); _right = new CastExpr(_right, Type.String); } } } else if (tleft instanceof ReferenceType) { _right = new CastExpr(_right, Type.Reference); } else if (tright instanceof ReferenceType) { _left = new CastExpr(_left, Type.Reference); } // the following 2 cases optimize @attr|.|.. = 'string' else if (tleft instanceof NodeType && tright == Type.String) { _left = new CastExpr(_left, Type.String); } else if (tleft == Type.String && tright instanceof NodeType) { _right = new CastExpr(_right, Type.String); } // optimize node/node else if (tleft instanceof NodeType && tright instanceof NodeType) { _left = new CastExpr(_left, Type.String); _right = new CastExpr(_right, Type.String); } else if (tleft instanceof NodeType && tright instanceof NodeSetType) { // compare(Node, NodeSet) will be invoked } else if (tleft instanceof NodeSetType && tright instanceof NodeType) { swapArguments(); // for compare(Node, NodeSet) } else { // At least one argument is of type node, node-set or result-tree // Promote an expression of type node to node-set if (tleft instanceof NodeType) { _left = new CastExpr(_left, Type.NodeSet); } if (tright instanceof NodeType) { _right = new CastExpr(_right, Type.NodeSet); } // If one arg is a node-set then make it the left one if (tleft.isSimple() || tleft instanceof ResultTreeType && tright instanceof NodeSetType) { swapArguments(); } // Promote integers to doubles to have fewer compares if (_right.getType() instanceof IntType) { _right = new CastExpr(_right, Type.Real); } } return _type = Type.Boolean; }
public Expression staticCheck(ModuleContext context, int flags) { caught = context.staticCheck(caught, 0); type = caught.getType(); for (int i = 0; i < catches.length; i++) { Catch cat = catches[i]; LocalVariable mark = context.latestLocalVariable(); if (cat.codeVarName != null) { cat.codeVar = context.defineLocalVariable(cat.codeVarName, XQType.QNAME, this); cat.codeVar.storageType(XQType.QNAME, context); } if (cat.descVarName != null) { cat.descVar = context.defineLocalVariable(cat.descVarName, XQType.STRING, this); cat.descVar.storageType(XQType.STRING, context); } if (cat.valueVarName != null) { cat.valueVar = context.defineLocalVariable(cat.valueVarName, XQType.ANY, this); cat.valueVar.storageType(XQType.ANY, context); } cat.handler = context.staticCheck(cat.handler, 0); context.popLocalVariables(mark); type = type.unionWith(cat.handler.getType(), true); } return this; }
/** * Sets the right-hand side of the expression. * * @param right the right-hand side of the expression * @throws NullPointerException the key expression was null * @throws IllegalArgumentException the key could not be evaluated as a number */ public void setRight(Expression right) { if ((right.getType() & ExpressionUtils.EXPRESSION_TYPE_NUMBER) == 0) { throw new IllegalArgumentException( "Numeric expression is required for lessthanorequals operation"); } super.setRight(right); }
/** Get condition type error */ public String getConditionTypeError() { String lineAndColumn = getLineNumber() + ":" + getColumnNumber() + ": "; String error = "Type Error: the condition expression type is " + condition.getType().toString() + " and must be int"; return lineAndColumn + error; }
@Override public boolean analyze( SalsaNode parent, Map<String, SymbolType> typeEnv, Map<String, SymbolType> knownTypes) { expression.analyze(this, typeEnv, knownTypes); if (!expression.getType().getCanonicalName().equalsIgnoreCase("boolean")) this.log(expression.getSalsaSource() + " needs to be a boolean type"); return super.analyze(parent, typeEnv, knownTypes); }
private Rvalue compileCompoundAssignment(IntermediateCompiler ic, Scope scope) throws SyntaxException { CType leftType, rightType; if (operator.type == BinaryExpression.Type.SHIFT) { leftType = left.getType(scope).decay().promote(); rightType = CType.INT; } else if (left.getType(scope).decay().isPointer()) { leftType = new PointerType(CType.CHAR); rightType = CType.PTRDIFF_T; } else { leftType = rightType = CType.getCommonType(left.getType(scope).decay(), right.getType(scope).decay()); } return compileImpl(ic, scope, leftType, rightType); }
/** * Given a method call, first checks that it's a static method call, and if it is, returns the * class node for the receiver. For example, with the following code: <code></code>Person.findAll * { ... }</code>, it would return the class node for <i>Person</i>. If it's not a static method * call, returns null. * * @param call a method call * @return null if it's not a static method call, or the class node for the receiver instead. */ public ClassNode extractStaticReceiver(MethodCall call) { if (call instanceof StaticMethodCallExpression) { return ((StaticMethodCallExpression) call).getOwnerType(); } else if (call instanceof MethodCallExpression) { Expression objectExpr = ((MethodCallExpression) call).getObjectExpression(); if (objectExpr instanceof ClassExpression && ClassHelper.CLASS_Type.equals(objectExpr.getType())) { GenericsType[] genericsTypes = objectExpr.getType().getGenericsTypes(); if (genericsTypes != null && genericsTypes.length == 1) { return genericsTypes[0].getType(); } } if (objectExpr instanceof ClassExpression) { return objectExpr.getType(); } } return null; }
@Override public Class<?> getType() { if (this.type == null) { Expression symbol = this.command.getProjectedSymbols().iterator().next(); this.type = symbol.getType(); } // may still be null if this.command wasn't resolved return this.type; }
private FunctionType getFunctionType(Scope scope) throws SyntaxException { CType funcType = functionPointer.getType(scope).decay().dereference(); if (!funcType.isFunction()) { throw new SyntaxException( "Expression does not evaluate to a function pointer.", getPosition()); } return (FunctionType) funcType; }
private Expression translate0(RexNode expr) { if (expr instanceof RexInputRef) { // TODO: multiple inputs, e.g. joins final Expression input = getInput(0); final int index = ((RexInputRef) expr).getIndex(); final List<RelDataTypeField> fields = program.getInputRowType().getFieldList(); final RelDataTypeField field = fields.get(index); if (fields.size() == 1) { return input; } else if (input.getType() == Object[].class) { return Expressions.convert_( Expressions.arrayIndex(input, Expressions.constant(field.getIndex())), Types.box(JavaRules.EnumUtil.javaClass(typeFactory, field.getType()))); } else { return Expressions.field(input, field.getName()); } } if (expr instanceof RexLocalRef) { return translate(program.getExprList().get(((RexLocalRef) expr).getIndex())); } if (expr instanceof RexLiteral) { return Expressions.constant( ((RexLiteral) expr).getValue(), typeFactory.getJavaClass(expr.getType())); } if (expr instanceof RexCall) { final RexCall call = (RexCall) expr; final SqlOperator operator = call.getOperator(); final ExpressionType expressionType = SQL_TO_LINQ_OPERATOR_MAP.get(operator); if (expressionType != null) { switch (operator.getSyntax()) { case Binary: return Expressions.makeBinary( expressionType, translate(call.getOperands()[0]), translate(call.getOperands()[1])); case Postfix: case Prefix: return Expressions.makeUnary(expressionType, translate(call.getOperands()[0])); default: throw new RuntimeException("unknown syntax " + operator.getSyntax()); } } Method method = SQL_OP_TO_JAVA_METHOD_MAP.get(operator); if (method != null) { List<Expression> exprs = translateList(Arrays.asList(call.operands)); return !Modifier.isStatic(method.getModifiers()) ? Expressions.call(exprs.get(0), method, exprs.subList(1, exprs.size())) : Expressions.call(method, exprs); } switch (expr.getKind()) { default: throw new RuntimeException("cannot translate expression " + expr); } } throw new RuntimeException("cannot translate expression " + expr); }
private void ensureNotNullArgs(Expression exp, Label nullArg) { if (exp instanceof FixedExpression) { if (((FixedExpression) exp).canBeNull()) { mv.visitJumpInsn(GOTO, nullArg); } } else if (exp instanceof EvaluatedExpression) { if (!exp.getType().isPrimitive()) { jitEvaluatedExpression((EvaluatedExpression) exp, true, Object.class); mv.visitJumpInsn(IFNULL, nullArg); } } else if (exp instanceof VariableExpression) { if (!exp.getType().isPrimitive()) { jitVariableExpression((VariableExpression) exp); mv.visitJumpInsn(IFNULL, nullArg); } } else if (exp instanceof AritmeticExpression) { ensureNotNullInAritmeticExpression((AritmeticExpression) exp, nullArg); } }
private void jitBinary(SingleCondition singleCondition) { Expression left = singleCondition.getLeft(); Expression right = singleCondition.getRight(); Class<?> commonType = singleCondition.getOperation().needsSameType() ? findCommonClass( left.getType(), !left.canBeNull(), right.getType(), !right.canBeNull()) : null; if (commonType == Object.class && singleCondition.getOperation().isComparison()) { commonType = Comparable.class; } if (commonType != null && commonType.isPrimitive()) { jitPrimitiveBinary(singleCondition, left, right, commonType); } else { jitObjectBinary(singleCondition, left, right, commonType); } }
/** * Returns the value in an expression of the form 'step = value'. A value may be either a literal * string or a variable whose type is string. Optimization if off if null is returned. */ public Expression getCompareValue() { // Returned cached value if called more than once if (_value != null) { return _value; } // Nothing to to do if _exp is null if (_exp == null) { return null; } // Ignore if not an equality expression if (_exp instanceof EqualityExpr) { EqualityExpr exp = (EqualityExpr) _exp; Expression left = exp.getLeft(); Expression right = exp.getRight(); // Return if left is literal string if (left instanceof LiteralExpr) { _value = left; return _value; } // Return if left is a variable reference of type string if (left instanceof VariableRefBase && left.getType() == Type.String) { _value = left; return _value; } // Return if right is literal string if (right instanceof LiteralExpr) { _value = right; return _value; } // Return if left is a variable reference whose type is string if (right instanceof VariableRefBase && right.getType() == Type.String) { _value = right; return _value; } } return null; }
Object[] getExpressionValues(Session session) { Object[] values; if (expression.getType() == OpTypes.ROW) { values = expression.getRowValue(session); } else if (expression.getType() == OpTypes.TABLE_SUBQUERY) { values = expression.subQuery.queryExpression.getSingleRowValues(session); if (values == null) { // todo - verify semantics return null; } } else { values = new Object[1]; values[0] = expression.getValue(session, variables[0].dataType); } return values; }