{
// IN ((literal|parameter) [, (literal|parameter)])
processPrimary();
if (stack.peek() == null)
{
throw new QueryCompilerSyntaxException("Expected literal|parameter but got " +
p.remaining(), p.getIndex(), p.getInput());
}
// Generate node for comparison with this value
numArgs++;
Node valueNode = stack.pop();
p.skipWS();
if (numArgs == 1 && !p.peekStringIgnoreCase(",") && valueNode.getNodeType() == NodeType.PARAMETER &&
parameterValues != null && parameterValues.containsKey(valueNode.getNodeValue()))
{
// Special case of "xxx IN :param" where param is multiple-valued
Object paramValue = parameterValues.get(valueNode.getNodeValue());
if (paramValue instanceof Collection)
{
// Node (PARAMETER, param)
// ---> Node (INVOKE, "contains")
// ---> Node(IDENTIFIER, inputNode)
Node containsNode = new Node(NodeType.INVOKE, "contains");
containsNode.addProperty(inputNode);
valueNode.appendChildNode(containsNode);
inNode = valueNode;
break;
}
}
Node compareNode = new Node(NodeType.OPERATOR, (not ? "!=" : "=="));
compareNode.appendChildNode(inputNode);
compareNode.appendChildNode(valueNode);
if (inNode == null)
{
inNode = compareNode;
}
else
{
Node newInNode = new Node(NodeType.OPERATOR, (not ? "&&" : "||"));
newInNode.appendChildNode(inNode);
newInNode.appendChildNode(compareNode);
inNode = newInNode;
}
} while (p.parseChar(','));
if (!p.parseChar(')'))
{
throw new QueryCompilerSyntaxException("Expected: ')' but got " + p.remaining(),
p.getIndex(), p.getInput());
}
stack.push(inNode);
}