diff --git a/.DS_Store b/.DS_Store index ca5d0e6..c4fd023 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/src/TBD_macros.jl b/src/TBD_macros.jl index 2502761..d2f0a3b 100644 --- a/src/TBD_macros.jl +++ b/src/TBD_macros.jl @@ -191,17 +191,17 @@ macro mutate(sqlquery, mutations...) col_expr = expr_to_sql(expr.args[2], sq) # Ensure you have a function that can handle this conversion # Construct window_clause based on grouping and ordering - partition_clause = !isempty(sq.groupBy) && !isempty(sq.windowFrame) ? "PARTITION BY $(sq.groupBy)" : "" - order_clause = !isempty(sq.window_order) ? "ORDER BY $(sq.window_order)" : "" - frame_clause = !isempty(sq.windowFrame) ? "$(sq.windowFrame)" : "ROWS UNBOUNDED PRECEDING" - window_clause = !isempty(order_clause) || !isempty(partition_clause) ? " OVER ($partition_clause $order_clause $frame_clause)" : "" + # partition_clause = !isempty(sq.groupBy) && !isempty(sq.windowFrame) ? "PARTITION BY $(sq.groupBy)" : "" + # order_clause = !isempty(sq.window_order) ? "ORDER BY $(sq.window_order)" : "" + # frame_clause = !isempty(sq.windowFrame) ? "$(sq.windowFrame)" : "ROWS UNBOUNDED PRECEDING" + # window_clause = !isempty(order_clause) || !isempty(partition_clause) ? " OVER ($partition_clause $order_clause $frame_clause)" : "" if col_name in all_columns # Replace the existing column expression with the mutation - select_expressions[findfirst(==(col_name), select_expressions)] = string(col_expr, window_clause, " AS ", col_name) + select_expressions[findfirst(==(col_name), select_expressions)] = string(col_expr, " AS ", col_name) else # Append the mutation as a new column expression - push!(select_expressions, string(col_expr, window_clause, " AS ", col_name)) + push!(select_expressions, string(col_expr, " AS ", col_name)) # Update metadata to include this new column push!(sq.metadata, Dict("name" => col_name, "type" => "UNKNOWN", "current_selxn" => 1)) end diff --git a/src/db_parsing.jl b/src/db_parsing.jl index f824d35..ed24bf3 100644 --- a/src/db_parsing.jl +++ b/src/db_parsing.jl @@ -342,21 +342,36 @@ function parse_interpolation2(expr) end end end -my_var = "gear" -my_var = :gear -my_val = 3.7 +#my_var = "gear" +#my_var = :gear +#my_val = 3.7 #my_var = [:gear, :cyl] -expr = :((!!my_var) * (!!my_val)) -parse_interpolation2(expr) +#expr = :((!!my_var) * (!!my_val)) +#parse_interpolation2(expr) -expr = :((!!my_val) * (!!my_var)) -parse_interpolation2(expr) +#expr = :((!!my_val) * (!!my_var)) +#parse_interpolation2(expr) function construct_window_clause(sq::SQLQuery) - # This helper function constructs the window function clause based on groupBy and windowFrame settings - partition_clause = !isempty(sq.groupBy) ? "OVER (PARTITION BY $(sq.groupBy))" : "OVER ()" - return partition_clause + # Construct the partition clause, considering both groupBy and window_order + partition_clause = !isempty(sq.groupBy) ? "PARTITION BY $(sq.groupBy)" : "" + if !isempty(sq.window_order) + # If there's already a partition clause, append the order clause; otherwise, start with ORDER BY + order_clause = !isempty(partition_clause) ? ", ORDER BY $(sq.window_order)" : "ORDER BY $(sq.window_order)" + else + order_clause = "" + end + + # Construct the frame clause based on windowFrame, defaulting to "ROWS UNBOUNDED PRECEDING" if not specified + frame_clause = !isempty(sq.windowFrame) ? sq.windowFrame : "ROWS UNBOUNDED PRECEDING" + + # Combine partition, order, and frame clauses for the complete window function clause + # Ensure to include space only when needed to avoid syntax issues + partition_and_order_clause = partition_clause * (!isempty(order_clause) ? " " * order_clause : "") + window_clause = (!isempty(partition_clause) || !isempty(order_clause)) ? "OVER ($partition_and_order_clause $frame_clause)" : "OVER ()" + + return window_clause end function parse_blocks(exprs...) diff --git a/src/fxns.jl b/src/fxns.jl index cdead7d..17a5c95 100644 --- a/src/fxns.jl +++ b/src/fxns.jl @@ -1,67 +1,3 @@ -#module TidierDB -using LibPQ -using DataFrames -using MacroTools -using Chain -using SQLite -using Reexport -using DuckDB -#@reexport using DataFrames: DataFrame, Cols, describe, nrow, proprow, Not, Between, select -#@reexport using Chain -#export start_query_meta, set_sql_mode, @arrange, @group_by, @filter, @select, @mutate, @summarize, @summarise, @distinct, @left_join, @right_join, @inner_join, @count, @window_order, @show_query, @collect, @slice_max, @slice_min, @slice_sample -#include("docstrings.jl") -include("db_parsing.jl") -include("TBD_macros.jl") -include("postgresparsing.jl") -include("joins_sq.jl") -include("slices_sq.jl") - -#@reexport using Chain -mutable struct CTE - name::String - select::String - from::String - where::String - groupBy::String - having::String - # Additional fields as necessary - - # Default constructor - CTE() = new("", "", "", "", "", "") - - # Custom constructor accepting keyword arguments - function CTE(;name::String="", select::String="", from::String="", where::String="", groupBy::String="", having::String="") - new(name, select, from, where, groupBy, having) - end -end - -using DataFrames - -mutable struct SQLQuery - select::String - from::String - where::String - groupBy::String - orderBy::String - having::String - window_order::String - windowFrame::String # New field to store window frame specifications - is_aggregated::Bool - post_aggregation::Bool - metadata::DataFrame - distinct::Bool - db::Any # Change the type from SQLite.DB to Any - ctes::Vector{CTE} - cte_count::Int - - SQLQuery() = new("", "", "", "", "", "", "", "", false, false, DataFrame(), false, nothing, Vector{CTE}(), 0) - - function SQLQuery(;select::String="", from::String="", where::String="", groupBy::String="", orderBy::String="", having::String="", window_order::String="", windowFrame::String="", is_aggregated::Bool=false, post_aggregation::Bool=false, metadata::DataFrame=DataFrame(), distinct::Bool=false, db::Any=nothing, ctes::Vector{CTE}=Vector{CTE}(), cte_count::Int=0) - new(select, from, where, groupBy, orderBy, having, window_order, windowFrame, is_aggregated, post_aggregation, metadata, distinct, db, ctes, cte_count) - end -end - - current_sql_mode = Ref(:lite) # Function to switch modes