Skip to content

IsHypertable regression in 10.0.5: no longer accepts custom time-column types (e.g. NodaTime Instant) #50

@marcgallego

Description

@marcgallego

Hi! First of all, let me thank you for this amazing library! I have a problem regarding the use of NodaTime.

Environment

  • CmdScale.EntityFrameworkCore.TimescaleDB 10.0.5 (works on 10.0.4)
  • EF Core 10.0.8, Npgsql + Npgsql.NodaTime, NodaTime 3.3.2
  • .NET 10 (SDK 10.0.107)

Description

In 10.0.4, IsHypertable accepted Expression<Func<TEntity, object>>, so any property type could be used as the time column (the method only reads the property name). 10.0.5 replaced this with strongly-typed overloads (DateTime, DateTimeOffset, DateOnly, long, int, short) and removed the flexible one. This breaks projects mapping the time column to a custom type — e.g. NodaTime Instant, which Npgsql maps to timestamptz.

This looks like an unintended side effect of #48 ("Accept any time column type in IsContinuousAggregate"): the same refactor widened continuous aggregates but narrowed IsHypertable in the opposite direction.

Steps to Reproduce

  1. Create a project targeting net10.0 with these packages:

    <PackageReference Include="CmdScale.EntityFrameworkCore.TimescaleDB" Version="10.0.5" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.2" />
    <PackageReference Include="NodaTime" Version="3.3.2" />
  2. Define an entity whose time column is a NodaTime Instant and mark it as a hypertable:

    using Microsoft.EntityFrameworkCore;
    using NodaTime;
    using CmdScale.EntityFrameworkCore.TimescaleDB.Configuration.Hypertable;
    
    public class Observation
    {
        public long Id { get; set; }
        public Instant Timestamp { get; set; }
        public double Value { get; set; }
    }
    
    public class AppDbContext : DbContext
    {
        public DbSet<Observation> Observations => Set<Observation>();
    
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseNpgsql("Host=localhost;Database=test;Username=test;Password=test",
                    o => o.UseNodaTime())
                .UseTimescaleDb();
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Observation>(entity =>
            {
                entity.HasKey(o => new { o.Id, o.Timestamp });
                entity.IsHypertable(o => o.Timestamp);   // <-- regression here
            });
        }
    }
  3. Build the project (dotnet build).

Actual Behaviour

Compilation fails. The compiler binds to the short overload because no overload accepts Instant:

error CS0029: Cannot implicitly convert type 'NodaTime.Instant' to 'short'
error CS1662: Cannot convert lambda expression to intended delegate type
             because some of the return types in the block are not implicitly
             convertible to the delegate return type

Expected Behaviour

The project compiles and Observation is configured as a hypertable, as it did in 10.0.4. Any property type usable as a TimescaleDB time column (timestamp/integer-backed, including custom or value-converted types like NodaTime Instant) should be accepted, consistent with what #48 did for IsContinuousAggregate. Restoring a generic/object overload of IsHypertable (delegating to IsHypertableCore) would achieve this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions