public static ITable GroupConcat(QueryProcessor processor, bool distinct, ITable group, Expression[] args) { // The output string StringBuilder return_string = new StringBuilder(); // Find the distinct subset of group if (distinct) group = processor.DistinctSubset(group, args); // Push the group table onto the processor stack processor.PushTable(group); // Iterator over the group IRowCursor i = group.GetRowCursor(); bool first = true; while (i.MoveNext()) { RowId rowid = i.Current; processor.UpdateTableRow(rowid); foreach (Expression op in args) { ITable val = processor.Execute(op); SqlObject ob = QueryProcessor.Result(val)[0]; if (!ob.IsNull) { if (!first) { return_string.Append(", "); } return_string.Append(SqlValue.FromObject(ob.Value).ToString()); first = false; } } } // Pop the table and return the result processor.PopTable(); return QueryProcessor.ResultTable(new SqlObject(return_string.ToString())); }
private static ITable ProcessAggregate(QueryProcessor processor, bool distinct, ITable group, Expression[] args, IAggregateInspector aggregator) { // Qualify the return type of the parameter SqlType type = processor.GetExpressionType(group, args[0]); // If an empty group if (group.RowCount == 0) { // Null return type if group is empty, return QueryProcessor.ResultTable(SqlObject.MakeNull(type)); } // Find the distinct subset of group if (distinct) group = processor.DistinctSubset(group, args); // Push the group table onto the processor stack processor.PushTable(group); // Scan the group table, returning null on a null value IRowCursor i = group.GetRowCursor(); while (i.MoveNext()) { RowId rowid = i.Current; processor.UpdateTableRow(rowid); ITable val = processor.Execute(args[0]); SqlObject ob = QueryProcessor.Result(val)[0]; // If we hit a null value, we ignore it. SQL-92 apparently says we // should generate a warning for nulls that are eliminated by set // functions. if (!ob.IsNull) { aggregator.Accumulate(ob); } } // Pop the table and return the result processor.PopTable(); SqlObject result = aggregator.Result(); return QueryProcessor.ResultTable(result ?? SqlObject.MakeNull(type)); }