Skip to content

Repository files navigation

SQLiteDataIssue

Compiling never finishes when a query sorts by a field held inside an optional @Selection enum column group whose case payload is a struct.

Reproducing

Open SQLiteDataIssue.xcodeproj and build. Queries.swift never finishes compiling. Commenting out the marked .order line in workoutRows(_:) makes the file compile in a few seconds.

The CasePaths and LazyInitializableByDefault traits are enabled on the swift-structured-queries dependency.

The shape

healthRecords is a shared header table for every kind of record, so it carries several @Selection enum column groups. time is one of them — an interval or a calendar day, and optional, because some records have no time at all. Each case payload holds several fields, so the cases are structs rather than single values:

@Selection
enum RecordTime: Hashable, Sendable {
    case interval(Interval)
    case calendar(Day)

    @Selection
    struct Interval: Codable, Hashable, Sendable {
        var startDate: Date
        var endDate: Date?
        var timeSemantics: TimeSemantics
        var durationStatus: DurationStatus
        var timeZoneIdentifier: String?
        var timeZoneSecondsFromGMT: Int?
    }

    @Selection
    struct Day: Codable, Hashable, Sendable {}
}

@Table
struct HealthRecord: Identifiable {
    let id: UUID
    var type: RecordType            // @Selection enum, 7 cases
    var time: RecordTime?           // @Selection enum, optional
    var representation: Representation?  // @Selection enum, optional
    var origin: RecordOrigin        // @Selection enum, 6 cases
    …
}

The query:

WorkoutRecord
    .join(HealthRecord.all) { $0.id.eq($1.id) }
    .order { _, header in header.time.interval.startDate.desc() }
    .select { workout, header in  }

Other spellings tried

In a smaller SwiftPM package with the same RecordTime enum but a four-column HealthRecord and no join, the same .order expression compiles in about 20 seconds. Growing the table to the shape above and building it as an app target is what stops it finishing.

Filtering on a field inside a case is rejected rather than slow:

// error: no exact matches in reference to instance method 'eq'
.where { $0.time.interval.timeSemantics.eq(TimeSemantics.session) }

// error: instance method 'gt' requires the types 'Date??' and 'Date'
//        be equivalent
.where { $0.time.interval.startDate.gt(someDate) }

// compiles — the double optional is matched on both sides
.where { $0.time.interval.timeSemantics.eq(TimeSemantics?.some(.session)) }

Ordering by the case itself is rejected, since the payload is a struct rather than a single value:

// error: referencing instance method 'desc(nulls:)' on 'Optional'
//        requires that 'RecordTime.Interval' conform to 'QueryBindable'
.order { $0.time.interval.desc() }

Coalescing the double optional before sorting also never finishes:

.order { _, header in
    (header.time.interval.startDate ?? Date.distantPast).desc()
}

On the #337 branch

Pointing the same project at json-each-availability-group-updates (StructuredQueriesSQLite, same traits, same sources) fails fast instead of hanging, but it fails on the schema rather than the query, so the .order line is never reached:

Type 'HealthRecord.RecordTime.Interval' does not conform to
protocol 'QueryRepresentable'

reported in the macro expansion for RecordTime's @Selection. HealthRecord then stops conforming to Table, so .all, .order and the return type all error too.

The same project on 0.34.0 hangs, so this is a difference on the branch rather than in how the project is set up.

Environment

  • Xcode 27.0 (27A5228h), Swift 6.4
  • swift-structured-queries 0.34.0 (StructuredQueriesSQLite), traits CasePaths and LazyInitializableByDefault
  • No sqlite-data dependency: the hang is in type checking, so nothing is executed and no database is needed

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages