/// <devdoc>
/// parse the argument to an Aggregate function.
/// the syntax is
/// Func(child[(relation_name)].column_name)
/// When the function is called we have already parsed the Aggregate name, and open paren
/// </devdoc>
private ExpressionNode ParseAggregateArgument(FunctionId aggregate)
{
Debug.Assert(token == Tokens.LeftParen, "ParseAggregateArgument(): Invalid argument, token <> '('");
bool child;
string relname;
string colname;
Scan();
try {
if (token != Tokens.Child)
{
if (token != Tokens.Name)
{
throw ExprException.AggregateArgument();
}
colname = NameNode.ParseName(text, start, pos);
ScanToken(Tokens.RightParen);
return(new AggregateNode(_table, aggregate, colname));
}
child = (token == Tokens.Child);
prevOperand = Scalar;
// expecting an '(' or '.'
Scan();
if (token == Tokens.LeftParen)
{
//read the relation name
ScanToken(Tokens.Name);
relname = NameNode.ParseName(text, start, pos);
ScanToken(Tokens.RightParen);
ScanToken(Tokens.Dot);
}
else
{
relname = null;
CheckToken(Tokens.Dot);
}
ScanToken(Tokens.Name);
colname = NameNode.ParseName(text, start, pos);
ScanToken(Tokens.RightParen);
}
catch (Exception e) {
//
if (!Common.ADP.IsCatchableExceptionType(e))
{
throw;
}
throw ExprException.AggregateArgument();
}
return(new AggregateNode(_table, aggregate, colname, !child, relname));
}