Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement column-as keyword for 'select' with SelectAs(). #499

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement column-as keyword for 'select' with SelectAs().
dgeelen-uipath committed Jul 2, 2021
commit 417f86e29d93bf0500e0656dd2804011a0f555c8
54 changes: 54 additions & 0 deletions QueryBuilder.Tests/SelectTests.cs
Original file line number Diff line number Diff line change
@@ -35,6 +35,45 @@ public void BasicSelectEnumerable()
Assert.Equal("SELECT \"id\", \"name\" FROM \"users\"", c[EngineCodes.Oracle]);
}

[Fact]
public void SelectAsOneColumn()
{
var query = new Query().SelectAs("Row", "Alias").From("Table");

var c = Compile(query);
Assert.Equal("SELECT [Row] AS [Alias] FROM [Table]", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT `Row` AS `Alias` FROM `Table`", c[EngineCodes.MySql]);
Assert.Equal("SELECT \"Row\" AS \"Alias\" FROM \"Table\"", c[EngineCodes.PostgreSql]);
Assert.Equal("SELECT \"ROW\" AS \"ALIAS\" FROM \"TABLE\"", c[EngineCodes.Firebird]);
Assert.Equal("SELECT \"Row\" \"Alias\" FROM \"Table\"", c[EngineCodes.Oracle]);
}

[Fact]
public void SelectAsSingletonList()
{
var query = new Query().SelectAs(("Row", "Alias")).From("Table");

var c = Compile(query);
Assert.Equal("SELECT [Row] AS [Alias] FROM [Table]", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT `Row` AS `Alias` FROM `Table`", c[EngineCodes.MySql]);
Assert.Equal("SELECT \"Row\" AS \"Alias\" FROM \"Table\"", c[EngineCodes.PostgreSql]);
Assert.Equal("SELECT \"ROW\" AS \"ALIAS\" FROM \"TABLE\"", c[EngineCodes.Firebird]);
Assert.Equal("SELECT \"Row\" \"Alias\" FROM \"Table\"", c[EngineCodes.Oracle]);
}

[Fact]
public void SelectAsMultipleColumns()
{
var query = new Query().SelectAs(("Row1", "Alias1"), ("Row2", "Alias2")).From("Table");

var c = Compile(query);
Assert.Equal("SELECT [Row1] AS [Alias1], [Row2] AS [Alias2] FROM [Table]", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT `Row1` AS `Alias1`, `Row2` AS `Alias2` FROM `Table`", c[EngineCodes.MySql]);
Assert.Equal("SELECT \"Row1\" AS \"Alias1\", \"Row2\" AS \"Alias2\" FROM \"Table\"", c[EngineCodes.PostgreSql]);
Assert.Equal("SELECT \"ROW1\" AS \"ALIAS1\", \"ROW2\" AS \"ALIAS2\" FROM \"TABLE\"", c[EngineCodes.Firebird]);
Assert.Equal("SELECT \"Row1\" \"Alias1\", \"Row2\" \"Alias2\" FROM \"Table\"", c[EngineCodes.Oracle]);
}

[Fact]
public void BasicSelectWhereBindingIsEmptyOrNull()
{
@@ -74,6 +113,21 @@ public void ExpandedSelect()
Assert.Equal("SELECT `users`.`id`, `users`.`name`, `users`.`age` FROM `users`", c[EngineCodes.MySql]);
}

[Fact]
public void ExpandedSelectAs()
{
var q = new Query().From("users").SelectAs(("users.{id,name, age}", "Alias"));
var c = Compile(q);

// This result is weird (but valid syntax), and at least it works in
// a somewhat explainable way, as opposed to regular Select() when
// combining the expanded syntax and the 'as' SQLKata keyword support
// which simply silently stops working when the {...} expansion is
// applied.
Assert.Equal("SELECT [users].[id] AS [Alias], [users].[name] AS [Alias], [users].[age] AS [Alias] FROM [users]", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT `users`.`id` AS `Alias`, `users`.`name` AS `Alias`, `users`.`age` AS `Alias` FROM `users`", c[EngineCodes.MySql]);
}

[Fact]
public void ExpandedSelectWithSchema()
{
6 changes: 6 additions & 0 deletions QueryBuilder/Clauses/ColumnClause.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System.Diagnostics;

namespace SqlKata
{
public abstract class AbstractColumn : AbstractClause
{
public string Alias { get; set; }
}

/// <summary>
@@ -26,6 +29,7 @@ public override AbstractClause Clone()
Engine = Engine,
Name = Name,
Component = Component,
Alias = Alias,
};
}
}
@@ -50,6 +54,7 @@ public override AbstractClause Clone()
Engine = Engine,
Query = Query.Clone(),
Component = Component,
Alias = Alias,
};
}
}
@@ -68,6 +73,7 @@ public class RawColumn : AbstractColumn
/// <inheritdoc />
public override AbstractClause Clone()
{
Debug.Assert(string.IsNullOrEmpty(Alias), "Raw columns cannot have an alias");
return new RawColumn
{
Engine = Engine,
6 changes: 6 additions & 0 deletions QueryBuilder/Compilers/Compiler.cs
Original file line number Diff line number Diff line change
@@ -472,6 +472,12 @@ public virtual string CompileColumn(SqlResult ctx, AbstractColumn column)
return "(" + subCtx.RawSql + $"){alias}";
}

if (!string.IsNullOrWhiteSpace(column.Alias))
{
return $"{Wrap((column as Column).Name)} {ColumnAsKeyword}{Wrap(column.Alias)}";

}

return Wrap((column as Column).Name);

}
31 changes: 23 additions & 8 deletions QueryBuilder/Query.Select.cs
Original file line number Diff line number Diff line change
@@ -6,27 +6,42 @@ namespace SqlKata
{
public partial class Query
{
public Query Select(params string[] columns) =>
Select(columns.AsEnumerable());

public Query Select(params string[] columns)
{
return Select(columns.AsEnumerable());
}
public Query Select(IEnumerable<string> columns) =>
SelectAs(
columns
.Select(x => (x, null as string))
.ToArray()
);

/// <summary>
/// Select a column with an alias
/// </summary>
/// <returns></returns>
public Query SelectAs(string column, string alias) =>
SelectAs((column, alias));

public Query Select(IEnumerable<string> columns)
/// <summary>
/// Select columns with an alias
/// </summary>
/// <returns></returns>
public Query SelectAs(params (string, string)[] columns)
{
Method = "select";

columns = columns
.Select(x => Helper.ExpandExpression(x))
.Select(x => Helper.ExpandExpression(x.Item1).Select(y => (y, x.Item2)))
.SelectMany(x => x)
.ToArray();


foreach (var column in columns)
{
AddComponent("select", new Column
{
Name = column
Name = column.Item1,
Alias = column.Item2
});
}