Skip to content

Commit 2482659

Browse files
committed
allow select without table to support cross apply
1 parent 87b4947 commit 2482659

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
lines changed

QueryBuilder.Tests/SelectTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,5 +803,40 @@ public void EscapeClauseThrowsForMultipleCharacters()
803803
.HavingContains("Column1", @"TestString\%", false, @"\aa");
804804
});
805805
}
806+
807+
808+
[Fact]
809+
public void BasicSelectRaw_WithNoTable()
810+
{
811+
var q = new Query().SelectRaw("somefunction() as c1");
812+
813+
var c = Compilers.CompileFor(EngineCodes.SqlServer, q);
814+
Assert.Equal("SELECT somefunction() as c1", c.ToString());
815+
}
816+
817+
[Fact]
818+
public void BasicSelect_WithNoTable()
819+
{
820+
var q = new Query().Select("c1");
821+
var c = Compilers.CompileFor(EngineCodes.SqlServer, q);
822+
Assert.Equal("SELECT [c1]", c.ToString());
823+
}
824+
825+
[Fact]
826+
public void CrossApply_Column_Reusability()
827+
{
828+
var q = new Query("users").Select("name", "salary", "taxbracket", "taxamount", "grosspay")
829+
.CrossApply(new Query().SelectRaw("case when salary < 5000 then 10 when salary < 10000 then 20 else 30 end as taxbracket").As("t1"), j => j)
830+
.CrossApply(new Query().SelectRaw("salary * taxbracket as taxamount").As("t2"), j => j)
831+
.CrossApply(new Query().SelectRaw("salary - taxamount as grosspay").As("t3"), j => j);
832+
var c = Compilers.CompileFor(EngineCodes.SqlServer, q);
833+
834+
Assert.Equal(string.Join("\n", new[] {
835+
"SELECT [name], [salary], [taxbracket], [taxamount], [grosspay] FROM [users] ",
836+
"CROSS APPLY (SELECT case when salary < 5000 then 10 when salary < 10000 then 20 else 30 end as taxbracket) AS [t1]",
837+
"CROSS APPLY (SELECT salary * taxbracket as taxamount) AS [t2]",
838+
"CROSS APPLY (SELECT salary - taxamount as grosspay) AS [t3]",
839+
}), c.ToString());
840+
}
806841
}
807842
}

QueryBuilder/Compilers/Compiler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -647,14 +647,14 @@ public virtual string CompileTableExpression(SqlResult ctx, AbstractFrom from)
647647

648648
public virtual string CompileFrom(SqlResult ctx)
649649
{
650-
if (!ctx.Query.HasComponent("from", EngineCode))
650+
if (ctx.Query.HasComponent("from", EngineCode))
651651
{
652-
throw new InvalidOperationException("No table is set");
653-
}
652+
var from = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
654653

655-
var from = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
654+
return "FROM " + CompileTableExpression(ctx, from);
655+
}
656656

657-
return "FROM " + CompileTableExpression(ctx, from);
657+
return string.Empty;
658658
}
659659

660660
public virtual string CompileJoins(SqlResult ctx)

QueryBuilder/Query.Join.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,45 @@ public Query CrossJoin(string table)
7171
return Join(j => j.JoinWith(table).AsCross());
7272
}
7373

74+
public Query CrossApply(string table, string first, string second, string op = "=")
75+
{
76+
return Join(table, first, second, op, "cross apply");
77+
}
78+
79+
public Query CrossApply(string table, Func<Join, Join> callback)
80+
{
81+
return Join(table, callback, "cross apply");
82+
}
83+
84+
public Query CrossApply(Query query, Func<Join, Join> onCallback)
85+
{
86+
return Join(query, onCallback, "cross apply");
87+
}
88+
89+
public Query CrossApply(Query query)
90+
{
91+
return Join(query, j => j, "cross apply");
92+
}
93+
94+
public Query OuterApply(string table, string first, string second, string op = "=")
95+
{
96+
return Join(table, first, second, op, "outer apply");
97+
}
98+
99+
public Query OuterApply(string table, Func<Join, Join> callback)
100+
{
101+
return Join(table, callback, "outer apply");
102+
}
103+
104+
public Query OuterApply(Query query, Func<Join, Join> onCallback)
105+
{
106+
return Join(query, onCallback, "outer apply");
107+
}
108+
109+
public Query OuterApply(Query query)
110+
{
111+
return Join(query, j => j, "outer apply");
112+
}
113+
74114
}
75115
}

0 commit comments

Comments
 (0)