Clean up from/select bind value handling (RT#61025)
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / SQLMaker / LimitDialects.pm
index d4689a7..294c579 100644 (file)
@@ -202,7 +202,6 @@ SELECT $out_sel FROM (
 
 EOS
 
-  $sql =~ s/\s*\n\s*/ /g;   # easier to read in the debugger
   return $sql;
 }
 
@@ -266,8 +265,8 @@ sub _FirstSkip {
  SELECT * FROM (
   SELECT *, ROWNUM rownum__index FROM (
    SELECT ...
-  )
- ) WHERE rownum__index BETWEEN ($offset+1) AND ($limit+$offset)
+  ) WHERE ROWNUM <= ($limit+$offset)
+ ) WHERE rownum__index >= ($offset+1)
 
 Supported by B<Oracle>.
 
@@ -285,17 +284,28 @@ sub _RowNum {
   my $idx_name = $self->_quote ('rownum__index');
   my $order_group_having = $self->_parse_rs_attrs($rs_attrs);
 
-  $sql = sprintf (<<EOS, $offset + 1, $offset + $rows, );
+  if ($offset) {
+
+    $sql = sprintf (<<EOS, $offset + $rows, $offset + 1 );
 
 SELECT $outsel FROM (
   SELECT $outsel, ROWNUM $idx_name FROM (
     SELECT $insel ${sql}${order_group_having}
-  ) $qalias
-) $qalias WHERE $idx_name BETWEEN %u AND %u
+  ) $qalias WHERE ROWNUM <= %u
+) $qalias WHERE $idx_name >= %u
 
 EOS
+  }
+  else {
+    $sql = sprintf (<<EOS, $rows );
+
+  SELECT $outsel FROM (
+    SELECT $insel ${sql}${order_group_having}
+  ) $qalias WHERE ROWNUM <= %u
+
+EOS
+  }
 
-  $sql =~ s/\s*\n\s*/ /g;   # easier to read in the debugger
   return $sql;
 }
 
@@ -336,7 +346,7 @@ sub _Top {
   my $inner_order = ($order_by_requested
     ? $requested_order
     : [ map
-      { join ('', $rs_attrs->{alias}, $self->{name_sep}||'.', $_ ) }
+      { "$rs_attrs->{alias}.$_" }
       ( $rs_attrs->{_rsroot_source_handle}->resolve->_pri_cols )
     ]
   );
@@ -378,9 +388,9 @@ sub _Top {
 
     # since whatever order bindvals there are, they will be realiased
     # and need to show up in front of the entire initial inner subquery
-    # Unshift *from_bind* to make this happen (horrible, horrible, but
-    # we don't have another mechanism yet)
-    unshift @{$self->{from_bind}}, @{$self->{order_bind}};
+    # *unshift* the selector bind stack to make this happen (horrible,
+    # horrible, but we don't have another mechanism yet)
+    unshift @{$self->{select_bind}}, @{$self->{order_bind}};
   }
 
   # and this is order re-alias magic
@@ -421,7 +431,6 @@ sub _Top {
     $order_by_requested,
   ) if ( ($offset && $order_by_requested) || ($mid_sel ne $out_sel) );
 
-  $sql =~ s/\s*\n\s*/ /g;   # easier to read in the debugger
   return $sql;
 }
 
@@ -567,7 +576,6 @@ EOS
     ,
   );
 
-  $sql =~ s/\s*\n\s*/ /g;   # easier to read in the debugger
   return $sql;
 }
 
@@ -590,17 +598,13 @@ EOS
 # also return a hashref (order doesn't matter) of QUOTED EXTRA-SEL =>
 # QUOTED ALIAS pairs, which is a list of extra selectors that do *not*
 # exist in the original select list
-
 sub _subqueried_limit_attrs {
   my ($self, $rs_attrs) = @_;
 
   croak 'Limit dialect implementation usable only in the context of DBIC (missing $rs_attrs)'
     unless ref ($rs_attrs) eq 'HASH';
 
-  my ($re_sep, $re_alias) = map { quotemeta $_ } (
-    $self->name_sep || '.',
-    $rs_attrs->{alias},
-  );
+  my ($re_sep, $re_alias) = map { quotemeta $_ } ( $self->{name_sep}, $rs_attrs->{alias} );
 
   # correlate select and as, build selection index
   my (@sel, $in_sel_index);
@@ -610,7 +614,6 @@ sub _subqueried_limit_attrs {
     my $sql_sel = $self->_recurse_fields ($s);
     my $sql_alias = (ref $s) eq 'HASH' ? $s->{-as} : undef;
 
-
     push @sel, {
       sql => $sql_sel,
       unquoted_sql => do { local $self->{quote_char}; $self->_recurse_fields ($s) },
@@ -641,7 +644,11 @@ sub _subqueried_limit_attrs {
   # for possible further chaining)
   my (@in_sel, @out_sel, %renamed);
   for my $node (@sel) {
-    if (first { $_ =~ / (?<! ^ $re_alias ) $re_sep /x } ($node->{as}, $node->{unquoted_sql}) )  {
+    if (
+      $node->{as} =~ / (?<! ^ $re_alias ) \. /x
+        or
+      $node->{unquoted_sql} =~ / (?<! ^ $re_alias ) $re_sep /x
+    ) {
       $node->{as} = $self->_unqualify_colname($node->{as});
       my $quoted_as = $self->_quote($node->{as});
       push @in_sel, sprintf '%s AS %s', $node->{sql}, $quoted_as;
@@ -680,8 +687,7 @@ sub _subqueried_limit_attrs {
 
 sub _unqualify_colname {
   my ($self, $fqcn) = @_;
-  my $re_sep = quotemeta($self->name_sep || '.');
-  $fqcn =~ s/ $re_sep /__/xg;
+  $fqcn =~ s/ \. /__/xg;
   return $fqcn;
 }