module SPARQL; module Algebra
class Operator
##
# The SPARQL `max` set function.
#
# [127] Aggregate::= ... | 'MAX' '(' 'DISTINCT'? Expression ')'
#
# @example SPARQL Grammar
# PREFIX :
# SELECT (MAX(?o) AS ?max)
# WHERE { ?s ?p ?o }
#
# @example SSE
# (prefix ((: ))
# (project (?max)
# (extend ((?max ??.0))
# (group () ((??.0 (max ?o)))
# (bgp (triple ?s ?p ?o))))))
#
# @see https://www.w3.org/TR/sparql11-query/#defn_aggMax
class Max < Operator
include Aggregate
NAME = :max
def initialize(*operands, **options)
raise ArgumentError,
"max operator accepts at most one argument with an optional :distinct" if
(operands - %i{distinct}).length != 1
super
end
##
# Max is a SPARQL set function that return the maximum value from a group respectively.
#
# It makes use of the SPARQL ORDER BY ordering definition, to allow ordering over arbitrarily typed expressions.
#
# @param [Enumerable>] enum
# enum of evaluated operand
# @return [RDF::Literal] The maximum value of the terms
def apply(enum, **options)
# FIXME: we don't actually do anything with distinct
operands.shift if distinct = (operands.first == :distinct)
if enum.empty?
raise TypeError, "Maximum of an empty multiset"
elsif enum.flatten.all? {|n| n.literal?}
RDF::Literal(enum.flatten.max)
else
raise TypeError, "Maximum of non-literals: #{enum.flatten}"
end
end
##
#
# Returns a partial SPARQL grammar for this operator.
#
# @return [String]
def to_sparql(**options)
"MAX(" + operands.to_sparql(**options) + ")"
end
end # Max
end # Operator
end; end # SPARQL::Algebra