| RDF-Query documentation | Contained in the RDF-Query distribution. |
RDF::Query::Expression::Function - Class for Function expressions
This document describes RDF::Query::Expression::Function version 2.907.
Beyond the methods documented below, this class inherits methods from the RDF::Query::Expression class.
new ( $uri, @arguments )Returns a new Expr structure.
uriReturns the URI of the function.
argumentsReturns a list of the arguments to the function.
sseReturns the SSE string for this algebra expression.
as_sparqlReturns the SPARQL string for this algebra expression.
typeReturns the type of this algebra expression.
qualify_uris ( \%namespaces, $base_uri )Returns a new algebra pattern where all referenced Resource nodes representing QNames (ns:local) are qualified using the supplied %namespaces.
evaluate ( $query, \%bound, $context )Evaluates the expression using the supplied bound variables. Will return a RDF::Query::Node object.
Gregory Todd Williams <gwilliams@cpan.org>
| RDF-Query documentation | Contained in the RDF-Query distribution. |
# RDF::Query::Expression::Function # -----------------------------------------------------------------------------
package RDF::Query::Expression::Function; use strict; use warnings; no warnings 'redefine'; use base qw(RDF::Query::Expression); use RDF::Query::Error qw(:try); use Data::Dumper; use Scalar::Util qw(blessed reftype); use Carp qw(carp croak confess); ###################################################################### our ($VERSION); BEGIN { $VERSION = '2.907'; } ###################################################################### our %FUNCTION_MAP = ( str => "STR", strdt => "STRDT", strlang => "STRLANG", lang => "LANG", langmatches => "LANGMATCHES", sameterm => "sameTerm", datatype => "DATATYPE", bound => "BOUND", isuri => "isURI", isiri => "isIRI", isblank => "isBlank", isliteral => "isLiteral", regex => "REGEX", iri => "IRI", uri => "IRI", bnode => "BNODE", in => "IN", notin => "NOT IN", if => "IF", );
sub new { my $class = shift; my $uri = shift; my @args = @_; unless (blessed($uri) and $uri->isa('RDF::Trine::Node::Resource')) { $uri = RDF::Query::Node::Resource->new( $uri ); } return $class->SUPER::new( $uri, @args ); }
sub uri { my $self = shift; return $self->op; }
sub arguments { my $self = shift; return $self->operands; }
sub sse { my $self = shift; my $context = shift; my $uri = $self->uri->uri_value; if ($uri =~ m/^(sop|sparql):(in|notin|str|strdt|strlang|if|iri|uri|bnode|lang|langmatches|sameTerm|datatype|regex|bound|is(URI|IRI|Blank|Literal))/i) { my $func = $2; return sprintf( '(%s %s)', $func, join(' ', map { $_->sse( $context ) } $self->arguments), ); } else { return sprintf( '(%s %s)', $self->uri->sse( $context ), join(' ', map { $_->sse( $context ) } $self->arguments), ); } }
sub as_sparql { my $self = shift; my $context = shift; my $indent = shift; my @args = $self->arguments; my $uri = $self->uri->uri_value; my $func = ($uri =~ m/^(sop|sparql):(in|notin|str|strdt|strlang|if|iri|uri|bnode|lang|langmatches|sameTerm|datatype|regex|bound|is(URI|IRI|Blank|Literal))/i) ? $FUNCTION_MAP{ lc($2) } : $self->uri->as_sparql( $context, $indent ); if ($func eq 'IN' or $func eq 'NOT IN') { my $term = shift(@args); my $string = sprintf( "%s %s (%s)", $term->as_sparql( $context, $indent ), $func, join(', ', map { $_->as_sparql( $context, $indent ) } @args), ); return $string; } else { my $string = sprintf( "%s(%s)", $func, join(', ', map { $_->as_sparql( $context, $indent ) } @args), ); return $string; } }
sub type { return 'FUNCTION'; }
sub qualify_uris { my $self = shift; my $class = ref($self); my $ns = shift; my $base_uri = shift; my @args; foreach my $arg ($self->construct_args) { if (blessed($arg) and $arg->isa('RDF::Query::Algebra')) { push(@args, $arg->qualify_uris( $ns, $base_uri )); } elsif (blessed($arg) and $arg->isa('RDF::Query::Node::Resource')) { my $uri = $arg->uri; if (ref($uri)) { my ($n,$l) = @$uri; unless (exists($ns->{ $n })) { throw RDF::Query::Error::QuerySyntaxError -text => "Namespace $n is not defined"; } my $resolved = RDF::Query::Node::Resource->new( join('', $ns->{ $n }, $l), $base_uri ); push(@args, $resolved); } else { push(@args, $arg); } } else { push(@args, $arg); } } return $class->new( @args ); }
sub evaluate { my $self = shift; my $query = shift || 'RDF::Query'; my $bound = shift; my $context = shift; my $uri = $self->uri; no warnings 'uninitialized'; my $uriv = $uri->uri_value; if ($uriv =~ /^sparql:logical-(.+)$/ or $uriv =~ /^sparql:(not)?in$/ or $uriv eq 'sparql:coalesce') { # logical operators must have their arguments passed lazily, because # some of them can still succeed even if some of their arguments throw # TypeErrors (e.g. true || fail ==> true). my @args = $self->arguments; my $args = sub { my $value = shift(@args); return unless (blessed($value)); my $val = 0; try { $val = $value->isa('RDF::Query::Expression') ? $value->evaluate( $query, $bound, $context ) : ($value->isa('RDF::Trine::Node::Variable')) ? $bound->{ $value->name } : $value; } otherwise {}; return $val || 0; }; my $func = $query->get_function( $uri ); my $value = $func->( $query, $args ); return $value; } elsif ($uriv =~ /^sparql:if$/) { my @args = $self->arguments; my $ebv = RDF::Query::Node::Resource->new( "sparql:ebv" ); my $expr = shift(@args); my $index = 1; try { my $exprval = $query->var_or_expr_value( $bound, $expr, $context ); my $func = RDF::Query::Expression::Function->new( $ebv, $exprval ); my $value = $func->evaluate( $query, {}, $context ); my $bool = ($value->literal_value eq 'true') ? 1 : 0; if ($bool) { $index = 0; } } catch RDF::Query::Error::TypeError with {}; my $expr2 = $args[$index]; return $query->var_or_expr_value( $bound, $expr2, $context ); } elsif ($uriv eq 'sparql:exists') { my $func = $query->get_function($uri); my ($ggp) = $self->arguments; return $func->( $query, $context, $bound, $ggp ); } else { my @args = map { $_->isa('RDF::Query::Algebra') ? $_->evaluate( $query, $bound, $context ) : ($_->isa('RDF::Trine::Node::Variable')) ? $bound->{ $_->name } : $_ } $self->arguments; my $func = $query->get_function($uri); unless ($func) { throw RDF::Query::Error::ExecutionError -text => "Failed to get function for IRI $uri"; } my $value = $func->( $query, @args ); return $value; } } 1; __END__