my @parts=@{$self->{components}};
my($tag, $tagval);
$self->{elements}=[];
+ $self->{bare_not}=0;
+ my $root_not=0;
+ my $tags_seen=0;
while(defined(my $name=shift @parts))
{
# print "NAME: $name\n";
}
elsif($name eq "NOT")
{
+ $root_not=1;
push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($self->{db}, $name));
$self->state($STATE_BOOLEAN);
}
if($tag)
{
push(@{$self->{elements}}, $tag);
+ $tags_seen++;
$self->state($STATE_TAG);
}
else
if($tag)
{
push(@{$self->{elements}}, $tag);
+ $tags_seen++;
$self->state($STATE_TAG);
}
else
$self->state($STATE_INVALID);
}
}
+
+ print "ROOT_NOT: $root_not TAGS_SEEN: $tags_seen\n";
+ if($root_not && ($tags_seen < 2))
+ {
+ $self->{bare_not}=1;
+ }
+
# remove trailing boolean
my @elements=@{$self->{elements}};
while(@elements && ref($elements[$#elements]) eq "ID3FS::PathElement::Boolean")
sub tags_subselect
{
my($self)=@_;
+ # we need to specially handle a bare /NOT/tag with no other clauses,
+ # using a simple WHERE id !='tagid' instead of a LEFT JOIN
+ if($self->{bare_not})
+ {
+ return $self->bare_not_subselect();
+ }
my $tree=$self->{tagtree};
my $hasvals=$self->tag_has_values();
my $parent=$self->trailing_tag_parent();
return $sql;
}
+sub bare_not_subselect
+{
+ my($self)=@_;
+ my @tags=grep { ref($_) eq "ID3FS::PathElement::Tag"; } @{$self->{elements}};
+ my $sql=("\tSELECT f1.id AS files_id FROM files f1 WHERE f1.id NOT IN (\n" .
+ "\t\tSELECT fxt1.files_id FROM tags t1\n" .
+ "\t\tINNER JOIN files_x_tags fxt1 ON t1.id=fxt1.tags_id\n" .
+ "\t\tWHERE ");
+ if(scalar(@tags) > 1)
+ {
+ $sql .= ("(t1.parents_id='" . $tags[0]->{id} . "' AND t1.id='" .
+ $tags[1]->{id} . "')");
+ }
+ else
+ {
+ $sql .= ("(t1.parents_id='' AND t1.id='" . $tags[0]->{id} . "')");
+ }
+ $sql .= "\n\t\tGROUP BY fxt1.files_id\n\t)\n";
+ return($sql);
+}
+
sub tags_subselect_and_not
{
my($self,@constraints)=@_;
$not=1;
push(@joins, "LEFT");
push(@outjoins, "LEFT");
- print("LEFT: ", $left->print(), "\n") if ($left);
- print("RIGHT: ", $right->print(), "\n") if($right);
+# print("LEFT: ", $left->print(), "\n") if ($left);
+# print("RIGHT: ", $right->print(), "\n") if($right);
}
}
my ($rightstr, @rightjoins) = $self->node_to_sql($right, $not, @joins);