use base qw(Exporter);
our @EXPORT = qw(
- expr SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC LIMIT OFFSET
+ expr SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC LIMIT OFFSET NULLS FIRST LAST
);
sub expr (&) {
}
while (is_Order($_[0])) {
my $order = shift;
- $from_dq = Order($order->{by}, $order->{reverse}, $from_dq);
+ $from_dq = Order($order->{by}, $order->{reverse}, $order->{nulls}, $from_dq);
}
return ($from_dq, @_);
}
}
sub DESC { bless({}, 'LIES::DESC'), @_ }
+sub NULLS { bless(\shift, 'LIES::NULLS'), @_ }
+sub FIRST { 1, @_ }
+sub LAST { -1, @_ }
sub ORDER {
my @order = map _value($_), _run_expr(shift);
0;
}
};
- return ((compose { Order($b, $reverse, $a) } @order, undef), @_);
+ my $nulls = $_[0]->$_isa('LIES::NULLS') ? ${+shift} : undef;
+
+ return ((compose { Order($b, $reverse, $nulls, $a) } @order, undef), @_);
}
sub LIMIT (&;@) {
Operator => [ qw(operator args) ],
Select => [ qw(select from) ],
Where => [ qw(where from) ],
- Order => [ qw(by reverse from) ],
+ Order => [ qw(by reverse nulls from) ],
Group => [ qw(by from) ],
Delete => [ qw(where target) ],
Update => [ qw(set where target) ],
]
}
-sub _render_order {
+sub _order_chunk {
my ($self, $dq) = @_;
- my @ret = (
- $self->_format_keyword('ORDER BY'),
+ return +(
$self->_render($dq->{by}),
($dq->{reverse}
? $self->_format_keyword('DESC')
- : ())
+ : ()),
+ ($dq->{nulls}
+ ? $self->_format_keyword('NULLS '.('', qw(FIRST LAST))[$dq->{nulls}])
+ : ()),
+ );
+}
+
+sub _render_order {
+ my ($self, $dq) = @_;
+ my @ret = (
+ $self->_format_keyword('ORDER BY'),
+ $self->_order_chunk($dq),
);
my $from;
while ($from = $dq->{from}) {
$dq = $from;
push @ret, (
',',
- $self->_render($dq->{by}),
- ($dq->{reverse}
- ? $self->_format_keyword('DESC')
- : ())
+ $self->_order_chunk($dq),
);
}
unshift @ret, $self->_render($from) if $from;
? Select(
\@outside_select_list,
compose {
- Order($b->{by}, $b->{reverse}, $a)
+ Order($b->{by}, $b->{reverse}, $b->{nulls}, $a)
} (
@outside_order,
Alias($default_inside_alias, $_)
: (),
],
compose {
- Order($b->{by}, !$b->{reverse}, $a)
+ Order($b->{by}, !$b->{reverse}, -$b->{nulls}, $a)
} (
@outside_order,
Alias(
Select(
\@inside_select_list,
compose {
- Order($b->{by}, $b->{reverse}, $a)
+ Order($b->{by}, $b->{reverse}, $b->{nulls}, $a)
} @inside_order, $inner_body
)
)
return $self->render(
Select(
$remapped{outside_select_list},
- (compose { no warnings 'once'; Order($b->{by}, $b->{reverse}, $a) }
+ (compose { no warnings 'once'; Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) }
@{$remapped{outside_order}},
Where(
$count_where,
my $rno_name = 'rno__row__index';
- my $order = compose { Order($b->{by}, $b->{reverse}, $a) }
+ my $order = compose { Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) }
@outside_order, undef;
my $rno_node = Alias($rno_name, $self->_rno_literal($order));
);
DwarnL to_sql(
- SELECT { $_->cd->name } FROM { $_->cds, AS 'cd' } ORDER BY { $_->year }
+ SELECT { $_->cd->name } FROM { $_->cds, AS 'cd' } ORDER BY { $_->year } DESC NULLS LAST
);
my $lo =