Skip to content

Commit e42ab42

Browse files
authored
Merge pull request #436 from DataObjects-NET/7.1-pg-trimscale
Apply 'trim_scale' function to results of aggregation to improve compatibility with .NET decimal
2 parents 26fe487 + 69ac29c commit e42ab42

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

ChangeLog/7.1.6-dev.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[postgresql] For PostgreSQL 13+ apply 'trim_scale' function to results of aggregation to improve compatibility with .NET decimal

Orm/Xtensive.Orm.PostgreSql/Orm.Providers.PostgreSql/DomainHandler.cs

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2008-2020 Xtensive LLC.
1+
// Copyright (C) 2008-2025 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Alexey Gamzov
@@ -18,15 +18,24 @@ namespace Xtensive.Orm.Providers.PostgreSql
1818
/// </summary>
1919
public class DomainHandler : Providers.DomainHandler
2020
{
21+
/// <summary>
22+
/// <see langword="true"/> if storage can trim insignificant zeros in numeric values
23+
/// </summary>
24+
protected bool HasNativeTrimOfInsignificantZerosInDecimals =>
25+
Handlers.ProviderInfo.StorageVersion.Major >= 13;
26+
2127
/// <inheritdoc/>
2228
protected override ICompiler CreateCompiler(CompilerConfiguration configuration) =>
2329
new SqlCompiler(Handlers, configuration);
2430

2531
/// <inheritdoc/>
2632
protected override IPreCompiler CreatePreCompiler(CompilerConfiguration configuration)
2733
{
28-
var decimalAggregateCorrector = new AggregateOverDecimalColumnCorrector(Handlers.Domain.Model);
29-
return new CompositePreCompiler(decimalAggregateCorrector, base.CreatePreCompiler(configuration));
34+
if (!HasNativeTrimOfInsignificantZerosInDecimals) {
35+
var decimalAggregateCorrector = new AggregateOverDecimalColumnCorrector(Handlers.Domain.Model);
36+
return new CompositePreCompiler(decimalAggregateCorrector, base.CreatePreCompiler(configuration));
37+
}
38+
return base.CreatePreCompiler(configuration);
3039
}
3140

3241
/// <inheritdoc/>

Orm/Xtensive.Orm.PostgreSql/Orm.Providers.PostgreSql/PostgresqlSqlDml.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// Copyright (C) 2014-2020 Xtensive LLC.
1+
// Copyright (C) 2014-2025 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Alena Mikshina
55
// Created: 2014.05.06;
66

77
using Xtensive.Core;
8+
using Xtensive.Sql;
89
using Xtensive.Sql.Dml;
910

1011
namespace Xtensive.Orm.Providers.PostgreSql
@@ -16,6 +17,15 @@ namespace Xtensive.Orm.Providers.PostgreSql
1617
/// </summary>
1718
public class PostgresqlSqlDml
1819
{
20+
/// <summary>
21+
/// Creates an expression for native "trim_scale" function call. The function is supported starting from PostgreSQL 13
22+
/// </summary>
23+
public static SqlExpression DecimalTrimScale(SqlExpression operand)
24+
{
25+
ArgumentValidator.EnsureArgumentNotNull(operand, nameof(operand));
26+
return SqlDml.FunctionCall("TRIM_SCALE", operand);
27+
}
28+
1929
#region Spatial types
2030

2131
/// <summary>

Orm/Xtensive.Orm.PostgreSql/Orm.Providers.PostgreSql/SqlCompiler.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2009-2021 Xtensive LLC.
1+
// Copyright (C) 2009-2025 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Denis Krjuchkov
@@ -21,6 +21,8 @@ internal class SqlCompiler : Providers.SqlCompiler
2121
{
2222
private const int MaxDotnetDecimalPrecision = 28;
2323

24+
private readonly bool canRemoveInsignificantZerosInDecimals;
25+
2426
protected override SqlProvider VisitFreeText(FreeTextProvider provider)
2527
{
2628
var rankColumnName = provider.Header.Columns[provider.Header.Columns.Count - 1].Name;
@@ -61,6 +63,11 @@ protected override SqlExpression ProcessAggregate(SqlProvider source, List<SqlEx
6163
var aggregateType = aggregateColumn.AggregateType;
6264
var originCalculateColumn = source.Origin.Header.Columns[aggregateColumn.SourceIndex];
6365
if (AggregateRequiresDecimalAdjustments(aggregateColumn)) {
66+
if (canRemoveInsignificantZerosInDecimals) {
67+
return (IsCalculatedColumn(originCalculateColumn))
68+
? PostgresqlSqlDml.DecimalTrimScale(SqlDml.Cast(result, Driver.MapValueType(aggregateColumn.Type)))
69+
: PostgresqlSqlDml.DecimalTrimScale(result);
70+
}
6471
if (!IsCalculatedColumn(originCalculateColumn)) {
6572
// this is aggregate by one column, result will be defined by the precision and scale of the column
6673
return result;
@@ -138,6 +145,7 @@ AggregateType.Min or
138145
public SqlCompiler(HandlerAccessor handlers, CompilerConfiguration configuration)
139146
: base(handlers, configuration)
140147
{
148+
canRemoveInsignificantZerosInDecimals = handlers.ProviderInfo.StorageVersion.Major >= 13;
141149
}
142150
}
143151
}

0 commit comments

Comments
 (0)