1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

Ticket #408 (closed defect: fixed)

Opened 18 months ago

Last modified 18 months ago

xsd:string cast fails for non-numeric data

Reported by: thompsonbry Owned by: mrpersonick
Priority: critical Milestone: Query
Component: Bigdata RDF Database Version: TERMS_REFACTOR_BRANCH
Keywords: Cc: thompsonbry

Description

This query is part of BSBM BI Q4.

prefix bsbm: <http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/>
prefix bsbm-inst: <http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/instances/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

Select ?feature ?price2 (xsd:string(?price2) As ?sumF)
      {
        ?product2 a <http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/instances/ProductType3> ;
                 bsbm:productFeature ?feature .
        ?offer2 bsbm:product ?product2 ;
               bsbm:price ?price2 .
      }
LIMIT 10

It relies on a cast to xsd:string of some values which look like:

    <literal datatype='http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/USD'>10.26</literal>

The cast is delegated by FuncBOp to the Sesame StringCast? operator. That operator looks like this:

	public Literal evaluate(ValueFactory valueFactory, Value... args)
		throws ValueExprEvaluationException
	{
		if (args.length != 1) {
			throw new ValueExprEvaluationException("xsd:string cast requires exactly 1 argument, got " + args.length);
		}

		Value value = args[0];
		if (value instanceof URI) {
			return valueFactory.createLiteral(value.toString(), XMLSchema.STRING);
		}
		else if (value instanceof Literal) {
			Literal literal = (Literal)value;
			URI datatype = literal.getDatatype();

			if (QueryEvaluationUtil.isSimpleLiteral(literal)) {
				return valueFactory.createLiteral(literal.getLabel(), XMLSchema.STRING);
			}
			else if (datatype != null) {
				if (datatype.equals(XMLSchema.STRING)) {
					return literal;
				}
				else if (XMLDatatypeUtil.isNumericDatatype(datatype) || datatype.equals(XMLSchema.BOOLEAN)
						|| datatype.equals(XMLSchema.DATETIME))
				{
					// FIXME: conversion to xsd:string is much more complex than
					// this, see
					// http://www.w3.org/TR/xpath-functions/#casting-from-primitive-to-primitive
					return valueFactory.createLiteral(literal.getLabel(), XMLSchema.STRING);
				}
			}
		}

		throw new ValueExprEvaluationException("Invalid argument for xsd:string cast: " + value);
	}

The cast fails with a ValueExprEvaluationException?, which is then turned into a SPARQLTypeErrorException. This cases the bindings for (xsd:string(?price2) As ?sumF) to be silently dropped from the aggregation in BSBM BI Q4.

Change History

Changed 18 months ago by mrpersonick

  • status changed from new to closed
  • resolution set to fixed

I fixed it by adding an xsd:string cast operator, but this is not actually a legal cast (from USD to xsd:string). See:

http://www.w3.org/TR/xpath-functions/#casting-from-primitive-to-primitive

Since USD is not actually a primitive type, a type error is actually the correct behavior. They should be using the Str operator in Sparql, not the xsd:string cast operator.

Note: See TracTickets for help on using tickets.