if (m_left.isConstant() && !m_right.isConstant())
{
if (isSymmetric())
{
Operator left = m_left;
m_left = m_right;
m_right = left;
}
else
{
ComparisonOperator op = createSymmetric();
op.setParent(m_parent);
op.setLeft(m_right);
op.setRight(m_left);
return op.normalize(nFlags | NORMALIZE_NORECUR);
}
}
Type leftType = m_left.getType();
Type rightType = m_right.getType();
if (leftType == null)
{
assert m_left.isConstant();
assert m_right.isConstant();
setConstantValue(Boolean.valueOf(nullPredicate(m_right.getValue() == null)));
return this;
}
if (rightType == null)
{
rightType = leftType;
m_right.setType(rightType);
}
if (!isEquivalence())
{
if (rightType == null || m_right.isConstant() && m_right.getValue() == null)
{
Operator op = createNullComparison();
op.setParent(m_parent);
if (op.getOrdinal() != ConstantOperator.ORDINAL)
{
ComparisonOperator cmpOp = (ComparisonOperator)op;
cmpOp.setLeft(m_left);
cmpOp.setRight(m_right);
}
return op.normalize(nFlags | NORMALIZE_NORECUR);
}
}
setSource(findCommonSource(m_left, m_right), nFlags);
if (leftType.isPrimitive())
{
if (rightType != null)
{
if (!rightType.isPrimitive())
{
throw new TypeMismatchException(getSymbol());
}
}
if (leftType == Primitive.ANY && m_left.isConstant() && m_right.isConstant())
{
foldObjectComparison();
return this;
}
ConversionMapper mapper = null;
BinaryDescriptor descriptor = null;
if (m_source != null)
{
mapper = m_source.getAdapter().getConversionMapper();
descriptor = mapper.getBinaryDescriptor(this);
}
if (descriptor == null)
{
m_source = null;
mapper = getConversionMapper();
descriptor = mapper.getBinaryDescriptor(this);
if (descriptor == null)
{
throw new TypeMismatchException(getSymbol());
}
}
Primitive rightPrimitive = (Primitive)rightType;
if (mapper.getType(rightPrimitive) != mapper.getType(descriptor.getRightType()))
{
setRight(new TypeConversionOperator(descriptor.getRightType(), m_right));
m_right = m_right.normalize(nFlags | NORMALIZE_NORECUR);
}
Primitive leftPrimitive = (Primitive)leftType;
if (mapper.getType(leftPrimitive) != mapper.getType(descriptor.getLeftType()))
{
if (m_right.isConstant() && Primitive.isOrderPreserved(leftPrimitive, descriptor.getLeftType()))
{
if (m_right.getValue() != null)
{
m_bConstant = false;
if (unconvertConstantComparison(leftPrimitive, rightPrimitive, m_right.getValue()))
{
if (m_bConstant)
{
return this;
}
}
else
{
setLeft(new TypeConversionOperator(descriptor.getLeftType(), m_left));
m_left = m_left.normalize(nFlags | NORMALIZE_NORECUR);
}
}
}
else
{
setLeft(new TypeConversionOperator(descriptor.getLeftType(), m_left));
m_left = m_left.normalize(nFlags | NORMALIZE_NORECUR);
}
}
if (m_left.isConstant())
{
assert m_right.isConstant();
setConstantValue(evaluate());
}
else if (m_right.isConstant())
{
if (m_left.getOrdinal() == AttributeOperator.ORDINAL)
{
AttributeOperator left = (AttributeOperator)m_left;
Converter converter = left.getConverter();
if (converter != null && (isEquivalence() ||
Primitive.isOrderPreserved(converter.getSourceType(), converter.getDestinationType())))
{
left.setType(converter.getSourceType());
left.setNoConversion(true);
m_right.setValue(converter.getInverseFunction().invoke(m_right.getValue()));
m_right.setType(converter.getSourceType());
}
}
else if (m_left.getType() == Primitive.BOOLEAN && m_right.getValue() != null)
{
switch (booleanPredicate(((Boolean)m_right.getValue()).booleanValue()))
{
case BOOL_LHS:
return m_left;
case BOOL_NOT:
NotOperator op = new NotOperator();
op.setOperand(m_left);
op.normalize(nFlags | NORMALIZE_NORECUR);
return op;
case BOOL_TRUE:
setConstantValue(Boolean.TRUE);
break;
case BOOL_FALSE:
setConstantValue(Boolean.FALSE);
break;
}
}
}
}
else
{
assert m_left.getOrdinal() == AttributeOperator.ORDINAL;
if (rightType != null)
{
if (rightType.isPrimitive() &&
(rightType != Primitive.ANY || !m_right.isConstant() ||
m_right.getValue() != null && !(m_right.getValue() instanceof OIDHolder)))
{
throw new TypeMismatchException(getSymbol());
}
}
if (m_left.isConstant())
{
foldObjectComparison();
return this;
}
if ((nFlags & NORMALIZE_PERSISTENCE) != 0 && m_source != null)
{
PersistenceAdapter adapter = m_source.getAdapter();
Field[] leftFieldArray = adapter.getFields(m_left.getSource());
if (leftFieldArray != null)
{
Field[] rightFieldArray = null;
Object[] valueArray = null;
if (m_right.isConstant())
{
if (m_right.getValue() != null)
{
OID oid = ((OIDHolder)m_right.getValue()).getOID();
if (oid != null)
{
valueArray = adapter.getValues(oid, m_left.getSource());
if (leftFieldArray.length != valueArray.length)
{
throw new TypeMismatchException(getSymbol());
}
}
else if (isEquivalence())
{
setConstantValue(Boolean.valueOf(nullPredicate(false)));
return this;
}
}
}
else
{
assert m_right.getOrdinal() == AttributeOperator.ORDINAL;
rightFieldArray = adapter.getFields((Query)m_right.getSource());
assert rightFieldArray != null;
if (leftFieldArray.length != rightFieldArray.length)
{
throw new TypeMismatchException(getSymbol());
}
}
assert leftFieldArray.length > 0;
Operator result = null;
if (leftFieldArray.length == 1)
{
Field field = leftFieldArray[0];
if (m_left.getQuery().getConstraint() != this)
{
m_left.setSource(field);
m_left.setType(field.getType());
if (rightFieldArray != null)
{
field = rightFieldArray[0];
m_right.setSource(field);
m_right.setType(field.getType());
}
else
{
ConstantOperator cons;
Object value = (valueArray == null) ? null : valueArray[0];
if (m_right.getOrdinal() == ConstantOperator.ORDINAL)
{
cons = (ConstantOperator)m_right;
cons.setType(Primitive.primitiveOf(value));
cons.setValue(value);
}
else
{
cons = new ConstantOperator(value);
setRight(cons);
}
}
result = this;
}
else
{
ComparisonOperator cmp = createSame();
cmp.setParent(m_parent);
cmp.setLeft(new AttributeOperator(field));
if (rightFieldArray != null)
{
cmp.setRight(new AttributeOperator(rightFieldArray[0]));
}
else
{
cmp.setRight(new ConstantOperator((valueArray == null) ? null : valueArray[0]));
}
result = cmp;
}
}
else if (isEquivalence())
{
MultiArgOperator combinator;
if (rightFieldArray == null && valueArray == null)
{
combinator = new AndOperator();
}
else
{
if (isCombinatorDisjunctive())
{
combinator = new OrOperator();
}
else
{
combinator = new AndOperator();
}
}
combinator.setParent(m_parent);
for (int i = 0; i < leftFieldArray.length; ++i)
{
ComparisonOperator cmp = createSame();
cmp.setLeft(new AttributeOperator(leftFieldArray[i]));
if (rightFieldArray != null)
{
cmp.setRight(new AttributeOperator(rightFieldArray[i]));
}
else
{
cmp.setRight(new ConstantOperator((valueArray == null) ? null : valueArray[i]));
}
combinator.addOperand(cmp);
}
result = combinator;
}
else
{
OrOperator or = new OrOperator();
or.setParent(m_parent);
int nCount = leftFieldArray.length - 1;
for (int i = 0; i <= nCount; ++i)
{
MultiArgOperator combinator;
if (i == 0)
{
combinator = or;
}
else
{
combinator = new AndOperator();
or.addOperand(combinator);
}
for (int k = 0; k <= i; ++k)
{
ComparisonOperator cmp;
if (k == i)
{
if (i == nCount)
{
cmp = createSame();
}
else
{
cmp = createStrict();
}
}
else
{
cmp = new EqualsOperator();
}
cmp.setLeft(new AttributeOperator(leftFieldArray[i]));
if (rightFieldArray != null)
{
cmp.setRight(new AttributeOperator(rightFieldArray[i]));
}
else
{
cmp.setRight(new ConstantOperator((valueArray == null) ? null : valueArray[i]));
}
combinator.addOperand(cmp);
}
}
result = or;
}
return result.normalize(nFlags & ~NORMALIZE_NORECUR);
}
}
}
return this;