Author: spadkins
Date: Tue Feb 17 20:51:26 2009
New Revision: 12510

Modified:
   p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm
   p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm
   p5ee/trunk/App-Repository/t/DBI-select-limit.t

Log:
handle implied summaries with respect to startrow/endrow

Modified: p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm Tue Feb 17 20:51:26 2009
@@ -1209,13 +1209,7 @@
             ############################################################
             # accumulate group-by columns and whether grouping reqd
             ############################################################
-            if (($dbexpr =~ /sum *\(/i) ||
-                ($dbexpr =~ /min *\(/i) ||
-                ($dbexpr =~ /max *\(/i) ||
-                ($dbexpr =~ /avg *\(/i) ||
-                ($dbexpr =~ /std *\(/i) ||
-                ($dbexpr =~ /stddev *\(/i) || # Oracle extension (supported by 
MySQL)
-                ($dbexpr =~ /count *\(/i)) {
+            if ($dbexpr =~ /(sum|count|min|max|avg|std|stddev) *\(/i) {
                 $group_reqd = 1;
             }
             else {
@@ -1398,6 +1392,32 @@
     return("");
 }
 
+sub _assess_implied_summaries {
+    &App::sub_entry if ($App::trace);
+    my ($self, $table, $columns, $options) = @_;
+
+    my $table_def = $self->get_table_def($table);
+    my $is_summary_implied = 0;
+    my $summary_key_exists = 0;
+    my ($column, $column_def, $dbexpr);
+    for (my $idx = 0; $idx <= $#$columns; $idx++) {
+        $column = $columns->[$idx];
+        $column_def = $table_def->{column}{$column};
+        next if (!defined $column_def);
+        $dbexpr = $column_def->{dbexpr};
+        $dbexpr ||= $column;
+        if ($dbexpr =~ /(sum|count|min|max|avg|std|stddev) *\(/i) {
+            $is_summary_implied = 1;
+        }
+        else {
+            $summary_key_exists = 1;
+        }
+        last if ($is_summary_implied && $summary_key_exists);
+    }
+    &App::sub_exit($is_summary_implied, $summary_key_exists) if ($App::trace);
+    return($is_summary_implied, $summary_key_exists);
+}
+
 sub _require_tables {
     &App::sub_entry;
     &App::sub_entry if ($App::trace >= 3);

Modified: p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm      (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/Oracle.pm      Tue Feb 17 
20:51:26 2009
@@ -131,9 +131,28 @@
             $offset = $startrow - 1;
         }
         #print STDERR "use_rownum_on_query? startrow=[$startrow] 
endrow=[$endrow] offset=[$offset] order_by=[$options->{order_by}]\n";
-        if (($startrow && $endrow && $endrow < $startrow) || ($endrow && 
!$offset && !$options->{order_by})) {
+        if ($startrow && $endrow && $endrow < $startrow) {
             $options->{use_rownum_on_query} = 1;
         }
+        elsif ($endrow && !$offset && !$options->{order_by}) {
+            my $is_summary = 0;
+            if ($options->{group_by}) {
+                $is_summary = 1;
+            }
+            else {
+                my ($is_summary_implied, $summary_key_exists) = 
$self->_assess_implied_summaries($table, $cols);
+                if ($is_summary_implied) {
+                    $is_summary = 1;
+                }
+                if (!$summary_key_exists) {
+                    delete $options->{endrow};
+                    $endrow = 0;
+                }
+            }
+            if (!$is_summary) {
+                $options->{use_rownum_on_query} = 1;
+            }
+        }
 
         $sql = $self->$method($table, $params, $cols, $options);
 

Modified: p5ee/trunk/App-Repository/t/DBI-select-limit.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-select-limit.t      (original)
+++ p5ee/trunk/App-Repository/t/DBI-select-limit.t      Tue Feb 17 20:51:26 2009
@@ -391,6 +391,65 @@
             
&test_get_rows($expect_sql,$nrows,$id0,$idn,$msg,"test_person",{},["person_id"],$options);
         }
     }
+    if ($dbtype eq "oracle") {
+        my ($row);
+        $expect_sql = <<EOF;
+select
+   count(*) as count_
+from test_person p
+EOF
+        $row = $rep->get_row("test_person", {}, ["count(*)"]);
+        $sql = $rep->{sql};
+        is($sql, $expect_sql,            "select count(*) limit 1 (Oracle) got 
right sql");
+        ok($row && ref($row) eq "ARRAY", "select count(*) limit 1 (Oracle) got 
one row");
+
+        $expect_sql = <<EOF;
+select a.* from
+(select
+   p.gender as gnd,
+   count(*) as count_
+from test_person p
+group by
+   p.gender
+) a where rownum <= 1
+EOF
+        $row = $rep->get_row("test_person", {}, ["gender", "count(*)"]);
+        $sql = $rep->{sql};
+        is($sql, $expect_sql,            "select gender, count(*) limit 1 
(Oracle) got right sql");
+        ok($row && ref($row) eq "ARRAY", "select gender, count(*) limit 1 
(Oracle) got one row");
+
+        $expect_sql = <<EOF;
+select a.* from
+(select
+   p.gender as gnd,
+   count(*) as count_
+from test_person p
+group by
+   p.gender
+) a where rownum <= 1
+EOF
+        $row = $rep->get_row("test_person", {}, ["gender", "count(*)"], 
{group_by => ["gender"]});
+        $sql = $rep->{sql};
+        is($sql, $expect_sql,            "select gender, count(*) limit 1 
(Oracle) got right sql");
+        ok($row && ref($row) eq "ARRAY", "select gender, count(*) limit 1 
(Oracle) got one row");
+
+        $expect_sql = <<EOF;
+select a.* from
+(select
+   p.gender as gnd,
+   count(*) as count_
+from test_person p
+group by
+   p.gender
+order by
+   gnd
+) a where rownum <= 1
+EOF
+        $row = $rep->get_row("test_person", {}, ["gender", "count(*)"], 
{order_by => ["gender"]});
+        $sql = $rep->{sql};
+        is($sql, $expect_sql,            "select gender, count(*) limit 1 
(Oracle) got right sql");
+        ok($row && ref($row) eq "ARRAY", "select gender, count(*) limit 1 
(Oracle) got one row");
+    }
 }
 
 exit 0;

Reply via email to