File Coverage

blib/lib/RDF/Query/Plan/Distinct.pm
Criterion Covered Total %
statement 44 60 73.3
branch 9 14 64.2
condition n/a
subroutine 11 15 73.3
pod 11 11 100.0
total 75 100 75.0


line stmt bran cond sub pod time code
1             # RDF::Query::Plan::Distinct
2             # -----------------------------------------------------------------------------
3              
4             =head1 NAME
5              
6             RDF::Query::Plan::Distinct - Executable query plan for Distincts.
7              
8             =head1 VERSION
9              
10             This document describes RDF::Query::Plan::Distinct 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::Distinct;
22              
23 35     35   190 use strict;
  35         75  
  35         891  
24 35     35   185 use warnings;
  35         67  
  35         936  
25 35     35   249 use base qw(RDF::Query::Plan);
  35         71  
  35         3148  
26              
27             ######################################################################
28              
29             our ($VERSION);
30             BEGIN {
31 35     35   25467 $VERSION = '2.915_01';
32             }
33              
34             ######################################################################
35              
36             =item C<< new ( $plan ) >>
37              
38             =cut
39              
40             sub new {
41 10     10 1 22 my $class = shift;
42 10         18 my $plan = shift;
43 10         57 my $self = $class->SUPER::new( $plan );
44 10         52 $self->[0]{referenced_variables} = [ $plan->referenced_variables ];
45 10         45 return $self;
46             }
47              
48             =item C<< execute ( $execution_context ) >>
49              
50             =cut
51              
52             sub execute ($) {
53 10     10 1 20 my $self = shift;
54 10         17 my $context = shift;
55 10         43 $self->[0]{delegate} = $context->delegate;
56 10 50       56 if ($self->state == $self->OPEN) {
57 0         0 throw RDF::Query::Error::ExecutionError -text => "DISTINCT plan can't be executed while already open";
58             }
59 10         23 my $plan = $self->[1];
60 10         52 $plan->execute( $context );
61              
62 10 50       44 if ($plan->state == $self->OPEN) {
63 10         28 $self->[0]{seen} = {};
64 10         45 $self->state( $self->OPEN );
65             } else {
66 0         0 warn "could not execute plan in distinct";
67             }
68 10         34 $self;
69             }
70              
71             =item C<< next >>
72              
73             =cut
74              
75             sub next {
76 30     30 1 49 my $self = shift;
77 30 50       94 unless ($self->state == $self->OPEN) {
78 0         0 throw RDF::Query::Error::ExecutionError -text => "next() cannot be called on an un-open DISTINCT";
79             }
80 30         56 my $plan = $self->[1];
81 30         47 while (1) {
82 33         112 my $row = $plan->next;
83 33 100       298 return undef unless ($row);
84 26 100       104 if (not $self->[0]{seen}{ $row->as_string }++) {
85 23 50       692 if (my $d = $self->delegate) {
86 0         0 $d->log_result( $self, $row );
87             }
88 23         74 return $row;
89             }
90             }
91             }
92              
93             =item C<< close >>
94              
95             =cut
96              
97             sub close {
98 10     10 1 25 my $self = shift;
99 10 50       36 unless ($self->state == $self->OPEN) {
100 0         0 throw RDF::Query::Error::ExecutionError -text => "close() cannot be called on an un-open DISTINCT";
101             }
102 10         34 delete $self->[0]{seen};
103 10         49 $self->[1]->close();
104 10         44 $self->SUPER::close();
105             }
106              
107             =item C<< pattern >>
108              
109             Returns the query plan that will be used to produce the data to be made distinct.
110              
111             =cut
112              
113             sub pattern {
114 10     10 1 20 my $self = shift;
115 10         58 return $self->[1];
116             }
117              
118             =item C<< distinct >>
119              
120             Returns true if the pattern is guaranteed to return distinct results.
121              
122             =cut
123              
124             sub distinct {
125 10     10 1 42 return 1;
126             }
127              
128             =item C<< ordered >>
129              
130             Returns true if the pattern is guaranteed to return ordered results.
131              
132             =cut
133              
134             sub ordered {
135 10     10 1 18 my $self = shift;
136 10         35 return $self->pattern->ordered;
137             }
138              
139             =item C<< plan_node_name >>
140              
141             Returns the string name of this plan node, suitable for use in serialization.
142              
143             =cut
144              
145             sub plan_node_name {
146 0     0 1   return 'distinct';
147             }
148              
149             =item C<< plan_prototype >>
150              
151             Returns a list of scalar identifiers for the type of the content (children)
152             nodes of this plan node. See L<RDF::Query::Plan> for a list of the allowable
153             identifiers.
154              
155             =cut
156              
157             sub plan_prototype {
158 0     0 1   my $self = shift;
159 0           return qw(P);
160             }
161              
162             =item C<< plan_node_data >>
163              
164             Returns the data for this plan node that corresponds to the values described by
165             the signature returned by C<< plan_prototype >>.
166              
167             =cut
168              
169             sub plan_node_data {
170 0     0 1   my $self = shift;
171 0           return ($self->pattern);
172             }
173              
174             =item C<< graph ( $g ) >>
175              
176             =cut
177              
178             sub graph {
179 0     0 1   my $self = shift;
180 0           my $g = shift;
181 0           my $c = $self->pattern->graph( $g );
182 0           $g->add_node( "$self", label => "Distinct" . $self->graph_labels );
183 0           $g->add_edge( "$self", $c );
184 0           return "$self";
185             }
186              
187              
188             1;
189              
190             __END__
191              
192             =back
193              
194             =head1 AUTHOR
195              
196             Gregory Todd Williams <gwilliams@cpan.org>
197              
198             =cut