diff --git a/src/query_translation.jl b/src/query_translation.jl index 14d50802..b591b890 100644 --- a/src/query_translation.jl +++ b/src/query_translation.jl @@ -124,7 +124,6 @@ function query_expression_translation_phase_1(qe) deleteat!(sub_query.args[end].args,6) translate_query(sub_query) - length(sub_query.args)==1 || throw(QueryException("@group ... into subquery too long", sub_query)) qe[1] = :( @from $x in $(sub_query.args[1]) ) @@ -387,13 +386,31 @@ function replace_transparent_identifier_in_anonym_func(ex::Expr, names_to_put_in end end +# translates (:a, :((b.c).d)) to :(((a.b).c).d) +function shift_access!(sym::Symbol, ex::Expr) + while ex.args[1] isa Expr + ex = ex.args[1] + end + ex.args[1] = Expr(:., sym, QuoteNode(ex.args[1])) + return +end + function find_names_to_put_in_scope(ex::Expr) names = [] for child_ex in ex.args[2:end] if isa(child_ex,Expr) && child_ex.head==:transparentidentifier child_names = find_names_to_put_in_scope(child_ex) for child_name in child_names - push!(names, (Expr(:., ex.args[1], QuoteNode(child_name[1])), child_name[2])) + c = child_name[1] + if c isa Symbol + xx = (Expr(:., ex.args[1], QuoteNode(c)), child_name[2]) + elseif c.args[1] isa Symbol + xx = (Expr(:., Expr(:., ex.args[1], QuoteNode(c.args[1])), c.args[2]), child_name[2]) + else + shift_access!(ex.args[1], c) + xx = (c, child_name[2]) + end + push!(names, xx) end elseif isa(child_ex, Symbol) push!(names,(ex.args[1],child_ex)) diff --git a/test/runtests.jl b/test/runtests.jl index 4dfa13bb..a7ac1249 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -32,6 +32,14 @@ end @test !Query.iscall(:(map(1,2,3,4)), :map, 3) end + @testset "shift_access!" begin + ex = Expr(:., :c, QuoteNode(:d)) + Query.shift_access!(:b, ex) + @test ex == :((b.c).d) + Query.shift_access!(:a, ex) + @test ex == :(((a.b).c).d) + end + source_df = DataFrame(name=["John", "Sally", "Kirk"], age=[23., 42., 59.], children=[3,5,2]) q = @from i in source_df begin @@ -455,6 +463,18 @@ end @test q["Sally"]==5 @test q["Kirk"]==2 +q = @from i in source_df begin + @let j = i.name + @let k = i.children + @let l = i.age + @select {a=j, b=k, c=l} + @collect DataFrame +end + +@test q.a == ["John", "Sally", "Kirk"] +@test q.b == [3, 5, 2] +@test q.c == [23., 42., 59.] + @test @count(source_df)==3 @test @count(source_df, i->i.children>3)==1