for (;;)
{
if (p.parseString("="))
{
processAdditiveExpression();
Node expr = new Node(Node.OPERATOR, "==");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseString("<>"))
{
processAdditiveExpression();
Node expr = new Node(Node.OPERATOR, "!=");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseStringIgnoreCase("NOT "))
{
if (p.parseStringIgnoreCase("BETWEEN "))
{
// {expression} NOT BETWEEN {lower} AND {upper}
Node inputNode = stack.pop();
processAdditiveExpression();
Node lowerNode = stack.pop();
if (p.parseStringIgnoreCase("AND "))
{
processAdditiveExpression();
Node upperNode = stack.pop();
Node leftNode = new Node(Node.OPERATOR, "<");
leftNode.appendChildNode(inputNode);
leftNode.appendChildNode(lowerNode);
Node rightNode = new Node(Node.OPERATOR, ">");
rightNode.appendChildNode(inputNode);
rightNode.appendChildNode(upperNode);
Node betweenNode = new Node(Node.OPERATOR, "||");
betweenNode.appendChildNode(leftNode);
betweenNode.appendChildNode(rightNode);
stack.push(betweenNode);
}
else
{
throw new NucleusUserException("Query has BETWEEN keyword with no AND clause");
}
}
else if (p.parseStringIgnoreCase("LIKE "))
{
processLikeExpression();
Node notNode = new Node(Node.OPERATOR, "!");
notNode.insertChildNode(stack.pop());
stack.push(notNode);
}
else if (p.parseStringIgnoreCase("IN"))
{
// {expression} NOT IN (expr1 [,expr2[,expr3]])
processInExpression(true);
}
else if (p.parseStringIgnoreCase("MEMBER "))
{
processMemberExpression(true);
}
else
{
throw new NucleusException("Unsupported query syntax NOT followed by unsupported keyword");
}
}
else if (p.parseStringIgnoreCase("BETWEEN "))
{
// {expression} BETWEEN {lower} AND {upper}
Node inputNode = stack.pop();
processAdditiveExpression();
Node lowerNode = stack.pop();
if (p.parseStringIgnoreCase("AND "))
{
processAdditiveExpression();
Node upperNode = stack.pop();
Node leftNode = new Node(Node.OPERATOR, ">=");
leftNode.appendChildNode(inputNode);
leftNode.appendChildNode(lowerNode);
Node rightNode = new Node(Node.OPERATOR, "<=");
rightNode.appendChildNode(inputNode);
rightNode.appendChildNode(upperNode);
Node betweenNode = new Node(Node.OPERATOR, "&&");
betweenNode.appendChildNode(rightNode);
betweenNode.appendChildNode(leftNode);
stack.push(betweenNode);
}
else
{
throw new NucleusUserException("Query has BETWEEN keyword with no AND clause");
}
}
else if (p.parseStringIgnoreCase("LIKE "))
{
// {expression} LIKE {pattern_value} [ESCAPE {escape_char}]
processLikeExpression();
}
else if (p.parseStringIgnoreCase("IN"))
{
// {expression} IN (expr1 [,expr2[,expr3]])
processInExpression(false);
}
else if (p.parseStringIgnoreCase("MEMBER "))
{
processMemberExpression(false);
}
else if (p.parseStringIgnoreCase("IS "))
{
// {expression} IS [NOT] [NULL | EMPTY]
Node inputNode = stack.pop();
boolean not = false;
if (p.parseStringIgnoreCase("NOT "))
{
not = true;
}
if (p.parseStringIgnoreCase("NULL"))
{
Node isNode = new Node(Node.OPERATOR, (not ? "!=" : "=="));
Node compareNode = new Node(Node.LITERAL, null);
isNode.insertChildNode(compareNode);
isNode.insertChildNode(inputNode);
stack.push(isNode);
}
else if (p.parseStringIgnoreCase("EMPTY"))
{
// Convert IS EMPTY to a method call of isEmpty() on collection/map
Node isNode = new Node(Node.INVOKE, "isEmpty");
inputNode.insertChildNode(isNode);
if (not)
{
Node notExpr = new Node(Node.OPERATOR, "!");
notExpr.insertChildNode(inputNode);
stack.push(notExpr);
}
else
{
stack.push(inputNode);
}
}
else
{
throw new NucleusException("Encountered IS " + (not ? "NOT " : " ") +
" that should be followed by NULL | EMPTY but isnt");
}
}
else if (p.parseString("<="))
{
processAdditiveExpression();
Node expr = new Node(Node.OPERATOR, "<=");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseString(">="))
{
processAdditiveExpression();
Node expr = new Node(Node.OPERATOR, ">=");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseChar('<'))
{
processAdditiveExpression();
Node expr = new Node(Node.OPERATOR, "<");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseChar('>'))
{
processAdditiveExpression();
Node expr = new Node(Node.OPERATOR, ">");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else
{
break;