Skip to content

Commit 506a9e1

Browse files
authored
Merge pull request #128 from TidierOrg/repl_print
switch to repl print
2 parents dec61c2 + d7f5e05 commit 506a9e1

File tree

6 files changed

+79
-69
lines changed

6 files changed

+79
-69
lines changed

docs/examples/UserGuide/pivoting.jl

Whitespace-only changes.

src/TidierDB.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,15 @@ function copy_to(conn, df_or_path::Union{DataFrame, AbstractString}, name::Strin
325325
DBInterface.execute(conn, "CREATE $rep TABLE $name AS SELECT * FROM $name_view")
326326
DBInterface.execute(conn, "DROP VIEW $name_view ")
327327
# Check for 'group' in column names and warn if found
328+
# COV_EXCL_START
328329
if any(any(lowercase(string(name)) == word for word in sql_words) for name in names(df_or_path))
329330
found_words = [word for word in sql_words if any(lowercase(string(name)) == word for name in names(df_or_path))]
330331
@warn "Column names containing SQL keywords detected: $(join(found_words, ", ")).
331332
These may cause issues as they are reserved SQL keywords.
332333
Consider renaming the columns before copying to DuckDB."
333334
end
334335
end
335-
# COV_EXCL_START
336+
336337
elseif isa(df_or_path, AbstractString)
337338
if current_sql_mode[] != duckdb()
338339
error("Direct file loading is only supported for DuckDB in this implementation.")

src/TidierDB_macros.jl

Lines changed: 70 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ macro filter(sqlquery, conditions...)
5252

5353
if isa(sq, SQLQuery)
5454
if !sq.is_aggregated
55-
if sq.post_join
55+
if sq.post_join || sq.post_mutate
5656
combined_conditions = String[]
5757
for condition in $(esc(conditions))
5858
condition_str = string(expr_to_sql(condition, sq))
@@ -76,7 +76,7 @@ macro filter(sqlquery, conditions...)
7676
sq.where = combined_condition_str
7777
# println(sq.from)
7878
build_cte!(sq)
79-
sq.select = " * "
79+
#sq.select = " * "
8080
end
8181
else
8282
aggregated_columns = Set{String}()
@@ -168,7 +168,8 @@ macro arrange(sqlquery, columns...)
168168
sq = $(esc(sqlquery))
169169
sq = sq.post_first ? t($(esc(sqlquery))) : sq
170170
sq.post_first = false;
171-
sq.orderBy = " ORDER BY " * $order_clause
171+
172+
sq.orderBy = " ORDER BY " * $order_clause
172173
sq
173174
end
174175
end
@@ -360,6 +361,7 @@ macro rename(sqlquery, renamings...)
360361
end
361362

362363
# COV_EXCL_START
364+
# will delete
363365
cyan_crayon = Crayon(foreground = :cyan, bold = true) # for FROM and SELECT
364366
blue_crayon = Crayon(foreground = :blue, bold = true) # for JOINs
365367
yellow_crayon = Crayon(foreground = :yellow, bold = true) # for GROUP BY
@@ -371,64 +373,77 @@ light_gray = Crayon(foreground = :red, bold = true)
371373
green = Crayon(foreground = :green, bold = false)
372374
# COV_EXCL_STOP
373375

376+
mutable struct DBQuery
377+
val::String
378+
end
379+
380+
function Base.show(io::IO, ::MIME"text/plain", mytype::DBQuery)
381+
print(io, mytype.val)
382+
end
374383

375384
macro show_query(sqlquery)
376385
return quote
377-
final_query = finalize_query($(esc(sqlquery)))
378-
379-
formatted_query = replace(final_query, r"(?<=\)), " => ",\n")
380-
formatted_query = replace(formatted_query, "SELECT " => "\nSELECT ")
381-
formatted_query = replace(formatted_query, "AS (SELECT " => "AS ( \n\tSELECT ")
382-
formatted_query = replace(formatted_query, " FROM " => "\n\tFROM ")
383-
formatted_query = replace(formatted_query, " WHERE " => "\n\tWHERE ")
384-
formatted_query = replace(formatted_query, " GROUP BY " => "\n\tGROUP BY ")
385-
formatted_query = replace(formatted_query, " ORDER BY " => "\n\tORDER BY ")
386-
formatted_query = replace(formatted_query, " HAVING " => "\n\tHAVING ")
387-
formatted_query = replace(formatted_query, " LEFT JOIN " => "\n\tLEFT JOIN ")
388-
formatted_query = replace(formatted_query, " RIGHT JOIN " => "\n\tRIGHT JOIN ")
389-
formatted_query = replace(formatted_query, " INNER JOIN " => "\n\tINNER JOIN ")
390-
formatted_query = replace(formatted_query, " OUTER JOIN " => "\n\tOUTER JOIN ")
391-
formatted_query = replace(formatted_query, " ASOF " => "\n\tASOF ")
392-
formatted_query = replace(formatted_query, " LIMIT " => "\n\tLIMIT ")
393-
formatted_query = replace(formatted_query, " ANY_VALUE" => "\n\tANY_VALUE")
394-
395-
pattern = r"\b(cte_\w+|WITH|FROM|SELECT|AS|LEFT|JOIN|RIGHT|OUTER|UNION|INNER|ASOF|GROUP\s+BY|CASE|WHEN|THEN|ELSE|END|WHERE|HAVING|ORDER\s+BY|PARTITION|ASC|DESC|INNER)\b"
396-
# COV_EXCL_START
397-
if TidierDB.color[]
398-
formatted_query = replace(formatted_query, pattern => s -> begin
399-
token = String(s)
400-
token_upper = uppercase(strip(token))
401-
402-
if token_upper in ["FROM", "SELECT", "WITH"]
403-
return $cyan_crayon(token)
404-
elseif token_upper in ["AS"]
405-
return $green(token)
406-
elseif token_upper in ["ASOF", "RIGHT", "LEFT", "OUTER", "SEMI", "JOIN", "INNER"]
407-
return $blue_crayon(token)
408-
elseif occursin(r"^GROUP\s+BY$", token_upper)
409-
return $yellow_crayon(token)
410-
elseif token_upper in ["CASE", "WHEN", "THEN", "ELSE", "END"]
411-
return $orange_crayon(token)
412-
elseif token_upper in ["WHERE", "HAVING"]
413-
return $lightblue_crayon(token)
414-
elseif occursin(r"^ORDER\s+BY$", token_upper)
415-
return $pink_crayon(token)
416-
elseif token_upper in ["ASC", "DESC", "PARTITION"]
417-
return $pink_crayon(token)
418-
# elseif occursin(r"^CTE_\w+$", token_upper)
419-
# return $light_magenta(token)
420-
else
421-
return token
422-
end
423-
end)
424-
end
425-
# COV_EXCL_STOP
426-
println(formatted_query)
386+
final_query = finalize_query($(esc(sqlquery)))
387+
formatted_query = format_sql_query(final_query)
388+
389+
display(DBQuery(formatted_query))
390+
# $(esc(sqlquery));
427391
end
392+
428393
end
429394

430-
431-
395+
# COV_EXCL_START
396+
function format_sql_query(final_query::String)
397+
# Format basic SQL structure with newlines and indentation
398+
formatted_query = replace(final_query, r"(?<=\)), " => ",\n")
399+
formatted_query = replace(formatted_query, "SELECT " => "\nSELECT ")
400+
formatted_query = replace(formatted_query, "AS (SELECT " => "AS ( \n\tSELECT ")
401+
formatted_query = replace(formatted_query, " FROM " => "\n\tFROM ")
402+
formatted_query = replace(formatted_query, " WHERE " => "\n\tWHERE ")
403+
formatted_query = replace(formatted_query, " GROUP BY " => "\n\tGROUP BY ")
404+
formatted_query = replace(formatted_query, " ORDER BY " => "\n\tORDER BY ")
405+
formatted_query = replace(formatted_query, " HAVING " => "\n\tHAVING ")
406+
formatted_query = replace(formatted_query, " LEFT JOIN " => "\n\tLEFT JOIN ")
407+
formatted_query = replace(formatted_query, " RIGHT JOIN " => "\n\tRIGHT JOIN ")
408+
formatted_query = replace(formatted_query, " INNER JOIN " => "\n\tINNER JOIN ")
409+
formatted_query = replace(formatted_query, " OUTER JOIN " => "\n\tOUTER JOIN ")
410+
formatted_query = replace(formatted_query, " ASOF " => "\n\tASOF ")
411+
formatted_query = replace(formatted_query, " LIMIT " => "\n\tLIMIT ")
412+
formatted_query = replace(formatted_query, " ANY_VALUE" => "\n\tANY_VALUE")
413+
414+
# pattern for SQL keywords
415+
pattern = r"\b(cte_\w+|WITH|FROM|SELECT|AS|LEFT|JOIN|RIGHT|OUTER|UNION|INNER|ASOF|GROUP\s+BY|CASE|WHEN|THEN|ELSE|END|WHERE|HAVING|ORDER\s+BY|PARTITION|ASC|DESC|INNER)\b"
416+
417+
if TidierDB.color[]
418+
formatted_query = replace(formatted_query, pattern => s -> begin
419+
token = String(s)
420+
token_upper = uppercase(strip(token))
421+
422+
if token_upper in ["FROM", "SELECT", "WITH"]
423+
"\e[36m$(token)\e[0m" # Cyan
424+
elseif token_upper in ["AS"]
425+
"\e[32m$(token)\e[0m" # Green
426+
elseif token_upper in ["ASOF", "RIGHT", "LEFT", "OUTER", "SEMI", "JOIN", "INNER"]
427+
"\e[34m$(token)\e[0m" # Blue
428+
elseif occursin(r"^GROUP\s+BY$", token_upper)
429+
"\e[33m$(token)\e[0m" # Yellow
430+
elseif token_upper in ["CASE", "WHEN", "THEN", "ELSE", "END"]
431+
"\e[38;5;208m$(token)\e[0m" # Orange
432+
elseif token_upper in ["WHERE", "HAVING"]
433+
"\e[94m$(token)\e[0m" # Light Blue
434+
elseif occursin(r"^ORDER\s+BY$", token_upper)
435+
"\e[35m$(token)\e[0m" # Pink
436+
elseif token_upper in ["ASC", "DESC", "PARTITION"]
437+
"\e[35m$(token)\e[0m" # Pink
438+
else
439+
token
440+
end
441+
end)
442+
end
443+
444+
return formatted_query
445+
end
446+
# COV_EXCL_STOP
432447

433448
function final_collect(sqlquery::SQLQuery, ::Type{<:duckdb})
434449
final_query = finalize_query(sqlquery)
@@ -489,7 +504,6 @@ $docstring_collect
489504
"""
490505
macro collect(sqlquery, stream = false)
491506
return quote
492-
493507
backend = current_sql_mode[]
494508
if backend == duckdb()
495509
if $stream

src/mutate_and_summ.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ macro mutate(sqlquery, mutations...)
119119
sq = $(esc(sqlquery))
120120
sq = sq.post_first ? t($(esc(sqlquery))) : sq
121121
sq.post_first = false;
122-
122+
sq.post_mutate = true
123123
if isa(sq, SQLQuery)
124124
cte_name = "cte_" * string(sq.cte_count + 1)
125125

src/structs.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ mutable struct SQLQuery
3333
ch_settings::String
3434
join_count::Int
3535
post_unnest::Bool
36+
post_mutate::Bool
3637
function SQLQuery(;post_first = true, select::String="", from::String="", where::String="", groupBy::String="", orderBy::String="", having::String="",
3738
window_order::String="", windowFrame::String="", is_aggregated::Bool=false, post_aggregation::Bool=false, post_join::Bool=false, metadata::DataFrame=DataFrame(),
3839
distinct::Bool=false, db::Any=nothing, ctes::Vector{CTE}=Vector{CTE}(), cte_count::Int=0, athena_params::Any=nothing, limit::String="",
39-
ch_settings::String="", join_count::Int = 0, post_unnest::Bool = false)
40+
ch_settings::String="", join_count::Int = 0, post_unnest::Bool = false, post_mutate::Bool = false)
4041
new(post_first, select, from, where, groupBy, orderBy, having, window_order, windowFrame, is_aggregated,
41-
post_aggregation, post_join, metadata, distinct, db, ctes, cte_count, athena_params, limit, ch_settings, join_count, post_unnest)
42+
post_aggregation, post_join, metadata, distinct, db, ctes, cte_count, athena_params, limit, ch_settings, join_count, post_unnest, post_mutate)
4243
end
4344
end
4445

src/union_intersect_setdiff.jl

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,8 @@ function perform_set_operation(sq::SQLQuery, uq_or_table, op::String; all::Bool=
99
# 1) Possibly create a new CTE for the left query (sq)
1010
needs_new_cte_sq = !isempty(sq.select) || !isempty(sq.where) || sq.is_aggregated || !isempty(sq.ctes)
1111
if needs_new_cte_sq
12-
sq.cte_count += 1
13-
cte_name_sq = "cte_" * string(sq.cte_count)
14-
most_recent_source_sq = !isempty(sq.ctes) ? "cte_" * string(sq.cte_count - 1) : sq.from
15-
select_sql_sq = "SELECT * FROM " * most_recent_source_sq
16-
new_cte_sq = CTE(name=cte_name_sq, select=select_sql_sq)
17-
up_cte_name(sq, cte_name_sq)
18-
19-
push!(sq.ctes, new_cte_sq)
20-
sq.from = cte_name_sq
12+
build_cte!(sq)
13+
# sq.from = cte_name_sq
2114
end
2215

2316
local op_clause
@@ -45,6 +38,7 @@ function perform_set_operation(sq::SQLQuery, uq_or_table, op::String; all::Bool=
4538
new_cte_uq = CTE(name=cte_name_uq, select=select_sql_uq)
4639
push!(uq.ctes, new_cte_uq)
4740
uq.from = cte_name_uq
41+
# uq.where = ""
4842
end
4943

5044
# Combine

0 commit comments

Comments
 (0)