// Right operand is whatever subquery selects.
ValueNode rightOperand =
selectNode.getResultColumns().get(0).getExpression();
if (leftOperand instanceof ColumnReference && selectNode.getResultColumns().size() != 1) {
throw new UnsupportedSQLException("Subquery must have one column");
}
boolean additionalEQ = false;
switch (subqueryNode.getSubqueryType()) {
case IN:
case EQ_ANY:
additionalEQ = true;
break;
}
additionalEQ = additionalEQ && ((leftOperand instanceof ConstantNode) ||
(leftOperand instanceof ColumnReference) ||
(leftOperand instanceof ParameterNode));
if (!isUniqueSubquery(selectNode, additionalEQ ? rightOperand : null))
return result;
// Yes, we can flatten it.
currentSelectNode.getFromList().addAll(selectNode.getFromList());
currentSelectNode.setWhereClause(mergeWhereClause(currentSelectNode.getWhereClause(),
selectNode.getWhereClause()));
if (leftOperand == null) {
ValueNode node = (ValueNode)nodeFactory.getNode(NodeTypes.BOOLEAN_CONSTANT_NODE, Boolean.TRUE, parserContext);
node.setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID, false));
return node;
}
int nodeType = 0;
if (parentComparisonOperator != null)
nodeType = parentComparisonOperator.getNodeType();
else {
switch (subqueryNode.getSubqueryType()) {
// TODO: The ALL and NOT_IN cases aren't actually supported here yet.
case IN:
case EQ_ANY:
case NOT_IN:
case NE_ALL:
nodeType = NodeTypes.BINARY_EQUALS_OPERATOR_NODE;
break;
case NE_ANY:
case EQ_ALL:
nodeType = NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE;
break;
case LE_ANY:
case GT_ALL:
nodeType = NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE;
break;
case LT_ANY:
case GE_ALL:
nodeType = NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE;
break;
case GE_ANY:
case LT_ALL:
nodeType = NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE;
break;
case GT_ANY:
case LE_ALL:
nodeType = NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE;
break;
default:
assert false;
}
}
// when multiple columns in the leftOperand
if (leftOperand instanceof RowConstructorNode) {
RowConstructorNode rcn = (RowConstructorNode)leftOperand;
if (rcn.listSize() != selectNode.getResultColumns().size()) {
throw new UnsupportedSQLException("Subquery needs equal number of columns on left and right side of ... IN ... clause ");
}
ResultColumnList rcl = selectNode.getResultColumns();
ValueNode leftO = null, rightO = null;
// create branch of equivalent relations for the different columns, connected by AndNodes, and ending with a True Node
for (int i = rcn.listSize()-1; i >= 0; i--) {