elsif($state==$STATE_BOOLEAN)
{
my $parent=$self->tail();
- unless($self->is($TYPE_BOOL, $parent) && $parent->{name} eq "NOT")
+ unless($self->is($TYPE_BOOL, $parent) && $parent->name() eq "NOT")
{
@dents=("NOT");
}
my $parent=$self->tail();
my $allownot=1;
if($self->is($TYPE_BOOL, $parent) &&
- $parent->{name} eq "NOT")
+ $parent->name() eq "NOT")
{
$allownot=0;
}
my $nextjoin=undef;
my $lastop=undef;
return (@joins) unless(@elements);
- while(my $thing=shift @elements)
+ while(my $node=shift @elements)
{
- if($thing->type() == $TYPE_BOOL)
+ if($node->type() == $TYPE_BOOL)
{
- my $op=$thing->name();
+ my $op=$node->name();
if($op eq "AND")
{
$nextjoin="INNER";
if(@elements)
{
# if tag has a value, eat the tag, shifting to the value
- $thing=shift(@elements) if($elements[0]->type() == $TYPE_TAG);
+ if($elements[0]->type() == $TYPE_TAG)
+ {
+ $node->hasvals(1);
+ $node=shift(@elements);
+ }
+ else
+ {
+ $node->hasvals(0);
+ }
}
- elsif($self->{db}->tag_has_values($thing->id()))
+ elsif($self->{db}->tag_has_values($node->id()))
{
# if the expression ends in a tag that has a value
# (ie we have the tag and want the value)
push(@joins, $nextjoin);
$nextjoin=undef;
}
- $thing->table($table);
+ $node->table($table);
}
}
return @joins;
my($self, $elements)=@_;
return undef unless(@$elements);
my ($left, $right, $op)=(undef, undef, undef);
- my $thing=pop @$elements;
- if($self->is($TYPE_BOOL, $thing))
+ my $node=pop @$elements;
+ if($self->is($TYPE_BOOL, $node))
{
$right=$self->elements_to_tree($elements);
- if($thing->{name} ne "NOT")
+ if($node->name() ne "NOT")
{
$left=$self->elements_to_tree($elements);
}
- $thing->left($left);
- $thing->right($right);
+ $node->left($left);
+ $node->right($right);
}
- return $thing;
+ return $node;
}
# Dijkstra's shunting-yard algorithm
my ($self, @input)=@_;
my @opstack=();
my @output=();
- while(my $thing = shift @input)
+ while(my $node = shift @input)
{
- if($self->is($TYPE_TAG, $thing))
+ if($self->is($TYPE_TAG, $node))
{
# Handle tag values by dropping parent
if(@input && $self->is($TYPE_TAG, $input[0]))
{
- $thing=shift @input;
+ $node=shift @input;
}
- push(@output, $thing);
+ push(@output, $node);
}
- elsif($self->is($TYPE_BOOL, $thing))
+ elsif($self->is($TYPE_BOOL, $node))
{
while(@opstack &&
- ($priorities{$thing->{name}} <= $priorities{$opstack[$#opstack]->{name}}))
+ ($priorities{$node->name()} <= $priorities{$opstack[$#opstack]->name()}))
{
push(@output, pop(@opstack));
}
- push(@opstack, $thing);
+ push(@opstack, $node);
}
}
while(@opstack)
sub is
{
- my($self, $type, $thing)=@_;
- return 0 unless($thing);
- return 0 unless($thing->type());
- return 1 if($type == $thing->type());
+ my($self, $type, $node)=@_;
+ return 0 unless($node);
+ return 0 unless($node->type());
+ return 1 if($type == $node->type());
return 0;
}
my $sql="SELECT DISTINCT name FROM tags WHERE parents_id='';";
return($self->{db}->cmd_firstcol($sql));
}
- my $hasvals=$self->expecting_values();
my $sql="SELECT tags.name FROM ";
if($self->want_all_tags())
{
my $id=$self->trailing_tag_id();
my $parentclause= "tags.parents_id='";
- $parentclause .= $id if($hasvals);
+ $parentclause .= $id if($self->expecting_values());
$parentclause .= "'";
push(@andclauses, $parentclause);
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 ($sqlclause, @joins)=$tree->to_sql() if($tree);
my $sql="\tSELECT fxt1.files_id FROM tags t1";
my @crosses=();
my @inners=();
$self->{name}=shift;
$self->{parents_id}=shift;
$self->{table}=1;
- $self->{join}=undef;
+ $self->{hasvals}=undef;
if($self->{type} != $TYPE_BOOL)
{
my $table='';
sub id { return shift->set("id", shift); }
sub parents_id { return shift->set("parents_id", shift); }
sub table { return shift->set("table", shift); }
-sub join { return shift->set("join", shift); }
+sub hasvals { return shift->set("hasvals", shift); }
sub to_sql
{
- my($self, $hasvals, $not)=@_;
+ my($self, $not)=@_;
$not=0 unless(defined($not));
- $hasvals=0 unless(defined($hasvals));
my $str='';
if($self->type() != $TYPE_BOOL)
{
$str .= "t" . $self->table() . ".id='" . $self->{id} . "'";
- if($not && !$hasvals)
+ if($not && !$self->hasvals())
{
$str = "(" . $str . " AND fxt" . $self->table() . ".files_id IS NULL)";
}
my $right=$self->right();
return ("") unless($left || $right);
- my $leftstr = $left->to_sql($hasvals, $not) if($left);
+ my $leftstr = $left->to_sql($not) if($left);
my $op=$self->name();
$not=1 if(defined($op) && ($op eq "NOT"));
- my $rightstr = $right->to_sql($hasvals, $not) if($right);
+ my $rightstr = $right->to_sql($not) if($right);
$str = $leftstr;
$str .= " $op " if($op && !$not);
$str .= $rightstr;