... my $selfJoin = $self->{leftTable}->same($self->{rightTable}); if ($selfJoin && !defined $self->{leftFromLabel}) { # one side must be fed from Pre label (but still let the user override) $self->{leftFromLabel} = $self->{leftTable}->getPreLabel(); } ... my ($leftLeft, $rightLeft); if ($self->{type} eq "inner") { $leftLeft = 0; $rightLeft = 0; } elsif ($self->{type} eq "left") { $leftLeft = 1; $rightLeft = 0; } elsif ($self->{type} eq "right") { $leftLeft = 0; $rightLeft = 1; } elsif ($self->{type} eq "outer") { $leftLeft = 1; $rightLeft = 1; } else { Carp::confess("Unknown value '" . $self->{type} . "' of option 'type', must be one of inner|left|right|outer"); } $self->{leftRowType} = $self->{leftTable}->getRowType(); $self->{rightRowType} = $self->{rightTable}->getRowType(); ... for my $side ( ("left", "right") ) { if (defined $self->{"${side}FromLabel"}) { ... } else { $self->{"${side}FromLabel"} = $self->{"${side}Table"}->getOutputLabel(); } my @keys; ($self->{"${side}IdxType"}, @keys) = $self->{"${side}Table"}->getType()->findIndexKeyPath(@{$self->{"${side}IdxPath"}}); # would already confess if the index is not found if (!$self->{overrideSimpleMinded}) { if (!$self->{"${side}IdxType"}->isLeaf() && ($self->{type} ne "inner" && $self->{type} ne $side) ) { my $table = $self->{"${side}Table"}; my $ixt = $self->{"${side}IdxType"}; if ($selfJoin && $side eq "left") { # the special case, reading from the table's Pre label; # must adjust the count for what will happen after the row gets processed $self->{"${side}GroupSizeCode"} = sub { # (opcode, row) if (&Triceps::isInsert($_[0])) { $table->groupSizeIdx($ixt, $_[1])+1; } else { $table->groupSizeIdx($ixt, $_[1])-1; } }; } else { $self->{"${side}GroupSizeCode"} = sub { # (opcode, row) $table->groupSizeIdx($ixt, $_[1]); }; } } } ... my $fieldsMirrorKey = 1; my $uniq = $self->{fieldsUniqKey}; if ($uniq eq "first") { $uniq = $self->{fieldsLeftFirst} ? "left" : "right"; } if ($uniq eq "none") { $fieldsMirrorKey = 0; } elsif ($uniq eq "manual") { # nothing to do } elsif ($uniq =~ /^(left|right)$/) { my($side, @keys); if ($uniq eq "left") { $side = "right"; @keys = @rightkeys; } else { $side = "left"; @keys = @leftkeys; } if (!defined $self->{"${side}Fields"}) { $self->{"${side}Fields"} = [ ".*" ]; # the implicit pass-all } unshift(@{$self->{"${side}Fields"}}, map("!$_", @keys) ); } else { Carp::confess("Unknown value '" . $self->{fieldsUniqKey} . "' of option 'fieldsUniqKey', must be one of none|manual|left|right|first"); } # now create the LookupJoins $self->{leftLookup} = Triceps::LookupJoin->new( unit => $self->{unit}, name => $self->{name} . ".leftLookup", leftRowType => $self->{leftRowType}, rightTable => $self->{rightTable}, rightIdxPath => $self->{rightIdxPath}, leftFields => $self->{leftFields}, rightFields => $self->{rightFields}, fieldsLeftFirst => $self->{fieldsLeftFirst}, fieldsMirrorKey => $fieldsMirrorKey, by => \@leftby, isLeft => $leftLeft, automatic => 1, oppositeOuter => ($rightLeft && !$self->{overrideSimpleMinded}), groupSizeCode => $self->{leftGroupSizeCode}, saveJoinerTo => $self->{leftSaveJoinerTo}, ); $self->{rightLookup} = Triceps::LookupJoin->new( unit => $self->{unit}, name => $self->{name} . ".rightLookup", leftRowType => $self->{rightRowType}, rightTable => $self->{leftTable}, rightIdxPath => $self->{leftIdxPath}, leftFields => $self->{rightFields}, rightFields => $self->{leftFields}, fieldsLeftFirst => !$self->{fieldsLeftFirst}, fieldsMirrorKey => $fieldsMirrorKey, by => \@rightby, isLeft => $rightLeft, automatic => 1, oppositeOuter => ($leftLeft && !$self->{overrideSimpleMinded}), groupSizeCode => $self->{rightGroupSizeCode}, saveJoinerTo => $self->{rightSaveJoinerTo}, ); # create the output label $self->{outputLabel} = $self->{unit}->makeDummyLabel($self->{leftLookup}->getResultRowType(), $self->{name} . ".out"); Carp::confess("$!") unless (ref $self->{outputLabel} eq "Triceps::Label"); # and connect them together $self->{leftFromLabel}->chain($self->{leftLookup}->getInputLabel()); $self->{rightFromLabel}->chain($self->{rightLookup}->getInputLabel()); $self->{leftLookup}->getOutputLabel()->chain($self->{outputLabel}); $self->{rightLookup}->getOutputLabel()->chain($self->{outputLabel});
So in the end it boils down to two LookupJoins, with the options computed from the JoinTwo's options. But you might notice that there are a few LookupJoin options that haven't been described before. And a few otehr methods not described before. They'll be described shortly.
No comments:
Post a Comment