LP1281280: Improve query tree compression
authorMike Rylander <mrylander@gmail.com>
Tue, 15 Nov 2016 19:26:48 +0000 (14:26 -0500)
committerKathy Lussier <klussier@masslnc.org>
Thu, 9 Feb 2017 20:45:08 +0000 (15:45 -0500)
In addition to collapsing adjacent nodes sharing the same boolean operator,
we'll now also do the following two things: collapse filters, facets and
modifiers when there exists only a single subnode; and absorb single node
subplans.

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/QueryParser.pm

index 7d3b86d..090b944 100644 (file)
@@ -1552,6 +1552,32 @@ sub pullup {
     warn "Entering pullup depth ". $self->plan_level . "\n"
         if $self->QueryParser->debug;
 
+    my $old_qnodes = $self->query_nodes; # we will ignore all but ::node objects in this list
+    warn @$old_qnodes . " plans at pullup depth ". $self->plan_level . "\n"
+        if $self->QueryParser->debug;
+
+    # PASS 0: If I only have one child, collapse filters/modifiers into me 
+    if (@$old_qnodes == 1) {
+        my $kid = $$old_qnodes[0];
+        if ($kid->isa('QueryParser::query_plan')) {
+            $self->add_filter($_) foreach @{$kid->filters};
+            $self->add_facet($_) foreach @{$kid->facets};
+            $self->add_modifier($_) foreach @{$kid->modifiers};
+            $kid->{filters} = [];
+            $kid->{facets} = [];
+            $kid->{modifiers} = [];
+
+            my $kid_qnodes = $kid->query_nodes;
+            if (@$kid_qnodes == 1) { # And if my kid is a plan with only one node, absorb that
+                my $a = $$kid_qnodes[0];
+                if ($a->isa('QueryParser::query_plan')) {
+                    $self->{query} = [$a];
+                    return $self;
+                }
+            }
+        }
+    }
+
     # PASS 1: loop, attempting to pull up simple nodes
     my @new_nodes;
     my $prev_node;
@@ -1559,10 +1585,6 @@ sub pullup {
 
     my $prev_joiner;
 
-    my $old_qnodes = $self->query_nodes; # we will ignore all but ::node objects in this list
-    warn @$old_qnodes . " plans at pullup depth ". $self->plan_level . "\n"
-        if $self->QueryParser->debug;
-
     while (my $p = shift(@$old_qnodes)) {
 
         # joiners and ::node's get pushed onto the stack of new nodes
@@ -1618,7 +1640,6 @@ sub pullup {
     warn @new_nodes . " nodes after pullup of simple nodes at depth ". $self->plan_level . "\n"
         if $self->QueryParser->debug;
 
-
     # PASS 2: merge adjacent ::node's
     my $dangling = 0;
     my $sync_node = $prev_joiner = undef;