GenieFramework / SearchLight.jl

ORM layer for Genie.jl, the highly productive Julia web framework
https://genieframework.com
MIT License
139 stars 16 forks source link

SQLColumn table_name get lost when doing a join operation #69

Open jonathanBieler opened 1 year ago

jonathanBieler commented 1 year ago

I was trying to do a join query and came across this bug, I'm doing someting like this:

on = SQLOn( SQLColumn("comments.user_id"), SQLColumn("users.id"))
j = Vector{SQLJoin}([
    SQLJoin(Users.User, columns = [SQLColumn("users.name")], [on])
])
q = SQLQuery(where = [SQLWhereExpression("$(SQLColumn(:topic_id)) = ?", topic_id)], order = SQLOrder(:datetime, "DESC"))
DataFrame(Comments.Comment, q, j)

And I get an error telling me "comments.name" doesn't exists, while I asked for "users.name" in my query. The table_name is lost and replaced during the preparation of the query (in prepare_column_name).

The issue is that table_name that was already parsed in SQLColumn constructor is ignored here :

https://github.com/GenieFramework/SearchLight.jl/blob/0b72060b09cf9764429d86c6957adf7124082a0e/src/SearchLight.jl#L956

This fixes the issue, but seems a bit hacky. Not sure why we need to parse the column again, feels like that should be the job of the constructor.

@eval SearchLight begin

    function prepare_column_name(column::SearchLight.SQLColumn, m::Type{T})::String where {T<:SearchLight.AbstractModel}
        if column.raw
          column.value |> string
        else
          column_data::Dict{Symbol,Any} = SearchLight.from_literal_column_name(column)
          if ! haskey(column_data, :table_name)
            column_data[:table_name] = SearchLight.table(m)
          end
          if ! haskey(column_data, :alias)
            column_data[:alias] = ""
          end

          column_data_to_column_name(column, column_data)
        end
      end

      function from_literal_column_name(column::SearchLight.SQLColumn)
        c = column.value
        result = Dict{Symbol,String}()
        result[:original_string] = c
        result[:table_name] = column.table_name

        # has alias?
        if occursin(" AS ", c)
          parts = split(c, " AS ")
          result[:column_name] = parts[1]
          result[:alias] = parts[2]
        else
          result[:column_name] = c
        end

        # is fully qualified?
        if occursin(".", result[:column_name])
          parts = split(result[:column_name], ".")
          result[:table_name] = parts[1]
          result[:column_name] = parts[2]
        end

        result
      end
end

SearchLightSQLite v2.2.1