...
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