-bind => sub { shift; +{ @_ } },
-in => '_expand_in',
-not_in => '_expand_in',
+ -list => sub {
+ my ($self, $node, $args) = @_;
+ +{ $node => [ map $self->expand_expr($_), @$args ] };
+ },
};
$opt{expand_op} = {
),
(not => '_render_op_not'),
(map +($_ => '_render_op_andor'), qw(and or)),
- ',' => '_render_op_multop',
+ ',' => sub { shift->_render_op_multop(@_, 1) },
};
return bless \%opt, $class;
my ($sql, @bind) = @$literal;
my $opened_sql = $self->_open_outer_paren($sql);
return +{ -op => [
- $op, $self->_expand_ident(-ident => $k),
+ $op, $self->expand_expr($k, -ident),
[ { -literal => [ $opened_sql, @bind ] } ]
] };
}
return +{ -op => [
$op,
- $self->_expand_ident(-ident => $k),
+ $self->expand_expr($k, -ident),
\@rhs
] };
}
sub _render_list {
my ($self, $list) = @_;
- my @parts = grep length($_->[0]), map [ $self->render_aqt($_) ], @$list;
- return join(', ', map $_->[0], @parts), map @{$_}[1..$#$_], @parts;
+ my ($sql, @bind) = $self->_render_op([ ',', @$list ]);
+ return "($sql)", @bind;
}
sub _render_func {
}
sub _render_op_multop {
- my ($self, $op, $args) = @_;
+ my ($self, $op, $args, $strip_left) = @_;
my @parts = grep length($_->[0]), map [ $self->render_aqt($_) ], @$args;
return '' unless @parts;
return @{$parts[0]} if @parts == 1;
my ($final_sql) = join(
- ' '.$self->_sqlcase(join ' ', split '_', $op).' ',
+ ($strip_left ? '' : ' ').$self->_sqlcase(join ' ', split '_', $op).' ',
map $_->[0], @parts
);
return (
sub _expand_maybe_list_expr {
my ($self, $expr, $default) = @_;
- my $e = do {
- if (ref($expr) eq 'ARRAY') {
- return { -list => [
- map $self->expand_expr($_, $default), @$expr
- ] } if @$expr > 1;
- $expr->[0]
- } else {
- $expr
- }
- };
- return $self->expand_expr($e, $default);
+ return +{ -op => [ ',',
+ map $self->expand_expr($_, $default),
+ ref($expr) eq 'ARRAY' ? @$expr : $expr
+ ] };
}
# highly optimized, as it's called way too often
bind => [ 4, 2 ],
test => 'Top level -in',
},
+# This works but then SQL::Abstract::Tree breaks - something for a later commit
+# {
+# where => { -in => [ { -list => [ qw(x y) ] }, { -list => [ 1, 3 ] }, { -list => [ 2, 4 ] } ] },
+# stmt => ' WHERE ((x, y) IN ((?, ?), (?, ?))',
+# bind => [ 1, 3, 2, 4 ],
+# test => 'Top level -in with list args',
+# },
{
where => { -between => [42, 69] },
throws => qr/Illegal use of top-level '-between'/,