Skip to content

Commit 60bcdda

Browse files
committed
enahance/fix AsCount support
initial fix for issues #185 and #186 add aggregate query builder tests
1 parent 886679d commit 60bcdda

3 files changed

Lines changed: 136 additions & 20 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Xunit;
5+
6+
namespace SqlKata.Tests
7+
{
8+
public partial class QueryBuilderTest
9+
{
10+
[Fact]
11+
public void Count()
12+
{
13+
var query = new Query("A").AsCount();
14+
15+
var c = Compile(query);
16+
17+
Assert.Equal("SELECT COUNT(*) AS [count] FROM [A]", c[0]);
18+
Assert.Equal("SELECT COUNT(*) AS `count` FROM `A`", c[1]);
19+
Assert.Equal("SELECT COUNT(*) AS \"count\" FROM \"A\"", c[2]);
20+
Assert.Equal("SELECT COUNT(*) AS \"COUNT\" FROM \"A\"", c[3]);
21+
}
22+
23+
[Fact]
24+
public void CountMultipleColumns()
25+
{
26+
var query = new Query("A").AsCount("ColumnA", "ColumnB");
27+
28+
var c = Compile(query);
29+
30+
Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT 1 FROM [A] WHERE [ColumnA] IS NOT NULL AND [ColumnB] IS NOT NULL) AS [countQuery]", c[0]);
31+
}
32+
33+
[Fact]
34+
public void DistinctCount()
35+
{
36+
var query = new Query("A").Distinct().AsCount();
37+
38+
var c = Compile(query);
39+
40+
Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT * FROM [A]) AS [countQuery]", c[0]);
41+
}
42+
43+
[Fact]
44+
public void DistinctCountMultipleColumns()
45+
{
46+
var query = new Query("A").Distinct().AsCount("ColumnA", "ColumnB");
47+
48+
var c = Compile(query);
49+
50+
Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT [ColumnA], [ColumnB] FROM [A]) AS [countQuery]", c[0]);
51+
}
52+
53+
[Fact]
54+
public void Average()
55+
{
56+
var query = new Query("A").AsAverage("TTL");
57+
58+
var c = Compile(query);
59+
60+
Assert.Equal("SELECT AVG([TTL]) AS [avg] FROM [A]", c[0]);
61+
}
62+
63+
[Fact]
64+
public void Sum()
65+
{
66+
var query = new Query("A").AsSum("PacketsDropped");
67+
68+
var c = Compile(query);
69+
70+
Assert.Equal("SELECT SUM([PacketsDropped]) AS [sum] FROM [A]", c[0]);
71+
}
72+
73+
[Fact]
74+
public void Max()
75+
{
76+
var query = new Query("A").AsMax("LatencyMs");
77+
78+
var c = Compile(query);
79+
80+
Assert.Equal("SELECT MAX([LatencyMs]) AS [max] FROM [A]", c[0]);
81+
}
82+
83+
[Fact]
84+
public void Min()
85+
{
86+
var query = new Query("A").AsMin("LatencyMs");
87+
88+
var c = Compile(query);
89+
90+
Assert.Equal("SELECT MIN([LatencyMs]) AS [min] FROM [A]", c[0]);
91+
}
92+
}
93+
}

QueryBuilder.Tests/QueryBuilderTest.cs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace SqlKata.Tests
1010
{
11-
public class QueryBuilderTest
11+
public partial class QueryBuilderTest
1212
{
1313
private readonly Compiler pgsql;
1414
private readonly MySqlCompiler mysql;
@@ -817,20 +817,6 @@ public void Return_Different_MethodInfo_WhenSame_Method_With_Different_GenericTy
817817
Assert.NotSame(call1, call2);
818818
}
819819

820-
821-
[Fact]
822-
public void Count()
823-
{
824-
var query = new Query("A").AsCount().Limit(1);
825-
826-
var c = Compile(query);
827-
828-
Assert.Equal("SELECT COUNT(*) AS [count] FROM [A]", c[0]);
829-
Assert.Equal("SELECT COUNT(*) AS `count` FROM `A`", c[1]);
830-
Assert.Equal("SELECT COUNT(*) AS \"count\" FROM \"A\"", c[2]);
831-
Assert.Equal("SELECT COUNT(*) AS \"COUNT\" FROM \"A\"", c[3]);
832-
}
833-
834820
[Fact]
835821
public void Should_Equal_AfterMultipleCompile()
836822
{

QueryBuilder/Compilers/Compiler.cs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,35 @@ protected SqlResult PrepareResult(SqlResult ctx)
5757
return ctx;
5858
}
5959

60+
private Query TransformAggregateQuery(Query query)
61+
{
62+
var clause = query.GetOneComponent<AggregateClause>("aggregate", EngineCode);
63+
if (clause.Columns.Count == 1 && !query.IsDistinct) return query;
64+
65+
if (query.IsDistinct)
66+
{
67+
query.ClearComponent("aggregate", EngineCode);
68+
query.Select(clause.Columns.ToArray());
69+
}
70+
else
71+
{
72+
foreach (var column in clause.Columns)
73+
{
74+
query.WhereNotNull(column);
75+
}
76+
}
77+
78+
var outerClause = new AggregateClause()
79+
{
80+
Columns = new List<string> {"*"},
81+
Type = clause.Type
82+
};
83+
84+
return new Query()
85+
.AddComponent("aggregate", outerClause)
86+
.From(query, $"{clause.Type}Query");
87+
}
88+
6089
protected virtual SqlResult CompileRaw(Query query)
6190
{
6291
SqlResult ctx;
@@ -80,6 +109,8 @@ protected virtual SqlResult CompileRaw(Query query)
80109
query.ClearComponent("limit")
81110
.ClearComponent("order")
82111
.ClearComponent("group");
112+
113+
query = TransformAggregateQuery(query);
83114
}
84115

85116
ctx = CompileSelectQuery(query);
@@ -395,7 +426,6 @@ protected virtual SqlResult OnBeforeSelect(SqlResult ctx)
395426

396427
protected virtual string CompileColumns(SqlResult ctx)
397428
{
398-
399429
if (ctx.Query.HasComponent("aggregate", EngineCode))
400430
{
401431
var aggregate = ctx.Query.GetOneComponent<AggregateClause>("aggregate", EngineCode);
@@ -404,14 +434,21 @@ protected virtual string CompileColumns(SqlResult ctx)
404434
.Select(x => CompileColumn(ctx, new Column { Name = x }))
405435
.ToList();
406436

407-
var sql = string.Join(", ", aggregateColumns);
437+
string sql = string.Empty;
408438

409-
if (ctx.Query.IsDistinct)
439+
if (aggregateColumns.Count == 1)
410440
{
411-
sql = "DISTINCT " + sql;
441+
sql = string.Join(", ", aggregateColumns);
442+
443+
if (ctx.Query.IsDistinct)
444+
{
445+
sql = "DISTINCT " + sql;
446+
}
447+
448+
return "SELECT " + aggregate.Type.ToUpper() + "(" + sql + $") {ColumnAsKeyword}" + WrapValue(aggregate.Type);
412449
}
413450

414-
return "SELECT " + aggregate.Type.ToUpper() + "(" + sql + $") {ColumnAsKeyword}" + WrapValue(aggregate.Type);
451+
return "SELECT 1";
415452
}
416453

417454
var columns = ctx.Query

0 commit comments

Comments
 (0)