;
}
+sub _escape_char {
+ $_[0]->{escape_char} || ($_[0]->_quote_chars)[1] || '';
+}
+
+sub _unquote {
+ my ($self, $value) = @_;
+
+ return $value unless defined $value;
+
+ my ($l, $r, $e) = map { quotemeta $_ } $self->_quote_chars, $self->_escape_char;
+
+ # no quoting, all bets are off
+ return $value unless length $e;
+
+ my $re = $self->_quoted_ident_re($l, $r, $e);
+
+ if ($value =~ /\A$re\z/) {
+ $value =~ s/\A$l//;
+ $value =~ s/$r\z//;
+ $value =~ s/( $e [$e$r] )/substr($1, 1)/gex;
+ return $value;
+ }
+ else {
+ # not a quoted value, assume it's an identifier
+ return $value;
+ }
+}
+
+sub _quoted_ident_re {
+ my $self = shift;
+ my ($l, $r, $e) = @_ ? @_ : map { quotemeta $_ } $self->_quote_chars, $self->_escape_char;
+ return qr/ $l (?: [^$e$r] | $e [$e$r] )+ $r /x;
+}
+
# FIXME when we bring in the storage weaklink, check its schema
# weaklink and channel through $schema->throw_exception
sub throw_exception { DBIx::Class::Exception->throw($_[1]) }
# name_sep, otherwise sorry nasty legacy syntax like
# { 'count(foo.id)' => { '>' => 3 } } will stop working >:(
local $sql_maker->{quote_char} = $sql_maker->{quote_char};
+ local $sql_maker->{escape_char} = $sql_maker->{escape_char};
local $sql_maker->{name_sep} = $sql_maker->{name_sep};
unless (defined $sql_maker->{quote_char} and length $sql_maker->{quote_char}) {
$sql_maker->{quote_char} = ["\x00", "\xFF"];
+ $sql_maker->{escape_char} = "\xFF";
# if we don't unset it we screw up retarded but unfortunately working
# 'MAX(foo.bar)' => { '>', 3 }
$sql_maker->{name_sep} = '';
# now loop through all fully qualified columns and get the corresponding
# alias (should work even if they are in scalarrefs)
+ my $ident_re = $sql_maker->_quoted_ident_re;
for my $alias (keys %$alias_list) {
my $al_re = qr/
- $lquote \Q$alias\E $rquote $sep (?: $lquote ([^$rquote]+) $rquote )?
+ $lquote \Q$alias\E $rquote $sep ($ident_re)?
|
\b \Q$alias\E \. ([^\s\)\($rquote]+)?
/x;
for my $type (keys %$to_scan) {
for my $piece (@{$to_scan->{$type}}) {
- if (my @matches = $piece =~ /$al_re/g) {
+ if (my @matches = map { $sql_maker->_unquote($_) } $piece =~ /$al_re/g) {
$aliases_by_type->{$type}{$alias} ||= { -parents => $alias_list->{$alias}{-join_path}||[] };
$aliases_by_type->{$type}{$alias}{-seen_columns}{"$alias.$_"} = "$alias.$_"
for grep { defined $_ } @matches;