my ($self, $chunk) = @_;
# strip off sort modifiers, but always succeed, so $1 gets reset
- $chunk =~ s/ (?: \s+ (ASC|DESC) )? \s* $//ix;
+ $chunk =~ s/ (?: \s+ (ASC|DESC) )? (?: \s+ NULLS \s+ (FIRST|LAST) )? \s* $//ix;
return (
$chunk,
( $1 and uc($1) eq 'DESC' ) ? 1 : 0,
+ $2 ? uc($2) : undef
);
}
for my $ch ($self->_order_by_chunks ($inner_order)) {
$ch = $ch->[0] if ref $ch eq 'ARRAY';
- ($ch, my $is_desc) = $self->_split_order_chunk($ch);
-
- # !NOTE! outside chunks come in reverse order ( !$is_desc )
- push @out_chunks, { ($is_desc ? '-asc' : '-desc') => \$ch };
+ ($ch, my ($is_desc, $nulls_pos) ) = $self->_split_order_chunk($ch);
+
+ # !NOTE! outside chunks come in reverse order ( !$is_desc, !$nulls_pos )
+ push @out_chunks, {
+ ($is_desc ? '-asc' : '-desc') => \$ch,
+ $nulls_pos ? (
+ -nulls => ($nulls_pos eq 'FIRST' ? 'LAST' : 'FIRST')
+ ) : (),
+ };
}
$sq_attrs->{order_by_middle} = $self->_order_by (\@out_chunks);
for my $bit (@order_bits) {
- ($bit, my $is_desc) = $self->_split_order_chunk($bit);
+ ($bit, my ($is_desc, $nulls_pos)) = $self->_split_order_chunk($bit);
push @is_desc, $is_desc;
push @unqualified_names, $usable_order_colinfo->{$bit}{-colname};
push @qualified_names, $usable_order_colinfo->{$bit}{-fq_colname};
- push @new_order_by, { ($is_desc ? '-desc' : '-asc') => $usable_order_colinfo->{$bit}{-fq_colname} };
+ push @new_order_by, {
+ ($is_desc ? '-desc' : '-asc') => $usable_order_colinfo->{$bit}{-fq_colname},
+ ($nulls_pos ? ( -nulls => lc $nulls_pos ) : ()),
+ };
};
my (@where_cond, @skip_colpair_stack);
map { ref $_ eq 'ARRAY' ? $_ : [ $_ ] } $sql_maker->_order_by_chunks($attrs->{order_by})
];
+ # FIXME: MIN/MAX can't handle NULLS FIRST/LAST
my ($chunk, $is_desc) = $sql_maker->_split_order_chunk($order_chunks->[$o_idx][0]);
# we reached that far - wrap any part of the order_by that "responded"
order_outer => 'name DESC',
order_req => 'name',
},
+ {
+ order_by => [
+ { -asc => 'title', -nulls => 'first' },
+ { -desc => 'bar', -nulls => 'last' },
+ ],
+ order_inner => 'title ASC NULLS FIRST, bar DESC NULLS LAST',
+ order_outer => 'ORDER__BY__001 DESC NULLS LAST, ORDER__BY__002 ASC NULLS FIRST',
+ order_req => 'ORDER__BY__001 ASC NULLS FIRST, ORDER__BY__002 DESC NULLS LAST',
+ exselect_outer => 'ORDER__BY__001, ORDER__BY__002',
+ exselect_inner => 'title AS ORDER__BY__001, bar AS ORDER__BY__002',
+ },
) {
my $o_sel = $ord_set->{exselect_outer}
? ', ' . $ord_set->{exselect_outer}
exselect_outer => 'ORDER__BY__001, ORDER__BY__002, ORDER__BY__003',
exselect_inner => 'title AS ORDER__BY__001, bar AS ORDER__BY__002, sensors AS ORDER__BY__003',
},
+ {
+ order_by => [
+ { -asc => 'title', -nulls => 'first' },
+ { -desc => 'bar', -nulls => 'last' },
+ ],
+ order_inner => 'title ASC NULLS FIRST, bar DESC NULLS LAST',
+ order_outer => 'ORDER__BY__001 DESC NULLS LAST, ORDER__BY__002 ASC NULLS FIRST',
+ order_req => 'ORDER__BY__001 ASC NULLS FIRST, ORDER__BY__002 DESC NULLS LAST',
+ exselect_outer => 'ORDER__BY__001, ORDER__BY__002',
+ exselect_inner => 'title AS ORDER__BY__001, bar AS ORDER__BY__002',
+ },
) {
my $o_sel = $ord_set->{exselect_outer}
? ', ' . $ord_set->{exselect_outer}