Node::to_sql: NOT: only return an extra join, don't pass it to $right->to_sql()
authorIan Beckwith <ianb@erislabs.net>
Thu, 21 Oct 2010 14:08:16 +0000 (15:08 +0100)
committerIan Beckwith <ianb@erislabs.net>
Thu, 21 Oct 2010 14:08:16 +0000 (15:08 +0100)
lib/ID3FS/Path.pm
lib/ID3FS/Path/Node.pm

index 744946c..c683101 100644 (file)
@@ -670,6 +670,8 @@ sub tags_subselect
     my($self)=@_;
     my $hasvals=$self->expecting_values();
     my $tree=$self->{tagtree};
+    use Data::Dumper;
+    print Dumper $tree;
     my ($sqlclause, @joins)=$tree->to_sql($hasvals) if($tree);
     my $sql="\tSELECT fxt1.files_id FROM tags t1";
     my @crosses=();
index 3171dd4..a0a6b70 100644 (file)
@@ -79,6 +79,7 @@ sub to_sql
 
     if($self->type() != $TYPE_BOOL)
     {
+       print $self->{id}, " = ", $self->{name}, "\n";
        $str .= "t" . scalar(@joins) . ".id='" . $self->{id} . "'";
        if($not && !$hasvals)
        {
@@ -98,32 +99,23 @@ sub to_sql
     my $op=$self->name();
     if(defined($op))
     {
-       my $join=undef;
        # if we are ANDing add an inner join
-       # also if we are NOTing, but we are looking for a tag *value*
        if($op eq "AND")
        {
            # if right child is a NOT, we don't need extra join/brackets
            # NOT will do the same and we will end up with an extra one
-           $join= "INNER" unless($right && $right->name() && $right->name() eq "NOT");
+#          unless($right && $right->name() && $right->name() eq "NOT")
+#          {
+               push(@joins, "INNER");
+               push(@outjoins, "INNER");
+#          }
        }
        elsif($op eq "NOT")
        {
            $not=1;
-           $join = ($hasvals ? "INNER" : "LEFT");
-       }
-       elsif($op eq "OR")
-       {
-           # if the rightmost part of the left sub-expression ends in
-           # NOT, then we need an extra join. This doesn't apply if
-           # (as above) the righthand expression is a NOT.
-           $join="INNER" if(($self->right_ends_in_not($left)) &&
-                            !($right && $right->name() && $right->name() eq "NOT"));
-       }
-       if($join)
-       {
-           push(@joins, $join);
-           push(@outjoins, $join);
+           # return an extra join, but don't pass it down to $right->to_sql
+           # if we are looking for a tag *value*, use INNER join rather than LEFT
+           push(@outjoins, ($hasvals ? "INNER" : "LEFT"));
        }
     }
     my ($rightstr, @rightjoins) = $right->to_sql($hasvals, $not, @joins) if($right);
@@ -132,6 +124,14 @@ sub to_sql
     $str .= " $op " if($op && !$not);
     $str .= $rightstr;
     $str=("(" . $str . ")") if($op && $left && $right);
+#    print "LEFT (", scalar(@$leftjoins), "): ";
+#    print $leftstr if $leftstr;
+#    print "\n";
+#    print "OP: $op\n" if $op;
+#    print "RIGHT (", scalar(@$rightjoins), "): ";
+#    print $rightstr if $rightstr;
+#    print "\n";
+    print "OUT(", scalar(@outjoins), "): $str\n";
     return($str, @outjoins);
 }
 
@@ -148,6 +148,7 @@ sub used_tags
     return $self->id();
 }
 
+# does the bottom right-most expression end in a NOT?
 sub right_ends_in_not
 {
     my($self, $node)=@_;