Skip to content

Commit 0b1c179

Browse files
committed
Enforce Equatable/Comparable datatypes in expressions
This prevents BLOB columns from being compared (though they can be equated). If someone has a valid reason for extending Blob to be Comparable, I'm all ears. In the meantime, it seems like an accident waiting to happen. Signed-off-by: Stephen Celis <stephen@stephencelis.com>
1 parent 35066a6 commit 0b1c179

File tree

2 files changed

+56
-50
lines changed

2 files changed

+56
-50
lines changed

SQLite Common/Expression.swift

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -226,167 +226,167 @@ public func collate(collation: Collation, expression: Expression<String?>) -> Ex
226226

227227
// MARK: - Predicates
228228

229-
public func ==<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
229+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
230230
return infix("=", lhs, rhs)
231231
}
232-
public func ==<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
232+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
233233
return infix("=", lhs, rhs)
234234
}
235-
public func ==<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
235+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
236236
return infix("=", lhs, rhs)
237237
}
238-
public func ==<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
238+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
239239
return infix("=", lhs, rhs)
240240
}
241-
public func ==<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
241+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
242242
return lhs == Expression(value: rhs.datatypeValue)
243243
}
244-
public func ==<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: V?) -> Expression<Bool?> {
244+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V?>, rhs: V?) -> Expression<Bool?> {
245245
if let rhs = rhs { return lhs == Expression(value: rhs.datatypeValue) }
246246
return Expression("\(lhs.SQL) IS ?", lhs.bindings + [nil])
247247
}
248-
public func ==<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
248+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
249249
return Expression(value: lhs.datatypeValue) == rhs
250250
}
251-
public func ==<V: Value where V.Datatype: Binding>(lhs: V?, rhs: Expression<V?>) -> Expression<Bool?> {
251+
public func ==<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: V?, rhs: Expression<V?>) -> Expression<Bool?> {
252252
if let lhs = lhs { return Expression(value: lhs.datatypeValue) == rhs }
253253
return Expression("? IS \(rhs.SQL)", [nil] + rhs.bindings)
254254
}
255255

256-
public func !=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
256+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
257257
return infix(__FUNCTION__, lhs, rhs)
258258
}
259-
public func !=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
259+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
260260
return infix(__FUNCTION__, lhs, rhs)
261261
}
262-
public func !=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
262+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
263263
return infix(__FUNCTION__, lhs, rhs)
264264
}
265-
public func !=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
265+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
266266
return infix(__FUNCTION__, lhs, rhs)
267267
}
268-
public func !=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
268+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
269269
return lhs != Expression(value: rhs.datatypeValue)
270270
}
271-
public func !=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: V?) -> Expression<Bool?> {
271+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: Expression<V?>, rhs: V?) -> Expression<Bool?> {
272272
if let rhs = rhs { return lhs != Expression(value: rhs.datatypeValue) }
273273
return Expression("\(lhs.SQL) IS NOT ?", lhs.bindings + [nil])
274274
}
275-
public func !=<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
275+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
276276
return Expression(value: lhs.datatypeValue) != rhs
277277
}
278-
public func !=<V: Value where V.Datatype: Binding>(lhs: V?, rhs: Expression<V?>) -> Expression<Bool?> {
278+
public func !=<V: Value where V.Datatype: protocol<Binding, Equatable>>(lhs: V?, rhs: Expression<V?>) -> Expression<Bool?> {
279279
if let lhs = lhs { return Expression(value: lhs.datatypeValue) != rhs }
280280
return Expression("? IS NOT \(rhs.SQL)", [nil] + rhs.bindings)
281281
}
282282

283-
public func ><V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
283+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
284284
return infix(__FUNCTION__, lhs, rhs)
285285
}
286-
public func ><V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
286+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
287287
return infix(__FUNCTION__, lhs, rhs)
288288
}
289-
public func ><V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
289+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
290290
return infix(__FUNCTION__, lhs, rhs)
291291
}
292-
public func ><V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
292+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
293293
return infix(__FUNCTION__, lhs, rhs)
294294
}
295-
public func ><V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
295+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
296296
return lhs > Expression(value: rhs.datatypeValue)
297297
}
298-
public func ><V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
298+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
299299
return lhs > Expression(value: rhs.datatypeValue)
300300
}
301-
public func ><V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
301+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
302302
return Expression(value: lhs.datatypeValue) > rhs
303303
}
304-
public func ><V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
304+
public func ><V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
305305
return Expression(value: lhs.datatypeValue) > rhs
306306
}
307307

308-
public func >=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
308+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
309309
return infix(__FUNCTION__, lhs, rhs)
310310
}
311-
public func >=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
311+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
312312
return infix(__FUNCTION__, lhs, rhs)
313313
}
314-
public func >=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
314+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
315315
return infix(__FUNCTION__, lhs, rhs)
316316
}
317-
public func >=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
317+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
318318
return infix(__FUNCTION__, lhs, rhs)
319319
}
320-
public func >=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
320+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
321321
return lhs >= Expression(value: rhs.datatypeValue)
322322
}
323-
public func >=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
323+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
324324
return lhs >= Expression(value: rhs.datatypeValue)
325325
}
326-
public func >=<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
326+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
327327
return Expression(value: lhs.datatypeValue) >= rhs
328328
}
329-
public func >=<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
329+
public func >=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
330330
return Expression(value: lhs.datatypeValue) >= rhs
331331
}
332332

333-
public func <<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
333+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
334334
return infix(__FUNCTION__, lhs, rhs)
335335
}
336-
public func <<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
336+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
337337
return infix(__FUNCTION__, lhs, rhs)
338338
}
339-
public func <<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
339+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
340340
return infix(__FUNCTION__, lhs, rhs)
341341
}
342-
public func <<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
342+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
343343
return infix(__FUNCTION__, lhs, rhs)
344344
}
345-
public func <<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
345+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
346346
return lhs < Expression(value: rhs.datatypeValue)
347347
}
348-
public func <<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
348+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
349349
return lhs < Expression(value: rhs.datatypeValue)
350350
}
351-
public func <<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
351+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
352352
return Expression(value: lhs.datatypeValue) < rhs
353353
}
354-
public func <<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
354+
public func <<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
355355
return Expression(value: lhs.datatypeValue) < rhs
356356
}
357357

358-
public func <=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
358+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V>) -> Expression<Bool> {
359359
return infix(__FUNCTION__, lhs, rhs)
360360
}
361-
public func <=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
361+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: Expression<V?>) -> Expression<Bool?> {
362362
return infix(__FUNCTION__, lhs, rhs)
363363
}
364-
public func <=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
364+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V>) -> Expression<Bool?> {
365365
return infix(__FUNCTION__, lhs, rhs)
366366
}
367-
public func <=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
367+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: Expression<V?>) -> Expression<Bool?> {
368368
return infix(__FUNCTION__, lhs, rhs)
369369
}
370-
public func <=<V: Value where V.Datatype: Binding>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
370+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V>, rhs: V) -> Expression<Bool> {
371371
return lhs <= Expression(value: rhs.datatypeValue)
372372
}
373-
public func <=<V: Value where V.Datatype: Binding>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
373+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: Expression<V?>, rhs: V) -> Expression<Bool?> {
374374
return lhs <= Expression(value: rhs.datatypeValue)
375375
}
376-
public func <=<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
376+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V>) -> Expression<Bool> {
377377
return Expression(value: lhs.datatypeValue) <= rhs
378378
}
379-
public func <=<V: Value where V.Datatype: Binding>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
379+
public func <=<V: Value where V.Datatype: protocol<Binding, Comparable>>(lhs: V, rhs: Expression<V?>) -> Expression<Bool?> {
380380
return Expression(value: lhs.datatypeValue) <= rhs
381381
}
382382

383383
public prefix func -<V: Number>(rhs: Expression<V>) -> Expression<V> { return wrap(__FUNCTION__, rhs) }
384384
public prefix func -<V: Number>(rhs: Expression<V?>) -> Expression<V?> { return wrap(__FUNCTION__, rhs) }
385385

386-
public func ~=<I: IntervalType, V: Value where V: Binding, V == I.Bound>(lhs: I, rhs: Expression<V>) -> Expression<Bool> {
386+
public func ~=<I: IntervalType, V: Value where V: protocol<Binding, Comparable>, V == I.Bound>(lhs: I, rhs: Expression<V>) -> Expression<Bool> {
387387
return Expression("\(rhs.SQL) BETWEEN ? AND ?", rhs.bindings + [lhs.start, lhs.end])
388388
}
389-
public func ~=<I: IntervalType, V: Value where V: Binding, V == I.Bound>(lhs: I, rhs: Expression<V?>) -> Expression<Bool?> {
389+
public func ~=<I: IntervalType, V: Value where V: protocol<Binding, Comparable>, V == I.Bound>(lhs: I, rhs: Expression<V?>) -> Expression<Bool?> {
390390
return Expression<Bool?>(lhs ~= Expression<V>(rhs))
391391
}
392392

SQLite Common/Value.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public struct Blob {
5959

6060
}
6161

62+
extension Blob: Equatable {}
63+
64+
public func ==(lhs: Blob, rhs: Blob) -> Bool {
65+
return lhs.data == rhs.data
66+
}
67+
6268
extension Blob: Binding, Value {
6369

6470
public typealias Datatype = Blob

0 commit comments

Comments
 (0)