sparqlrdf

Virtuoso 37000 Error SP031: SPARQL compiler: Variable is not allowed in a constant clause


This the result of my attempt to fill empty "published at" dates with "creation" dates.

Virtuoso 37000 Error SP031: SPARQL compiler: Variable 'entity' is not allowed in a constant clause

SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1

INSERT DATA {
  GRAPH <http://mysite.eu/collection/published> {
    ?entity <http://mysite.eu/collection/published-at> ?created
    WHERE {
      SELECT ?entity ?created WHERE {
        GRAPH <http://mysite.eu/collection/published> {
          {
            ?entity <http://purl.org/dc/terms/issued> ?created .
            OPTIONAL { ?s <http://mysite.eu/collection/published-at> ?published . }
            FILTER(!bound(?published))
          }
        }
      }
    }
  }
}

What is wrong here? What does the mentioned constant clause? How to fix this?

EDIT 1:

I can have a similar error with a simpler query, like this:

Virtuoso 37000 Error SP031: SPARQL compiler: Variable 'o' is not allowed in a constant clause

SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1

DELETE DATA {
  GRAPH <http://mysite.eu/collection/published> {
    <http://data.europa.eu/w21/33598e9e-2654-4639-9528-d70772837ce4> <http://mysite.eu/collection/published-at> ?o
  }
}

EDIT 2: The DELETE query works well like this:

DELETE WHERE {
  GRAPH <http://mysite.eu/collection/published> {
    <http://data.europa.eu/w21/33598e9e-2654-4639-9528-d70772837ce4> <http://mysite.eu/collection/published-at> ?o
  }
}

Solution

  • This SPARQL Update query is invalid. The INSERT DATA operation doesn’t allow variables, WHERE, FILTER etc. You need to use the INSERT operation, which has a WHERE clause:

    INSERT {
      # you can refer to the variables from the WHERE clause here
    }
    
    WHERE {
      # you can create variables here
    }
    

    Your WHERE clause itself also has an issue: ?entity contains all instances that have a dcterms:issued value. ?s contains all instances (instead of just the instances in ?entity) that don’t have a :published-at value. So, you probably want to use the variable ?entity instead of ?s.

    Something like this might work for you:

    PREFIX dcterms: <http://purl.org/dc/terms/>
    PREFIX : <http://mysite.eu/collection/>
    
    WITH <http://mysite.eu/collection/published> 
    # only use WITH to query and write to the same graph
    # if you don’t want that, you can include 'GRAPH' patterns in the 'INSERT' and in the 'WHERE' instead
    
    INSERT {
      ?entity :published-at ?created .
    }
    
    WHERE {
      ?entity dcterms:issued ?created .
      FILTER NOT EXISTS { ?entity :published-at [] . }
    }