File Coverage

blib/lib/AtteanX/API/JoinRotatingPlanner.pm
Criterion Covered Total %
statement 18 18 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 27 27 100.0


line stmt bran cond sub pod time code
1 1     1   8177 use v5.14;
  1         3  
2 1     1   7 use warnings;
  1         2  
  1         73  
3              
4             =encoding utf8
5              
6             =head1 NAME
7              
8             AtteanX::API::JoinRotatingPlanner - Query planning role to produce alternative join plans
9              
10             =head1 VERSION
11              
12             This document describes AtteanX::API::JoinRotatingPlanner version 0.032
13              
14             =head1 DESCRIPTION
15              
16             The AtteanX::API::JoinRotatingPlanner role, when used with L<Attean::QueryPlanner>,
17             produces alternatives for join query plans. Specifically, joins of the form
18             (A⋈B)⋈C are rotated to A⋈(B⋈C), with the ability to coalesce B⋈C (e.g. for
19             adjacent BGPs).
20              
21             =head1 REQUIRED METHODS
22              
23             =over 4
24              
25             =item C<< allow_join_rotation( $join_plan ) >>
26              
27             Returns true if join rotation should be attempted on the given join plan.
28              
29             =item C<< coalesce_rotated_join( $join_plan ) >>
30              
31             Given a L<Attean::API::Plan::Join> plan C<< $join_plan >>, returns a list of
32             equivalent plans. This is useful when the join can be reduced to a more
33             fundamental plan type, such as merging two adjacent BGP plans into a single
34             plan.
35              
36             =cut
37              
38             # Rotate joins like (A⋈B)⋈C to A⋈(B⋈C), with the ability to coalesce B⋈C (e.g. for adjacent BGPs)
39             use Attean;
40 1     1   7 use Attean::RDF;
  1         2  
  1         7  
41 1     1   4  
  1         2  
  1         14  
42             use Moo::Role;
43 1     1   929  
  1         2  
  1         8  
44             requires 'coalesce_rotated_join';
45             requires 'allow_join_rotation';
46            
47             return 1;
48             }
49 20     20 1 76
50             my $self = shift;
51             my $plan = shift;
52             return $plan;
53 48     48 1 83 }
54 48         62
55 48         147 around 'join_plans' => sub {
56             my $orig = shift;
57             my $self = shift;
58             my $model = shift;
59             my $active_graphs = shift;
60             my $default_graphs = shift;
61             my $lplans = shift;
62             my $rplans = shift;
63             my $type = shift;
64             my @plans = $orig->($self, $model, $active_graphs, $default_graphs, $lplans, $rplans, $type, @_);
65             if ($type eq 'inner') {
66             my @rotated;
67             foreach my $p (@plans) {
68             if ($self->allow_join_rotation($p)) {
69             my ($lhs, $rhs) = @{ $p->children };
70             if ($lhs->does('Attean::API::Plan::Join')) {
71             my ($a, $b) = @{ $lhs->children };
72             my $c = $rhs;
73             # (A⋈B)⋈C -> A⋈(B⋈C)
74             foreach my $q ($orig->($self, $model, $active_graphs, $default_graphs, [$b], [$c], $type, @_)) {
75             push(@rotated, $orig->($self, $model, $active_graphs, $default_graphs, [$a], [$self->coalesce_rotated_join($q)], $type, @_))
76             }
77             } elsif ($rhs->does('Attean::API::Plan::Join')) {
78             my $a = $lhs;
79             my ($b, $c) = @{ $rhs->children };
80             # A⋈(B⋈C) -> (A⋈B)⋈C
81             foreach my $q ($orig->($self, $model, $active_graphs, $default_graphs, [$a], [$b], $type, @_)) {
82             push(@rotated, $orig->($self, $model, $active_graphs, $default_graphs, [$self->coalesce_rotated_join($q)], [$c], $type, @_));
83             }
84             }
85             }
86             push(@rotated, $p);
87             }
88             return @rotated;
89             } else {
90             return @plans;
91             }
92             };
93             }
94              
95             1;
96              
97              
98             =back
99              
100             =head1 BUGS
101              
102             Please report any bugs or feature requests to through the GitHub web interface
103             at L<https://github.com/kasei/attean/issues>.
104              
105             =head1 SEE ALSO
106              
107              
108              
109             =head1 AUTHOR
110              
111             Gregory Todd Williams C<< <gwilliams@cpan.org> >>
112              
113             =head1 COPYRIGHT
114              
115             Copyright (c) 2014--2022 Gregory Todd Williams.
116             This program is free software; you can redistribute it and/or modify it under
117             the same terms as Perl itself.
118              
119             =cut