1 package Data::Query::ExprDeclare;
4 use Data::Query::ExprBuilder::Identifier;
5 use Data::Query::ExprHelpers;
6 use Data::Query::Constants;
12 expr SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC LIMIT OFFSET NULLS FIRST LAST
16 _run_expr($_[0])->{expr};
20 local $_ = Data::Query::ExprBuilder::Identifier->new({
27 if ($_[0]->$_isa('Data::Query::ExprBuilder')) {
29 } elsif (ref($_[0])) {
32 perl_scalar_value($_[0]);
38 (bless(\$as, 'LIES::AS'), @_);
42 my @select = map _value($_), _run_expr(shift);
45 my $e = shift @select;
47 (ref($select[0]) eq 'LIES::AS'
48 ? Alias(${shift(@select)}, $e)
53 my $final = Select(\@final, shift);
55 if (is_Slice($_[0])) {
56 my ($limit, $offset) = @{+shift}{qw(limit offset)};
57 $final = Slice($offset, $limit, $final);
66 my @from = _run_expr(shift);
68 if (@from == 2 and ref($from[1]) eq 'LIES::AS') {
69 Alias(${$from[1]}, _value($from[0]))
70 } elsif (@from == 1) {
74 while (is_Join($_[0])) {
75 $from_dq = { %{+shift}, left => $from_dq };
77 if (is_Where($_[0])) {
78 my $where = shift->{where};
79 if (is_Select($from_dq)) {
80 $from_dq = Select($from_dq->{select}, Where($where, $from_dq->{from}));
82 $from_dq = Where($where, $from_dq);
85 while (is_Order($_[0])) {
87 $from_dq = Order($order->{by}, $order->{reverse}, $order->{nulls}, $from_dq);
89 return ($from_dq, @_);
93 my ($join, @rest) = @_;
94 die "LEFT used as modifier on non-join ${join}"
95 unless is_Join($join);
96 return +{ %$join, outer => 'LEFT' }, @rest;
100 my ($join) = FROM(\&{+shift});
102 if ($_[0]->$_isa('LIES::ON')) {
108 Join(undef, $join, $on), @_;
112 my $on = _value(_run_expr(shift));
113 return bless(\$on, 'LIES::ON'), @_;
118 return Where(_value(_run_expr($w))), @_;
121 sub DESC { bless({}, 'LIES::DESC'), @_ }
122 sub NULLS { bless(\shift, 'LIES::NULLS'), @_ }
127 my @order = map _value($_), _run_expr(shift);
129 if ($_[0]->$_isa('LIES::DESC')) {
135 my $nulls = $_[0]->$_isa('LIES::NULLS') ? ${+shift} : undef;
137 return ((compose { Order($b, $reverse, $nulls, $a) } @order, undef), @_);
141 my ($limit) = map _value($_), _run_expr(shift);
142 if (is_Slice($_[0])) {
144 return +{ %{$slice}, limit => $limit }, @_;
146 return Slice(undef, $limit), @_;
150 my ($offset) = map _value($_), _run_expr(shift);
151 return Slice($offset, undef), @_;