Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
eca2805
InfinityAliasTest changes
alex-kulakov Oct 24, 2025
97e8520
InfinityAliasTest changes
alex-kulakov Oct 24, 2025
7550a79
InfinityAliasTest: Fixed reading data
alex-kulakov Oct 24, 2025
d2ef8c9
InfinityAliasTest changes
alex-kulakov Oct 24, 2025
78d48c3
Merge branch 'master' into master-pgsql-tests
alex-kulakov Oct 24, 2025
309fdd4
Add temp logging for Npgsql switches
alex-kulakov Oct 25, 2025
53fd569
Publish temp log files as wf artifacts
alex-kulakov Oct 25, 2025
d4955ca
Fix typo in comment
alex-kulakov Oct 25, 2025
e83ab74
Fix error in wf
alex-kulakov Oct 25, 2025
e0508e0
Try fix more problems with wf
alex-kulakov Oct 25, 2025
c57a9b3
Publish temp log files as artifacts
alex-kulakov Oct 25, 2025
da6a63b
Change default target framework for test
alex-kulakov Oct 25, 2025
43eda37
Change making final report condition
alex-kulakov Oct 25, 2025
aead6c1
Merge branch 'master' into master-pgsql-tests
alex-kulakov Oct 25, 2025
f07899f
Instance Identifier for driver factory
alex-kulakov Oct 25, 2025
40047d9
Remove unnecessary ternary operator
alex-kulakov Oct 25, 2025
776de68
Try make test to be suitable for any timezone
alex-kulakov Oct 26, 2025
0388878
Handle hour part extraction in different timezones
alex-kulakov Oct 26, 2025
f857da7
Improve checks of native extraction results
alex-kulakov Oct 26, 2025
457e652
Revert temp changes for logging
alex-kulakov Oct 26, 2025
905570e
Reusable workflows' improvements
alex-kulakov Oct 26, 2025
c47fb19
Merge branch '6.0' into 7.0
alex-kulakov Oct 26, 2025
d4e7aa2
Reusable workflows: change default target framework
alex-kulakov Oct 26, 2025
4908db1
Merge branch '7.0' into 7.1
alex-kulakov Oct 26, 2025
febea5b
Merge branch 'master-pgsql-tests'
alex-kulakov Oct 26, 2025
9529220
Merge branch '7.1'
alex-kulakov Oct 26, 2025
c2d0fb8
Merge remote-tracking branch 'upstream/master' into mergeUpstream
SergeiPavlov Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/reusable-storage-dependant-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
target_framework:
description: 'Target framework'
required: true
default: 'net6.0'
default: 'net8.0'
type: string
specific_sha:
description: 'Commit SHA to checkout'
Expand Down Expand Up @@ -158,14 +158,6 @@ jobs:
run: |
docker stop $(docker ps -a -q)

- name: Temp log output
if: |
!cancelled()
run: |
echo "github event name: ${{ github.event_name }}"
echo "reproc step outcome: ${{ steps.reprocessing.outcome }}"
echo "complex step outcome: ${{ steps.complex_tests.outcome }}"

- name: Publish raw test results as files
if: |
(!cancelled() && inputs.publish_raw_results) || failure()
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/reusable-storage-independant-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
target_framework:
description: 'Target framework'
required: true
default: 'net6.0'
default: 'net8.0'
type: string
test_output_verbosity:
description: 'Verbosity for dotnet test command'
Expand Down Expand Up @@ -123,10 +123,9 @@ jobs:

- name: Make Final Test report
if: |
(github.event_name == 'push' && steps.complex_tests.outcome != 'cancelled')
|| (github.event_name == 'pull_request' && steps.complex_tests.outcome != 'cancelled')
|| (github.event_name == 'workflow_dispatch' && steps.complex_tests.outcome != 'cancelled')
|| steps.complex_tests.outcome == 'failure'
!cancelled()
&& ((github.event_name == 'push') || (github.event_name == 'pull_request') || (github.event_name == 'workflow_dispatch')
|| (steps.reprocessing.outcome == 'failure' || steps.complex_tests.outcome == 'failure'))
timeout-minutes: 1
uses: dorny/test-reporter@v2.1.1
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class DriverFactory : SqlDriverFactory
{
private const string DatabaseAndSchemaQuery = "select current_database(), current_schema()";

private readonly static Guid InstanceIdentifier;

private readonly static bool InfinityAliasForDatesEnabled;
private readonly static bool LegacyTimestamptBehaviorEnabled;

Expand Down Expand Up @@ -225,8 +227,10 @@ private static bool GetSwitchValueOrSet(string switchName, bool valueToSet)

static DriverFactory()
{
// Starging from Npgsql 6.0 they broke compatibility by forcefully replacing
// DateTime.MinValue/MaxValue of parameters with -Infinity and Infinity values.
InstanceIdentifier = Guid.NewGuid();

// Starting from Npgsql 6.0 they broke compatibility by forcefully replacing
// DateTime.MinValue/MaxValue in parameters with -Infinity and Infinity values.
// This new "feature", though doesn't affect reading/writing of values and equality/inequality
// filters, breaks some of operations such as parts extraction, default values for columns
// (which are constants and declared on high levels of abstraction) and some others.
Expand Down
101 changes: 67 additions & 34 deletions Orm/Xtensive.Orm.Tests.Sql/PostgreSql/InfinityAliasTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public sealed class InfinityAliasTest : SqlTest
private TypeMapping dateTimeTypeMapping;
private TypeMapping dateTimeOffsetTypeMapping;

private TimeSpan localTimezone;

protected override void CheckRequirements()
{
Require.ProviderIs(StorageProvider.PostgreSql);
Expand All @@ -39,6 +41,7 @@ protected override void TestFixtureSetUp()
base.TestFixtureSetUp();

var localZone = DateTimeOffset.Now.ToLocalTime().Offset;
localTimezone = localZone;
var localZoneString = ((localZone < TimeSpan.Zero) ? "-" : "+") + localZone.ToString(@"hh\:mm");
var initConnectionCommand = Connection.CreateCommand($"SET TIME ZONE INTERVAL '{localZoneString}' HOUR TO MINUTE");
_ = initConnectionCommand.ExecuteNonQuery();
Expand Down Expand Up @@ -466,10 +469,14 @@ private void TestMinDateTimeOffsetSelectDatePart(bool isOn)
DateTimeOffset.MinValue.Day,
isOn);

// timezone for DateTimeOffset.MinValue value in postgre is set to 04:02:33, at least when instance is in UTC+5 timezone
var serverSideHours = (localTimezone > TimeSpan.Zero)
? localTimezone.Hours // positive zone
: (localTimezone < TimeSpan.Zero)
? 23 + localTimezone.Hours // negative zone
: localTimezone.Hours; // UTC
TestDateTimeOffsetPartExtraction(DateTimeOffsetMinValueTable, SqlDateTimeOffsetPart.Hour,
5,
isOn ? DateTimeOffset.MinValue.Hour : 5,
serverSideHours,
serverSideHours,
isOn);
TestDateTimeOffsetPartExtraction(DateTimeOffsetMinValueTable, SqlDateTimeOffsetPart.Minute,
DateTimeOffset.MinValue.Minute,
Expand Down Expand Up @@ -546,27 +553,39 @@ public void DateTimeOffsetMaxSelectDatePartDateTest()

private void TestMaxDateTimeOffsetSelectDatePart(bool isOn)
{
var overflowHappens = localTimezone > TimeSpan.Zero;

// There is overflow of year because of PostgreSQL time zone functionality
var overflowYearValue = overflowHappens ? 1 : 0;
TestDateTimeOffsetPartExtraction(DateTimeOffsetMaxValueTable, SqlDateTimeOffsetPart.Year,
DateTimeOffset.MaxValue.Year + 1,
(isOn) ? DateTimeOffset.MaxValue.Year : DateTimeOffset.MaxValue.Year + 1,
DateTimeOffset.MaxValue.Year + overflowYearValue,
DateTimeOffset.MaxValue.Year + overflowYearValue,
isOn);

// there is value overflow to 01 in case of no aliases
var serverSideMonths = (localTimezone > TimeSpan.Zero) ? 1 : 12;
TestDateTimeOffsetPartExtraction(DateTimeOffsetMaxValueTable, SqlDateTimeOffsetPart.Month,
1,
(isOn) ? DateTimeOffset.MaxValue.Month : 1,
serverSideMonths,
serverSideMonths,
isOn);

// there is value overflow to 01 in case of no aliases
var serverSideDays = (localTimezone > TimeSpan.Zero) ? 1 : 31;
TestDateTimeOffsetPartExtraction(DateTimeOffsetMaxValueTable, SqlDateTimeOffsetPart.Day,
1,
(isOn) ? DateTimeOffset.MaxValue.Day : 1,
serverSideDays,
serverSideDays,
isOn);

// timezone for DateTimeOffset.MaxValue value in postgre is set to 04:59:59.999999, at least when instance is in UTC+5 timezone
var serverSideHours = (localTimezone > TimeSpan.Zero)
? localTimezone.Hours - 1 // positive zone
: (localTimezone < TimeSpan.Zero)
? 23 + localTimezone.Hours // negative zone
: 23; // UTC

TestDateTimeOffsetPartExtraction(DateTimeOffsetMaxValueTable, SqlDateTimeOffsetPart.Hour,
4,
(isOn) ? DateTimeOffset.MaxValue.Hour : 4,
serverSideHours,
serverSideHours,
isOn);
TestDateTimeOffsetPartExtraction(DateTimeOffsetMaxValueTable, SqlDateTimeOffsetPart.Minute,
DateTimeOffset.MaxValue.Minute,
Expand All @@ -587,22 +606,26 @@ private void TestDatePartExtraction(string table, SqlDatePart part, int expected
using (var reader = command.ExecuteReader()) {

while (reader.Read()) {
if (aliasesEnabled && part != SqlDatePart.Year) {
// year from +-infinity -> +-infinity
if (aliasesEnabled) {
// +-infinify
// year from +-infinity -> +-infinity (or 0 in case of versions older than 9.6)
// month from +-infinity -> null (or 0 in case of versions older that 9.6)
if (Driver.CoreServerInfo.ServerVersion >= StorageProviderVersion.PostgreSql96) {
Assert.That(reader.IsDBNull(0));
if (part != SqlDatePart.Year) {
Assert.That(reader.IsDBNull(0));
}
else {
var partValue = reader.GetDouble(0);
Assert.That(double.IsInfinity(partValue), Is.True);
}
}
else {
var partValue = reader.GetDouble(0);
Assert.That(partValue, Is.Zero);
}
}
if (Driver.CoreServerInfo.ServerVersion < StorageProviderVersion.PostgreSql96) {
var partValue = reader.GetDouble(0);
Assert.That(partValue, Is.Zero);
}
else {
// pure dates
var partValue = reader.GetDouble(0);
CheckPartNative(partValue, expectedValueNative, aliasesEnabled);
}
Expand Down Expand Up @@ -632,21 +655,26 @@ private void TestDateTimePartExtraction(string table, SqlDateTimePart part, int
using (var reader = command.ExecuteReader()) {

while (reader.Read()) {
if (aliasesEnabled && part != SqlDateTimePart.Year) {
// year from +-infinity -> +-infinity
if (aliasesEnabled) {
// +-infinify
// year from +-infinity -> +-infinity (or 0 in case of versions older than 9.6)
// month from +-infinity -> null (or 0 in case of versions older that 9.6)
if (Driver.CoreServerInfo.ServerVersion >= StorageProviderVersion.PostgreSql96)
Assert.That(reader.IsDBNull(0));
if (Driver.CoreServerInfo.ServerVersion >= StorageProviderVersion.PostgreSql96) {
if (part != SqlDateTimePart.Year) {
Assert.That(reader.IsDBNull(0));
}
else {
var partValue = reader.GetDouble(0);
Assert.That(double.IsInfinity(partValue), Is.True);
}
}
else {
var partValue = reader.GetDouble(0);
Assert.That(partValue, Is.Zero);
}
}
if (Driver.CoreServerInfo.ServerVersion < StorageProviderVersion.PostgreSql96) {
var partValue = reader.GetDouble(0);
Assert.That(partValue, Is.Zero);
}
else {
// pure dates
var partValue = reader.GetDouble(0);
CheckPartNative(partValue, expectedValueNative, aliasesEnabled);
}
Expand Down Expand Up @@ -676,21 +704,26 @@ private void TestDateTimeOffsetPartExtraction(string table, SqlDateTimeOffsetPar
using (var reader = command.ExecuteReader()) {

while (reader.Read()) {
if (aliasesEnabled && part != SqlDateTimeOffsetPart.Year) {
// year from +-infinity -> +-infinity
if (aliasesEnabled) {
// +-infinify
// year from +-infinity -> +-infinity (or 0 in case of versions older than 9.6)
// month from +-infinity -> null (or 0 in case of versions older that 9.6)
if (Driver.CoreServerInfo.ServerVersion >= StorageProviderVersion.PostgreSql96 )
Assert.That(reader.IsDBNull(0));
if (Driver.CoreServerInfo.ServerVersion >= StorageProviderVersion.PostgreSql96) {
if (part != SqlDateTimeOffsetPart.Year) {
Assert.That(reader.IsDBNull(0));
}
else {
var partValue = reader.GetDouble(0);
Assert.That(double.IsInfinity(partValue), Is.True);
}
}
else {
var partValue = reader.GetDouble(0);
Assert.That(partValue, Is.Zero);
}
}
if (Driver.CoreServerInfo.ServerVersion < StorageProviderVersion.PostgreSql96) {
var partValue = reader.GetDouble(0);
Assert.That(partValue, Is.Zero);
}
else {
// pure dates
var partValue = reader.GetDouble(0);
CheckPartNative(partValue, expectedValueNative, aliasesEnabled);
}
Expand Down
Loading