Add SQLMaker methods for matching and unquoting quoted identifiers
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBIHacks.pm
index ef89092..350bb56 100644 (file)
@@ -15,7 +15,6 @@ use mro 'c3';
 
 use List::Util 'first';
 use Scalar::Util 'blessed';
-use Sub::Name 'subname';
 use DBIx::Class::_Util 'UNRESOLVABLE_CONDITION';
 use SQL::Abstract qw(is_plain_value is_literal_value);
 use namespace::clean;
@@ -112,8 +111,8 @@ sub _adjust_select_args_for_complex_prefetch {
   my $outer_attrs = { %$attrs };
   delete @{$outer_attrs}{qw(from bind rows offset group_by _grouped_by_distinct having)};
 
-  my $inner_attrs = { %$attrs };
-  delete @{$inner_attrs}{qw(for collapse select as _related_results_construction)};
+  my $inner_attrs = { %$attrs, _simple_passthrough_construction => 1 };
+  delete @{$inner_attrs}{qw(for collapse select as)};
 
   # there is no point of ordering the insides if there is no limit
   delete $inner_attrs->{order_by} if (
@@ -403,10 +402,12 @@ sub _resolve_aliastypes_from_select_args {
   # 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} = '';
@@ -483,16 +484,17 @@ sub _resolve_aliastypes_from_select_args {
 
   # 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 $alias $rquote $sep (?: $lquote ([^$rquote]+) $rquote )?
+      $lquote \Q$alias\E $rquote $sep ($ident_re)?
         |
-      \b $alias \. ([^\s\)\($rquote]+)?
+      \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;
@@ -506,7 +508,7 @@ sub _resolve_aliastypes_from_select_args {
   for my $col (keys %$colinfo) {
     next if $col =~ / \. /x;   # if column is qualified it was caught by the above
 
-    my $col_re = qr/ $lquote ($col) $rquote /x;
+    my $col_re = qr/ $lquote (\Q$col\E) $rquote /x;
 
     for my $type (keys %$to_scan) {
       for my $piece (@{$to_scan->{$type}}) {