protected virtual void ProcessLimitAndOffsetOperators(
StringBuilder sb,
List<TakeResultOperator> limit,
List<SkipResultOperator> offset,
List<FirstResultOperator> first,
List<SingleResultOperator> single)
{
if (first.Count == 1)
{
sb.AppendLine("LIMIT 1");
if (offset.Count == 1)
sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
}
else if (single.Count == 1)
{
if (limit.Count == 0)
sb.Append("LIMIT 2");
else
{
if (limit.TrueForAll(it => it.Count is ConstantExpression))
{
var min = limit.Min(it => (int)(it.Count as ConstantExpression).Value);
if (min > 1) min = 2;
sb.Append("LIMIT ").Append(min);
}
else
{
sb.Append("LIMIT LEAST(2,");
sb.Append(string.Join(", ", limit.Select(it => GetSqlExpression(it.Count))));
sb.AppendLine(")");
}
}
if (offset.Count == 1)
sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
}
else if (limit.Count > 0 && offset.Count == 0)
{
sb.Append("LIMIT ");
if (limit.Count > 1)
sb.Append("LEAST(")
.Append(
string.Join(
", ",
limit.Select(it => GetSqlExpression(it.Count))))
.AppendLine(")");
else sb.AppendLine(GetSqlExpression(limit[0].Count));
}
else if (limit.Count == 0 && offset.Count > 0)
{
sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
for (int i = 1; i < offset.Count; i++)
sb.Append(" + " + GetSqlExpression(offset[i].Count));
}
else if (limit.Count == 1 && offset.Count == 1)
{
if (ResultOperators.IndexOf(limit[0]) < ResultOperators.IndexOf(offset[0]))
sb.AppendLine("LIMIT ({0} - {1})".With(GetSqlExpression(limit[0].Count), GetSqlExpression(offset[0].Count)));
else
sb.AppendLine("LIMIT " + GetSqlExpression(limit[0].Count));
sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
}
else if (limit.Count > 1 || offset.Count > 1)
throw new NotSupportedException("Unsupported combination of limits and offsets in query. More than one offset and more than one limit found.");
}