From f836f5e2af93768416231339ced21820565c773c Mon Sep 17 00:00:00 2001 From: Sergey Strebulaev Date: Thu, 6 Apr 2023 13:42:04 +0300 Subject: [PATCH] Minimize ad-hoc queries by omitting repeating column name specifiers --- QueryBuilder.Tests/GeneralTests.cs | 12 ++++++------ QueryBuilder.Tests/ParameterTypeTests.cs | 4 ++-- QueryBuilder/Compilers/Compiler.cs | 25 ++++++++++++++---------- README.md | 2 +- sqlkata.sln | 2 +- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs index 63fb3d3f..7996a645 100644 --- a/QueryBuilder.Tests/GeneralTests.cs +++ b/QueryBuilder.Tests/GeneralTests.cs @@ -466,7 +466,7 @@ public void AdHoc_SingletonRow() Assert.Equal("WITH `rows` AS (SELECT 1 AS `a`)\nSELECT * FROM `rows`", c[EngineCodes.MySql].ToString()); Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\")\nSELECT * FROM \"rows\"", c[EngineCodes.Sqlite].ToString()); Assert.Equal("WITH \"ROWS\" AS (SELECT 1 AS \"A\" FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"", c[EngineCodes.Firebird].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\" FROM DUAL)\nSELECT * FROM \"rows\"", c[EngineCodes.Oracle].ToString()); + Assert.Equal("WITH \"rows\" AS (SELECT 1 \"a\" FROM DUAL)\nSELECT * FROM \"rows\"", c[EngineCodes.Oracle].ToString()); } [Fact] @@ -482,11 +482,11 @@ public void AdHoc_TwoRows() var c = Compilers.Compile(query); Assert.Equal("WITH [rows] AS (SELECT [a], [b], [c] FROM (VALUES (1, 2, 3), (4, 5, 6)) AS tbl ([a], [b], [c]))\nSELECT * FROM [rows]", c[EngineCodes.SqlServer].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\")\nSELECT * FROM \"rows\"", c[EngineCodes.PostgreSql].ToString()); - Assert.Equal("WITH `rows` AS (SELECT 1 AS `a`, 2 AS `b`, 3 AS `c` UNION ALL SELECT 4 AS `a`, 5 AS `b`, 6 AS `c`)\nSELECT * FROM `rows`", c[EngineCodes.MySql].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\")\nSELECT * FROM \"rows\"", c[EngineCodes.Sqlite].ToString()); - Assert.Equal("WITH \"ROWS\" AS (SELECT 1 AS \"A\", 2 AS \"B\", 3 AS \"C\" FROM RDB$DATABASE UNION ALL SELECT 4 AS \"A\", 5 AS \"B\", 6 AS \"C\" FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"", c[EngineCodes.Firebird].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" FROM DUAL UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\" FROM DUAL)\nSELECT * FROM \"rows\"", c[EngineCodes.Oracle].ToString()); + Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4, 5, 6)\nSELECT * FROM \"rows\"", c[EngineCodes.PostgreSql].ToString()); + Assert.Equal("WITH `rows` AS (SELECT 1 AS `a`, 2 AS `b`, 3 AS `c` UNION ALL SELECT 4, 5, 6)\nSELECT * FROM `rows`", c[EngineCodes.MySql].ToString()); + Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4, 5, 6)\nSELECT * FROM \"rows\"", c[EngineCodes.Sqlite].ToString()); + Assert.Equal("WITH \"ROWS\" AS (SELECT 1 AS \"A\", 2 AS \"B\", 3 AS \"C\" FROM RDB$DATABASE UNION ALL SELECT 4, 5, 6 FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"", c[EngineCodes.Firebird].ToString()); + Assert.Equal("WITH \"rows\" AS (SELECT 1 \"a\", 2 \"b\", 3 \"c\" FROM DUAL UNION ALL SELECT 4, 5, 6 FROM DUAL)\nSELECT * FROM \"rows\"", c[EngineCodes.Oracle].ToString()); } [Fact] diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs index 095a6e53..b1060992 100644 --- a/QueryBuilder.Tests/ParameterTypeTests.cs +++ b/QueryBuilder.Tests/ParameterTypeTests.cs @@ -22,9 +22,9 @@ public class ParameterTypeGenerator : IEnumerable private readonly List _data = new List { new object[] {"1", 1}, - new object[] {Convert.ToSingle("10.5", CultureInfo.InvariantCulture).ToString(), 10.5}, + new object[] {Convert.ToSingle("10.5", CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture), 10.5}, new object[] {"-2", -2}, - new object[] {Convert.ToSingle("-2.8", CultureInfo.InvariantCulture).ToString(), -2.8}, + new object[] {Convert.ToSingle("-2.8", CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture), -2.8}, new object[] {"cast(1 as bit)", true}, new object[] {"cast(0 as bit)", false}, new object[] {"'2018-10-28 19:22:00'", new DateTime(2018, 10, 28, 19, 22, 0)}, diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs index aa15c789..a91b4667 100644 --- a/QueryBuilder/Compilers/Compiler.cs +++ b/QueryBuilder/Compilers/Compiler.cs @@ -231,16 +231,22 @@ protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { var ctx = new SqlResult(); - var row = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"{parameterPlaceholder} AS {Wrap(col)}")); + var firstRow = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"{parameterPlaceholder} {ColumnAsKeyword}{Wrap(col)}")); + var row = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"{parameterPlaceholder}")); var fromTable = SingleRowDummyTableName; if (fromTable != null) { - row += $" FROM {fromTable}"; + var fromClause = $" FROM {fromTable}"; + firstRow += fromClause; + row += fromClause; } - var rows = string.Join(" UNION ALL ", Enumerable.Repeat(row, adHoc.Values.Count / adHoc.Columns.Count)); + var rowCount = adHoc.Values.Count / adHoc.Columns.Count; + var rows = rowCount > 0 + ? string.Join(" UNION ALL ", Enumerable.Repeat(row, rowCount - 1).Prepend(firstRow)) + : string.Empty; ctx.RawSql = rows; ctx.Bindings = adHoc.Values; @@ -555,7 +561,7 @@ public virtual string CompileColumn(SqlResult ctx, AbstractColumn column) return $"{agg}(CASE WHEN {filterCondition} THEN {col} END){alias}"; } - return Wrap((column as Column).Name); + return Wrap(((Column)column).Name); } @@ -618,11 +624,9 @@ protected virtual string CompileColumns(SqlResult ctx) .Select(x => CompileColumn(ctx, new Column { Name = x })) .ToList(); - string sql = string.Empty; - if (aggregateColumns.Count == 1) { - sql = string.Join(", ", aggregateColumns); + var sql = string.Join(", ", aggregateColumns); if (ctx.Query.IsDistinct) { @@ -675,7 +679,7 @@ public virtual string CompileUnion(SqlResult ctx) } else { - var combineRawClause = clause as RawCombine; + var combineRawClause = (RawCombine)clause; ctx.Bindings.AddRange(combineRawClause.Bindings); @@ -802,9 +806,10 @@ public virtual string CompileOrders(SqlResult ctx) return WrapIdentifiers(raw.Expression); } - var direction = (x as OrderBy).Ascending ? "" : " DESC"; + var orderByClause = (OrderBy)x; + var direction = orderByClause.Ascending ? "" : " DESC"; - return Wrap((x as OrderBy).Column) + direction; + return Wrap(orderByClause.Column) + direction; }); return "ORDER BY " + string.Join(", ", columns); diff --git a/README.md b/README.md index 70d49967..c1744247 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ I announce updates on My [Twitter Account](https://twitter.com/ahmadmuzavi), and Usually it's impossible to support all available database vendors, this why we focus on the major ones, and we encourage you to create your own compiler for your database. ### Do you accept new compilers? -Unfortunetly no, the reason is this will add overhead for the project contributors, we prefer to improve the quality of the existing compilers instead. +Unfortunately no, the reason is this will add overhead for the project contributors, we prefer to improve the quality of the existing compilers instead. ### How can I support the project? - Star the project here in Github, and share it with your friends diff --git a/sqlkata.sln b/sqlkata.sln index 957e67a0..7002b8a6 100644 --- a/sqlkata.sln +++ b/sqlkata.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26124.0 @@ -14,6 +13,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{86D00525-7428-4DD7-914D-0A10D5C53EDE}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + README.md = README.md EndProjectSection EndProject Global