jsonObject() and jsonGroupArray() flatten nested Codable types instead of preserving their structure
bug
### Description
### Summary
When calling jsonObject() or jsonGroupArray() on a `@Table` type that contains a nested Codable struct, the generated SQL flattens all columns into a single json_object level. This produces JSON that does not match the structure Codable expects when decoding, causing a failure with "The data couldn't be read because it is missing."
### Root Cause
Both functions use Self.allColumns to enumerate the columns to serialize. allColumns returns the flat SQLite columns (e.g. bucket, value, createdAt, updatedAt), with no awareness that createdAt and updatedAt belong to a nested Swift property (timestamps: Timestamps). The generated JSON therefore has the wrong shape for Codable to decode.
### Checklist
- [ ] I have determined whether this bug is also reproducible in a vanilla SwiftUI project.
- [x] If possible, I've reproduced the issue using the `main` branch of this package.
- [x] This issue hasn't been addressed in an [existing GitHub issue](https://github.com/pointfreeco/swift-structured-queries/issues) or [discussion](https://github.com/pointfreeco/swift-structured-queries/discussions).
### Expected behavior
Both functions should mirror the Codable structure, nesting createdAt/updatedAt under a timestamps key:
``` sql
-- jsonObject()
SELECT json_object(
'bucket', json_quote("timestampedItems"."bucket"),
'value', json_quote("timestampedItems"."value"),
'timestamps', json_object( -- ✅ nested key
'createdAt', json_quote("timestampedItems"."createdAt"),
'updatedAt', json_quote("timestampedItems"."updatedAt")
)
)
FROM "timestampedItems"
-- jsonGroupArray()
SELECT json_group_array(json_object(
'bucket', json_quote("timestampedItems"."bucket"),
'value', json_quote("timestampedItems"."value"),
'timestamps', json_object( -- ✅ nested key
'createdAt', json_quote("timestampedItems"."createdAt"),
'updatedAt', json_quote("timestampedItems"."updatedAt")
)
))
FROM "timestampedItems"
GROUP BY "timestampedItems"."bucket"
```
Both round-trip correctly through Codable and return the expected decoded values.
### Actual behavior
Both functions flatten the nested timestamps struct into the top-level json_object:
``` sql
-- jsonObject()
SELECT json_object(
'bucket', json_quote("timestampedItems"."bucket"),
'value', json_quote("timestampedItems"."value"),
'createdAt', json_quote("timestampedItems"."createdAt"), -- ❌ wrong level
'updatedAt', json_quote("timestampedItems"."updatedAt") -- ❌ wrong level
)
FROM "timestampedItems"
-- jsonGroupArray()
SELECT json_group_array(json_object(
'bucket', json_quote("timestampedItems"."bucket"),
'value', json_quote("timestampedItems"."value"),
'createdAt', json_quote("timestampedItems"."createdAt"), -- ❌ wrong level
'updatedAt', json_quote("timestampedItems"."updatedAt") -- ❌ wrong level
))
FROM "timestampedItems"
GROUP BY "timestampedItems"."bucket"
```
Both fail to decode: "The data couldn't be read because it is missing."
### Reproducing project
Define a @Table type with a nested struct stored via Codable:
``` swift
@Table
struct TimestampedItem: Codable {
var bucket: Int
var value: Int
var timestamps: Timestamps // nested type
}
struct Timestamps: Codable {
var createdAt: Date
var updatedAt: Date
}
```
#### jsonObject()
``` swift
TimestampedItem.all.select { $0.jsonObject() }
```
#### jsonGroupArray()
``` swift
TimestampedItem
.group(by: \.bucket)
.select {
GroupedTimestampedItem.Columns(
bucket: $0.bucket,
timestampedItems: $0.jsonGroupArray()
)
}
```
[swift-structured-queries_jsonObject-and-jsonGroupArray-with-nested-types.patch](https://github.com/user-attachments/files/30168477/swift-structured-queries_jsonObject-and-jsonGroupArray-with-nested-types.patch)
### Structured Queries version information
0.33.3
### Destination operating system
macOS 26.5.2 (25F84)
### Xcode version information
Version 26.6 (17F113)
### Swift Compiler version information
```shell
swift-driver version: 1.148.6 Apple Swift version 6.3.3 (swiftlang-6.3.3.1.3 clang-2100.1.1.101)
Target: arm64-apple-macosx26.0
```
4 条评论