p.getIndex(), p.getInput());
}
// Find what we are joining to
String name = p.parseIdentifier();
Node joinedNode = new Node(NodeType.IDENTIFIER, name);
Node parentNode = joinedNode;
while (p.nextIsDot())
{
p.parseChar('.');
String subName = p.parseIdentifier();
Node subNode = new Node(NodeType.IDENTIFIER, subName);
parentNode.appendChildNode(subNode);
parentNode = subNode;
}
if (!p.parseChar(')'))
{
throw new QueryCompilerSyntaxException("Expected: ')' but got " + p.remaining(),
p.getIndex(), p.getInput());
}
p.parseStringIgnoreCase("AS"); // Optional
String alias = p.parseIdentifier();
// Create candidate class node with alias, and put at top of stack
Node classNode = new Node(NodeType.CLASS, candidateClassName);
Node classAliasNode = new Node(NodeType.NAME, candidateAlias);
classNode.insertChildNode(classAliasNode);
stack.push(classNode);
// Translate the "IN(...) alias" into the equivalent JOIN syntax nodes
Node joinNode = new Node(NodeType.OPERATOR, "JOIN_INNER");
joinNode.appendChildNode(joinedNode);
Node joinAliasNode = new Node(NodeType.NAME, alias);
joinNode.appendChildNode(joinAliasNode);
classNode.appendChildNode(joinNode);
// Include any joins for this expression
processFromJoinExpression();
nodes.add(classNode);
}
else
{
// "candidate [AS] alias"
// This will create a node of type "Node.CLASS" and child of type "Node.NAME" (alias)
// Any JOINs will be child nodes of type "Node.OPERATOR"
processExpression();
Node id = stack.pop();
StringBuilder className = new StringBuilder(id.getNodeValue().toString());
while (id.getChildNodes().size() > 0)
{
id = id.getFirstChild();
className.append(".").append(id.getNodeValue().toString());
}
String alias = p.parseIdentifier();
if (alias != null && alias.equalsIgnoreCase("AS"))
{
alias = p.parseIdentifier();
}
if (candidateClassName == null)
{
candidateClassName = className.toString();
candidateAlias = alias;
}
// Create candidate class node with alias, and put at top of stack
Node classNode = new Node(NodeType.CLASS, className.toString());
Node aliasNode = new Node(NodeType.NAME, alias);
classNode.insertChildNode(aliasNode);
stack.push(classNode);
// Include any joins for this expression
processFromJoinExpression();