fix NOT with tagvals
authorIan Beckwith <ianb@erislabs.net>
Sat, 16 Oct 2010 22:06:46 +0000 (23:06 +0100)
committerIan Beckwith <ianb@erislabs.net>
Sat, 16 Oct 2010 22:06:46 +0000 (23:06 +0100)
lib/ID3FS/Path.pm
lib/ID3FS/Path/Node.pm

index bb4eea0..dcfe0b7 100644 (file)
@@ -782,7 +782,7 @@ sub tags_subselect
 #      print "Trailing id: $tag\n";
     }
     my ($sqlclause, @joins)=(undef, ());
-    ($sqlclause, @joins) = $tree->to_sql() if($tree);
+    ($sqlclause, @joins) = $tree->to_sql($hasvals) if($tree);
 #    print "SQL(" . scalar(@joins) .": $sqlclause\n";
     my $sql="\tSELECT fxt1.files_id FROM tags t1";
     my @crosses=();
index 472fe41..fe74252 100644 (file)
@@ -58,7 +58,7 @@ sub print_node
 
 sub to_sql
 {
-    my($self, $not, @joins)=@_;
+    my($self, $hasvals, $not, @joins)=@_;
     $not=0 unless(defined($not));
     my @outjoins=();
     # init
@@ -69,16 +69,26 @@ sub to_sql
     my $left=$self->left();
     my $right=$self->right();
     return ("", @outjoins) unless($left || $right);
-    my ($leftstr, @leftjoins) = $self->node_to_sql($left, $not, @joins);
+    my ($leftstr, @leftjoins) = $self->node_to_sql($left, $hasvals, $not, @joins);
     push(@joins, @leftjoins);
     push(@outjoins, @leftjoins);
     my $op=$self->op();
     if(defined($op))
     {
-       if($op->{name} eq "AND")
+       # if we are ANDing, add an inner join
+       # also if we are NOTing, but we are looking for a tag *value*
+       if( ($op->{name}  eq "AND") ||
+           ($hasvals && ($op->{name} eq "NOT")))
        {
-           push(@joins, "INNER");
-           push(@outjoins, "INNER");
+           # hack - 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
+           unless($right && $right->{op}
+                  && $right->{op}->{name}
+                  && $right->{op}->{name} eq "NOT")
+           {
+               push(@joins, "INNER");
+               push(@outjoins, "INNER");
+           }
        }
        elsif($op->{name} eq "NOT")
        {
@@ -89,7 +99,7 @@ sub to_sql
 #          print("RIGHT: ", $right->print(), "\n") if($right);
        }
     }
-    my ($rightstr, @rightjoins) = $self->node_to_sql($right, $not, @joins);
+    my ($rightstr, @rightjoins) = $self->node_to_sql($right, $hasvals, $not, @joins);
     push(@outjoins, @rightjoins);
 #    print "LEFT (", scalar(@leftjoins), "): $leftstr\n";
 #    print "RIGHT (", scalar(@rightjoins), "): $rightstr\n";
@@ -106,9 +116,9 @@ sub to_sql
 
 sub node_to_sql
 {
-    my($self, $node, $not, @joins)=@_;
+    my($self, $node, $hasvals, $not, @joins)=@_;
     return ("", ()) unless(defined($node));
-    return $node->to_sql($not, @joins) if(ref($node) eq "ID3FS::Path::Node");
+    return $node->to_sql($hasvals, $not, @joins) if(ref($node) eq "ID3FS::Path::Node");
     my $sql;
     my $cnt=scalar(@joins)+1;
     if(defined($node->{parents_id}))
@@ -121,7 +131,7 @@ sub node_to_sql
        $sql= "(t" . scalar(@joins) .".parents_id=''";
        $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'";
     }
-    if($not)
+    if($not && !$hasvals)
     {
        $sql .= " AND fxt" . scalar(@joins) . ".files_id IS NULL";
     }