Skip to content

Commit 2f560fa

Browse files
committed
Validate SQLite type
1 parent 01115d4 commit 2f560fa

3 files changed

Lines changed: 39 additions & 3 deletions

File tree

Sources/Compiler/Sema/StmtTypeChecker.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,12 +891,20 @@ extension StmtTypeChecker {
891891
}
892892

893893
/// Will figure out the final SQL column type from the syntax
894-
private func typeFor(column: borrowing ColumnDefSyntax) -> Type {
894+
private mutating func typeFor(column: borrowing ColumnDefSyntax) -> Type {
895895
// Technically you can have a NULL primary key but I don't
896896
// think people actually do that...
897897
let isNotNullable = column.constraints
898898
.contains { $0.isPkConstraint || $0.isNotNullConstraint }
899899

900+
// Validate it is an actual SQLite type since SQlite doesnt care.
901+
if !Type.validTypeNames.contains(column.type.name.value) {
902+
diagnostics.add(.init(
903+
"Invalid type '\(column.type.name.value)'",
904+
at: column.type.location
905+
))
906+
}
907+
900908
let nominal: Type = .nominal(column.type.name.value)
901909

902910
let type: Type = if let alias = column.type.alias {

Sources/Compiler/Sema/Type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ public enum Type: Equatable, CustomStringConvertible, Sendable {
110110
static let blob: Type = .nominal("BLOB")
111111
static let any: Type = .nominal("ANY")
112112

113+
static let validTypeNames: Set<Substring> = [
114+
"TEXT", "INT", "INTEGER", "REAL", "BLOB", "ANY"
115+
]
116+
113117
/// The underlying root inner type
114118
var root: Type {
115119
return switch self {

Tests/CompilerTests/Compiler/CompileCreateTable.sql

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ PRAGMA feather_require_strict_tables = TRUE;
3636
-- CHECK: NAME baz
3737
-- CHECK: COLUMNS
3838
-- CHECK: KEY foo
39-
-- CHECK: VALUE TEXT?
39+
-- CHECK: VALUE DECIMAL?
4040
-- CHECK: PRIMARY_KEY
4141
-- CHECK: foo
4242
-- CHECK: KIND normal
4343
-- CHECK-ERROR: Missing STRICT table option
44+
-- CHECK-ERROR: Invalid type 'DECIMAL'
4445
-- CHECK-ERROR: Column 'bar' does not exist
4546
CREATE TABLE baz (
46-
foo TEXT,
47+
foo DECIMAL,
4748
PRIMARY KEY (foo, bar)
4849
);
4950

@@ -70,7 +71,30 @@ CREATE TABLE qux (
7071
-- CHECK: KEY TABLE
7172
-- CHECK: VALUE KEY?
7273
-- CHECK: KIND normal
74+
-- CHECK-ERROR: Invalid type 'KEY'
7375
CREATE TABLE "PRIMARY" (
7476
"TABLE" INTEGER,
7577
[TABLE] `KEY`
7678
) STRICT;
79+
80+
-- CHECK: TABLE
81+
-- CHECK: NAME allValidTypes
82+
-- CHECK: COLUMNS
83+
-- CHECK: KEY int
84+
-- CHECK: VALUE INT?
85+
-- CHECK: KEY integer
86+
-- CHECK: VALUE INTEGER?
87+
-- CHECK: KEY text
88+
-- CHECK: VALUE TEXT?
89+
-- CHECK: KEY blob
90+
-- CHECK: VALUE BLOB?
91+
-- CHECK: KEY any
92+
-- CHECK: VALUE ANY?
93+
-- CHECK: KIND normal
94+
CREATE TABLE allValidTypes (
95+
int INT,
96+
integer INTEGER,
97+
text TEXT,
98+
blob BLOB,
99+
any ANY
100+
) STRICT;

0 commit comments

Comments
 (0)