$changes++;
}
- # only *ONE* LITERAL element
+ # only *ONE* LITERAL or placeholder element
elsif (
- @{$child->[1]} == 1 && $child->[1][0][0] eq 'LITERAL'
+ @{$child->[1]} == 1 && (
+ $child->[1][0][0] eq 'LITERAL'
+ or
+ $child->[1][0][0] eq 'PLACEHOLDER'
+ )
) {
push @children, $child->[1][0];
$changes++;
# mathop, and our content is:
# a single non-mathop child with a single PAREN grandchild which
# would indicate mathop ( nonmathop ( ... ) )
- # or a single non-mathop with a single LITERAL ( nonmathop ? )
+ # or a single non-mathop with a single LITERAL ( nonmathop foo )
+ # or a single non-mathop with a single PLACEHOLDER ( nonmathop ? )
elsif (
@{$child->[1]} == 1
and
and
(
$child->[1][0][1][0][0] eq 'PAREN'
- or
+ or
$child->[1][0][1][0][0] eq 'LITERAL'
+ or
+ $child->[1][0][1][0][0] eq 'PLACEHOLDER'
)
) {
push @children, $child->[1][0];
my $quote_left = qr/[\`\'\"\[]/;
my $quote_right = qr/[\`\'\"\]]/;
+my $placeholder_re = qr/(?: \? | \$\d+ )/x;
+
# These SQL keywords always signal end of the current expression (except inside
# of a parenthesized subexpression).
# Format: A list of strings that will be compiled to extended syntax ie.
$binary_op_re,
"$op_look_behind (?i: AND|OR|NOT ) $op_look_ahead",
(map { quotemeta $_ } qw/, ( ) */),
+ $placeholder_re,
);
$all_known_re = qr/$all_known_re/x;
my $expr_term_re = qr/ ^ (?: $expr_start_re | \) ) $/x;
my $rhs_term_re = qr/ ^ (?: $expr_term_re | $binary_op_re | (?i: AND | OR | NOT | \, ) ) $/x;
-my $func_start_re = qr/^ (?: \? | \$\d+ | \( ) $/x;
+my $func_start_re = qr/^ (?: \* | $placeholder_re | \( ) $/x;
my %indents = (
select => 0,
: [ $op => [$right] ];
}
+ elsif ( $token =~ $placeholder_re) {
+ $left = $left ? [ $left, [ PLACEHOLDER => [ $token ] ] ]
+ : [ PLACEHOLDER => [ $token ] ];
+ }
# we're now in "unknown token" land - start eating tokens until
# we see something familiar
else {
return join (' ', map $self->_unparse($_, $bindargs, $depth), @$tree);
}
elsif ($car eq 'LITERAL') {
- if ($cdr->[0] eq '?') {
- return $self->fill_in_placeholder($bindargs)
- }
return $cdr->[0];
}
+ elsif ($car eq 'PLACEHOLDER') {
+ return $self->fill_in_placeholder($bindargs);
+ }
elsif ($car eq 'PAREN') {
return '(' .
join(' ',