private void StringifySqlAst(Node?parent, Node node, IReadOnlyCollection <string> prefix, IResolveFieldContext context, ICollection <string> selections, ICollection <string> tables, ICollection <WhereCondition> wheres, ICollection <string> orders, IEnumerable batchScope, SqlCompilerContext compilerContext) { switch (node) { case SqlTable sqlTable: HandleTable(parent, sqlTable, prefix, context, selections, tables, wheres, orders, batchScope, compilerContext); if (ThisIsNotTheEndOfThisBatch(parent, sqlTable)) { foreach (var child in sqlTable.Children) { StringifySqlAst(node, child, new List <string>(prefix) { sqlTable.As }, context, selections, tables, wheres, orders, batchScope, compilerContext); } } break; case SqlColumn sqlColumn: { if (!(parent is SqlTable table)) { throw new ArgumentException($"'{nameof(parent)}' must be of type {typeof(SqlTable)}", nameof(parent)); } var parentTable = table.As; string columnName; if (sqlColumn.Expression != null) { columnName = sqlColumn.Expression(_dialect.Quote(parentTable), sqlColumn.Arguments, context, table); } else if (table.ColumnExpression != null) { columnName = table.ColumnExpression(_dialect.Quote(parentTable), sqlColumn.Name, sqlColumn.Arguments, context); } else { columnName = $"{_dialect.Quote(parentTable)}.{_dialect.Quote(sqlColumn.Name)}"; } selections.Add($"{columnName} AS {_dialect.Quote(JoinPrefix(prefix) + sqlColumn.As)}"); break; } case SqlComposite sqlComposite: { if (!(parent is SqlTable table)) { throw new ArgumentException($"'{nameof(parent)}' must be of type {typeof(SqlTable)}", nameof(parent)); } var parentTable = table.As; selections.Add($"{_dialect.CompositeKey(parentTable, sqlComposite.Name)} AS {_dialect.Quote(JoinPrefix(prefix) + sqlComposite.As)}"); break; } case SqlJunction _: case SqlNoop _: break; default: throw new ArgumentOutOfRangeException(nameof(node), $"Don't know how to handle {node.GetType()}."); } }