-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
E.g. take the example table definition from the TestHelper:
SQLite.swift/Tests/SQLiteTests/TestHelpers.swift
Lines 22 to 31 in f1bee07
| CREATE TABLE users ( | |
| id INTEGER PRIMARY KEY, | |
| email TEXT NOT NULL UNIQUE, | |
| age INTEGER, | |
| salary REAL, | |
| admin BOOLEAN NOT NULL DEFAULT 0 CHECK (admin IN (0, 1)), | |
| manager_id INTEGER, | |
| created_at DATETIME, | |
| FOREIGN KEY(manager_id) REFERENCES users(id) | |
| ) |
According to 3.1. Determination Of Column Affinity the affinity of a column is based on the declared type. With the "parsing" following a set of five rules (see linked page).
So for the above table definition, the column affinity should be:
id-> rule 1:INTEGER✅email-> rule 2:TEXT✅age-> rule 1:INTEGER✅salary-> rule 4:REAL✅admin-> rule 5:NUMERIC❌manager_id-> rule 1:INTEGER✅created_at-> rule 5:NUMERIC❌
but the affinity is incorrect for the following columns: admin and created_at (TEXT instead of NUMERIC).
See
SQLite.swift/Tests/SQLiteTests/Schema/SchemaReaderTests.swift
Lines 17 to 57 in f1bee07
| ColumnDefinition(name: "id", | |
| primaryKey: .init(autoIncrement: false, onConflict: nil), | |
| type: .INTEGER, | |
| nullable: true, | |
| defaultValue: .NULL, | |
| references: nil), | |
| ColumnDefinition(name: "email", | |
| primaryKey: nil, | |
| type: .TEXT, | |
| nullable: false, | |
| defaultValue: .NULL, | |
| references: nil), | |
| ColumnDefinition(name: "age", | |
| primaryKey: nil, | |
| type: .INTEGER, | |
| nullable: true, | |
| defaultValue: .NULL, | |
| references: nil), | |
| ColumnDefinition(name: "salary", | |
| primaryKey: nil, | |
| type: .REAL, | |
| nullable: true, | |
| defaultValue: .NULL, | |
| references: nil), | |
| ColumnDefinition(name: "admin", | |
| primaryKey: nil, | |
| type: .TEXT, | |
| nullable: false, | |
| defaultValue: .numericLiteral("0"), | |
| references: nil), | |
| ColumnDefinition(name: "manager_id", | |
| primaryKey: nil, type: .INTEGER, | |
| nullable: true, | |
| defaultValue: .NULL, | |
| references: .init(table: "users", column: "manager_id", primaryKey: "id", onUpdate: nil, onDelete: nil)), | |
| ColumnDefinition(name: "created_at", | |
| primaryKey: nil, | |
| type: .TEXT, | |
| nullable: true, | |
| defaultValue: .NULL, | |
| references: nil) |
A possible solution is to create the Affinity and implement the 5 rules, e.g. like here: stefansaasen@fabbe8c
There is one important thing to consider here, the default affinity for declared types that are not covered is now NUMERIC instead of TEXT. E.g. with the gotcha mentioned here: https://www.sqlite.org/datatype3.html#determination_of_column_affinity
And the declared type of "STRING" has an affinity of NUMERIC, not TEXT
Should probably considered to be a breaking change.
P.S.: Happy to create a PR if the approach in the commit linked above is acceptable.
Build Information
- Include the SQLite.swift version: 0.14.1
- Mention Xcode and OS X versions affected: Xcode
14.3and macOS Ventura13.4 - How do do you integrate SQLite.swift in your project: Swift Package manager