From 24826597fc11b8a72ea47ae8a9df92090987bc04 Mon Sep 17 00:00:00 2001 From: mnsrulz Date: Fri, 19 Nov 2021 23:40:04 -0500 Subject: [PATCH 1/2] allow select without table to support cross apply --- QueryBuilder.Tests/SelectTests.cs | 35 ++++++++++++++++++++++++++ QueryBuilder/Compilers/Compiler.cs | 10 ++++---- QueryBuilder/Query.Join.cs | 40 ++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 8341bf1f..29f77b31 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -803,5 +803,40 @@ public void EscapeClauseThrowsForMultipleCharacters() .HavingContains("Column1", @"TestString\%", false, @"\aa"); }); } + + + [Fact] + public void BasicSelectRaw_WithNoTable() + { + var q = new Query().SelectRaw("somefunction() as c1"); + + var c = Compilers.CompileFor(EngineCodes.SqlServer, q); + Assert.Equal("SELECT somefunction() as c1", c.ToString()); + } + + [Fact] + public void BasicSelect_WithNoTable() + { + var q = new Query().Select("c1"); + var c = Compilers.CompileFor(EngineCodes.SqlServer, q); + Assert.Equal("SELECT [c1]", c.ToString()); + } + + [Fact] + public void CrossApply_Column_Reusability() + { + var q = new Query("users").Select("name", "salary", "taxbracket", "taxamount", "grosspay") + .CrossApply(new Query().SelectRaw("case when salary < 5000 then 10 when salary < 10000 then 20 else 30 end as taxbracket").As("t1"), j => j) + .CrossApply(new Query().SelectRaw("salary * taxbracket as taxamount").As("t2"), j => j) + .CrossApply(new Query().SelectRaw("salary - taxamount as grosspay").As("t3"), j => j); + var c = Compilers.CompileFor(EngineCodes.SqlServer, q); + + Assert.Equal(string.Join("\n", new[] { + "SELECT [name], [salary], [taxbracket], [taxamount], [grosspay] FROM [users] ", + "CROSS APPLY (SELECT case when salary < 5000 then 10 when salary < 10000 then 20 else 30 end as taxbracket) AS [t1]", + "CROSS APPLY (SELECT salary * taxbracket as taxamount) AS [t2]", + "CROSS APPLY (SELECT salary - taxamount as grosspay) AS [t3]", + }), c.ToString()); + } } } diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs index a71b0743..df1fe405 100644 --- a/QueryBuilder/Compilers/Compiler.cs +++ b/QueryBuilder/Compilers/Compiler.cs @@ -647,14 +647,14 @@ public virtual string CompileTableExpression(SqlResult ctx, AbstractFrom from) public virtual string CompileFrom(SqlResult ctx) { - if (!ctx.Query.HasComponent("from", EngineCode)) + if (ctx.Query.HasComponent("from", EngineCode)) { - throw new InvalidOperationException("No table is set"); - } + var from = ctx.Query.GetOneComponent("from", EngineCode); - var from = ctx.Query.GetOneComponent("from", EngineCode); + return "FROM " + CompileTableExpression(ctx, from); + } - return "FROM " + CompileTableExpression(ctx, from); + return string.Empty; } public virtual string CompileJoins(SqlResult ctx) diff --git a/QueryBuilder/Query.Join.cs b/QueryBuilder/Query.Join.cs index 3fe3bbb1..d80b5df9 100644 --- a/QueryBuilder/Query.Join.cs +++ b/QueryBuilder/Query.Join.cs @@ -71,5 +71,45 @@ public Query CrossJoin(string table) return Join(j => j.JoinWith(table).AsCross()); } + public Query CrossApply(string table, string first, string second, string op = "=") + { + return Join(table, first, second, op, "cross apply"); + } + + public Query CrossApply(string table, Func callback) + { + return Join(table, callback, "cross apply"); + } + + public Query CrossApply(Query query, Func onCallback) + { + return Join(query, onCallback, "cross apply"); + } + + public Query CrossApply(Query query) + { + return Join(query, j => j, "cross apply"); + } + + public Query OuterApply(string table, string first, string second, string op = "=") + { + return Join(table, first, second, op, "outer apply"); + } + + public Query OuterApply(string table, Func callback) + { + return Join(table, callback, "outer apply"); + } + + public Query OuterApply(Query query, Func onCallback) + { + return Join(query, onCallback, "outer apply"); + } + + public Query OuterApply(Query query) + { + return Join(query, j => j, "outer apply"); + } + } } From 666e112b8c4880df8e9b44d2821525666b96e97a Mon Sep 17 00:00:00 2001 From: mnsrulz Date: Sat, 26 Feb 2022 15:43:13 +0000 Subject: [PATCH 2/2] removed cross apply unit test --- QueryBuilder.Tests/SelectTests.cs | 18 +------------- QueryBuilder/Query.Join.cs | 40 ------------------------------- 2 files changed, 1 insertion(+), 57 deletions(-) diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index d9f61f71..a08c20c2 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -832,22 +832,6 @@ public void BasicSelect_WithNoTable() var c = Compilers.CompileFor(EngineCodes.SqlServer, q); Assert.Equal("SELECT [c1]", c.ToString()); } - - [Fact] - public void CrossApply_Column_Reusability() - { - var q = new Query("users").Select("name", "salary", "taxbracket", "taxamount", "grosspay") - .CrossApply(new Query().SelectRaw("case when salary < 5000 then 10 when salary < 10000 then 20 else 30 end as taxbracket").As("t1"), j => j) - .CrossApply(new Query().SelectRaw("salary * taxbracket as taxamount").As("t2"), j => j) - .CrossApply(new Query().SelectRaw("salary - taxamount as grosspay").As("t3"), j => j); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); - - Assert.Equal(string.Join("\n", new[] { - "SELECT [name], [salary], [taxbracket], [taxamount], [grosspay] FROM [users] ", - "CROSS APPLY (SELECT case when salary < 5000 then 10 when salary < 10000 then 20 else 30 end as taxbracket) AS [t1]", - "CROSS APPLY (SELECT salary * taxbracket as taxamount) AS [t2]", - "CROSS APPLY (SELECT salary - taxamount as grosspay) AS [t3]", - }), c.ToString()); - } + } } diff --git a/QueryBuilder/Query.Join.cs b/QueryBuilder/Query.Join.cs index d80b5df9..3fe3bbb1 100644 --- a/QueryBuilder/Query.Join.cs +++ b/QueryBuilder/Query.Join.cs @@ -71,45 +71,5 @@ public Query CrossJoin(string table) return Join(j => j.JoinWith(table).AsCross()); } - public Query CrossApply(string table, string first, string second, string op = "=") - { - return Join(table, first, second, op, "cross apply"); - } - - public Query CrossApply(string table, Func callback) - { - return Join(table, callback, "cross apply"); - } - - public Query CrossApply(Query query, Func onCallback) - { - return Join(query, onCallback, "cross apply"); - } - - public Query CrossApply(Query query) - { - return Join(query, j => j, "cross apply"); - } - - public Query OuterApply(string table, string first, string second, string op = "=") - { - return Join(table, first, second, op, "outer apply"); - } - - public Query OuterApply(string table, Func callback) - { - return Join(table, callback, "outer apply"); - } - - public Query OuterApply(Query query, Func onCallback) - { - return Join(query, onCallback, "outer apply"); - } - - public Query OuterApply(Query query) - { - return Join(query, j => j, "outer apply"); - } - } }