From 4d9a3e779039ded464b86ddec75994b540ced90a Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Thu, 21 Oct 2010 15:08:16 +0100 Subject: [PATCH] Node::to_sql: NOT: only return an extra join, don't pass it to $right->to_sql() --- lib/ID3FS/Path.pm | 2 ++ lib/ID3FS/Path/Node.pm | 35 ++++++++++++++++++----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/ID3FS/Path.pm b/lib/ID3FS/Path.pm index 744946c..c683101 100644 --- a/lib/ID3FS/Path.pm +++ b/lib/ID3FS/Path.pm @@ -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=(); diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index 3171dd4..a0a6b70 100644 --- a/lib/ID3FS/Path/Node.pm +++ b/lib/ID3FS/Path/Node.pm @@ -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)=@_; -- 2.11.0