Skip to content

Incorrect SQL with .join() #16

@mjmsmith

Description

@mjmsmith

I'm not sure if this is still an issue with the changes recently pushed to master, but it affects 0.8.2.

Given two models Foo and Bar, a join might look like this:

let foos = Foo.selectQuery
              .join(Bar.self, using: .Inner, leftKey: .id, rightKey: .foo)
                 ...filters...
             .fetch(User.connection)

This SQL will be generated:

SELECT * FROM foo INNER JOIN bar ON foo.id = bar.foo

But SELECT * means it's going to return all fields in the join, not just the ones from Foo. This will cause unpredictable behavior if the two models have fields with the same name. For instance, if Foo and Bar both have primary keys named id, the Foo object may get generated using the Bar id from the result row.

I fixed this like so:

diff --git a/Sources/SQL/Query/Select.swift b/Sources/SQL/Query/Select.swift
index e403a8a..afae5c3 100644
--- a/Sources/SQL/Query/Select.swift
+++ b/Sources/SQL/Query/Select.swift
@@ -110,11 +110,11 @@ public protocol SelectQuery: FilteredQuery, FetchQuery {
 }

 public extension SelectQuery {
     public var queryComponents: QueryComponents {
         var components = QueryComponents(components: [
             "SELECT",
-            fields.isEmpty ? "*" : fields.queryComponentsForSelectingFields(useQualifiedNames: true, useAliasing: true, isolateQueryComponents: false),
+            fields.isEmpty ? QueryComponents("\(tableName).*") : fields.queryComponentsForSelectingFields(useQualifiedNames: true, useAliasing: true, isolateQueryComponents: false),
             "FROM",
             QueryComponents(tableName)
             ]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions