-module(galchemy@sql@compiler). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src\\galchemy\\sql\\compiler.gleam"). -export([default_config/0, compile_select_with/2, compile_select/1, compile_insert_with/2, compile_insert/1, compile_update_with/2, compile_update/1, compile_delete_with/2, compile_with/2, compile/1, compile_delete/1]). -export_type([compiled_query/0, compile_error/0, compiler_config/0, compile_state/0]). -type compiled_query() :: {compiled_query, binary(), list(galchemy@ast@expression:sql_value())}. -type compile_error() :: missing_from | empty_in_list | empty_insert_values | empty_update_assignments | inconsistent_insert_row_shape | having_without_group_by | {invalid_function_name, binary()} | {invalid_limit, integer()} | {invalid_offset, integer()}. -type compiler_config() :: {compiler_config, fun((binary()) -> binary()), fun((binary()) -> {ok, binary()} | {error, compile_error()})}. -type compile_state() :: {compile_state, integer(), list(galchemy@ast@expression:sql_value()), compiler_config()}. -file("src\\galchemy\\sql\\compiler.gleam", 40). -spec result_try( {ok, HAO} | {error, HAP}, fun((HAO) -> {ok, HAS} | {error, HAP}) ) -> {ok, HAS} | {error, HAP}. result_try(Result, Next) -> case Result of {ok, Value} -> Next(Value); {error, Error} -> {error, Error} end. -file("src\\galchemy\\sql\\compiler.gleam", 54). -spec new_state(compiler_config()) -> compile_state(). new_state(Config) -> {compile_state, 1, [], Config}. -file("src\\galchemy\\sql\\compiler.gleam", 456). -spec same_insert_shape( list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}), list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}) ) -> boolean(). same_insert_shape(One, Other) -> case {One, Other} of {[], []} -> true; {[{Left_column, _} | Left_rest], [{Right_column, _} | Right_rest]} -> (Left_column =:= Right_column) andalso same_insert_shape( Left_rest, Right_rest ); {_, _} -> false end. -file("src\\galchemy\\sql\\compiler.gleam", 632). -spec push_param(galchemy@ast@expression:sql_value(), compile_state()) -> {binary(), compile_state()}. push_param(Value, State) -> Placeholder = <<"$"/utf8, (erlang:integer_to_binary(erlang:element(2, State)))/binary>>, Next_state = {compile_state, erlang:element(2, State) + 1, [Value | erlang:element(3, State)], erlang:element(4, State)}, {Placeholder, Next_state}. -file("src\\galchemy\\sql\\compiler.gleam", 899). -spec compile_limit(gleam@option:option(integer())) -> {ok, binary()} | {error, compile_error()}. compile_limit(Limit) -> case Limit of none -> {ok, <<""/utf8>>}; {some, V} -> case V < 0 of true -> {error, {invalid_limit, V}}; false -> {ok, <<" LIMIT "/utf8, (erlang:integer_to_binary(V))/binary>>} end end. -file("src\\galchemy\\sql\\compiler.gleam", 911). -spec compile_offset(gleam@option:option(integer())) -> {ok, binary()} | {error, compile_error()}. compile_offset(Offset) -> case Offset of none -> {ok, <<""/utf8>>}; {some, V} -> case V < 0 of true -> {error, {invalid_offset, V}}; false -> {ok, <<" OFFSET "/utf8, (erlang:integer_to_binary(V))/binary>>} end end. -file("src\\galchemy\\sql\\compiler.gleam", 968). -spec compile_identifier(binary(), compiler_config()) -> binary(). compile_identifier(Identifier, Config) -> {compiler_config, Render_identifier, _} = Config, Render_identifier(Identifier). -file("src\\galchemy\\sql\\compiler.gleam", 923). -spec compile_table_ref(galchemy@ast@schema:table(), compiler_config()) -> binary(). compile_table_ref(Table, Config) -> {table, Schema_name, Name, Alias} = Table, Qualified_name = case Schema_name of none -> compile_identifier(Name, Config); {some, Schema_name@1} -> <<<<(compile_identifier(Schema_name@1, Config))/binary, "."/utf8>>/binary, (compile_identifier(Name, Config))/binary>> end, case Alias of none -> Qualified_name; {some, A} -> <<<>/binary, (compile_identifier(A, Config))/binary>> end. -file("src\\galchemy\\sql\\compiler.gleam", 939). -spec compile_column_ref(galchemy@ast@schema:column_meta(), compiler_config()) -> binary(). compile_column_ref(Column, Config) -> {column_meta, Table, Column_name} = Column, {table, Schema_name, Table_name, Alias} = Table, Qualifier = case Alias of none -> case Schema_name of none -> compile_identifier(Table_name, Config); {some, Schema_name@1} -> <<<<(compile_identifier(Schema_name@1, Config))/binary, "."/utf8>>/binary, (compile_identifier(Table_name, Config))/binary>> end; {some, A} -> compile_identifier(A, Config) end, <<<>/binary, (compile_identifier(Column_name, Config))/binary>>. -file("src\\galchemy\\sql\\compiler.gleam", 960). -spec compile_column_name(galchemy@ast@schema:column_meta(), compiler_config()) -> binary(). compile_column_name(Column, Config) -> {column_meta, _, Name} = Column, compile_identifier(Name, Config). -file("src\\galchemy\\sql\\compiler.gleam", 976). -spec compile_function_name(binary(), compiler_config()) -> {ok, binary()} | {error, compile_error()}. compile_function_name(Name, Config) -> {compiler_config, _, Validate_function_name} = Config, Validate_function_name(Name). -file("src\\galchemy\\sql\\compiler.gleam", 987). -spec default_render_identifier(binary()) -> binary(). default_render_identifier(Identifier) -> <<<<"\""/utf8, (gleam@string:replace(Identifier, <<"\""/utf8>>, <<"\"\""/utf8>>))/binary>>/binary, "\""/utf8>>. -file("src\\galchemy\\sql\\compiler.gleam", 991). -spec default_validate_function_name(binary()) -> {ok, binary()} | {error, compile_error()}. default_validate_function_name(Name) -> case gleam@string:is_empty(Name) of true -> {error, {invalid_function_name, Name}}; false -> {ok, Name} end. -file("src\\galchemy\\sql\\compiler.gleam", 47). -spec default_config() -> compiler_config(). default_config() -> {compiler_config, fun default_render_identifier/1, fun default_validate_function_name/1}. -file("src\\galchemy\\sql\\compiler.gleam", 998). -spec op_to_sql(galchemy@ast@expression:comparison_op()) -> binary(). op_to_sql(Op) -> case Op of eq -> <<"="/utf8>>; neq -> <<"!="/utf8>>; gt -> <<">"/utf8>>; gte -> <<">="/utf8>>; lt -> <<"<"/utf8>>; lte -> <<"<="/utf8>> end. -file("src\\galchemy\\sql\\compiler.gleam", 1009). -spec unary_operator_to_sql(galchemy@ast@expression:unary_operator()) -> binary(). unary_operator_to_sql(Operator) -> case Operator of negate -> <<"-"/utf8>> end. -file("src\\galchemy\\sql\\compiler.gleam", 1015). -spec binary_operator_to_sql(galchemy@ast@expression:binary_operator()) -> binary(). binary_operator_to_sql(Operator) -> case Operator of add -> <<"+"/utf8>>; subtract -> <<"-"/utf8>>; multiply -> <<"*"/utf8>>; divide -> <<"/"/utf8>>; concat -> <<"||"/utf8>> end. -file("src\\galchemy\\sql\\compiler.gleam", 1032). -spec join_strings_loop(list(binary()), binary(), binary()) -> binary(). join_strings_loop(Parts, Acc, Sep) -> case Parts of [] -> Acc; [Part | Rest] -> join_strings_loop( Rest, <<<>/binary, Part/binary>>, Sep ) end. -file("src\\galchemy\\sql\\compiler.gleam", 1025). -spec join_strings(list(binary()), binary()) -> binary(). join_strings(Parts, Sep) -> case Parts of [] -> <<""/utf8>>; [First | Rest] -> join_strings_loop(Rest, First, Sep) end. -file("src\\galchemy\\sql\\compiler.gleam", 1039). -spec concat_strings(list(binary())) -> binary(). concat_strings(Parts) -> case Parts of [] -> <<""/utf8>>; [P | Rest] -> <

> end. -file("src\\galchemy\\sql\\compiler.gleam", 1050). -spec reverse_loop(list(HGL), list(HGL)) -> list(HGL). reverse_loop(Items, Acc) -> case Items of [] -> Acc; [X | Xs] -> reverse_loop(Xs, [X | Acc]) end. -file("src\\galchemy\\sql\\compiler.gleam", 1046). -spec reverse(list(HGI)) -> list(HGI). reverse(Items) -> reverse_loop(Items, []). -file("src\\galchemy\\sql\\compiler.gleam", 58). -spec finalize(binary(), compile_state()) -> compiled_query(). finalize(Sql, State) -> {compiled_query, Sql, reverse(erlang:element(3, State))}. -file("src\\galchemy\\sql\\compiler.gleam", 276). -spec compile_ctes_loop( list(galchemy@ast@expression:cte()), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_ctes_loop(Ctes, Acc, State) -> case Ctes of [] -> {ok, {join_strings(reverse(Acc), <<", "/utf8>>), State}}; [Cte | Rest] -> {cte, Name, Cte_query} = Cte, result_try( compile_select_query(Cte_query, State), fun(_use0) -> {Cte_sql, Next_state} = _use0, Next_item = <<<<<<(compile_identifier( Name, erlang:element(4, State) ))/binary, " AS ("/utf8>>/binary, Cte_sql/binary>>/binary, ")"/utf8>>, compile_ctes_loop(Rest, [Next_item | Acc], Next_state) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 93). -spec compile_select_query( galchemy@ast@expression:select_query(), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_select_query(Q, State) -> {select_query, Ctes, Items, From, Joins, Where_, Group_by, Having_, Unions, Order_by, Limit, Offset, Distinct} = Q, case From of none -> {error, missing_from}; {some, Source} -> result_try( compile_ctes(Ctes, State), fun(_use0) -> {Ctes_sql, State1} = _use0, result_try( compile_select_items(Items, State1), fun(_use0@1) -> {Items_sql, State2} = _use0@1, result_try( compile_source(Source, State2), fun(_use0@2) -> {From_sql, State3} = _use0@2, result_try( compile_joins(Joins, State3), fun(_use0@3) -> {Joins_sql, State4} = _use0@3, result_try( compile_where(Where_, State4), fun(_use0@4) -> {Where_sql, State5} = _use0@4, result_try( compile_group_by( Group_by, State5 ), fun(_use0@5) -> {Group_by_sql, State6} = _use0@5, result_try( compile_having( Group_by, Having_, State6 ), fun(_use0@6) -> {Having_sql, State7} = _use0@6, result_try( compile_order_by( Order_by, State7 ), fun( _use0@7 ) -> {Order_sql, State8} = _use0@7, result_try( compile_limit( Limit ), fun( Limit_sql ) -> result_try( compile_offset( Offset ), fun( Offset_sql ) -> result_try( compile_set_operations( Unions, State8 ), fun( _use0@8 ) -> {Unions_sql, State9} = _use0@8, Distinct_sql = case Distinct of true -> <<"DISTINCT "/utf8>>; false -> <<""/utf8>> end, Base_sql = <<<<<<<<<<<<<<<<<<<<<<"SELECT "/utf8, Distinct_sql/binary>>/binary, Items_sql/binary>>/binary, " FROM "/utf8>>/binary, From_sql/binary>>/binary, Joins_sql/binary>>/binary, Where_sql/binary>>/binary, Group_by_sql/binary>>/binary, Having_sql/binary>>/binary, Order_sql/binary>>/binary, Limit_sql/binary>>/binary, Offset_sql/binary>>, {ok, {<<<>/binary, Unions_sql/binary>>, State9}} end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 259). -spec compile_ctes(list(galchemy@ast@expression:cte()), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_ctes(Ctes, State) -> case Ctes of [] -> {ok, {<<""/utf8>>, State}}; _ -> result_try( compile_ctes_loop(Ctes, [], State), fun(_use0) -> {Ctes_sql, Next_state} = _use0, {ok, {<<<<"WITH "/utf8, Ctes_sql/binary>>/binary, " "/utf8>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 84). -spec compile_select_with( galchemy@ast@expression:select_query(), compiler_config() ) -> {ok, compiled_query()} | {error, compile_error()}. compile_select_with(Q, Config) -> State0 = new_state(Config), result_try( compile_select_query(Q, State0), fun(_use0) -> {Sql, State1} = _use0, {ok, finalize(Sql, State1)} end ). -file("src\\galchemy\\sql\\compiler.gleam", 78). -spec compile_select(galchemy@ast@expression:select_query()) -> {ok, compiled_query()} | {error, compile_error()}. compile_select(Q) -> compile_select_with(Q, default_config()). -file("src\\galchemy\\sql\\compiler.gleam", 303). -spec compile_set_operations_loop( list(galchemy@ast@expression:set_operation()), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_set_operations_loop(Operations, Acc, State) -> case Operations of [] -> {ok, {concat_strings(reverse(Acc)), State}}; [Operation | Rest] -> {set_operation, Kind, Union_query} = Operation, Operator_sql = case Kind of union -> <<" UNION "/utf8>>; union_all -> <<" UNION ALL "/utf8>> end, result_try( compile_select_query(Union_query, State), fun(_use0) -> {Union_sql, Next_state} = _use0, compile_set_operations_loop( Rest, [<> | Acc], Next_state ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 296). -spec compile_set_operations( list(galchemy@ast@expression:set_operation()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_set_operations(Operations, State) -> compile_set_operations_loop(Operations, [], State). -file("src\\galchemy\\sql\\compiler.gleam", 646). -spec compile_source(galchemy@ast@expression:source(), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_source(Source, State) -> case Source of {table_source, Table} -> {ok, {compile_table_ref(Table, erlang:element(4, State)), State}}; {derived_source, Derived_query, Alias} -> result_try( compile_select_query(Derived_query, State), fun(_use0) -> {Query_sql, Next_state} = _use0, {ok, {<<<<<<"("/utf8, Query_sql/binary>>/binary, ") AS "/utf8>>/binary, (compile_identifier( Alias, erlang:element(4, State) ))/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 790). -spec compile_order_item(galchemy@ast@expression:order(), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_order_item(Item, State) -> {order, Expr, Direction} = Item, result_try( compile_expression(Expr, State), fun(_use0) -> {Expr_sql, State1} = _use0, Dir_sql = case Direction of asc -> <<"ASC"/utf8>>; desc -> <<"DESC"/utf8>> end, {ok, {<<<>/binary, Dir_sql/binary>>, State1}} end ). -file("src\\galchemy\\sql\\compiler.gleam", 511). -spec compile_expression(galchemy@ast@expression:expression(), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_expression(Expr, State) -> case Expr of {column_expr, Meta} -> {ok, {compile_column_ref(Meta, erlang:element(4, State)), State}}; {value_expr, null} -> {ok, {<<"NULL"/utf8>>, State}}; star_expr -> {ok, {<<"*"/utf8>>, State}}; {function_expr, Name, Arguments} -> result_try( compile_function_name(Name, erlang:element(4, State)), fun(Function_name) -> result_try( compile_expression_list(Arguments, State), fun(_use0) -> {Arguments_sql, Next_state} = _use0, {ok, {<<<<<>/binary, Arguments_sql/binary>>/binary, ")"/utf8>>, Next_state}} end ) end ); {unary_op_expr, Operator, Operand} -> result_try( compile_expression(Operand, State), fun(_use0@1) -> {Operand_sql, Next_state@1} = _use0@1, {ok, {<<<<<<"("/utf8, (unary_operator_to_sql(Operator))/binary>>/binary, Operand_sql/binary>>/binary, ")"/utf8>>, Next_state@1}} end ); {binary_op_expr, Lhs, Operator@1, Rhs} -> result_try( compile_expression(Lhs, State), fun(_use0@2) -> {Lhs_sql, State1} = _use0@2, result_try( compile_expression(Rhs, State1), fun(_use0@3) -> {Rhs_sql, State2} = _use0@3, {ok, {<<<<<<<<<<<<"("/utf8, Lhs_sql/binary>>/binary, " "/utf8>>/binary, (binary_operator_to_sql( Operator@1 ))/binary>>/binary, " "/utf8>>/binary, Rhs_sql/binary>>/binary, ")"/utf8>>, State2}} end ) end ); {window_expr, Function, Window} -> result_try( compile_expression(Function, State), fun(_use0@4) -> {Function_sql, State1@1} = _use0@4, result_try( compile_window_definition(Window, State1@1), fun(_use0@5) -> {Window_sql, State2@1} = _use0@5, {ok, {<<<<<>/binary, Window_sql/binary>>/binary, ")"/utf8>>, State2@1}} end ) end ); {subquery_expr, Select_query} -> result_try( compile_select_query(Select_query, State), fun(_use0@6) -> {Subquery_sql, Next_state@2} = _use0@6, {ok, {<<<<"("/utf8, Subquery_sql/binary>>/binary, ")"/utf8>>, Next_state@2}} end ); {value_expr, Value} -> {Placeholder, Next_state@3} = push_param(Value, State), {ok, {Placeholder, Next_state@3}} end. -file("src\\galchemy\\sql\\compiler.gleam", 577). -spec compile_window_definition( galchemy@ast@expression:window_definition(), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_window_definition(Window, State) -> {window_definition, Partition_by, Order_by} = Window, result_try( compile_window_partition(Partition_by, State), fun(_use0) -> {Partition_sql, State1} = _use0, result_try( compile_window_order(Order_by, State1), fun(_use0@1) -> {Order_sql, State2} = _use0@1, case {Partition_sql, Order_sql} of {<<""/utf8>>, <<""/utf8>>} -> {ok, {<<""/utf8>>, State2}}; {<<""/utf8>>, _} -> {ok, {Order_sql, State2}}; {_, <<""/utf8>>} -> {ok, {Partition_sql, State2}}; {_, _} -> {ok, {<<<>/binary, Order_sql/binary>>, State2}} end end ) end ). -file("src\\galchemy\\sql\\compiler.gleam", 616). -spec compile_window_order( list(galchemy@ast@expression:order()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_window_order(Order_by, State) -> case Order_by of [] -> {ok, {<<""/utf8>>, State}}; _ -> result_try( compile_order_items(Order_by, State), fun(_use0) -> {Order_sql, Next_state} = _use0, {ok, {<<"ORDER BY "/utf8, Order_sql/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 769). -spec compile_order_items( list(galchemy@ast@expression:order()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_order_items(Items, State) -> compile_order_items_loop(Items, [], State). -file("src\\galchemy\\sql\\compiler.gleam", 776). -spec compile_order_items_loop( list(galchemy@ast@expression:order()), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_order_items_loop(Items, Acc, State) -> case Items of [] -> {ok, {join_strings(reverse(Acc), <<", "/utf8>>), State}}; [Item | Rest] -> result_try( compile_order_item(Item, State), fun(_use0) -> {Item_sql, Next_state} = _use0, compile_order_items_loop(Rest, [Item_sql | Acc], Next_state) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 355). -spec compile_select_item( galchemy@ast@expression:select_item(), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_select_item(Item, State) -> {select_item, Expr, Alias} = Item, result_try( compile_expression(Expr, State), fun(_use0) -> {Expr_sql, State1} = _use0, Sql = case Alias of none -> Expr_sql; {some, A} -> <<<>/binary, (compile_identifier(A, erlang:element(4, State)))/binary>> end, {ok, {Sql, State1}} end ). -file("src\\galchemy\\sql\\compiler.gleam", 341). -spec compile_select_items_loop( list(galchemy@ast@expression:select_item()), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_select_items_loop(Items, Acc, State) -> case Items of [] -> {ok, {join_strings(reverse(Acc), <<", "/utf8>>), State}}; [Item | Rest] -> result_try( compile_select_item(Item, State), fun(_use0) -> {Item_sql, Next_state} = _use0, compile_select_items_loop( Rest, [Item_sql | Acc], Next_state ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 331). -spec compile_select_items( list(galchemy@ast@expression:select_item()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_select_items(Items, State) -> case Items of [] -> {ok, {<<"*"/utf8>>, State}}; _ -> compile_select_items_loop(Items, [], State) end. -file("src\\galchemy\\sql\\compiler.gleam", 431). -spec compile_insert_row_loop( list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}), list(binary()), list(binary()), compile_state() ) -> {ok, {binary(), binary(), compile_state()}} | {error, compile_error()}. compile_insert_row_loop(Row, Columns_acc, Values_acc, State) -> case Row of [] -> Columns_sql = join_strings(reverse(Columns_acc), <<", "/utf8>>), Values_sql = join_strings(reverse(Values_acc), <<", "/utf8>>), {ok, {Columns_sql, <<<<"("/utf8, Values_sql/binary>>/binary, ")"/utf8>>, State}}; [{Column, Expr} | Rest] -> result_try( compile_expression(Expr, State), fun(_use0) -> {Expr_sql, Next_state} = _use0, Column_sql = compile_column_name( Column, erlang:element(4, State) ), compile_insert_row_loop( Rest, [Column_sql | Columns_acc], [Expr_sql | Values_acc], Next_state ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 424). -spec compile_insert_row( list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}), compile_state() ) -> {ok, {binary(), binary(), compile_state()}} | {error, compile_error()}. compile_insert_row(Row, State) -> compile_insert_row_loop(Row, [], [], State). -file("src\\galchemy\\sql\\compiler.gleam", 396). -spec compile_insert_rows_loop( list(list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()})), list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}), list(binary()), compile_state() ) -> {ok, {list(binary()), compile_state()}} | {error, compile_error()}. compile_insert_rows_loop(Rows, First_row, Acc, State) -> case Rows of [] -> {ok, {Acc, State}}; [Row | Rest] -> case same_insert_shape(First_row, Row) of false -> {error, inconsistent_insert_row_shape}; true -> result_try( compile_insert_row(Row, State), fun(_use0) -> {_, Row_sql, Next_state} = _use0, compile_insert_rows_loop( Rest, First_row, lists:append(Acc, [Row_sql]), Next_state ) end ) end end. -file("src\\galchemy\\sql\\compiler.gleam", 370). -spec compile_insert_rows( list(list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()})), compile_state() ) -> {ok, {binary(), binary(), compile_state()}} | {error, compile_error()}. compile_insert_rows(Rows, State) -> case Rows of [] -> {error, empty_insert_values}; [First_row | Rest_rows] -> case First_row of [] -> {error, empty_insert_values}; _ -> result_try( compile_insert_row(First_row, State), fun(_use0) -> {Columns_sql, First_row_sql, State1} = _use0, result_try( compile_insert_rows_loop( Rest_rows, First_row, [First_row_sql], State1 ), fun(_use0@1) -> {Rest_rows_sql, State2} = _use0@1, {ok, {Columns_sql, join_strings( Rest_rows_sql, <<", "/utf8>> ), State2}} end ) end ) end end. -file("src\\galchemy\\sql\\compiler.gleam", 478). -spec compile_assignments_loop( list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_assignments_loop(Assignments, Acc, State) -> case Assignments of [] -> {ok, {join_strings(reverse(Acc), <<", "/utf8>>), State}}; [{Column, Expr} | Rest] -> result_try( compile_expression(Expr, State), fun(_use0) -> {Expr_sql, Next_state} = _use0, Assignment_sql = <<<<(compile_column_name( Column, erlang:element(4, State) ))/binary, " = "/utf8>>/binary, Expr_sql/binary>>, compile_assignments_loop( Rest, [Assignment_sql | Acc], Next_state ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 468). -spec compile_assignments( list({galchemy@ast@schema:column_meta(), galchemy@ast@expression:expression()}), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_assignments(Assignments, State) -> case Assignments of [] -> {error, empty_update_assignments}; _ -> compile_assignments_loop(Assignments, [], State) end. -file("src\\galchemy\\sql\\compiler.gleam", 494). -spec compile_returning( list(galchemy@ast@expression:select_item()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_returning(Returning, State) -> case Returning of [] -> {ok, {<<""/utf8>>, State}}; _ -> result_try( compile_select_items_loop(Returning, [], State), fun(_use0) -> {Items_sql, Next_state} = _use0, {ok, {<<" RETURNING "/utf8, Items_sql/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 167). -spec compile_insert_with(galchemy@ast@query:insert_query(), compiler_config()) -> {ok, compiled_query()} | {error, compile_error()}. compile_insert_with(Q, Config) -> {insert_query, Table, Rows, Returning} = Q, State0 = new_state(Config), result_try( compile_insert_rows(Rows, State0), fun(_use0) -> {Columns_sql, Rows_sql, State1} = _use0, result_try( compile_returning(Returning, State1), fun(_use0@1) -> {Returning_sql, State2} = _use0@1, Sql = <<<<<<<<<<<<"INSERT INTO "/utf8, (compile_table_ref( Table, erlang:element(4, State0) ))/binary>>/binary, " ("/utf8>>/binary, Columns_sql/binary>>/binary, ") VALUES "/utf8>>/binary, Rows_sql/binary>>/binary, Returning_sql/binary>>, {ok, finalize(Sql, State2)} end ) end ). -file("src\\galchemy\\sql\\compiler.gleam", 161). -spec compile_insert(galchemy@ast@query:insert_query()) -> {ok, compiled_query()} | {error, compile_error()}. compile_insert(Q) -> compile_insert_with(Q, default_config()). -file("src\\galchemy\\sql\\compiler.gleam", 753). -spec compile_order_by(list(galchemy@ast@expression:order()), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_order_by(Order_by, State) -> case Order_by of [] -> {ok, {<<""/utf8>>, State}}; _ -> result_try( compile_order_items(Order_by, State), fun(_use0) -> {Items_sql, Next_state} = _use0, {ok, {<<" ORDER BY "/utf8, Items_sql/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 885). -spec compile_expression_list_loop( list(galchemy@ast@expression:expression()), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_expression_list_loop(Exprs, Acc, State) -> case Exprs of [] -> {ok, {join_strings(reverse(Acc), <<", "/utf8>>), State}}; [Expr | Rest] -> result_try( compile_expression(Expr, State), fun(_use0) -> {Expr_sql, Next_state} = _use0, compile_expression_list_loop( Rest, [Expr_sql | Acc], Next_state ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 878). -spec compile_expression_list( list(galchemy@ast@expression:expression()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_expression_list(Exprs, State) -> compile_expression_list_loop(Exprs, [], State). -file("src\\galchemy\\sql\\compiler.gleam", 600). -spec compile_window_partition( list(galchemy@ast@expression:expression()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_window_partition(Partition_by, State) -> case Partition_by of [] -> {ok, {<<""/utf8>>, State}}; _ -> result_try( compile_expression_list(Partition_by, State), fun(_use0) -> {Partition_sql, Next_state} = _use0, {ok, {<<"PARTITION BY "/utf8, Partition_sql/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 715). -spec compile_group_by( list(galchemy@ast@expression:expression()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_group_by(Group_by, State) -> case Group_by of [] -> {ok, {<<""/utf8>>, State}}; _ -> result_try( compile_expression_list(Group_by, State), fun(_use0) -> {Items_sql, Next_state} = _use0, {ok, {<<" GROUP BY "/utf8, Items_sql/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 803). -spec compile_predicate(galchemy@ast@expression:predicate(), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_predicate(Pred, State) -> case Pred of {comparison, Lhs, Op, Rhs} -> result_try( compile_expression(Lhs, State), fun(_use0) -> {Lhs_sql, State1} = _use0, result_try( compile_expression(Rhs, State1), fun(_use0@1) -> {Rhs_sql, State2} = _use0@1, {ok, {<<<<<<<<<<<<"("/utf8, Lhs_sql/binary>>/binary, " "/utf8>>/binary, (op_to_sql(Op))/binary>>/binary, " "/utf8>>/binary, Rhs_sql/binary>>/binary, ")"/utf8>>, State2}} end ) end ); {'and', Left, Right} -> result_try( compile_predicate(Left, State), fun(_use0@2) -> {Left_sql, State1@1} = _use0@2, result_try( compile_predicate(Right, State1@1), fun(_use0@3) -> {Right_sql, State2@1} = _use0@3, {ok, {<<<<<<<<"("/utf8, Left_sql/binary>>/binary, " AND "/utf8>>/binary, Right_sql/binary>>/binary, ")"/utf8>>, State2@1}} end ) end ); {'or', Left@1, Right@1} -> result_try( compile_predicate(Left@1, State), fun(_use0@4) -> {Left_sql@1, State1@2} = _use0@4, result_try( compile_predicate(Right@1, State1@2), fun(_use0@5) -> {Right_sql@1, State2@2} = _use0@5, {ok, {<<<<<<<<"("/utf8, Left_sql@1/binary>>/binary, " OR "/utf8>>/binary, Right_sql@1/binary>>/binary, ")"/utf8>>, State2@2}} end ) end ); {'not', Inner} -> result_try( compile_predicate(Inner, State), fun(_use0@6) -> {Inner_sql, State1@3} = _use0@6, {ok, {<<<<"(NOT "/utf8, Inner_sql/binary>>/binary, ")"/utf8>>, State1@3}} end ); {in_list, Lhs@1, Rhs@1} -> case Rhs@1 of [] -> {error, empty_in_list}; _ -> result_try( compile_expression(Lhs@1, State), fun(_use0@7) -> {Lhs_sql@1, State1@4} = _use0@7, result_try( compile_expression_list(Rhs@1, State1@4), fun(_use0@8) -> {Rhs_sql@1, State2@3} = _use0@8, {ok, {<<<<<<<<"("/utf8, Lhs_sql@1/binary>>/binary, " IN ("/utf8>>/binary, Rhs_sql@1/binary>>/binary, "))"/utf8>>, State2@3}} end ) end ) end; {in_subquery, Lhs@2, Rhs@2} -> result_try( compile_expression(Lhs@2, State), fun(_use0@9) -> {Lhs_sql@2, State1@5} = _use0@9, result_try( compile_select_query(Rhs@2, State1@5), fun(_use0@10) -> {Rhs_sql@2, State2@4} = _use0@10, {ok, {<<<<<<<<"("/utf8, Lhs_sql@2/binary>>/binary, " IN ("/utf8>>/binary, Rhs_sql@2/binary>>/binary, "))"/utf8>>, State2@4}} end ) end ); {is_null, Expr} -> result_try( compile_expression(Expr, State), fun(_use0@11) -> {Expr_sql, State1@6} = _use0@11, {ok, {<<<<"("/utf8, Expr_sql/binary>>/binary, " IS NULL)"/utf8>>, State1@6}} end ); {is_not_null, Expr@1} -> result_try( compile_expression(Expr@1, State), fun(_use0@12) -> {Expr_sql@1, State1@7} = _use0@12, {ok, {<<<<"("/utf8, Expr_sql@1/binary>>/binary, " IS NOT NULL)"/utf8>>, State1@7}} end ); {like, Lhs@3, Rhs@3} -> result_try( compile_expression(Lhs@3, State), fun(_use0@13) -> {Lhs_sql@3, State1@8} = _use0@13, result_try( compile_expression(Rhs@3, State1@8), fun(_use0@14) -> {Rhs_sql@3, State2@5} = _use0@14, {ok, {<<<<<<<<"("/utf8, Lhs_sql@3/binary>>/binary, " LIKE "/utf8>>/binary, Rhs_sql@3/binary>>/binary, ")"/utf8>>, State2@5}} end ) end ); {ilike, Lhs@4, Rhs@4} -> result_try( compile_expression(Lhs@4, State), fun(_use0@15) -> {Lhs_sql@4, State1@9} = _use0@15, result_try( compile_expression(Rhs@4, State1@9), fun(_use0@16) -> {Rhs_sql@4, State2@6} = _use0@16, {ok, {<<<<<<<<"("/utf8, Lhs_sql@4/binary>>/binary, " ILIKE "/utf8>>/binary, Rhs_sql@4/binary>>/binary, ")"/utf8>>, State2@6}} end ) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 687). -spec compile_join(galchemy@ast@expression:join(), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_join(J, State) -> {join, Kind, Source, On} = J, Kind_sql = case Kind of inner_join -> <<" INNER JOIN "/utf8>>; left_join -> <<" LEFT JOIN "/utf8>> end, result_try( compile_source(Source, State), fun(_use0) -> {Source_sql, State1} = _use0, result_try( compile_predicate(On, State1), fun(_use0@1) -> {On_sql, State2} = _use0@1, {ok, {<<<<<>/binary, " ON "/utf8>>/binary, On_sql/binary>>, State2}} end ) end ). -file("src\\galchemy\\sql\\compiler.gleam", 673). -spec compile_joins_loop( list(galchemy@ast@expression:join()), list(binary()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_joins_loop(Joins, Acc, State) -> case Joins of [] -> {ok, {concat_strings(reverse(Acc)), State}}; [J | Rest] -> result_try( compile_join(J, State), fun(_use0) -> {Join_sql, Next_state} = _use0, compile_joins_loop(Rest, [Join_sql | Acc], Next_state) end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 666). -spec compile_joins(list(galchemy@ast@expression:join()), compile_state()) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_joins(Joins, State) -> compile_joins_loop(Joins, [], State). -file("src\\galchemy\\sql\\compiler.gleam", 702). -spec compile_where( gleam@option:option(galchemy@ast@expression:predicate()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_where(Where_, State) -> case Where_ of none -> {ok, {<<""/utf8>>, State}}; {some, Pred} -> result_try( compile_predicate(Pred, State), fun(_use0) -> {Pred_sql, Next_state} = _use0, {ok, {<<" WHERE "/utf8, Pred_sql/binary>>, Next_state}} end ) end. -file("src\\galchemy\\sql\\compiler.gleam", 201). -spec compile_update_with(galchemy@ast@query:update_query(), compiler_config()) -> {ok, compiled_query()} | {error, compile_error()}. compile_update_with(Q, Config) -> {update_query, Table, Assignments, Where_, Returning} = Q, State0 = new_state(Config), result_try( compile_assignments(Assignments, State0), fun(_use0) -> {Set_sql, State1} = _use0, result_try( compile_where(Where_, State1), fun(_use0@1) -> {Where_sql, State2} = _use0@1, result_try( compile_returning(Returning, State2), fun(_use0@2) -> {Returning_sql, State3} = _use0@2, Sql = <<<<<<<<<<"UPDATE "/utf8, (compile_table_ref( Table, erlang:element(4, State0) ))/binary>>/binary, " SET "/utf8>>/binary, Set_sql/binary>>/binary, Where_sql/binary>>/binary, Returning_sql/binary>>, {ok, finalize(Sql, State3)} end ) end ) end ). -file("src\\galchemy\\sql\\compiler.gleam", 195). -spec compile_update(galchemy@ast@query:update_query()) -> {ok, compiled_query()} | {error, compile_error()}. compile_update(Q) -> compile_update_with(Q, default_config()). -file("src\\galchemy\\sql\\compiler.gleam", 237). -spec compile_delete_with(galchemy@ast@query:delete_query(), compiler_config()) -> {ok, compiled_query()} | {error, compile_error()}. compile_delete_with(Q, Config) -> {delete_query, Table, Where_, Returning} = Q, State0 = new_state(Config), result_try( compile_where(Where_, State0), fun(_use0) -> {Where_sql, State1} = _use0, result_try( compile_returning(Returning, State1), fun(_use0@1) -> {Returning_sql, State2} = _use0@1, Sql = <<<<<<"DELETE FROM "/utf8, (compile_table_ref( Table, erlang:element(4, State0) ))/binary>>/binary, Where_sql/binary>>/binary, Returning_sql/binary>>, {ok, finalize(Sql, State2)} end ) end ). -file("src\\galchemy\\sql\\compiler.gleam", 66). -spec compile_with(galchemy@ast@query:'query'(), compiler_config()) -> {ok, compiled_query()} | {error, compile_error()}. compile_with(Q, Config) -> case Q of {select, S} -> compile_select_with(S, Config); {insert, I} -> compile_insert_with(I, Config); {update, U} -> compile_update_with(U, Config); {delete, D} -> compile_delete_with(D, Config) end. -file("src\\galchemy\\sql\\compiler.gleam", 62). -spec compile(galchemy@ast@query:'query'()) -> {ok, compiled_query()} | {error, compile_error()}. compile(Q) -> compile_with(Q, default_config()). -file("src\\galchemy\\sql\\compiler.gleam", 231). -spec compile_delete(galchemy@ast@query:delete_query()) -> {ok, compiled_query()} | {error, compile_error()}. compile_delete(Q) -> compile_delete_with(Q, default_config()). -file("src\\galchemy\\sql\\compiler.gleam", 731). -spec compile_having( list(galchemy@ast@expression:expression()), gleam@option:option(galchemy@ast@expression:predicate()), compile_state() ) -> {ok, {binary(), compile_state()}} | {error, compile_error()}. compile_having(Group_by, Having_, State) -> case Having_ of none -> {ok, {<<""/utf8>>, State}}; {some, Pred} -> case gleam@list:is_empty(Group_by) of true -> {error, having_without_group_by}; false -> result_try( compile_predicate(Pred, State), fun(_use0) -> {Pred_sql, Next_state} = _use0, {ok, {<<" HAVING "/utf8, Pred_sql/binary>>, Next_state}} end ) end end.