Sqlite.swift: Invalid SQL statements with Xcode 10.2

Created on 19 Mar 2019  路  14Comments  路  Source: stephencelis/SQLite.swift

Build Information

  • SQLite iOS Version 0.11.4 (however it's likely to impact all the targets)
  • Xcode 10.2 beta 4
  • manual integration in our project

General guidelines

In Xcode 10.2 beta 4 the macro#functionshows a different behaviour. As SQLite.swift relies on #function in different subroutines for the composition of SQLite queries, several bugs linked to invalid SQLite statements seem to be introduced.

I have just run the SQLite.swift tests with Xcode 10.2 beta 4 and there are several failures linked to this issue.

An example as follows:

In the following helper function (Helpers.swift line 107):

func wrap<T>(_ expression: Expressible, function: String = #function) -> Expression<T> {
    return function.wrap(expression)
}

when called from

static func count(_ star: Star) -> Expression<UnderlyingType>

the value of function when running in Xcode 10.2 beta 4 is count(_:) instead of count. This leads to invalid SQLite statements of the type SELECT count(_:)(*) myTable.

Most helpful comment

@stephencelis hello! Can you check this issue and linked pr? Any project with SQLite.swift will not work on new Xcode 10.2 without this fix.

All 14 comments

I have the exact same problem with Xcode Version 10.2 (10E125) (not the beta normally) !

Do you have a workaround or a fix ?

The best option in my opinion is to get rid altogether of the #function default parameter and explicitly passing the name of the SQL function (maybe an enum with string raw value). The #function macro seems to be intended for debug purposes (this explains this sort of change in a minor update of Xcode) and I would avoid relying on it for such a critical part of the SQL statement composition.

Here is a patch to apply if you have a pod install

mystuff.patch.zip

the simplest fix would be to just ignore any string after the first ( of #function

Here is a patch to apply if you have a pod install

mystuff.patch.zip

I tried your patch but now it started giving 148 errors similar to /Pods/SQLite.swift/Sources/SQLite/Typed/Operators.swift:471:12: Use of unresolved identifier 'infix'
/Pods/SQLite.swift/Sources/SQLite/Typed/CoreFunctions.swift:73:16: Use of unresolved identifier 'wrap'.

@christopheblin Could you please explain how you used the patch?

The Patch did not work properly

In folder where you cloned repo:
patch -p3 < mystuff.patch

All tests pass after patch applied

Thanks,
But for now, I forked the original repo and manually made changes.

@stephencelis hello! Can you check this issue and linked pr? Any project with SQLite.swift will not work on new Xcode 10.2 without this fix.

The symptom which lead me down this rabbit hole was first seeing was that it could not prepare a statement so: The operation couldn鈥檛 be completed. (SQLite.Result error 0.). Turning on the trace logging helped see which statements were successful. Finally spitting out query.asSQL() in the catch of the error showed that count and != had now been rendered as count(_:) and !=(_:_:).

I agree with @chess92. My simple workaround for now this change in Helpers.swift. It fixes all the problems I had, but obviously I'll toss it out and use a formal fix as soon as it's ready.

private func trimName(_ function: String) -> String {
    return function.components(separatedBy: "(").first ?? function
}

func infix<T>(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true, function: String = #function) -> Expression<T> {
    return trimName(function).infix(lhs, rhs, wrap: wrap)
}

func wrap<T>(_ expression: Expressible, function: String = #function) -> Expression<T> {
    return trimName(function).wrap(expression)
}

func wrap<T>(_ expressions: [Expressible], function: String = #function) -> Expression<T> {
    return trimName(function).wrap(", ".join(expressions))
}

@timshadel return function.components(separatedBy: "(").first ?? function yucky :)

Hello
Any solution for this problem?

@karishmapujara We have PR with the fix. Waiting for @stephencelis to review and merge

@timshadel return function.components(separatedBy: "(").first ?? function yucky :)

Right??!! Exactly why I was waiting for a real fix. 馃槂 It looks like #891 handles this nicely with several enums and removes the #function magic.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tommycloud picture tommycloud  路  6Comments

RockyQu picture RockyQu  路  6Comments

pgawlowski picture pgawlowski  路  6Comments

fortitude1990 picture fortitude1990  路  4Comments

WDDong picture WDDong  路  7Comments