sub to_sql
{
- my($self, $not, @joins)=@_;
+ my($self, $hasvals, $not, @joins)=@_;
$not=0 unless(defined($not));
my @outjoins=();
# init
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")
{
# 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";
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}))
$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";
}