1 package Data::Query::ExprDeclare;
4 use Data::Query::ExprBuilder::Identifier;
5 use Data::Query::ExprHelpers;
6 use Data::Query::Constants;
11 warnings->unimport('precedence');
12 goto &Exporter::import;
15 our @EXPORT = qw(expr);
18 SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC LIMIT OFFSET NULLS FIRST LAST
26 local $_ = Data::Query::ExprBuilder::Identifier->new({
33 if ($_[0]->$_isa('Data::Query::ExprBuilder')) {
35 } elsif (ref($_[0])) {
38 perl_scalar_value($_[0]);
44 (bless(\$as, 'LIES::AS'), @_);
48 my @select = map _value($_), _run_expr(shift);
51 my $e = shift @select;
53 (ref($select[0]) eq 'LIES::AS'
54 ? Alias(${shift(@select)}, $e)
59 my $final = Select(\@final, shift);
61 if (is_Slice($_[0])) {
62 my ($limit, $offset) = @{+shift}{qw(limit offset)};
63 $final = Slice($offset, $limit, $final);
72 my @from = _run_expr(shift);
74 if (@from == 2 and ref($from[1]) eq 'LIES::AS') {
75 Alias(${$from[1]}, _value($from[0]))
76 } elsif (@from == 1) {
80 while (is_Join($_[0])) {
81 $from_dq = { %{+shift}, left => $from_dq };
83 if (is_Where($_[0])) {
84 my $where = shift->{where};
85 if (is_Select($from_dq)) {
86 $from_dq = Select($from_dq->{select}, Where($where, $from_dq->{from}));
88 $from_dq = Where($where, $from_dq);
91 while (is_Order($_[0])) {
93 $from_dq = Order($order->{by}, $order->{reverse}, $order->{nulls}, $from_dq);
95 return ($from_dq, @_);
99 my ($join, @rest) = @_;
100 die "LEFT used as modifier on non-join ${join}"
101 unless is_Join($join);
102 return +{ %$join, outer => 'LEFT' }, @rest;
106 my ($join) = FROM(\&{+shift});
108 if ($_[0]->$_isa('LIES::ON')) {
114 Join(undef, $join, $on), @_;
118 my $on = _value(_run_expr(shift));
119 return bless(\$on, 'LIES::ON'), @_;
124 return Where(_value(_run_expr($w))), @_;
127 sub DESC { bless({}, 'LIES::DESC'), @_ }
128 sub NULLS { bless(\shift, 'LIES::NULLS'), @_ }
133 my @order = map _value($_), _run_expr(shift);
135 if ($_[0]->$_isa('LIES::DESC')) {
141 my $nulls = $_[0]->$_isa('LIES::NULLS') ? ${+shift} : undef;
143 return ((compose { Order($b, $reverse, $nulls, $a) } @order, undef), @_);
147 my ($limit) = map _value($_), _run_expr(shift);
148 if (is_Slice($_[0])) {
150 return +{ %{$slice}, limit => $limit }, @_;
152 return Slice(undef, $limit), @_;
156 my ($offset) = map _value($_), _run_expr(shift);
157 return Slice($offset, undef), @_;