1 package Data::Query::ExprDeclare;
4 use Data::Query::ExprBuilder::Identifier;
5 use Data::Query::ExprHelpers;
6 use Data::Query::Constants;
11 our @EXPORT = qw(expr);
14 SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC LIMIT OFFSET NULLS FIRST LAST
22 local $_ = Data::Query::ExprBuilder::Identifier->new({
29 if ($_[0]->$_isa('Data::Query::ExprBuilder')) {
31 } elsif (ref($_[0])) {
34 perl_scalar_value($_[0]);
40 (bless(\$as, 'LIES::AS'), @_);
44 my @select = map _value($_), _run_expr(shift);
47 my $e = shift @select;
49 (ref($select[0]) eq 'LIES::AS'
50 ? Alias(${shift(@select)}, $e)
55 my $final = Select(\@final, shift);
57 if (is_Slice($_[0])) {
58 my ($limit, $offset) = @{+shift}{qw(limit offset)};
59 $final = Slice($offset, $limit, $final);
68 my @from = _run_expr(shift);
70 if (@from == 2 and ref($from[1]) eq 'LIES::AS') {
71 Alias(${$from[1]}, _value($from[0]))
72 } elsif (@from == 1) {
76 while (is_Join($_[0])) {
77 $from_dq = { %{+shift}, left => $from_dq };
79 if (is_Where($_[0])) {
80 my $where = shift->{where};
81 if (is_Select($from_dq)) {
82 $from_dq = Select($from_dq->{select}, Where($where, $from_dq->{from}));
84 $from_dq = Where($where, $from_dq);
87 while (is_Order($_[0])) {
89 $from_dq = Order($order->{by}, $order->{reverse}, $order->{nulls}, $from_dq);
91 return ($from_dq, @_);
95 my ($join, @rest) = @_;
96 die "LEFT used as modifier on non-join ${join}"
97 unless is_Join($join);
98 return +{ %$join, outer => 'LEFT' }, @rest;
102 my ($join) = FROM(\&{+shift});
104 if ($_[0]->$_isa('LIES::ON')) {
110 Join(undef, $join, $on), @_;
114 my $on = _value(_run_expr(shift));
115 return bless(\$on, 'LIES::ON'), @_;
120 return Where(_value(_run_expr($w))), @_;
123 sub DESC { bless({}, 'LIES::DESC'), @_ }
124 sub NULLS { bless(\shift, 'LIES::NULLS'), @_ }
129 my @order = map _value($_), _run_expr(shift);
131 if ($_[0]->$_isa('LIES::DESC')) {
137 my $nulls = $_[0]->$_isa('LIES::NULLS') ? ${+shift} : undef;
139 return ((compose { Order($b, $reverse, $nulls, $a) } @order, undef), @_);
143 my ($limit) = map _value($_), _run_expr(shift);
144 if (is_Slice($_[0])) {
146 return +{ %{$slice}, limit => $limit }, @_;
148 return Slice(undef, $limit), @_;
152 my ($offset) = map _value($_), _run_expr(shift);
153 return Slice($offset, undef), @_;