File Coverage

blib/lib/RDF/Query/Plan/Join.pm
Criterion Covered Total %
statement 50 74 67.5
branch 1 12 8.3
condition 2 8 25.0
subroutine 15 16 93.7
pod 10 10 100.0
total 78 120 65.0


line stmt bran cond sub pod time code
1             # RDF::Query::Plan::Join
2             # -----------------------------------------------------------------------------
3              
4             =head1 NAME
5              
6             RDF::Query::Plan::Join - Join query plan base class.
7              
8             =head1 VERSION
9              
10             This document describes RDF::Query::Plan::Join version 2.915_01.
11              
12             =head1 METHODS
13              
14             Beyond the methods documented below, this class inherits methods from the
15             L<RDF::Query::Plan> class.
16              
17             =over 4
18              
19             =cut
20              
21             package RDF::Query::Plan::Join;
22              
23 35     35   268 use strict;
  35         61  
  35         854  
24 35     35   170 use warnings;
  35         68  
  35         1267  
25 35     35   239 use base qw(RDF::Query::Plan);
  35         61  
  35         2596  
26              
27 35     35   181 use Scalar::Util qw(blessed);
  35         68  
  35         1606  
28 35     35   19688 use RDF::Query::ExecutionContext;
  35         90  
  35         1574  
29              
30             ######################################################################
31              
32             our ($VERSION);
33             BEGIN {
34 35     35   24371 $VERSION = '2.915_01';
35             }
36              
37             ######################################################################
38              
39             =item C<< new ( $lhs, $rhs, $optional ) >>
40              
41             =cut
42              
43             sub new {
44 50     50 1 89 my $class = shift;
45 50         78 my $lhs = shift;
46 50         820 my $rhs = shift;
47 50         79 my $opt = shift;
48 50         212 my $self = $class->SUPER::new( $lhs, $rhs, $opt, @_ );
49            
50 50         90 my %vars;
51 50         232 my @lhs_rv = $lhs->referenced_variables;
52 50         185 my @rhs_rv = $rhs->referenced_variables;
53 50         131 foreach my $v (@lhs_rv, @rhs_rv) {
54 168         304 $vars{ $v }++;
55             }
56 50         284 $self->[0]{referenced_variables} = [ keys %vars ];
57 50         218 return $self;
58             }
59              
60             =item C<< lhs >>
61              
62             Returns the left-hand-side plan to the join.
63              
64             =cut
65              
66             sub lhs {
67 254     254 1 362 my $self = shift;
68 254         1258 return $self->[1];
69             }
70              
71             =item C<< rhs >>
72              
73             Returns the right-hand-side plan to the join.
74              
75             =cut
76              
77             sub rhs {
78 134     134 1 218 my $self = shift;
79 134         408 return $self->[2];
80             }
81              
82             =item C<< optional >>
83              
84             =cut
85              
86             sub optional {
87 8     8 1 14 my $self = shift;
88 8         38 return $self->[3];
89             }
90              
91             =item C<< bf () >>
92              
93             Returns a string representing the state of the nodes of the triple (bound or free).
94              
95             =cut
96              
97             sub bf {
98 0     0 1 0 my $self = shift;
99 0         0 my $context = shift;
100 0         0 my @bf;
101             my %var_to_num;
102 0         0 my %use_count;
103 0         0 my $counter = 1;
104 0         0 foreach my $t ($self->lhs, $self->rhs) {
105 0 0       0 unless ($t->can('bf')) {
106 0         0 throw RDF::Query::Error::ExecutionError -text => "Cannot compute bf for $t during join";
107             }
108 0         0 my $bf = $t->bf( $context );
109 0 0       0 if ($bf =~ /f/) {
110 0         0 $bf = '';
111 0         0 foreach my $n ($t->nodes) {
112 0 0       0 if ($n->isa('RDF::Trine::Node::Variable')) {
113 0         0 my $name = $n->name;
114 0   0     0 my $num = ($var_to_num{ $name } ||= $counter++);
115 0         0 $use_count{ $name }++;
116 0         0 $bf .= "{${num}}";
117             } else {
118 0         0 $bf .= 'b';
119             }
120             }
121             }
122 0         0 push(@bf, $bf);
123             }
124 0 0       0 if ($counter <= 10) {
125 0         0 for (@bf) {
126 0         0 s/[{}]//g;
127             }
128             }
129 0         0 my $bf = join(',',@bf);
130 0 0       0 return wantarray ? @bf : $bf;
131             }
132              
133             =item C<< join_classes >>
134              
135             Returns the class names of all available join algorithms.
136              
137             =cut
138              
139             sub join_classes {
140 44     44 1 88 my $class = shift;
141 44   50     123 my $config = shift || {};
142 44         61 our %JOIN_CLASSES;
143 44         244 my @classes = reverse sort keys %JOIN_CLASSES;
144             my @ok = grep {
145 44         97 my $name = lc($_);
  88         188  
146 88         368 $name =~ s/::/./g;
147 88 50 33     413 (exists $config->{ $name } and not($config->{ $name }))
148             ? 0
149             : 1
150             } @classes;
151 44         190 return @ok;
152             }
153              
154             =item C<< distinct >>
155              
156             Returns true if the pattern is guaranteed to return distinct results.
157              
158             =cut
159              
160             sub distinct {
161 25     25 1 111 return 0;
162             }
163              
164             =item C<< ordered >>
165              
166             Returns true if the pattern is guaranteed to return ordered results.
167              
168             =cut
169              
170             sub ordered {
171 25     25 1 246 return 0;
172             }
173              
174             =item C<< plan_prototype >>
175              
176             Returns a list of scalar identifiers for the type of the content (children)
177             nodes of this plan node. See L<RDF::Query::Plan> for a list of the allowable
178             identifiers.
179              
180             =cut
181              
182             sub plan_prototype {
183 7     7 1 16 my $self = shift;
184 7         26 return qw(P P);
185             }
186              
187             =item C<< plan_node_data >>
188              
189             Returns the data for this plan node that corresponds to the values described by
190             the signature returned by C<< plan_prototype >>.
191              
192             =cut
193              
194             sub plan_node_data {
195 10     10 1 17 my $self = shift;
196 10         16 my $expr = $self->[2];
197 10         34 return ($self->lhs, $self->rhs);
198             }
199              
200              
201             1;
202              
203             __END__
204              
205             =back
206              
207             =head1 AUTHOR
208              
209             Gregory Todd Williams <gwilliams@cpan.org>
210              
211             =cut