<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head profile="http://internetalchemy.org/2003/02/profile"> <link rel="foaf" type="application/rdf+xml" title="FOAF" href="http://www.openlinksw.com/dataspace/uda/about.rdf" /> <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" /> <meta name="dc.title" content="14. RDF Data Access and Data Management" /> <meta name="dc.subject" content="14. RDF Data Access and Data Management" /> <meta name="dc.creator" content="OpenLink Software Documentation Team ; " /> <meta name="dc.copyright" content="OpenLink Software, 1999 - 2009" /> <link rel="top" href="index.html" title="OpenLink Virtuoso Universal Server: Documentation" /> <link rel="search" href="/doc/adv_search.vspx" title="Search OpenLink Virtuoso Universal Server: Documentation" /> <link rel="parent" href="rdfandsparql.html" title="Chapter Contents" /> <link rel="prev" href="rdfdatarepresentation.html" title="Data Representation" /> <link rel="next" href="sparqlextensions.html" title="Extensions" /> <link rel="shortcut icon" href="../images/misc/favicon.ico" type="image/x-icon" /> <link rel="stylesheet" type="text/css" href="doc.css" /> <link rel="stylesheet" type="text/css" href="/doc/translation.css" /> <title>14. RDF Data Access and Data Management</title> <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> <meta name="author" content="OpenLink Software Documentation Team ; " /> <meta name="copyright" content="OpenLink Software, 1999 - 2009" /> <meta name="keywords" content="" /> <meta name="GENERATOR" content="OpenLink XSLT Team" /> </head> <body> <div id="header"> <a name="rdfsparql" /> <img src="../images/misc/logo.jpg" alt="" /> <h1>14. RDF Data Access and Data Management</h1> </div> <div id="navbartop"> <div> <a class="link" href="rdfandsparql.html">Chapter Contents</a> | <a class="link" href="rdfdatarepresentation.html" title="Data Representation">Prev</a> | <a class="link" href="sparqlextensions.html" title="Extensions">Next</a> </div> </div> <div id="currenttoc"> <form method="post" action="/doc/adv_search.vspx"> <div class="search">Keyword Search: <br /> <input type="text" name="q" /> <input type="submit" name="go" value="Go" /> </div> </form> <div> <a href="http://www.openlinksw.com/">www.openlinksw.com</a> </div> <div> <a href="http://docs.openlinksw.com/">docs.openlinksw.com</a> </div> <br /> <div> <a href="index.html">Book Home</a> </div> <br /> <div> <a href="contents.html">Contents</a> </div> <div> <a href="preface.html">Preface</a> </div> <br /> <div class="selected"> <a href="rdfandsparql.html">RDF Data Access and Data Management</a> </div> <br /> <div> <a href="rdfdatarepresentation.html">Data Representation</a> </div> <div class="selected"> <a href="rdfsparql.html">SPARQL</a> <div> <a href="#rdfsparqlimplementationextent" title="SPARQL Implementation Details">SPARQL Implementation Details</a> <a href="#rdfpredicatessparql" title="Query Constructs">Query Constructs</a> <a href="#rdfsparqlprotocolendpoint" title="SPARQL Web Services & APIs">SPARQL Web Services & APIs</a> <a href="#sparqldebug" title="Troubleshooting SPARQL Queries">Troubleshooting SPARQL Queries</a> <a href="#rdfsparqlinline" title="SPARQL Inline in SQL">SPARQL Inline in SQL</a> <a href="#rdfapi" title="API Functions">API Functions</a> <a href="#rdfinternalfunctions" title="Useful Internal Functions">Useful Internal Functions</a> <a href="#rdfdefaultgraph" title="Default and Named Graphs">Default and Named Graphs</a> <a href="#rdfsqlfromsparql" title="Calling SQL from SPARQL">Calling SQL from SPARQL</a> <a href="#rdfsqlfromsparqldescribe" title="SPARQL DESCRIBE">SPARQL DESCRIBE</a> <a href="#rdfsparqlimplementatiotrans" title="Transitivity in SPARQL">Transitivity in SPARQL</a> <a href="#rdfsparqlimplementatioptragmas" title="Supported SPARQL-BI "define" pragmas">Supported SPARQL-BI "define" pragmas</a> <a href="#rdfsparqlbif" title="Built-in bif functions">Built-in bif functions</a> </div> </div> <div> <a href="sparqlextensions.html">Extensions</a> </div> <div> <a href="rdfgraphsecurity.html">RDF Graphs Security</a> </div> <div> <a href="rdfviews.html">Linked Data Views over RDBMS Data Source</a> </div> <div> <a href="rdfrdfviewgnr.html">Automated Generation of RDF Views over Relational Data Sources</a> </div> <div> <a href="rdfviewsenterpr.html">Examples of Linked Data Views</a> </div> <div> <a href="rdfinsertmethods.html">RDF Insert Methods in Virtuoso</a> </div> <div> <a href="virtuososponger.html">RDFizer Middleware (Sponger)</a> </div> <div> <a href="virtuosospongerfacetinstall.html">Virtuoso Faceted Browser Installation and configuration</a> </div> <div> <a href="virtuosospongerfacent.html">Virtuoso Faceted Web Service</a> </div> <div> <a href="rdfiridereferencing.html">Linked Data</a> </div> <div> <a href="rdfsparqlrule.html">Inference Rules & Reasoning</a> </div> <div> <a href="rdfsparqlgeospat.html">RDF and Geometry</a> </div> <div> <a href="rdfperformancetuning.html">RDF Performance Tuning</a> </div> <div> <a href="rdfnativestorageproviders.html">RDF Data Access Providers (Drivers)</a> </div> <div> <a href="rdfgraphreplication.html">RDF Graph Replication</a> </div> <br /> </div> <div id="text"> <a name="rdfsparql" /> <h2>14.2. SPARQL</h2> <a name="rdfsparqlimplementationextent" /> <h3>14.2.1. SPARQL Implementation Details</h3> <p>Virtuoso's RDF support includes in-built support for the SPARQL query language. It also includes a number of powerful extensions that cover path traversal and business intelligence features. In addition, there is in-built security based on Virtuoso's support for row level policy-based security, custom authentication, and named graphs.</p> <p>The current implementation does not support some SPARQL features:</p> <ul> <li>Unicode characters in names are not supported.</li> <li>Comments inside SPARQL queries are not supported when the query is inlined in SQL code.</li> </ul> <p>On the other hand, Virtuoso implements some extensions to SPARQL:</p> <ul> <li>SPARUL statements, such as <strong>insert</strong>, <strong>modify</strong>, <strong>load</strong> etc, are supported.</li> <li>The SPARQL compiler can be configured using <strong>define ...</strong> clauses, e.g. <strong>define output:valmode "LONG"</strong>.</li> <li>Expressions are allowed in triple patterns, both in a <strong>where</strong> clause and in constructor patterns. Such expressions are delimited by backquotes.</li> <li>Expressions are allowed in select statement result lists.</li> <li>Parameters can be passed to the query from outside, using <strong>?:variablename</strong> syntax.</li> <li>Aggregate functions are supported.</li> <li>Subqueries may appear where group patterns are allowed.</li> <li>A set of operators has been added to configure the mapping of relational data to RDF (aka Linked Data Views).</li> </ul> <p>The following listing shows the SPARQL grammar expressed in BNF, including all Virtuoso extensions but excluding rules for the syntax of each lexical element. Rule numbers in square brackets are from W3C normative SPARQL grammar. An asterisk indicates that the rule differs from the W3C grammar due to Virtuoso extensions - <strong>[Virt]</strong> means that the rule is Virtuoso-specific, <strong>[DML]</strong> indicates a data manipulation language extension from SPARUL. </p> <div> <pre class="programlisting"> [1]* Query ::= Prolog ( QueryBody | SparulAction* | ( QmStmt ('.' QmStmt)* '.'? ) ) [1] QueryBody ::= SelectQuery | ConstructQuery | DescribeQuery | AskQuery [2]* Prolog ::= Define* BaseDecl? PrefixDecl* [Virt] Define ::= 'DEFINE' QNAME (QNAME | Q_IRI_REF | String ) [3] BaseDecl ::= 'BASE' Q_IRI_REF [4] PrefixDecl ::= 'PREFIX' QNAME_NS Q_IRI_REF [5]* SelectQuery ::= 'SELECT' 'DISTINCT'? ( ( Retcol ( ','? Retcol )* ) | '*' ) DatasetClause* WhereClause SolutionModifier [6] ConstructQuery ::= 'CONSTRUCT' ConstructTemplate DatasetClause* WhereClause SolutionModifier DatasetClause* WhereClause? SolutionModifier [8] AskQuery ::= 'ASK' DatasetClause* WhereClause [9] DatasetClause ::= 'FROM' ( DefaultGraphClause | NamedGraphClause ) [10]* DefaultGraphClause ::= SourceSelector SpongeOptionList? [11]* NamedGraphClause ::= 'NAMED' SourceSelector SpongeOptionList? [Virt] SpongeOptionList ::= 'OPTION' '(' ( SpongeOption ( ',' SpongeOption )* )? ')' [Virt] SpongeOption ::= QNAME PrecodeExpn [Virt] PrecodeExpn ::= Expn (* Only global variables can occur in Expn, local cannot *) [13] WhereClause ::= 'WHERE'? GroupGraphPattern [14] SolutionModifier ::= OrderClause? ((LimitClause OffsetClause?) | (OffsetClause LimitClause?))? [15] OrderClause ::= 'ORDER' 'BY' OrderCondition+ [16]* OrderCondition ::= ( 'ASC' | 'DESC' )? ( FunctionCall | Var | ( '(' Expn ')' ) | ( '[' Expn ']' ) ) [17] LimitClause ::= 'LIMIT' INTEGER [17] LimitClause ::= 'LIMIT' INTEGER [18] OffsetClause ::= 'OFFSET' INTEGER [18] OffsetClause ::= 'OFFSET' INTEGER [19]* GroupGraphPattern ::= '{' ( GraphPattern | SelectQuery ) '}' [20] GraphPattern ::= Triples? ( GraphPatternNotTriples '.'? GraphPattern )? [21]* GraphPatternNotTriples ::= QuadMapGraphPattern | OptionalGraphPattern | GroupOrUnionGraphPattern | GraphGraphPattern | Constraint [22] OptionalGraphPattern ::= 'OPTIONAL' GroupGraphPattern [Virt] QuadMapGraphPattern ::= 'QUAD' 'MAP' ( IRIref | '*' ) GroupGraphPattern [23] GraphGraphPattern ::= 'GRAPH' VarOrBlankNodeOrIRIref GroupGraphPattern [24] GroupOrUnionGraphPattern ::= GroupGraphPattern ( 'UNION' GroupGraphPattern )* [25]* Constraint ::= 'FILTER' ( ( '(' Expn ')' ) | BuiltInCall | FunctionCall ) [26]* ConstructTemplate ::= '{' ConstructTriples '}' [27] ConstructTriples ::= ( Triples1 ( '.' ConstructTriples )? )? [28] Triples ::= Triples1 ( '.' Triples? )? [29] Triples1 ::= VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList [30] PropertyList ::= PropertyListNotEmpty? [31] PropertyListNotEmpty ::= Verb ObjectList ( ';' PropertyList )? [32]* ObjectList ::= ObjGraphNode ( ',' ObjectList )? [Virt] ObjGraphNode ::= GraphNode TripleOptions? [Virt] TripleOptions ::= 'OPTION' '(' TripleOption ( ',' TripleOption )? ')' [Virt] TripleOption ::= 'INFERENCE' ( QNAME | Q_IRI_REF | SPARQL_STRING ) [33] Verb ::= VarOrBlankNodeOrIRIref | 'a' [34] TriplesNode ::= Collection | BlankNodePropertyList [35] BlankNodePropertyList ::= '[' PropertyListNotEmpty ']' [36] Collection ::= '(' GraphNode* ')' [37] GraphNode ::= VarOrTerm | TriplesNode [38] VarOrTerm ::= Var | GraphTerm [39]* VarOrIRIrefOrBackquoted ::= Var | IRIref | Backquoted [40]* VarOrBlankNodeOrIRIrefOrBackquoted ::= Var | BlankNode | IRIref | Backquoted [Virt] Retcol ::= ( Var | ( '(' Expn ')' ) | RetAggCall ) ( 'AS' ( VAR1 | VAR2 ) )? [Virt] RetAggCall ::= AggName '(', ( '*' | ( 'DISTINCT'? Var ) ) ')' [Virt] AggName ::= 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'SUM' [41]* Var ::= VAR1 | VAR2 | GlobalVar | ( Var ( '+>' | '*>' ) IRIref ) [Virt] GlobalVar ::= QUEST_COLON_PARAMNAME | DOLLAR_COLON_PARAMNAME | QUEST_COLON_PARAMNUM | DOLLAR_COLON_PARAMNUM [42]* GraphTerm ::= IRIref | RDFLiteral | ( '-' | '+' )? NumericLiteral | BooleanLiteral | BlankNode | NIL | Backquoted [Virt] Backquoted ::= '`' Expn '`' [43] Expn ::= ConditionalOrExpn [44] ConditionalOrExpn ::= ConditionalAndExpn ( '||' ConditionalAndExpn )* [45] ConditionalAndExpn ::= ValueLogical ( '&&' ValueLogical )* [46] ValueLogical ::= RelationalExpn [47]* RelationalExpn ::= NumericExpn ( ( ('='|'!='|'<'|'>'|'<='|'>='|'LIKE') NumericExpn ) | ( 'IN' '(' Expns ')' ) )? [49] AdditiveExpn ::= MultiplicativeExpn ( ('+'|'-') MultiplicativeExpn )* [50] MultiplicativeExpn ::= UnaryExpn ( ('*'|'/') UnaryExpn )* [51] UnaryExpn ::= ('!'|'+'|'-')? PrimaryExpn [58] PrimaryExpn ::= BracketedExpn | BuiltInCall | IRIrefOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | Var [55] IRIrefOrFunction ::= IRIref ArgList? [52]* BuiltInCall ::= ( 'STR' '(' Expn ')' ) | ( 'IRI' '(' Expn ')' ) | ( 'LANG' '(' Expn ')' ) | ( 'LANGMATCHES' '(' Expn ',' Expn ')' ) | ( 'DATATYPE' '(' Expn ')' ) | ( 'BOUND' '(' Var ')' ) | ( 'sameTERM' '(' Expn ',' Expn ')' ) | ( 'isIRI' '(' Expn ')' ) | ( 'isURI' '(' Expn ')' ) | ( 'isBLANK' '(' Expn ')' ) | ( 'isLITERAL' '(' Expn ')' ) | RegexExpn [53] RegexExpn ::= 'REGEX' '(' Expn ',' Expn ( ',' Expn )? ')' [54] FunctionCall ::= IRIref ArgList [56]* ArgList ::= ( NIL | '(' Expns ')' ) [Virt] Expns ::= Expn ( ',' Expn )* [59] NumericLiteral ::= INTEGER | DECIMAL | DOUBLE [60] RDFLiteral ::= String ( LANGTAG | ( '^^' IRIref ) )? [61] BooleanLiteral ::= 'true' | 'false' [63] IRIref ::= Q_IRI_REF | QName [64] QName ::= QNAME | QNAME_NS [65]* BlankNode ::= BLANK_NODE_LABEL | ( '[' ']' ) [DML] SparulAction ::= CreateAction | DropAction | LoadAction | InsertAction | InsertDataAction | DeleteAction | DeleteDataAction | ModifyAction | ClearAction [DML]* InsertAction ::= 'INSERT' ( ( 'IN' | 'INTO ) 'GRAPH' ( 'IDENTIFIED' 'BY' )? )? PrecodeExpn ConstructTemplate ( DatasetClause* WhereClause SolutionModifier )? [DML]* InsertDataAction ::= 'INSERT' 'DATA' ( ( 'IN' | 'INTO ) 'GRAPH' ( 'IDENTIFIED' 'BY' )? )? PrecodeExpn ConstructTemplate [DML]* DeleteAction ::= 'DELETE' ( 'FROM' 'GRAPH' ( 'IDENTIFIED' 'BY' )? )? PrecodeExpn ConstructTemplate ( DatasetClause* WhereClause SolutionModifier )? [DML]* DeleteDataAction ::= 'DELETE' 'DATA' ( 'FROM' 'GRAPH' ( 'IDENTIFIED' 'BY' )? )? PrecodeExpn ConstructTemplate [DML]* ModifyAction ::= 'MODIFY' ( 'GRAPH' ( 'IDENTIFIED' 'BY' )? PrecodeExpn? 'DELETE' ConstructTemplate 'INSERT' ConstructTemplate ( DatasetClause* WhereClause SolutionModifier )? [DML]* ClearAction ::= 'CLEAR' ( 'GRAPH' ( 'IDENTIFIED' 'BY' )? PrecodeExpn )? [DML]* LoadAction ::= 'LOAD' PrecodeExpn ( ( 'IN' | 'INTO' ) 'GRAPH' ( 'IDENTIFIED' 'BY' )? PrecodeExpn )? [DML]* CreateAction ::= 'CREATE' 'SILENT'? 'GRAPH' ( 'IDENTIFIED' 'BY' )? PrecodeExpn [DML]* DropAction ::= 'DROP' 'SILENT'? 'GRAPH' ( 'IDENTIFIED' 'BY' )? PrecodeExpn [Virt] QmStmt ::= QmSimpleStmt | QmCreateStorage | QmAlterStorage [Virt] QmSimpleStmt ::= QmCreateIRIClass | QmCreateLiteralClass | QmDropIRIClass | QmDropLiteralClass | QmCreateIRISubclass | QmDropQuadStorage | QmDropQuadMap [Virt] QmCreateIRIClass ::= 'CREATE' 'IRI' 'CLASS' QmIRIrefConst ( ( String QmSqlfuncArglist ) | ( 'USING' QmSqlfuncHeader ',' QmSqlfuncHeader ) ) [Virt] QmCreateLiteralClass ::= 'CREATE' 'LITERAL' 'CLASS' QmIRIrefConst 'USING' QmSqlfuncHeader ',' QmSqlfuncHeader QmLiteralClassOptions? [Virt] QmDropIRIClass ::= 'DROP' 'IRI' 'CLASS' QmIRIrefConst [Virt] QmDropLiteralClass ::= 'DROP' 'LITERAL' 'CLASS' QmIRIrefConst [Virt] QmCreateIRISubclass ::= 'IRI' 'CLASS' QmIRIrefConst 'SUBCLASS' 'OF' QmIRIrefConst [Virt] QmIRIClassOptions ::= 'OPTION' '(' QmIRIClassOption (',' QmIRIClassOption)* ')' [Virt] QmIRIClassOption ::= 'BIJECTION' | 'DEREF' | 'RETURNS' STRING ('UNION' STRING)* [Virt] QmLiteralClassOptions ::= 'OPTION' '(' QmLiteralClassOption (',' QmLiteralClassOption)* ')' [Virt] QmLiteralClassOption ::= ( 'DATATYPE' QmIRIrefConst ) | ( 'LANG' STRING ) | ( 'LANG' STRING ) | 'BIJECTION' | 'DEREF' | 'RETURNS' STRING ('UNION' STRING)* [Virt] QmCreateStorage ::= 'CREATE' 'QUAD' 'STORAGE' QmIRIrefConst QmSourceDecl* QmMapTopGroup [Virt] QmAlterStorage ::= 'ALTER' 'QUAD' 'STORAGE' QmIRIrefConst QmSourceDecl* QmMapTopGroup [Virt] QmDropStorage ::= 'DROP' 'QUAD' 'STORAGE' QmIRIrefConst [Virt] QmDropQuadMap ::= 'DROP' 'QUAD' 'MAP' 'GRAPH'? QmIRIrefConst [Virt] QmDrop ::= 'DROP' 'GRAPH'? QmIRIrefConst [Virt] QmSourceDecl ::= ( 'FROM' QTABLE 'AS' PLAIN_ID QmTextLiteral* ) | ( 'FROM' PLAIN_ID 'AS' PLAIN_ID QmTextLiteral* ) | QmCondition [Virt] QmTextLiteral ::= 'TEXT' 'XML'? 'LITERAL' QmSqlCol ( 'OF' QmSqlCol )? QmTextLiteralOptions? [Virt] QmTextLiteralOptions ::= 'OPTION' '(' QmTextLiteralOption ( ',' QmTextLiteralOption )* ')' [Virt] QmMapTopGroup ::= '{' QmMapTopOp ( '.' QmMapTopOp )* '.'? '}' [Virt] QmMapTopOp ::= QmMapOp | QmDropQuadMap | QmDrop [Virt] QmMapGroup ::= '{' QmMapOp ( '.' QmMapOp )* '.'? '}' [Virt] QmMapOp ::= ( 'CREATE' QmIRIrefConst 'AS' QmMapIdDef ) | ( 'CREATE' 'GRAPH'? QmIRIrefConst 'USING' 'STORAGE' QmIRIrefConst QmOptions? ) | ( QmNamedField+ QmOptions? QmMapGroup ) | QmTriples1 [Virt] QmMapIdDef ::= QmMapTriple | ( QmNamedField+ QmOptions? QmMapGroup ) [Virt] QmMapTriple ::= QmFieldOrBlank QmVerb QmObjField [Virt] QmTriples1 ::= QmFieldOrBlank QmProps [Virt] QmNamedField ::= ('GRAPH'|'SUBJECT'|'PREDICATE'|'OBJECT') QmField [Virt] QmProps ::= QmProp ( ';' QmProp )? [Virt] QmProp ::= QmVerb QmObjField ( ',' QmObjField )* [Virt] QmObjField ::= QmFieldOrBlank QmCondition* QmOptions? [Virt] QmIdSuffix ::= 'AS' QmIRIrefConst [Virt] QmVerb ::= QmField | ( '[' ']' ) | 'a' [Virt] QmFieldOrBlank ::= QmField | ( '[' ']' ) [Virt] QmField ::= NumericLiteral | RdfLiteral | ( QmIRIrefConst ( '(' ( QmSqlCol ( ',' QmSqlCol )* )? ')' )? ) | QmSqlCol [Virt] QmCondition ::= 'WHERE' ( ( '(' SQLTEXT ')' ) | String ) [Virt] QmOptions ::= 'OPTION' '(' QmOption ( ',' QmOption )* ')' [Virt] QmOption ::= ( 'SOFT'? 'EXCLUSIVE' ) | ( 'ORDER' INTEGER ) | ( 'USING' PLAIN_ID ) [Virt] QmSqlfuncHeader ::= 'FUNCTION' SQL_QTABLECOLNAME QmSqlfuncArglist 'RETURNS' QmSqltype [Virt] QmSqlfuncArglist ::= '(' ( QmSqlfuncArg ( ',' QmSqlfuncArg )* )? ')' [Virt] QmSqlfuncArg ::= ('IN' | QmSqlId) QmSqlId QmSqltype [Virt] QmSqltype ::= QmSqlId ( 'NOT' 'NULL' )? [Virt] QmSqlCol ::= QmSqlId | spar_qm_sql_id [Virt] QmSqlId ::= PLAIN_ID | 'TEXT' | 'XML' [Virt] QmIRIrefConst ::= IRIref | ( 'IRI' '(' String ')' ) </pre> </div> <p> <strong>Example: Using OFFSET and LIMIT</strong> </p> <p> Virtuoso uses a zero-based index for OFFSET. Thus, in the example below, the query returns 1000 rows starting from, and including, record 9001 of the result set. Note that the default value of the MaxSortedTopRows parameter in the [Parameters] section of the virtuoso.ini configuration file defaults to 10000, so in this example its value will need to have been increased beforehand. </p> <div> <pre class="programlisting"> SQL>SELECT ?name ORDER BY ?name OFFSET 9000 LIMIT 1000 </pre> </div> <p>LIMIT applies to the solution resulting from the graph patterns specified in the WHERE CLAUSE. This implies that SELECT and CONSTRUCT/DESCRIBE queries will behave a little differently. In the case of a SELECT, there is a straight translation i.e. LIMIT 4 implies 4 records in the result set. In the case of CONSTRUCTs where the solution is a graph (implying that the existence of duplicates and/or unbound variables is common) LIMIT is basically a maximum triples threshold of: [Solution Triples] x [LIMIT]. </p> <p> Example query: </p> <div> <pre class="programlisting"> SQL>SPARQL prefix dct:<http://purl.org/dc/terms/> prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> CONSTRUCT { ?resource dct:title ?title ; a ?type } FROM <http://msone.computas.no/graphs/inferred/classification> FROM <http://msone.computas.no/graphs> FROM <http://msone.computas.no/graphs/instance/nfi> FROM <http://msone.computas.no/graphs/instance/mo> FROM <http://msone.computas.no/graphs/ontology/mediasone> FROM <http://msone.computas.no/graphs/vocab/mediasone> FROM <http://msone.computas.no/graphs/inferred/nfi/realisation1> FROM <http://msone.computas.no/graphs/inferred/mo/realisation1> FROM <http://msone.computas.no/graphs/inferred/nfi/realisation2> FROM <http://msone.computas.no/graphs/inferred/mo/realisation2> FROM <http://msone.computas.no/graphs/inferred/agent-classification> FROM <http://msone.computas.no/graphs/ontology/mediasone/agent> WHERE { { ?resource a ?type . FILTER (?type = <http://www.w3.org/2002/07/owl#Class> ) . ?resource rdfs:label ?title . } UNION { ?resource a ?type . FILTER (?type in ( <http://musicbrainz.org/mm/mm-2.1#Track> , <http://www.csd.abdn.ac.uk/~ggrimnes/dev/imdb/IMDB#Movie> , <http://xmlns.com/foaf/0.1/Image> , <http://www.computas.com/mediasone#Text> ) ) . ?resource dct:title ?title . } FILTER regex(?title, "turi", "i") } ORDER BY ?title LIMIT 4 OFFSET 0 </pre> </div> <a name="rdfsparqlandxquery" /> <h4>14.2.1.1. SPARQL and XQuery Core Function Library</h4> <p>In the current implementation, the XQuery Core Function Library is not available from SPARQL.</p> <p>As a temporary workaround, string parsing functions are made available, because they are widely used in W3C DAWG examples and the like. They are:</p> <div> <pre class="programlisting"> xsd:boolean (in strg any) returns integer xsd:dateTime (in strg any) returns datetime xsd:double (in strg varchar) returns double precision xsd:float (in strg varchar) returns float xsd:integer (in strg varchar) returns integer </pre> </div> <p>(assuming that the query contains the declaration: 'PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>')</p> <br /> <br /> <a name="rdfpredicatessparql" /> <h3>14.2.2. Query Constructs</h3> <p>Starting from Version 5.0, Virtuoso supports filtering RDF objects triples by a given predicate.</p> <a name="rdfpredicatessparqlexamples" /> <h4>14.2.2.1. Examples</h4> <p>The boolean functions bif:contains, bif:xcontains, bif:xpath_contains and bif:xquery_contains can be used for objects that come from Linked Data Views as well as for regular "physical" triples. Each of these functions takes two arguments and returns a boolean value. The first argument is a local variable which should also be used as an object field in the group pattern where the filter condition is placed. </p> <p>In order to execute the examples below please run these commands:</p> <div> <pre class="programlisting"> SQL>SPARQL CLEAR GRAPH <http://MyTest.com>; DB.DBA.RDF_QUAD_URI_L ('http://MyTest.com', 'sxml1', 'p_all1', xtree_doc ('<Hello>world</Hello>')); DB.DBA.RDF_QUAD_URI_L ('http://MyTest.com', 'sxml2', 'p_all2', xtree_doc ('<Hello2>world</Hello2>')); DB.DBA.RDF_QUAD_URI_L ('http://MyTest.com', 'nonxml1', 'p_all3', 'Hello world'); VT_INC_INDEX_DB_DBA_RDF_OBJ(); DB.DBA.RDF_OBJ_FT_RULE_ADD ('http://MyTest.com', null, 'My test RDF Data'); </pre> </div> <p> <strong>bif:contains</strong> </p> <div> <pre class="programlisting"> SQL>SPARQL SELECT * FROM <http://MyTest.com> WHERE { ?s ?p ?o . ?o bif:contains "world" }; s p o VARCHAR VARCHAR VARCHAR _______________________________________________________________________________ sxml1 p_all1 <Hello>world</Hello> nonxml1 p_all3 Hello world sxml2 p_all2 <Hello2>world</Hello2> 3 Rows. -- 20 msec. </pre> </div> <p> <strong>bif:xcontains</strong> </p> <div> <pre class="programlisting"> SQL>SPARQL SELECT * FROM <http://MyTest.com> WHERE { ?s ?p ?o . ?o bif:xcontains "//Hello[text-contains (., 'world')]" }; s p o VARCHAR VARCHAR VARCHAR _______________________________________________________________________________ sxml1 p_all <Hello>world</Hello> 1 Rows. -- 10 msec. </pre> </div> <p> <strong>bif:xpath_contains</strong> </p> <div> <pre class="programlisting"> SQL>SPARQL SELECT * FROM <http://MyTest.com> WHERE { ?s ?p ?o . ?o bif:xpath_contains "//*" }; s p o VARCHAR VARCHAR VARCHAR _______________________________________________________________________________ sxml1 p_all1 <Hello>world</Hello> sxml2 p_all2 <Hello2>world</Hello2> 2 Rows. -- 20 msec. </pre> </div> <p> <strong>bif:xquery_contains</strong> </p> <div> <pre class="programlisting"> SQL>SPARQL SELECT * FROM <http://MyTest.com> WHERE { ?s ?p ?o . ?o bif:xquery_contains "//Hello2 , world" }; s p o VARCHAR VARCHAR VARCHAR _______________________________________________________________________________ sxml2 p_all2 <Hello2>world</Hello2> 1 Rows. -- 20 msec. </pre> </div> <br /> <br /> <a name="rdfsparqlprotocolendpoint" /> <h3>14.2.3. SPARQL Web Services & APIs</h3> <a name="rdfsparqlprotocolendpointintro" /> <h4>14.2.3.1. Introduction</h4> <p>The Virtuoso SPARQL query service implements the <a href="http://www.w3.org/TR/rdf-sparql-protocol/">SPARQL Protocol for RDF</a> (W3C Working Draft 25 January 2006) providing SPARQL query processing for RDF data available on the open internet.</p> <p>The query processor extends the standard protocol to provide support for multiple output formats. At present this uses additional query parameters.</p> <p>Supported features include:</p> <ul> <li>Support for GET and POST requests</li> <li>Support for a variety of transfer MIME-types, including RDF /XML and TURTLE</li> <li>Support for a <strong>default-graph-uri</strong> parameter</li> <li>Support for a variety of query types including CONSTRUCT and DESCRIBE</li> </ul> <p>Virtuoso also supports /sparql-graph-crud/ web service endpoint that implements the current draft of <a href="http://www.w3.org/TR/sparql11-http-rdf-update/">W3C SPARQL Graph Update protocol</a>. Both /sparql /sparql-graph-crud/ endpoints use the same SPARQL user account, so this user should be member of SPARQL_UPDATE group in order to modify data via Graph Update protocol. Note that /sparql/ endpoint has /sparql-auth/ variant that uses web authentication. Similarly, /sparql-graph-crud/ has /sparql-graph-crud-auth/ variant. As soon as user is member of SPARQL_UPDATE group, she/he can modify the stored data via /sparql-graph-crud-auth/ as well as via /sparql-auth/ . The /sparql-graph-crud/ endpoint is primarily for serving requests from applications, not for manual interactions via browser. See more information in our <a href="rdfsparql.html#sparqloauthendpointauth">SPARQL Authentication</a> section. </p> <br /> <a name="rdfsupportedprotocolendpoint" /> <h4>14.2.3.2. Service Endpoint</h4> <p>Virtuoso uses the pre-assigned endpoints "/sparql" and "/SPARQL" as the defaults for exposing its REST based SPARQL Web Services.</p> <p>The port number associated with the SPARQL services is determined by the 'ServerPort' key value in the '[HTTPServer]' section of the virtuoso.ini file. Thus, if the Virtuoso instance is configured to listen at a none default port e.g. 8890, the SPARQL endpoints would be accessible at http://example.com:8890/sparql/.</p> <p>The SPARQL endpoint supports both GET and POST requests. The client chooses between GET and POST automatically, using the length of query text as the criterion. If the SPARQL endpoint is accessed without any URL and requisite SPARQL protocol parameters, an interactive HTML page for capturing SPARQL input will be presented.</p> <a name="rdfsupportedprotocolendpointuricustm" /> <h5>14.2.3.2.1. Customizing SPARQL Endpoint Page</h5> <p>The SPARQL Endpoint Page can now be customized using a xsl stylesheet.</p> <p>This works by adding the following line with isql:</p> <div> <pre class="programlisting"> SQL> registry_set ('sparql_endpoint_xsl', 'http://host:port/path/isparql.xsl'); </pre> </div> <p>where obviously host, port, path and the name isparql.xsl can be set to anything.</p> <br /> <br /> <a name="rdfrequestparamsextensions" /> <h4>14.2.3.3. SPARQL Protocol Extensions</h4> <a name="rdfrequestparamsofunctions" /> <h5>14.2.3.3.1. Request Parameters</h5> <table class="data"> <caption>Table: 14.2.3.3.1.1. Request Parameters List</caption> <tr> <th class="data">Parameter</th> <th class="data">Notes</th> <th class="data">Required?</th> </tr> <tr> <td class="data">service</td> <td class="data">Service URI such as 'http://example.com/sparql/'</td> <td class="data">Yes</td> </tr> <tr> <td class="data">query</td> <td class="data">Text of the query</td> <td class="data">Yes</td> </tr> <tr> <td class="data">dflt_graph</td> <td class="data">Default graph URI (string or NULL)</td> <td class="data">No</td> </tr> <tr> <td class="data">named_graphs</td> <td class="data">Vector of named graphs (or NULL to prevent overriding named graphs specified in the query)</td> <td class="data">Yes</td> </tr> <tr> <td class="data">req_hdr</td> <td class="data">Additional HTTP headers that should be passed to the service, e.g. 'Host: ...'</td> <td class="data">No</td> </tr> <tr> <td class="data">maxrows</td> <td class="data">Limit on the numbers of rows that should be returned (the actual size of the result set may differ)</td> <td class="data">No</td> </tr> <tr> <td class="data">xslt-uri</td> <td class="data">Absolute URL of any XSLT stylesheet file to be applied to the SPARQL query results</td> <td class="data">No</td> </tr> <tr> <td class="data">timeout</td> <td class="data">Timeout for "anytime" query execution, in milliseconds, values less than 1000 are ignored; see <a href="anytimequeries.html">Anytime Queries</a> for more details</td> <td class="data">No</td> </tr> </table> <br /> <br /> <a name="rdfresponsecodeofprotocol" /> <h5>14.2.3.3.2. Response Codes</h5> <p>If the query is a CONSTRUCT or a DESCRIBE then the result set consists of a single row and a single column. The value inside is a dictionary of triples in 'long valmode'. Note that the dictionary object cannot be sent to a SQL client, say, via ODBC. The client may lose the database connection trying to fetch a result set row that contains a dictionary object. This disconnection does not disrupt the server, so the client may readily reconnect to the server, but the disconnected transaction will have been rolled back.</p> <div class="tip"> <div class="tiptitle">See Also:</div> <ul> <li> <a href="odbcimplementation.html#virtodbcsparql">Virtuoso ODBC RDF extensions for SPASQL</a> </li> </ul> </div> <br /> <a name="rdfsupportedmimesofprotocol" /> <h5>14.2.3.3.3. Response Format</h5> <p>All the SPARQL protocol standard MIME types are supported by a SPARQL web service client. Moreover, SPARQL web service endpont supports additional MIME types and in some cases additional query types for standard MIME types.</p> <table class="data"> <caption>Table: 14.2.3.3.3.1. Supported MIME Types list</caption> <tr> <th class="data">Content-Type</th> <th class="data">SPARQL query type</th> <th class="data">Support in Virtuoso</th> </tr> <tr> <td class="data">'application/sparql-results+xml'</td> <td class="data">SELECT, ASK</td> <td class="data">both client and endpoint</td> </tr> <tr> <td class="data">'application/rdf+xml'</td> <td class="data">CONSTRUCT, DESCRIBE</td> <td class="data">both client and endpoint</td> </tr> <tr> <td class="data">'application/rdf+xml'</td> <td class="data">SELECT</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'application/rdf+json'</td> <td class="data">CONSTRUCT, DESCRIBE</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'text/rdf+n3'</td> <td class="data">CONSTRUCT, DESCRIBE</td> <td class="data">both client and endpoint</td> </tr> <tr> <td class="data">'text/rdf+n3'</td> <td class="data">SELECT, ASK</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'text/html'</td> <td class="data">SELECT</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'application/javascript'</td> <td class="data">SELECT</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'application/sparql-results+json'</td> <td class="data">SELECT, ASK</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'application/vnd.ms-excel'</td> <td class="data">SELECT</td> <td class="data">endpoint only</td> </tr> <tr> <td class="data">'application/soap+xml' and 'application/soap+xml;11'</td> <td class="data">SELECT</td> <td class="data">endpoint only</td> </tr> </table> <br /> <p>The current implementation does not support returning the results of SELECT as RDF/XML or 'sparql-results-2'.</p> <p>If the HTTP header returned by the remote server does not contain a 'Content-Type' line, the client may guess MIME type from the text of the returned body.</p> <p>Error messages returned from the service are returned as XML documents, using the MIME type application/xml. The documents consist of a single element containing an error message.</p> <br /> <a name="rdfsupportedmimesofprotocoladdselect" /> <h5>14.2.3.3.4. Additional Response Formats -- SELECT</h5> <p>Use the format parameter to select one of the following alternate output formats:</p> <table class="data"> <caption>Table: 14.2.3.3.4.1. Additional Response formats list -- SELECT</caption> <tr> <th class="data">Format Value</th> <th class="data">Description</th> <th class="data">Mimetype</th> </tr> <tr> <td class="data">HTML</td> <td class="data">The result is a HTML document containing query summary and tabular results. The format is human-readable but not intended for using by applications because it makes strings undistinguishable from IRIs and loses other details such as exact datatypes of returned values.</td> <td class="data">text/html</td> </tr> <tr> <td class="data">json</td> <td class="data">Two separate MIME types exist for JSON: JSON serialization of results is 'application/sparql-results+json' and confirms to the draft specification "Serializing SPARQL Query Results in JSON". JSON serialization of triples is 'application/rdf+json' and interoperable with Talis. Sometimes a client needs a JSON but it does not know the type of query it sends to Virtuoso web service endpoint. In this case the client can specify either one MIME-type 'application/json' or both 'application/sparql-results+json' and 'application/rdf+json' in the "Accept" header line and Virtuoso will chose the appropriate one automatically. Similar trick works for other sorts of result types: Virtuoso inspects the whole "Accept" header line to find out the most appropriate return type for the given query. </td> <td class="data">application/sparql-results+json</td> </tr> <tr> <td class="data">json</td> <td class="data" /> <td class="data">application/rdf+json</td> </tr> <tr> <td class="data">js</td> <td class="data">Javascript serialization of results generates an HTML table with the CSS class sparql. The table contains a column indicating row number and additional columns for each query variable. Each query solution contributes one row of the table. Unbound variables are indicated with a non-breaking space in the appropriate table cells.</td> <td class="data">application/javascript</td> </tr> <tr> <td class="data">table</td> <td class="data" /> <td class="data">text/html</td> </tr> <tr> <td class="data">XML</td> <td class="data" /> <td class="data">text/html</td> </tr> <tr> <td class="data">TURTLE</td> <td class="data" /> <td class="data">text/html</td> </tr> </table> <br /> <br /> <a name="rdfsupportedmimesofprotocoladdcons" /> <h5>14.2.3.3.5. Additional Response Formats -- CONSTRUCT & DESCRIBE</h5> <p> <strong>Example output of DESCRIBE in rdf+json serialization format</strong> </p> <ol> <li>Go to the sparql endpoint at http://host:port/sparql, for ex. at http://dbpedia.org/sparql</li> <li>Enter query in the "Query text" area, for ex.: <div> <pre class="programlisting"> DESCRIBE <http://dbpedia.org/resource/%22S%22_Bridge_II> </pre> </div> </li> <li>Select for "Display Results As": JSON</li> <li>Click "Run Query" button.</li> <li>As result should be produced the following output: <div> <pre class="programlisting"> { { 'http://dbpedia.org/resource/%22S%22_Bridge_II' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/ontology/Place' } , { 'type' : 'uri', 'value' : 'http://dbpedia.org/ontology/Resource' } , { 'type' : 'uri', 'value' : 'http://dbpedia.org/ontology/HistoricPlace' } } , { 'http://dbpedia.org/ontology/added' : { 'type' : 'literal', 'value' : '1973-04-23' , 'datatype' : 'http://www.w3.org/2001/XMLSchema#date' } } , { 'http://www.w3.org/2003/01/geo/wgs84_pos#lat' : { 'type' : 'literal', 'value' : 39.99305725097656 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#float' } } , { 'http://www.w3.org/2003/01/geo/wgs84_pos#long' : { 'type' : 'literal', 'value' : -81.74666595458984 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#float' } } , { 'http://dbpedia.org/property/wikiPageUsesTemplate' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Template:infobox_nrhp' } } , { 'http://dbpedia.org/property/name' : { 'type' : 'literal', 'value' : '"S" Bridge II' , 'lang' : 'en' } } , { 'http://dbpedia.org/property/nearestCity' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/New_Concord%2C_Ohio' } , { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Ohio' } } , { 'http://dbpedia.org/property/latDirection' : { 'type' : 'literal', 'value' : 'N' , 'lang' : 'en' } } , { 'http://dbpedia.org/property/governingBody' : { 'type' : 'literal', 'value' : 'State' , 'lang' : 'en' } } , { 'http://www.georss.org/georss/point' : { 'type' : 'literal', 'value' : '39.99305556 -81.74666667' } , { 'type' : 'literal', 'value' : '39.9930555556 -81.7466666667' } } , { 'http://xmlns.com/foaf/0.1/name' : { 'type' : 'literal', 'value' : '"S" Bridge II' } } , { 'http://dbpedia.org/property/latDegrees' : { 'type' : 'literal', 'value' : 39 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://dbpedia.org/property/latMinutes' : { 'type' : 'literal', 'value' : 59 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://dbpedia.org/property/latSeconds' : { 'type' : 'literal', 'value' : 35 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://dbpedia.org/property/longDirection' : { 'type' : 'literal', 'value' : 'W' , 'lang' : 'en' } } , { 'http://dbpedia.org/property/architect' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Benjamin_Latrobe' } } , { 'http://dbpedia.org/property/added' : { 'type' : 'literal', 'value' : '1973-04-23' , 'datatype' : 'http://www.w3.org/2001/XMLSchema#date' } } , { 'http://www.w3.org/2000/01/rdf-schema#label' : { 'type' : 'literal', 'value' : '"S" Bridge II (Muskingum County, Ohio)' , 'lang' : 'nl' } , { 'type' : 'literal', 'value' : '"S" Bridge II' , 'lang' : 'en' } } , { 'http://dbpedia.org/ontology/architect' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Benjamin_Latrobe' } } , { 'http://xmlns.com/foaf/0.1/img' : { 'type' : 'uri', 'value' : 'http://upload.wikimedia.org/wikipedia/commons/d/d4/FoxRunS-Bridge_NewConcordOH.jpg' } } , { 'http://dbpedia.org/property/locmapin' : { 'type' : 'literal', 'value' : 'Ohio' , 'lang' : 'en' } } , { 'http://dbpedia.org/property/refnum' : { 'type' : 'literal', 'value' : 73001513 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://dbpedia.org/property/abstract' : { 'type' : 'literal', 'value' : '"S" Bridge II is a historic S bridge near New Concord, Ohio, United States. A part of the National Road, the first federally-financed highway in the United States, it was built in 1828. Its peculiar shape, typical for an S bridge, is designed to minimize the span and allow easy access. In 1973, it was listed on the National Register of Historic Places.' , 'lang' : 'en' } , { 'type' : 'literal', 'value' : '"S" Bridge II bij New Concord, Ohio, is een deel van de National Road, een van de eerste highways die door de federale overheid vanaf 1811 werden aangelegd. De vorm, die de brug als een S Brug kenmerkt, is bedoeld om de overspanning zo klein mogelijk te houden en toch gemakkelijk toegang tot de brug te verlenen. De brug staat sinds 1973 op de lijst van het National Register of Historic Places als monument vermeld.' , 'lang' : 'nl' } } , { 'http://www.w3.org/2004/02/skos/core#subject' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Category:National_Register_of_Historic_Places_in_Ohio' } , { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Category:Bridges_on_the_National_Register_of_Historic_Places' } } , { 'http://dbpedia.org/ontology/nearestCity' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/Ohio' } , { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/New_Concord%2C_Ohio' } } , { 'http://xmlns.com/foaf/0.1/depiction' : { 'type' : 'uri', 'value' : 'http://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/FoxRunS-Bridge_NewConcordOH.jpg/200px-FoxRunS-Bridge_NewConcordOH.jpg' } } , { 'http://dbpedia.org/property/caption' : { 'type' : 'literal', 'value' : 'The bridge in the fall' , 'lang' : 'en' } } , { 'http://dbpedia.org/property/longDegrees' : { 'type' : 'literal', 'value' : 81 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://dbpedia.org/property/longMinutes' : { 'type' : 'literal', 'value' : 44 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://dbpedia.org/property/longSeconds' : { 'type' : 'literal', 'value' : 48 , 'datatype' : 'http://www.w3.org/2001/XMLSchema#integer' } } , { 'http://www.w3.org/2000/01/rdf-schema#comment' : { 'type' : 'literal', 'value' : '"S" Bridge II is a historic S bridge near New Concord, Ohio, United States.' , 'lang' : 'en' } , { 'type' : 'literal', 'value' : '"S" Bridge II bij New Concord, Ohio, is een deel van de National Road, een van de eerste highways die door de federale overheid vanaf 1811 werden aangelegd.' , 'lang' : 'nl' } } , { 'http://xmlns.com/foaf/0.1/page' : { 'type' : 'uri', 'value' : 'http://en.wikipedia.org/wiki/%22S%22_Bridge_II' } } } , { 'http://dbpedia.org/resource/%22S%22_Bridge_II_%28Muskingum_County%2C_Ohio%29' : { 'http://dbpedia.org/property/redirect' : { 'type' : 'uri', 'value' : 'http://dbpedia.org/resource/%22S%22_Bridge_II' } } } } </pre> </div> </li> </ol> <p> <strong>Example output of CONSTRUCT in rdf+json serialization format</strong> </p> <ol> <li>Go to the sparql endpoint at http://host:port/sparql, for ex. at http://dbpedia.org/sparql</li> <li>Enter query in the "Query text" area, for ex.: <div> <pre class="programlisting"> CONSTRUCT { ?s a ?Concept . } WHERE { ?s a ?Concept . } LIMIT 10 </pre> </div> </li> <li>Select for "Display Results As": JSON</li> <li>Click "Run Query" button.</li> <li>As result should be produced the following output: <div> <pre class="programlisting"> { { 'http://dbpedia.org/ontology/Place' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/Area' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/City' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/River' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/Road' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/Lake' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/LunarCrater' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/ShoppingMall' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/Park' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } , { 'http://dbpedia.org/ontology/SiteOfSpecialScientificInterest' : { 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : { 'type' : 'uri', 'value' : 'http://www.w3.org/2002/07/owl#Class' } } } } </pre> </div> </li> </ol> <p> For interoperability with clients that were developed before current versions of SPARQL protocol and format specs are issued, Virtuoso supports some obsolete variants of standard MIME types. 'text/rdf+n3', 'text/rdf+ttl', 'application/turtle' and 'application/x-turtle' are understood for TURTLE output, 'application/x-rdf+json' and 'application/rdf+json' are for "Serializing SPARQL Query Results in JSON". When a client specifies obsolete MIME type but not its standard variant, an obsolete variant is returned for interoperability. </p> <br /> <a name="rdfsupportedmimesaddofprotocol" /> <h5>14.2.3.3.6. Virtuoso/PL APIs</h5> <p>Virtuoso also provides SPARQL protocol client APIs in Virtuoso PL, so you can communicate with SPARQL Query Services from Virtuoso stored procedures. The APIs are as follows: </p> <table class="data"> <caption>Table: 14.2.3.3.6.1. Virtuoso/PL APIs</caption> <tr> <th class="data">API</th> <th class="data">Notes</th> </tr> <tr> <td class="data">DB.DBA.SPARQL_REXEC</td> <td class="data">Behaves like DBA.SPARQL_EVAL, but executes the query on the specified server. The procedure does not return anything. Instead, it creates a result set.</td> </tr> <tr> <td class="data">DB.DBA.SPARQL_REXEC_TO_ARRAY</td> <td class="data">Behaves like DBA.SPARQL_EXEC_TO_ARRAY(), but executes the query on the specified server. The function returns a vector of rows, where every row is represented by a vector of field values.</td> </tr> <tr> <td class="data">DB.DBA.SPARQL_REXEC_WITH_META</td> <td class="data">Has no local SPARQL_EVAL analog. It produces not only an array of result rows together with an array of result set metadata in a format used by the exec() function.</td> </tr> </table> <br /> <br /> <a name="anytimequeriessparql" /> <h5>14.2.3.3.7. SPARQL Anytime Queries</h5> <p>Starting with version 6, Virtuoso offers a partial query evaluation feature that guarantees answers to arbitrary queries within a fixed time. This is intended for use in publicly available SPARQL or SQL end points on large databases. This enforces a finite duration to all queries and will strive to return meaningful partial results. Thus this provides the same security as a transaction timeout but will be more user friendly since results will generally be returned, also for aggregate queries. Outside of a public query service, this may also be handy when exploring a large data set with unknown properties. </p> <p>The feature is activated with the statement</p> <div> <pre class="programlisting"> set result_timeout == <expression>; </pre> </div> <p>Find more detailed information in the <a href="anytimequeries.html">Anytime Queries</a> section.</p> <a name="anytimequeriessparqlex" /> <h6>Example Dump arbitrary query result as N-Triples</h6> <p>Assume the following arbitrary query:</p> <div> <pre class="programlisting"> SPARQL define output:format "NT" CONSTRUCT { ?s a ?t } FROM virtrdf: WHERE { ?s a ?t }; </pre> </div> <p>For iteration over result-set of an arbitrary query, use <a href="fn_exec_next.html">exec_next()</a> in a loop that begins with <a href="fn_exec.html">exec()</a> with cursor output variable as an argument and ends with <a href="fn_exec_close.html">exec_close()</a> after it is out of data. </p> <br /> <br /> <br /> <a name="rdfsupportedprotocolendpointuri" /> <h4>14.2.3.4. Service Endpoint Security</h4> <p>Earlier releases of Virtuoso secured the SPARQL endpoint via privileges assigned to the service- specific SQL user account "SPARQL". This account was optionally granted "SPARQL_SELECT" or "SPARQL_UPDATE" roles. By default only the "SPARQL_SELECT" role was assigned, enabling all users to at least perform SELECT queries. The "SPARQL_UPDATE" role must be granted to allow updates to the Quad Store - a pre-requisite for the Virtuoso Sponger services to be functional i.e. to allow the Sponger to populate and update the Quad Store. In Virtuoso release 5.0.7, there is a new "SPARQL_SPONGE" role which can be assigned specifically to allow Sponger services to update the Quad Store but not SPARQL users via the SPARQL endpoint.</p> <p>Restricting a user's access to specific graphs can be done using Virtuoso row-level security functionality, via one of the Virtuoso Data Access APIs: ODBC, JDBC, ADO.Net or PL code.</p> <div class="tip"> <div class="tiptitle">See Also:</div> <ul> <li> <a href="odbcimplementation.html#virtodbcsparql">Virtuoso ODBC RDF extensions for SPASQL</a> </li> </ul> </div> <p>For example, users of OpenLink Data Space (ODS) applications are restricted in the RDF graphs accessible to them as follows:</p> <div> <pre class="programlisting"> DB.DBA.TABLE_DROP_POLICY ('DB.DBA.RDF_QUAD', 'S'); create procedure DB.DBA.RDF_POLICY (in tb varchar, in op varchar) { declare chost, ret varchar; chost := DB.DBA.WA_CNAME (); ret := sprintf ('(ID_TO_IRI (G) NOT LIKE \'http://%s/dataspace/%%/private#\' ' || 'OR G = IRI_TO_ID (sprintf (\'http://%s/dataspace/%%U/private#\', USER)))', chost, chost); return ret; } ; grant execute on DB.DBA.RDF_POLICY to public; DB.DBA.TABLE_SET_POLICY ('DB.DBA.RDF_QUAD', 'DB.DBA.RDF_POLICY', 'S'); </pre> </div> <p> where DB.DBA.WA_CNAME () is an ODS function returning the default host name. </p> <p>The effect of this policy is to restrict user 'user' to the graph http://cname/dataspace/user/private#</p> <p>Virtuoso reserves the path '/sparql-auth/' for a SPARQL service supporting authenticated SPARUL. This endpoint allows specific SQL accounts to perform SPARUL over the SPARQL protocol. To be allowed to login via SQL or ODBC and update physical triples, a user must be granted "SPARQL_UPDATE" privileges. To grant this role: </p> <ul> <li>Go to the Virtuoso administration UI i.e. http://host:port/conductor</li> <li>Login as user dba</li> <li>Go to System Admin->User Accounts->Users <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Conductor UI" src="../images/ui/usr1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.1. Conductor UI</td> </tr> </table> </li> <li>Click the link "Edit"</li> <li>In the displayed form check the "Allow SQL/ODBC Logins" check-box.</li> <li>Select from the list of available Account Roles "SPARQL_UPDATE" role and click the ">>" button so to add it to the right-hand list.</li> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Conductor UI" src="../images/ui/usr2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.1. Conductor UI</td> </tr> </table> <li>Click the "Save" button.</li> </ul> <p>Note that if a table is used in an RDF view, and this table is not granted to SPARQL_SELECT permission (or SPARQL_UPDATE, which implicitly confers SPARQL_SELECT), then all SELECTs on a graph defined by an RDF view will return an access violation error as the user account has no permissions to read the table. The user must have appropriate privileges on all tables included in an RDF View in order to be able to select on <strong>all</strong> graphs.</p> <a name="sparqwebservicetbl" /> <h5>14.2.3.4.1. Managing a SPARQL Web Service Endpoint</h5> <p> Virtuoso web service endpoints may provide different default configurations for different host names mentioned in an HTTP request. Host name configuration for SPARQL web service endpoints can be managed via the table <strong>DB.DBA.SYS_SPARQL_HOST</strong>. </p> <div> <pre class="programlisting"> create table DB.DBA.SYS_SPARQL_HOST ( SH_HOST varchar not null primary key, -- host mask SH_GRAPH_URI varchar, -- default 'default graph' uri SH_USER_URI varchar, -- reserved for any use in applications SH_DEFINES long varchar -- additional defines for requests ) </pre> </div> <p>You can find detailed descriptions of the table columns <a href="rdfsparql.html#rdfdefaultgraph">here</a>. Also, please read <a href="rdfperformancetuning.html#rdfperfindexes">these notes</a> on managing public web service endpoints.</p> <br /> <a name="sparqloauthendpointauth" /> <h5>14.2.3.4.2. Authentication</h5> <p>Virtuoso 5.0.7 introduced a new "SPARQL_SPONGE" role which can be assigned specifically for controlling Sponger middleware services which perform writes and graph creation in the RDF Quad Store. This role only allows updates through the Sponger. Quad Store updates via any other route require granting the SPARQL_UPDATE role.</p> <p> Virtuoso 5.0.11 onwards added three new methods for securing SPARQL endpoints that include: </p> <ul> <li>SQL authentication</li> <li>OAuth</li> <li>WebID Protocol based authentication</li> </ul> <p> Each of these authentication methods is associated with a purpose specific default SPARQL endpoint along the following lines: </p> <ul> <li>http://<cname>/sparql-auth (SQL authentication)</li> <li>http://<cname>/sparql-oauth (OAuth)</li> <li>http://<cname>/sparql-graph-crud-auth (OAuth CRUD)</li> <li>https://<cname>/sparql and https://<cname>/sparql-ssl (WebID Protocol)</li> </ul> <p>The Virtuoso Authentication Server offers a UI with options for managing:</p> <ul> <li> Application keys and protected SPARQL endpoints: OAuth provides a secure data transmission level mechanism for your SPARQL endpoint. It enables you to interact securely with your RDF database from a variety of locations. It also allows you to provide controlled access to private data to selected user profiles. </li> <li>WebID Protocol ACLs: WebID Protocol is an implementation of a conceptual authentication and authorization protocol that links a Web ID to a public key to create a global, decentralized/distributed, and open yet secure authentication system that functions with existing browsers.</li> </ul> <p>Virtuoso Authentication Server can be installed by downloading and installing the conductor_dav.vad package.</p> <p>The Authentication UI is accessible from the Conductor UI -> Linked Data -> Access Control -> SPARQL-SSL. Here is sample scenario:</p> <ul> <li>Download and install the <a href="http://s3.amazonaws.com/opldownload/uda/vad-packages/6.1/virtuoso/conductor_dav.vad">conductor_dav.vad</a> package.</li> <li> <a href="http://ods.openlinksw.com/dataspace/dav/wiki/ODS/ODSGenerateX509Certificate">Generate an X.509 Certificate hosted WebID</a>.</li> <li>Go to http://<cname>:<port>/conductor, where <cname>:<port> are replaced by your local server values.</li> <li>Log in as user "dba" or another user with DBA privileges.</li> <li>Go to Linked Data -> Access Controls -> SPARQL-SSL: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.2.1. SPARQL-SSL</td> </tr> </table> </li> <li>Enter in the presented form Web ID for ex.: <div> <pre class="programlisting"> http://id.myopenlink.net/dataspace/person/demo#this </pre> </div> <p> and select "SPARQL Role" for ex. "Sponge".</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth3.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.2.1. SPARQL-SSL</td> </tr> </table> </li> <li>Click the "Register" button.</li> <li>As result the WebID Protocol ACLs will be created: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth4.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.2.1. SPARQL-SSL</td> </tr> </table> </li> <li>Go to the SPARQL+SSL endpoint https://<cname>:<port>/sparql-ssl</li> <li>Select the user's certificate from above: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth5.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.2.1. SPARQL-SSL</td> </tr> </table> </li> <li>As result the SPARQL Query UI will be presented: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth6.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.2.1. SPARQL-SSL</td> </tr> </table> </li> <li>Execute sample query and view the results: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth6.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.2.1. SPARQL-SSL</td> </tr> </table> </li> </ul> <br /> <a name="sparqloauthendpoint" /> <h5>14.2.3.4.3. SPARQL OAuth Endpoint</h5> <p>OAuth provides a secure data transmission level mechanism for your SPARQL endpoint. It enables you to interact securely with your RDF database from a variety of locations. It also allows you to provide controlled access to private data to selected users.</p> <p>Virtuoso OAuth Server can be installed by downloading and installing the <a href="http://s3.amazonaws.com/opldownload/uda/vad-packages/6.1/virtuoso/ods_framework_dav.vad">ods_framework_dav.vad</a> package. The OAuth UI is accessible from the URL http://cname:port/oauth</p> <p>A user must have SQL privileges in order to run secured SPARQL statements.</p> <p>Here is a sample scenario:</p> <ol> <li>Download and install the <a href="http://s3.amazonaws.com/opldownload/uda/vad-packages/6.1/virtuoso/conductor_dav.vad">conductor_dav.vad</a> and <a href="http://s3.amazonaws.com/opldownload/uda/vad-packages/6.1/virtuoso/ods_framework_dav.vad">ods_framework_dav.vad</a> packages.</li> <li> <a href="http://ods.openlinksw.com/dataspace/dav/wiki/ODS/ODSGenerateX509Certificate">Generate an X.509 Certificate hosted WebID</a>.</li> <li>Go to http://<cname>:<port>/conductor, where <cname>:<port> are replaced by your local server values.</li> <li>Log in as user "dba" or another user with DBA privileges.</li> <li>Go to System Admin->User Accounts: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Click "Create New Account": <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>In the presented form enter respectively: <ol> <li>Account name, for ex:demo1; a password and then confirm the password;</li> <li>User type: SQL/ODBC and WebDAV;</li> <li>Account role: SPARQL_UPDATE <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so3.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> </ol> </li> <li>Click the "Save" button. </li> <li>The created user should be shown in the list of registered users: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so4.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Go to http://<cname>:<port>/oauth/, where <cname>:<port> are replaced by your local server values. <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so5.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Click the "OAuth keys" link: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so6.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Log in as user demo1: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so7.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>The OAuth application registration form will be shown. <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so8.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Select SPARQL from the "Application name" list, and click the "Generate Keys" button. </li> <li>A Consumer Key for SPARQL will be generated: <div> <pre class="programlisting"> 90baa79108b1d972525bacc76c0279c02d6421e8 </pre> </div> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so9.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Click the "Back to main menu" link.</li> <li>Click the "Protected SPARQL Endpoint" link.</li> <li>The OpenLink Virtuoso SPARQL Query form will be displayed. <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so11.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so12.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.2. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Enter a simple query, for ex: <div> <pre class="programlisting"> SELECT * WHERE { ?s ?p ?o } LIMIT 10 </pre> </div> </li> <li>Enter the value from below for the "OAuth token": <div> <pre class="programlisting"> 90baa79108b1d972525bacc76c0279c02d6421e8 </pre> </div> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so13.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Click the "Run Query" button.</li> <li>In the OAuth Authorization Service form enter the password for user demo1 and click the "Login" button. <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so16.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>Next you should authorize the request: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so15.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> <li>On successful authentication and authorization, the query results should be shown: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL OAuth Endpoint" src="../images/ui/so14.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.3.1. SPARQL OAuth Endpoint</td> </tr> </table> </li> </ol> <br /> <a name="sparqloauthendpointfoafssl" /> <h5>14.2.3.4.4. WebID Protocol ACLs</h5> <p>WebID Protocol is an implementation of a conceptual authentication and authorization protocol that links a Web ID to a public key, to create a global decentralized/distributed, and open yet secure authentication system that functions with existing browsers.</p> <p>To use WebID Protocol, download and install the <a href="http://s3.amazonaws.com/opldownload/uda/vad-packages/6.1/virtuoso/conductor_dav.vad">conductor_dav.vad</a> VAD package. Once installed, to access the WebID Protocol ACLs UI, go to URL http://cname:port/conductor -> Linked Data -> Access Controls -> SPARQL-SSL .</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="FOAFSSL" src="../images/ui/auth4.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. FOAFSSL</td> </tr> </table> <p> Configuring WebID Protocol ACLs is with a WebID Protocol certificate and a Web ID allows secure SPARQL queries to be performed against a Virtuoso SPARQL-SSL endpoint and viewing of the query results. The SPARQL-SSL endpoint URL is of the form https://cname:port/sparql-ssl</p> <p>The steps required to configure a sample WebID Protocol ACL are outlined below:</p> <ul> <li>Download and install the <a href="http://s3.amazonaws.com/opldownload/uda/vad-packages/6.1/virtuoso/conductor_dav.vad">conductor_dav.vad</a> package.</li> <li> <a href="http://ods.openlinksw.com/dataspace/dav/wiki/ODS/ODSGenerateX509Certificate">Generate an X.509 Certificate hosted WebID</a>.</li> <li>Go to http://<cname>:<port>/conductor, where <cname>:<port> are replaced by your local server values.</li> <li>Log in as user "dba" or another user with DBA privileges.</li> <li>Go to Linked Data -> Access Controls -> SPARQL-SSL: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. SPARQL-SSL</td> </tr> </table> </li> <li>Enter in the presented form Web ID for ex.: <div> <pre class="programlisting"> http://id.myopenlink.net/dataspace/person/demo#this </pre> </div> <p> and select "SPARQL Role" for ex. "Sponge".</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth3.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. SPARQL-SSL</td> </tr> </table> </li> <li>Click the "Register" button.</li> <li>As result the WebID Protocol ACLs will be created: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth4.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. SPARQL-SSL</td> </tr> </table> </li> <li>Go to the SPARQL+SSL endpoint https://<cname>:<port>/sparql-ssl</li> <li>Select the user's certificate from above: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth5.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. SPARQL-SSL</td> </tr> </table> </li> <li>As result the SPARQL Query UI will be presented: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth6.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. SPARQL-SSL</td> </tr> </table> </li> <li>Execute sample query and view the results: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL-SSL" src="../images/ui/auth6.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.4.1. SPARQL-SSL</td> </tr> </table> </li> </ul> <div class="tip"> <div class="tiptitle">See Also:</div> <p> <a href="odbcimplementation.html#secureodbcx509foafsll">WebID Protocol ODBC Login</a> </p> </div> <br /> <a name="sparqloauthendpointfoafsslsparql" /> <h5>14.2.3.4.5. Creating and Using a SPARQL-SSL based Endpoint</h5> <p>The following section describes the basic steps for setting up an SSL protected and WebID based SPARQL Endpoint (SPARQL-SSL). The guide also covers the use of Virtuoso PL functions and the Virtuoso Conductor for SPARQL endpoint creation and configuration. It also covers the use of cURL for exercising the newly generated SPARQL-SSL endpoint. </p> <ol> <li> <a href="vfoafssl.html#vfoafsslst509issuer">Setup the CA issuer and https listener</a> </li> <li>Define the /sparql-ssl endpoint on an HTTPS based listener (HTTPS service endpoint), for example using Virtuoso PL: <div> <pre class="programlisting"> DB.DBA.VHOST_DEFINE ( lhost=>'127.0.0.1:443', vhost=>'localhost', lpath=>'/sparql-ssl', ppath=>'/!sparql/', is_dav=>1, auth_fn=>'DB.DBA.FOAF_SSL_AUTH', vsp_user=>'dba', ses_vars=>0, auth_opts=>vector ( 'https_cert', 'db:https_key_localhost', 'https_key', 'db:https_key_localhost', 'https_verify', 3, 'https_cv_depth', 10 ), opts=>vector ('noinherit', 1), is_default_host=>0 ); </pre> </div> </li> <li> <a href="rdfsparql.html#sparqloauthendpointfoafssl">Setup the SPARQL-SSL endpoint and define ACLs</a> using the Virtuoso Conductor</li> <li>Export your private key and its associated WebID based X.509 certificate from your Firefox browser or System's Key Manager into PEM (PKCS12) file <ol> <li>If using Firefox use the menu path: Advanced -> View Certificates, then click Backup for your certificate with name "mykey". </li> <li>The file "mykey.p12" will be created. To disable password protection so that you can use this file in non-interactive mode (e.g. with cURL and other HTTP clients) execute: <div> <pre class="programlisting"> openssl pkcs12 -in mykey.p12 -out mykey.pem -nodes </pre> </div> </li> </ol> </li> <li>Test the SPARQL-SSL endpoint with cURL: (listening on default HTTPS 443 port): <ul> <li>Note: In this example we use the "-k / --insecure" option with cURL since we are going to be using self-signed X.509 certificates signed by self-signed root CA.</li> </ul> <div> <pre class="programlisting"> curl -k -E mykey.pem "https://localhost/sparql-ssl?query=select+*+where+\{+%3Fx+%3Fy+%3Fz+.+\}+limit+10&format=text%2Fn3" @prefix res: <http://www.w3.org/2005/sparql-results#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . _:_ a res:ResultSet . _:_ res:resultVariable "x" , "y" , "z" . @prefix ns0: <https://localhost/tutorial/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:hosting ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:xml ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:repl ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:rdfview ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:services ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:wap ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:bpeldemo ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:web ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:web2 ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:xmlxslt ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . </pre> </div> </li> <li>Import your key it via Conductor UI: <ol> <li>Go to Conductor -> System Admin->User Accounts <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Import key it via Conductor UI" src="../images/ui/fsp1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.5.1. Import key it via Conductor UI</td> </tr> </table> </li> <li>Click "Edit" for your user <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Import key it via Conductor UI" src="../images/ui/fsp2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.5.1. Import key it via Conductor UI</td> </tr> </table> </li> <li>Change "User type" to: SQL/ODBC and WebDAV <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Import key it via Conductor UI" src="../images/ui/fsp3.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.5.1. Import key it via Conductor UI</td> </tr> </table> </li> <li>Enter your ODS user WebID: <div> <pre class="programlisting"> http://cname:port/dataspace/person/username#this </pre> </div> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Import key it via Conductor UI" src="../images/ui/fsp4.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.5.1. Import key it via Conductor UI</td> </tr> </table> </li> <li>Click "Save"</li> <li>Click again "Edit" for your user</li> <li>In "PKCS12 file:" click the Browse" button and select your key.</li> <li>Enter a local Key Name, for e.g., "cli_key"</li> <li>Enter key password <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Import key it via Conductor UI" src="../images/ui/fsp5.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.5.1. Import key it via Conductor UI</td> </tr> </table> </li> <li>Click "Import Key"</li> <li>As result the key will be stored with name for ex. cli_key <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Import key it via Conductor UI" src="../images/ui/fsp6.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.5.1. Import key it via Conductor UI</td> </tr> </table> </li> <li>Click "Save"</li> </ol> </li> <li>Test the SPARQL-SSL endpoint with http_client (listening on default HTTPS 443 port): <ol> <li>Log in at Virtuos ISQL with your user credentials: <div> <pre class="programlisting"> C:\>isql localhost:1111 johndoe**** Connected to OpenLink Virtuoso Driver: 06.01.3127 OpenLink Virtuoso ODBC Driver OpenLink Interactive SQL (Virtuoso), version 0.9849b. Type HELP; for help and EXIT; to exit. SQL> </pre> </div> </li> <li>Execute: <div> <pre class="programlisting"> SQL>select http_client ('https://localhost/sparql-ssl?query=select+*+where+{+%3Fx+%3Fy+%3Fz+.+}+limit+10&format=text%2Fn3', cert_file=>'d b:cli_key', insecure=>1); callret VARCHAR _______________________________________________________________________________ @prefix res: <http://www.w3.org/2005/sparql-results#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . _:_ a res:ResultSet . _:_ res:resultVariable "x" , "y" , "z" . @prefix ns0: <https://localhost/tutorial/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:hosting ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:xml ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:repl ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:rdfview ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:services ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:wap ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:bpeldemo ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ res:binding [ res:variable "x" ; res:value ns0:web ] ; res:binding [ res:variable "y" ; res:value rdf:type ] ; res:binding [ res:variable "z" ; res:value "Tutorial" ] ] . _:_ res:solution [ 1 Rows. -- 281 msec. </pre> </div> </li> </ol> </li> </ol> <div class="tip"> <div class="tiptitle">See Also:</div> <p> <a href="http://demo.openlinksw.com/tutorial/rdf/fs_s_1/fs_s_1.vsp">Demo Example</a> Using HTTP client to perform WebID Protocol connection.</p> </div> <br /> <a name="sparqloauthendpointfoafsslsparqldisable" /> <h5>14.2.3.4.6. Disable Default SPARQL Endpoint</h5> <a name="sparqloauthendpointfoafsslsparqldisableisql" /> <h6>Using iSQL:</h6> <ul> <li>To disable /sparql, execute: <div> <pre class="programlisting"> DB.DBA.VHOST_REMOVE (lpath=>'/sparql'); </pre> </div> </li> <li>To add the endpoint again via PL, execute: <div> <pre class="programlisting"> DB.DBA.VHOST_DEFINE (lpath=>'/sparql/', ppath => '/!sparql/', is_dav => 1, vsp_user => 'dba', opts => vector('noinherit', 1)); </pre> </div> </li> </ul> <br /> <a name="sparqloauthendpointfoafsslsparqldisablecond" /> <h6>Using Conductor UI:</h6> <ul> <li>Go to http://cname:port/conductor .</li> <li>Enter user dba credentials.</li> <li>Go to "Web Application Server" -> "Virtual Domains & Directories". <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Disable SPARQL Endpoint" src="../images/ui/s1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.6.1. Disable SPARQL Endpoint</td> </tr> </table> </li> <li>Find the logical path "/sparql". <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Disable SPARQL Endpoint" src="../images/ui/s2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.6.1. Disable SPARQL Endpoint</td> </tr> </table> </li> <li>Click "Edit" from the "Action" column. <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Disable SPARQL Endpoint" src="../images/ui/s3.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.6.1. Disable SPARQL Endpoint</td> </tr> </table> </li> <li>Change "VSP User" to "nobody". <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Disable SPARQL Endpoint" src="../images/ui/s4.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.6.1. Disable SPARQL Endpoint</td> </tr> </table> </li> <li>Click "Save Changes".</li> <li>As result the SPARQL Endpoint should be shown as disabled: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Disable SPARQL Endpoint" src="../images/ui/s5.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.4.6.1. Disable SPARQL Endpoint</td> </tr> </table> </li> </ul> <br /> <br /> <br /> <a name="rdfsupportedrequestmethodsofprotocol" /> <h4>14.2.3.5. Request Methods</h4> <table class="data"> <caption>Table: 14.2.3.5.1. Methods List</caption> <tr> <th class="data">Method</th> <th class="data">Supported?</th> <th class="data">Notes</th> </tr> <tr> <td class="data">GET</td> <td class="data">Yes</td> <td class="data">Short queries are sent in GET mode</td> </tr> <tr> <td class="data">POST</td> <td class="data">Yes</td> <td class="data">Queries longer than 1900 bytes are POST-ed.</td> </tr> <tr> <td class="data">DELETE</td> <td class="data">No</td> <td class="data" /> </tr> <tr> <td class="data">PUT</td> <td class="data">No</td> <td class="data" /> </tr> </table> <br /> <br /> <a name="rdfsparqlclientfunctions" /> <h4>14.2.3.6. Functions</h4> <p>The SPARQL client can be invoked by three similar functions:</p> <table class="data"> <caption>Table: 14.2.3.6.1. Functions List</caption> <tr> <th class="data">Function</th> <th class="data">Notes</th> </tr> <tr> <td class="data">DB.DBA.SPARQL_REXEC</td> <td class="data">Behaves like DBA.SPARQL_EVAL, but executes the query on the specified server. The procedure does not return anything. Instead, it creates a result set. </td> </tr> <tr> <td class="data">DB.DBA.SPARQL_REXEC_TO_ARRAY</td> <td class="data">Behaves like DBA.SPARQL_EXEC_TO_ARRAY (), but executes the query on the specified server. The function return a vector of rows, where every row is represented by a vector of field values.</td> </tr> <tr> <td class="data">DB.DBA.SPARQL_REXEC_WITH_META</td> <td class="data">Has no local 'SPARQL_EVAL' analog. It produces an array of result rows together with an array of result set metadata in the same format as produced by the exec () function. This function can be used when the result should be passed later to exec_result_names () and exec_result () built-in functions. To process a local query in similar style, an application can use the SQL built-in function exec () - a SPARQL query (with the 'SPARQL' keyword in front) can be passed to exec () instead of a plain SQL SELECT statement.</td> </tr> </table> <br /> <div> <pre class="programlisting"> create procedure DB.DBA.SPARQL_REXEC ( in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any, in req_hdr any, in maxrows integer, in bnode_dict any ); </pre> </div> <div> <pre class="programlisting"> create function DB.DBA.SPARQL_REXEC_TO_ARRAY ( in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any, in req_hdr any, in maxrows integer, in bnode_dict any ) returns any; </pre> </div> <div> <pre class="programlisting"> create procedure DB.DBA.SPARQL_REXEC_WITH_META ( in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any, in req_hdr any, in maxrows integer, in bnode_dict any, out metadata any, -- metadata like exec () returns. out resultset any) -- results as 'long valmode' values. </pre> </div> <br /> <a name="rdfsparqlendpointexamples" /> <h4>14.2.3.7. Examples</h4> <p>Virtuoso's SPARQL demo offers a live demonstration of Virtuoso's implementation of the <a href="http://www.w3.org/TR/rdf-dawg-uc/">DAWG's SPARQL test-suite</a>, a collection of SPARQL query language use cases that enable interactive and simplified testing of a triple store implementation. If you have installed the SPARQL Demo VAD locally, it can be found at a URL similar to 'http://example.com:8080/sparql_demo/', the exact form will depend on your local configuration. Alternatively, a live version of the documentation is available at <a href="http://demo.openlinksw.com/sparql_demo">Virtuoso Demo Server</a>. </p> <a name="rdfsparqlendpointexamples1" /> <h5>14.2.3.7.1. Example SPARQL query issued via curl</h5> <div> <pre class="programlisting"> curl -F "query=SELECT DISTINCT ?p FROM <http://demo.openlinksw.com/DAV/home/demo/rdf_sink/> WHERE {?s ?p ?o}" http://demo.openlinksw.com/sparql </pre> </div> <p>The result should be:</p> <div> <pre class="programlisting"> <?xml version="1.0" ?> <sparql xmlns="http://www.w3.org/2005/sparql-results#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd"> <head> <variable name="p"/> </head> <results distinct="false" ordered="true"> <result> <binding name="p"><uri>http://www.w3.org/1999/02/22-rdf-syntax-ns#type</uri></binding> </result> <result> <binding name="p"><uri>http://xmlns.com/foaf/0.1/nick</uri></binding> </result> <result> <binding name="p"><uri>http://xmlns.com/foaf/0.1/name</uri></binding> </result> <result> <binding name="p"><uri>http://xmlns.com/foaf/0.1/homepage</uri></binding> </result> <result> <binding name="p"><uri>http://xmlns.com/foaf/0.1/knows</uri></binding> </result> <result> <binding name="p"><uri>http://xmlns.com/foaf/0.1/workplaceHomepage</uri></binding> </result> <result> <binding name="p"><uri>http://xmlns.com/foaf/0.1/mbox</uri></binding> </result> </results> </sparql> </pre> </div> <br /> <a name="rdfsparqlendpointexamples2" /> <h5>14.2.3.7.2. Other Examples of SPARQL query issued via curl</h5> <p> <strong>Further example SPARQL queries:</strong> </p> <div> <pre class="programlisting"> curl -F "query=SELECT DISTINCT ?Concept FROM <http://dbpedia.org> WHERE {?s a ?Concept} LIMIT 10" http://dbpedia.org/sparql </pre> </div> <div> <pre class="programlisting"> curl -F "query=SELECT DISTINCT ?Concept FROM <http://myopenlink.net/dataspace/person/kidehen> WHERE {?s a ?Concept} LIMIT 10" http://demo.openlinksw.com/sparql </pre> </div> <div> <pre class="programlisting"> curl -F "query=SELECT DISTINCT ?Concept FROM <http://data.openlinksw.com/oplweb/product_family/virtuoso> WHERE {?s a ?Concept} LIMIT 10" http://demo.openlinksw.com/sparql </pre> </div> <div> <pre class="programlisting"> curl -F "query=SELECT DISTINCT ?Concept FROM <http://openlinksw.com/dataspace/organization/openlink> WHERE {?s a ?Concept} LIMIT 10" http://demo.openlinksw.com/sparql </pre> </div> <br /> <a name="rdfsparqlendpointexamples3" /> <h5>14.2.3.7.3. Example with curl and SPARQL-SSL endpoint</h5> <div> <pre class="programlisting"> $ curl -H "Accept: text/rdf+n3" --cert test.pem -k https://demo.openlinksw.com/dataspace/person/demo Enter PEM pass phrase: ***** @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix ns1: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/demo%27s%20AddressBook/1046#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . ns1:this rdf:type foaf:Person . @prefix ns3: <http://www.pipian.com/rdf/tami/juliette.n3#> . ns3:juliette rdf:type foaf:Document . @prefix ns4: <https://demo.openlinksw.com/dataspace/person/> . ns4:demo rdf:type foaf:PersonalProfileDocument . @prefix ns5: <https://demo.openlinksw.com/dataspace/person/demo#> . @prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> . ns5:based_near rdf:type geo:Point . @prefix ns7: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/demo%27s%20AddressBook/1042#> . ns7:this rdf:type foaf:Person . ns5:this rdf:type foaf:Person . @prefix ns8: <https://demo.openlinksw.com/dataspace/person/demo/online_account/> . @prefix sioc: <http://rdfs.org/sioc/ns#> . ns8:demo rdf:type sioc:User . @prefix ns10: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/myAddressBook/1001#> . ns10:this rdf:type foaf:Person . @prefix ns11: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/demo%27s%20AddressBook/1045#> . ns11:this rdf:type foaf:Person . @prefix ns12: <https://demo.openlinksw.com/dataspace/demo#> . ns12:this rdf:type sioc:User . ns5:org rdf:type foaf:Organization . @prefix ns13: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/demo%27s%20AddressBook/1048#> . ns13:this rdf:type foaf:Person . @prefix ns14: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/myAddressBook/1001#this#> . ns14:org rdf:type foaf:Organization . @prefix ns15: <https://demo.openlinksw.com/dataspace/person/imitko#> . ns15:this rdf:type foaf:Person . @prefix ns16: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/myAddressBook/1049#> . ns16:this rdf:type foaf:Person . @prefix ns17: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/myAddressBook/1000#> . ns17:this rdf:type foaf:Person . ns8:MySpace rdf:type sioc:User . @prefix ns18: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/demo%27s%20AddressBook/1044#> . ns18:this rdf:type foaf:Person . @prefix dc: <http://purl.org/dc/elements/1.1/> . ns4:demo dc:title "demo demo's FOAF file" . ns14:org dc:title "OpenLink" . ns5:org dc:title "OpenLink" . ns18:this foaf:name "Kingsley Idehen" . ns13:this foaf:name "Juliette" . ns17:this foaf:name "Kingsley Idehen" . ns5:this foaf:name "demo demo" . ns15:this foaf:name "Mitko Iliev" . ns10:this foaf:name "test test12" . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . ns5:this rdfs:seeAlso ns4:demo . ns15:this rdfs:seeAlso ns4:imitko . ns4:demo foaf:maker ns5:this . ns15:this foaf:nick "imitko" . ns7:this foaf:nick "Orri Erling" . ns13:this foaf:nick "Juliette" . ns10:this foaf:nick "test1" . ns5:this foaf:nick "demo" . ns18:this foaf:nick "Kingsley" . ns17:this foaf:nick "Kingsley" . ns16:this foaf:nick "test2" . ns1:this foaf:nick "TEST" . ns11:this foaf:nick "TEST" . ns5:this foaf:holdsAccount ns8:demo , ns8:MySpace , ns12:this . @prefix ns21: <http://myopenlink.net/dataspace/person/imitko#> . ns5:this foaf:knows ns21:this , ns17:this , ns16:this , ns3:juliette , ns10:this , ns7:this . @prefix ns22: <http://myopenlink.net/dataspace/person/kidehen#> . ns5:this foaf:knows ns22:this , ns18:this , ns11:this , ns1:this . @prefix ns23: <http://bblfish.net/people/henry/card#me\u0020> . ns5:this foaf:knows ns23: , ns13:this , ns15:this ; foaf:firstName "demo" ; foaf:family_name "demo" ; foaf:gender "male" ; foaf:icqChatID "125968" ; foaf:msnChatID "45demo78" ; foaf:aimChatID "demo1234" ; foaf:yahooChatID "demo678" ; foaf:based_near ns5:based_near . @prefix ns24: <http://www.openlinksw.com> . ns5:this foaf:workplaceHomepage ns24: . ns5:org foaf:homepage ns24: . ns5:this foaf:homepage ns24: . ns14:org foaf:homepage ns24: . ns4:demo foaf:primaryTopic ns5:this . ns5:based_near geo:lat "47.333332" ; geo:long "13.333333" . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix ns1: <https://demo.openlinksw.com/dataspace/demo#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . ns1:this rdf:type foaf:OnlineAccount . @prefix ns3: <https://demo.openlinksw.com/dataspace/person/demo/online_account/> . ns3:MySpace rdf:type foaf:OnlineAccount . ns3:demo rdf:type foaf:OnlineAccount . @prefix ns4: <https://demo.openlinksw.com/dataspace/person/demo#> . ns4:this foaf:holdsAccount ns3:MySpace , ns1:this , ns3:demo . @prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> . ns4:this vcard:ADR ns4:addr . ns4:addr vcard:Country "United States" ; vcard:Locality "New York" ; vcard:Region "Nebraska" . @prefix ns6: <http://myspace.com> . ns3:MySpace foaf:accountServiceHomepage ns6: . @prefix ns7: <skype:demo?> . ns3:demo foaf:accountServiceHomepage ns7:chat ; foaf:accountName "demo" . ns3:MySpace foaf:accountName "MySpace" . @prefix ns8: <http://vocab.org/bio/0.1/> . ns4:this ns8:olb "this is short resume of user Demo." . @prefix ns9: <https://demo.openlinksw.com/dataspace/> . ns4:this foaf:openid ns9:demo ; ns8:keywords "demo, openlinksw, virtuoso, weblog, rdf" . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix ns1: <https://demo.openlinksw.com/dataspace/demo/subscriptions/> . @prefix ns2: <https://demo.openlinksw.com/dataspace/person/demo#> . ns1:DemoFeeds foaf:maker ns2:this . @prefix ns3: <https://demo.openlinksw.com/dataspace/demo/community/> . ns3:demoCommunity foaf:maker ns2:this . @prefix ns4: <https://demo.openlinksw.com/dataspace/demo/eCRM/demo%27s%20eCRM> . ns4: foaf:maker ns2:this . @prefix ns5: <https://demo.openlinksw.com/dataspace/demo/calendar/> . ns5:mycalendar foaf:maker ns2:this . @prefix ns6: <https://demo.openlinksw.com/dataspace/demo/photos/> . ns6:MyGallery foaf:maker ns2:this . @prefix ns7: <https://demo.openlinksw.com/dataspace/demo/briefcase/> . ns7:mybriefcase foaf:maker ns2:this . @prefix ns8: <https://demo.openlinksw.com/dataspace/demo/wiki/> . ns8:ESBWiki foaf:maker ns2:this . @prefix ns9: <https://demo.openlinksw.com/dataspace/demo/bookmark/> . ns9:mybookmarks foaf:maker ns2:this . @prefix ns10: <https://demo.openlinksw.com/dataspace/demo/weblog/> . ns10:myblog foaf:maker ns2:this . @prefix ns11: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/demo%27s%20AddressBook> . ns11: foaf:maker ns2:this . @prefix ns12: <https://demo.openlinksw.com/dataspace/demo/community/demo%27s%20Community> . ns12: foaf:maker ns2:this . ns8:mywiki foaf:maker ns2:this . @prefix ns13: <https://demo.openlinksw.com/dataspace/demo/eCRM/demo%20demo%27s%20eCRM> . ns13: foaf:maker ns2:this . @prefix ns14: <https://demo.openlinksw.com/dataspace/demo/polls/> . ns14:mypolls foaf:maker ns2:this . @prefix ns15: <https://demo.openlinksw.com/dataspace/demo/socialnetwork/> . ns15:myAddressBook foaf:maker ns2:this . ns3:SP2 foaf:maker ns2:this . ns2:this foaf:made ns11: , ns4: , ns3:demoCommunity , ns12: , ns15:myAddressBook , ns10:myblog , ns9:mybookmarks , ns7:mybriefcase , ns5:mycalendar , ns14:mypolls , ns8:mywiki , ns1:DemoFeeds , ns8:ESBWiki , ns6:MyGallery , ns3:SP2 , ns13: . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . ns9:mybookmarks rdfs:label "demo demo's Bookmarks" . ns15:myAddressBook rdfs:label "demo demo's AddressBook" . ns4: rdfs:label "demo demo's eCRM" . ns12: rdfs:label "demo's Community" . ns14:mypolls rdfs:label "demo demo's Polls" . ns13: rdfs:label "demo demo's eCRM Description" . ns8:mywiki rdfs:label "demo demo's Wiki" . ns7:mybriefcase rdfs:label "demo demo's Briefcase" . ns1:DemoFeeds rdfs:label "demo demo's Feeds" . ns10:myblog rdfs:label "demo's Weblog" . ns5:mycalendar rdfs:label "demo demo's Calendar" . ns11: rdfs:label "demo demo's AddressBook" . ns6:MyGallery rdfs:label "demo demo's Gallery" . ns8:ESBWiki rdfs:label "demo demo's Wiki" . ns3:demoCommunity rdfs:label "demo demo's Community" . ns3:SP2 rdfs:label "demo demo's Community" . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix ns1: <https://demo.openlinksw.com/dataspace/person/demo#> . @prefix ns2: <http://www.w3.org/ns/auth/rsa#> . ns1:cert rdf:type ns2:RSAPublicKey . @prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix ns4: <https://demo.openlinksw.com/dataspace/person/demo/projects#ods%20project> . ns4: dc:title "ods project" . @prefix foaf: <http://xmlns.com/foaf/0.1/> . ns4: foaf:maker ns1:this . ns1:this foaf:made ns4: . @prefix ns6: <http://www.w3.org/ns/auth/cert#> . ns1:cert ns6:identity ns1:this ; ns2:modulus ns1:cert_mod . ns1:cert_mod ns6:hex "b8edefa13092d05e85257d6be0aca54218091278583f1d18759c4bced0007948fa6e920018abc3c30b8885d303ec2e679f3a7c15036d38452ddd9ebfcbb41 e1bd08dca66b7737b744fd9e441ebefa425311363711714cd0fe3b334a79ce50be9eb3443193bcbf2f1486481e775382f1a1792a2a8438543ca6f478c3b13c5db2a7f9a12a9a5aed5ec498 6be0169a1859d027170812a28914d158fb76a5933f11777a06c8db64d10f7c02900c4bb4bbf2d24c0e34c6ca135fdb5e05241bc029196ceef13a2006f07d1800f17762c0cfe05b3dac3042 09e1b7a3973122e850e96fcd0396544f82f0b11a46f0d868ba0f3d8efd957e7ef224871905a06c3c5d85ac9" . ns1:cert ns2:public_exponent ns1:cert_exp . ns1:cert_exp ns6:decimal "65537" . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix ns1: <https://demo.openlinksw.com/dataspace/person/demo#> . @prefix ns2: <http://vocab.org/bio/0.1/> . ns1:event rdf:type ns2:Birth . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix ns4: <mailto:demo@openlinksw.com> . ns1:this foaf:mbox ns4: ; foaf:birthday "01-01" . @prefix dc: <http://purl.org/dc/elements/1.1/> . ns1:event dc:date "1968-01-01" . ns1:this ns2:event ns1:event . </pre> </div> <br /> <a name="rdfsparqlendpointexamples4" /> <h5>14.2.3.7.4. Example with curl and SPARQL-OAuth endpoint</h5> <p>Note: this is just an example as token had expired already. You can go to <a href="rdfsparql.html#sparqloauthendpoint">this</a> section to see how to interact with our Virtuoso UI.</p> <div> <pre class="programlisting"> $ curl "http://demo.openlinksw.com/oauth/sparql.vsp?debug=on&default-graph-uri=&format=text%2Fhtml&oauth_consumer_key=27f105a327f5f23163e0636f78901 8dacdd70bb5&oauth_nonce=a14d43339fcb2638&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1242106643&oauth_token=42e2af4d9264ef42521c1010aff99f60a8 ee95a2&oauth_version=1.0&query=select%20distinct%20%3FURI%20%3FObjectType%20where%20%7B%3FURI%20a%20%3FObjectType%7D%20limit%2050&oauth_signature=C w9yJ2saU1vgHuFxWcughai5cZY%3D" <table class="sparql" border="1"> <tr> <th>URI</th> <th>ObjectType</th> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-nonblank</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-nonblank-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarchar</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarchar-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarbinary</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarbinary-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-uri</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-uri-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-uri</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-uri-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-doubleprecision</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-doubleprecision-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-date</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-date-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-datetime</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-datetime-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#multipart-uri</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#multipart-uri-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#multipart-uri-fn-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#multipart-literal-fn-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-uri-fn</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-uri-fn-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-uri-fn</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-uri-fn-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-literal-fn</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-literal-fn-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-literal-fn</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-integer-literal-fn-nullable</td> <td>http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat</td> </tr> <tr> <td>http://www.w3.org/1999/02/22-rdf-syntax-ns#type</td> <td>http://www.w3.org/1999/02/22-rdf-syntax-ns#Property</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-nullable-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-nonblank-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-iid-nonblank-nullable-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#default-nullable-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-nullable-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarchar-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarchar-nullable-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarbinary-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-longvarbinary-nullable-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> <tr> <td>http://www.openlinksw.com/virtrdf-data-formats#sql-varchar-uri-SuperFormats</td> <td>http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat</td> </tr> </table> </pre> </div> <br /> <a name="rdfsparqlendpointexamples5" /> <h5>14.2.3.7.5. Example with CONSTRUCT</h5> <p>Go to the sparql endpoint UI: i.e. go to http://host:port/sparql</p> <p>For the Default Graph URI enter: http://www.w3.org/2001/sw/DataAccess/proto-tests/data/construct/simple-data.rdf</p> <p>Select "Retrieve remote RDF data for all missing source graphs".</p> <p>For the query text enter:</p> <div> <pre class="programlisting"> SELECT * WHERE {?s ?p ?o} </pre> </div> <p>Click the "Run Query" button.</p> <p>The query results, shown below, are cached locally (sponged). The remote RDF data is saved in the local RDF quad store as graph http://www.w3.org/2001/sw/DataAccess/proto-tests/data/construct/simple-data.rdf</p> <div> <pre class="programlisting"> s p o http://www.example/jose/foaf.rdf#jose http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://xmlns.com/foaf/0.1/Person http://www.example/jose/foaf.rdf#jose http://xmlns.com/foaf/0.1/nick Jo http://www.example/jose/foaf.rdf#jose http://xmlns.com/foaf/0.1/name Jose Jimen~ez http://www.example/jose/foaf.rdf#jose http://xmlns.com/foaf/0.1/knows http://www.example/jose/foaf.rdf#juan http://www.example/jose/foaf.rdf#jose http://xmlns.com/foaf/0.1/homepage http://www.example/jose/ http://www.example/jose/foaf.rdf#jose http://xmlns.com/foaf/0.1/workplaceHomepage http://www.corp.example/ http://www.example/jose/foaf.rdf#kendall http://xmlns.com/foaf/0.1/knows http://www.example/jose/foaf.rdf#edd http://www.example/jose/foaf.rdf#julia http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://xmlns.com/foaf/0.1/Person http://www.example/jose/foaf.rdf#julia http://xmlns.com/foaf/0.1/mbox mailto:julia@mail.example http://www.example/jose/foaf.rdf#juan http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://xmlns.com/foaf/0.1/Person http://www.example/jose/foaf.rdf#juan http://xmlns.com/foaf/0.1/mbox mailto:juan@mail.example </pre> </div> <p>Now let's take the CONSTRUCT query:</p> <div> <pre class="programlisting"> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX myfoaf: <http://www.example/jose/foaf.rdf#> CONSTRUCT { myfoaf:jose foaf:depiction <http://www.example/jose/jose.jpg>. myfoaf:jose foaf:schoolHomepage <http://www.edu.example/>. ?s ?p ?o. } FROM <http://www.w3.org/2001/sw/DataAccess/proto-tests/data/construct/simple-data.rdf> WHERE { ?s ?p ?o. myfoaf:jose foaf:nick "Jo". FILTER ( ! (?s = myfoaf:kendall && ?p = foaf:knows && ?o = myfoaf:edd ) && ! ( ?s = myfoaf:julia && ?p = foaf:mbox && ?o = <mailto:julia@mail.example> ) && ! ( ?s = myfoaf:julia && ?p = rdf:type && ?o = foaf:Person)) } </pre> </div> <p>From an HTTP client, issue the GET command with the above query added as a URL-encoded parameter value:</p> <div> <pre class="programlisting"> GET -e -s http://host:port/sparql/?query=PREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0D%0APREFIX+foaf%3A+%3Chttp%3A%2F%2Fxmlns.com%2Ffoaf%2F0.1%2F%3E%0D%0APREFIX+myfoaf%3A+%3Chttp%3A%2F%2Fwww.example%2Fjose%2Ffoaf.rdf%23%3E%0D%0A%0D%0ACONSTRUCT+%7B+myfoaf%3Ajose+foaf%3Adepiction+%3Chttp%3A%2F%2Fwww.example%2Fjose%2Fjose.jpg%3E.%0D%0A++++++++++++myfoaf%3Ajose+foaf%3AschoolHomepage+%3Chttp%3A%2F%2Fwww.edu.example%2F%3E.%0D%0A++++++++++++%3Fs+%3Fp+%3Fo.%7D%0D%0AFROM+%3Chttp%3A%2F%2Fwww.w3.org%2F2001%2Fsw%2FDataAccess%2Fproto-tests%2Fdata%2Fconstruct%2Fsimple-data.rdf%3E%0D%0AWHERE+%7B+%3Fs+%3Fp+%3Fo.+myfoaf%3Ajose+foaf%3Anick+%22Jo%22.%0D%0A+++++++FILTER+%28+%21+%28%3Fs+%3D+myfoaf%3Akendall+%26%26+%3Fp+%3D+foaf%3Aknows+%26%26+%3Fo+%3D+myfoaf%3Aedd+%29%0D%0A++++++++++++++%26%26+%21+%28+%3Fs+%3D+myfoaf%3Ajulia+%26%26+%3Fp+%3D+foaf%3Ambox+%26%26+%3Fo+%3D+%3Cmailto%3Ajulia%40mail.example%3E+%29%0D%0A++++++++++%26%26+%21+%28+%3Fs+%3D+myfoaf%3Ajulia+%26%26+%3Fp+%3D+rdf%3Atype+%26%26+%3Fo+%3D+foaf%3APerson%29%29%0D%0A%7D%0D%0A&format=application%2Frdf%2Bxml </pre> </div> <p>The request response will be similar to:</p> <div> <pre class="programlisting"> 200 OK Connection: close Date: Fri, 28 Dec 2007 10:06:14 GMT Accept-Ranges: bytes Server: Virtuoso/05.00.3023 (Win32) i686-generic-win-32 VDB Content-Length: 2073 Content-Type: application/rdf+xml; charset=UTF-8 Client-Date: Fri, 28 Dec 2007 10:06:14 GMT Client-Peer: 83.176.40.177:port Client-Response-Num: 1 <?xml version="1.0" encoding="utf-8" ?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#juan"><ns0pred:mbox xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="mailto:juan@mail.example"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:schoolHomepage xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.edu.example/"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:type xmlns:ns0pred="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:resource="http://xmlns.com/foaf/0.1/Person"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:homepage xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.example/jose/"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#juan"><ns0pred:type xmlns:ns0pred="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:resource="http://xmlns.com/foaf/0.1/Person"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:workplaceHomepage xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.corp.example/"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:nick xmlns:ns0pred="http://xmlns.com/foaf/0.1/">Jo</ns0pred:nick></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:depiction xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.example/jose/jose.jpg"/></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:name xmlns:ns0pred="http://xmlns.com/foaf/0.1/">Jose Jime?+ez</ns0pred:name></rdf:Description> <rdf:Description rdf:about="http://www.example/jose/foaf.rdf#jose"><ns0pred:knows xmlns:ns0pred="http://xmlns.com/foaf/0.1/" rdf:resource="http://www.example/jose/foaf.rdf#juan"/></rdf:Description> </rdf:RDF> Done </pre> </div> <br /> <a name="rdfsparqlendpointexamples6" /> <h5>14.2.3.7.6. Example with extraction part of literal as variable</h5> <p>The following example shows how to extract a part of a literal as a variable for use in a numeric comparison using SPARQL</p> <p>Suppose there are the following triples inserted:</p> <div> <pre class="programlisting"> SQL>SPARQL INSERT INTO GRAPH <http://mygraph.com> { <:a> <:p> "123 abc" }; callret-0 VARCHAR _______________________________________________________________________________ Insert into <http://mygraph.com>, 1 triples -- done 1 Rows. -- 30 msec. SQL>SPARQL INSERT INTO GRAPH <http://mygraph.com> { <:a> <:p> "234 abc" }; callret-0 VARCHAR _______________________________________________________________________________ Insert into <http://mygraph.com>, 1 triples -- done 1 Rows. -- 0 msec. </pre> </div> <p>In order to extract the numeric part, and then do a numeric (<.>,=), you can use atoi (), atol or atof in the filter:</p> <div> <pre class="programlisting"> SQL>SPARQL SELECT * FROM <http://mygraph.com> WHERE { ?s ?p ?o . filter (bif:atoi (?o) > 130) }; s p o VARCHAR VARCHAR VARCHAR ___________________________________ :a :p 234 abc 1 Rows. -- 10 msec. </pre> </div> <br /> <a name="rdfsparqlendpointexamples7" /> <h5>14.2.3.7.7. Example how to define rule</h5> See details <a href="rdfsparqlrule.html#rdfsparqlruleexamples">here</a> how to define rule context that is initialized from the contents of a given graph. <br /> <br /> <a name="rdfsparqlendpointimplnotes" /> <h4>14.2.3.8. Implementation Notes</h4> <p>This service has been implemented using <a href="http://docs.openlinksw.com/virtuoso">Virtuoso Server</a>.</p> <br /> <a name="rdftables" /> <h4>14.2.3.9. Virtuoso 'Semantic Bank' End Point</h4> <p> <strong>What is Piggy Bank?</strong> </p> <p> Piggy Bank is an extension to the Firefox Web browser that turns it into a Semantic Web browser, letting you make use of existing information on the Web in more useful and flexible ways not offered by the original Web sites. </p> <p /> <p> <strong>What is Semantic Bank?</strong> </p> <p> Semantic Bank is the server companion of Piggy Bank that lets you persist, share and publish data collected by individuals, groups or communities. Here is a screen shot of one in action: </p> <p> <strong>What can I do with this?</strong> </p> <p> A Semantic Bank allows you to: </p> <ul> <li> Persist your information remotely on a server - This is useful, for example, if you want to share data between two of your computers or to avoid losing it due to mistakes or failure. </li> <li> Share information with other people - The ability to tag resources creates a powerful serendipitous categorization (as proven by things like del.icio.us or Flickr). </li> <li> Lets you publish your information - Both in the "pure" RDF form (for those who know how to make use of it) or to regular web pages, with the usual Longwell faceted browsing view of it </li> </ul> <p> <strong>How can I help?</strong> </p> <p> Semantic Bank is Open Source software and built around the spirit of open participation and collaboration. </p> <p> There are several ways you can help: </p> <ul> <li>Install a Semantic Bank and let us know about it, so that we can update the list of available Semantic Banks.</li> <li>Subscribe to our mailing lists to show your interest and give us feedback</li> <li>Report problems and ask for new features through our issue tracking system.</li> <li>Send us patches or fixes to the code</li> </ul> <p> <strong>Licensing and Legal Issues</strong> </p> <p> Semantic Bank is open source software and is licensed under the BSD license. </p> <p> <strong>Note</strong>, however, that this software ships with libraries that are not released under the same license; that we interpret their licensing terms to be compatible with ours and that we are redistributing them unmodified. For more information on the licensing terms of the libraries Semantic Bank depends on, please refer to the source code. </p> <p> <strong>Download location:</strong> </p> <p> <a href="http://simile.mit.edu/dist/semantic-bank/">"http://simile.mit.edu/dist/semantic-bank/</a> </p> <p> <strong>The Virtuoso Semantic Bank End Point</strong> </p> <p> Before you can publish, you must register with one or more Semantic Banks: </p> <ul> <li>Invoke the menu command Tools > Piggy Bank > My Semantic Bank Accounts ...</li> <li>Click Add... in the Semantic Bank Accounts dialog box.</li> <li>In the popup dialog box, type in the URL to the Virtuoso Semantic Bank you want to register with. Example: http://server_name:server_port/bank</li> <li>Enter the account of a valid Virtuoso DAV user. (Note: currently we do not use encryption during authentication; do not use your precious password here.)</li> <li>Click OK, wait for the account to be registered, and then dismiss the Semantic Bank Accounts dialog box.</li> <li>To publish an item, just click the corresponding Publish button (much like how you save the item). To publish all the items being viewed, click the Publish All button.</li> </ul> <p> <strong>What is the graph name used by Virtuoso for the triples from PiggyBank?</strong> </p> <p> http://simile.org/piggybank/<piggybank-generated-name> </p> <p> The piggybank-generated-name is a Virtuoso DAV user ID. </p> <br /> <a name="rdfsparqlexnpointnorthwindexample" /> <h4>14.2.3.10. Making RDF Views Dereferenceable - Northwind Example</h4> <p>Consider an application that makes some relational data available for SPARQL requests, as described in the <a href="rdfviewsenterpr.html#rdfviewnorthwindexample1">first part of the Northwind RDF View example</a>. This may be sufficient for some clients but the IRIs of the described subjects are not dereferenceable. This means that external SPARQL processors cannot retrieve that data using the Virtuoso Sponger or the like. It also means that if some external resources refer to the IRI of some Northwind subject and a user browses that resource then he cannot look at the application's data by clicking on the subject link.</p> <p>To make RDF access complete, applications can do the following:</p> <ul> <li>Create a virtual directory</li> <li>Instruct the server how to prepare RDF resources on demand</li> <li>Configure rendering of RDF resources for non-RDF clients (including Web search engines)</li> <li>Make the used ontology available</li> <li>Provide an index or sitemap page to help users who try to browse published data but do not know the proper URLs</li> </ul> <p>The following sequence of operations demonstrates how to implement the listed features without writing any special web pages. All requests (except the application-specific index/sitemap) will be handled by existing web service endpoints.</p> <p>As a precaution, we erase any URL rewriting rule lists created by this example that may be in the database following a previous run of the script.</p> <div> <pre class="programlisting"> DB.DBA.URLREWRITE_DROP_RULELIST ('demo_nw_rule_list1', 1) ; </pre> </div> <p>Do the same for individual rewrite rules:</p> <div> <pre class="programlisting"> DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule1', 1) ; DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule2', 1) ; DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule3', 1) ; DB.DBA.URLREWRITE_DROP_RULE ('demo_nw_rule4', 1) ; </pre> </div> <p>As a sanity check we ensure that there are no other similarly named rules:</p> <div> <pre class="programlisting"> SQL>SELECT signal ('WEIRD', sprintf ('Rewrite rule "%s" found', URR_RULE)) FROM DB.DBA.URL_REWRITE_RULE WHERE URR_RULE like 'demo_nw%' ; </pre> </div> <p>Next we create URI rewrite rules based on regular expressions by calling <a href="fn_urlrewrite_create_regex_rule.html">DB.DBA.URLREWRITE_CREATE_REGEX_RULE</a>, so the same path will be redirected to different places depending on the MIME types the client can accept.</p> <p> For a given input path, that is a URI identifying a particular Linked Data entity, the rewrite rule below generates an N3 or RDF/XML representation of the entity using a CONSTRUCT query. (Note: In the regular expression identifying the Accept: MIME types this rule applies to, i.e. in rdf.n3 and rdf.xml, each period (.) replaces a literal character because some SPARQL web clients published before the relevant W3C recommendations produce slightly incorrect "Accept:" strings.) </p> <div> <pre class="programlisting"> SQL>DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'demo_nw_rule2', 1, '(/[^#]*)', vector('path'), 1, '/sparql?query=CONSTRUCT+{+%%3Chttp%%3A//^{URIQADefaultHost}^%U%%23this%%3E+%%3Fp+%%3Fo+}+FROM+%%3Chttp%%3A//^{URIQADefaultHost}^/Northwind%%3E+WHERE+{+%%3Chttp%%3A//^{URIQADefaultHost}^%U%%23this%%3E+%%3Fp+%%3Fo+}&format=%U', vector('path', 'path', '*accept*'), null, '(text/rdf.n3)|(application/rdf.xml)', 0, null ); </pre> </div> <div class="note"> <div class="notetitle">Note:</div> <p>The request URL for the SPARQL web service looks terrible because it is URL-encoded; the sprintf format string for it is even worse! The easiest way of composing encoded strings of this sort is to use the Conductor UI for configuring the rewrite rules. Alternatively open the SPARQL endpoint page (assuming it supports a UI for entering queries, if no query string is specified), type in the desired CONSTRUCT or DESCRIBE statement into the web form (using some sample URI), execute it, cut the URL of the page with results from the address line of the browser window, paste it into the script and then replace the host name with <strong>^{URIQADefaultHost}^</strong>, every percent with double percent, the parts of the sample IRI to be substituted with <strong>%U</strong>; finally adjust the vector of replacement parameters so that its length is equal to the number of <strong>%U</strong> or other format specifiers in the template.</p> </div> <p>The next rule redirects to the RDF browser service to display a description of the subject URI and let the user explore related subjects.</p> <div> <pre class="programlisting"> SQL>DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'demo_nw_rule1', 1, '(/[^#]*)', vector('path'), 1, '/rdfbrowser/index.html?uri=http%%3A//^{URIQADefaultHost}^%U%%23this', vector('path'), null, '(text/html)|(\\*/\\*)', 0, 303 ); </pre> </div> <p>This next rule removes any trailing slash from the input path. Note that <strong>\x24</strong> is the hex character code for the end-of-line pattern <strong>$</strong>. It is written escaped because the dollar sign indicates the beginning of macro in ISQL.</p> <div> <pre class="programlisting"> SQL>DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'demo_nw_rule3', 1, '(/[^#]*)/\x24', vector('path'), 1, '%s', vector('path'), null, null, 0, null ); </pre> </div> <p>To configure the server to furnish the ontology underpinning the example Northwind RDF view, the procedure LOAD_NW_ONTOLOGY_FROM_DAV, listed below, takes the ontology described in file /DAV/VAD/demo/sql/nw.owl and loads it into graph http://demo.openlinksw.com/schemas/NorthwindOntology/1.0/ in the local quad store. A rewrite rule is then created to query this graph when the input path identifies entities from this ontology. </p> <div> <pre class="programlisting"> SQL>create procedure DB.DBA.LOAD_NW_ONTOLOGY_FROM_DAV() { declare content1, urihost varchar; SELECT cast (RES_CONTENT as varchar) INTO content1 from WS.WS.SYS_DAV_RES WHERE RES_FULL_PATH = '/DAV/VAD/demo/sql/nw.owl'; DB.DBA.RDF_LOAD_RDFXML (content1, 'http://demo.openlinksw.com/schemas/northwind#', 'http://demo.openlinksw.com/schemas/NorthwindOntology/1.0/'); urihost := cfg_item_value(virtuoso_ini_path(), 'URIQA','DefaultHost'); if (urihost = 'demo.openlinksw.com') { DB.DBA.VHOST_REMOVE (lpath=>'/schemas/northwind'); DB.DBA.VHOST_DEFINE (lpath=>'/schemas/northwind', ppath=>'/DAV/VAD/demo/sql/nw.owl', vsp_user=>'dba', is_dav=>1, is_brws=>0); DB.DBA.VHOST_REMOVE (lpath=>'/schemas/northwind#'); DB.DBA.VHOST_DEFINE (lpath=>'/schemas/northwind#', ppath=>'/DAV/VAD/demo/sql/nw.owl', vsp_user=>'dba', is_dav=>1, is_brws=>0); } }; DB.DBA.LOAD_NW_ONTOLOGY_FROM_DAV(); drop procedure DB.DBA.LOAD_NW_ONTOLOGY_FROM_DAV; DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'demo_nw_rule4', 1, '/schemas/northwind#(.*)', vector('path'), 1, '/sparql?query=DESCRIBE%20%3Chttp%3A//demo.openlinksw.com/schemas/northwind%23%U%3E%20FROM%20%3Chttp%3A//demo.openlinksw.com/schemas/NorthwindOntology/1.0/%3E', vector('path'), null, '(text/rdf.n3)|(application/rdf.xml)', 0, null ); </pre> </div> <p>Next we define virtual directory <strong>/Northwind</strong> and associate with this a rulelist containing the URL rewriting rules defined above. Requests matching the rewriting rules should then be properly redirected to produce the requested data. Attempts to access the virtual directory root will execute the application's default VSP page, namely <strong>sfront.vspx</strong>.</p> <div> <pre class="programlisting"> SQL>DB.DBA.URLREWRITE_CREATE_RULELIST ( 'demo_nw_rule_list1', 1, vector ( 'demo_nw_rule1', 'demo_nw_rule2', 'demo_nw_rule3', 'demo_nw_rule4' )); VHOST_REMOVE (lpath=>'/Northwind'); DB.DBA.VHOST_DEFINE (lpath=>'/Northwind', ppath=>'/DAV/home/demo/', vsp_user=>'dba', is_dav=>1, def_page=>'sfront.vspx', is_brws=>0, opts=>vector ('url_rewrite', 'demo_nw_rule_list1')); </pre> </div> <p>Finally, to register the namespace prefix <strong>northwind</strong> as persistent we execute:</p> <div> <pre class="programlisting"> SQL>DB.DBA.XML_SET_NS_DECL ('northwind', 'http://demo.openlinksw.com/schemas/northwind#', 2); </pre> </div> <br /> <a name="rdfproxyservice" /> <h4>14.2.3.11. Sponger Proxy URI Service</h4> <p> In certain cases, such as Ajax applications, it's prohibited to issue HTTP requests to a server other than the original server. In other cases it is necessary to transform the content of a target to an RDF format. To this end Virtuoso Server provides a Sponger Proxy URI Service. This service takes as an argument a target URL and may return the target's content "as is" or the Sponger may try to transform the content and return an RDF representation of the target. When transforming to RDF, the RDF format (RDF/XML, N3, TURTLE etc) of the output can be forced by a URL parameter or by content negotiation. </p> <p> When the rdf_mappers package is installed, Virtuoso reserves the path '/about/[id|html|data|rdf]/http/' for the RDF proxy service. In the current implementation, Virtuoso defines virtual directories for HTTP requests that come to the port specified as 'ServerPort' in the '[HTTPServer]' section of Virtuoso configuration file and refer to the above path string. So, if the Virtuoso installation on host example.com listens for HTTP requests on port 8080, client applications should use the 'service endpoint' string equal to 'http://example.com:8080/about/[id|html|data|rdf]/http/'. </p> <p> If the rdf_mappers VAD package is not installed, then the path '/proxy/rdf/' is used for the Sponger Proxy URI Service. </p> <p> The old pattern for the Sponger Proxy URI Service, '/proxy/', is now deprecated. </p> <p> <strong>Note:</strong> If you do not have the rdf_mappers package installed, in order for the Sponger Proxy URI Service to work correctly, you must grant the SPARQL_UPDATE role to user SPARQL and grant execute permission on procedure RDF_SPONGE_UP. </p> <p> To enable SPARQL_UPDATE using the Conductor UI: </p> <ul> <li>Go to the Virtuoso Administration Conductor i.e. http://host:port/conductor</li> <li>Login as dba user</li> <li>Go to System Admin->User Accounts->Roles</li> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Conductor UI" src="../images/ui/cn1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.11.1. Conductor UI</td> </tr> </table> <li>Click the link "Edit" for "SPARQL_UPDATE</li> <li>Select from the list of available user/groups "SPARQL" and click the ">>" button so to add it to the right-positioned list.</li> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Conductor UI" src="../images/ui/cn2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.11.2. Conductor UI</td> </tr> </table> <li>Click the button "Update".</li> </ul> <p> To grant execute permission on RDF_SPONGE_UP: </p> <div> <pre class="programlisting"> grant execute on DB.DBA.RDF_SPONGE_UP to "SPARQL"; </pre> </div> <p> When invoked with a URL of the form http://host:port/proxy?..., the Sponger Proxy URI Service accepts the following query string parameters: </p> <ul> <li> <strong>force</strong> - if 'rdf' is specified, the Sponger will try to extract RDF data from the target and return it</li> <li> <strong>header</strong> - HTTP headers to be sent to the target</li> <li> <strong>output-format</strong> - if 'force=rdf' is given, designates the desired output MIME type of the RDF data. The default is 'rdf+xml'. Other supported MIME types are 'n3', 'turtle' or 'ttl'.</li> </ul> <p> When RDF data is requested and 'output-format' is not specified, the result will be serialized with a MIME type determined by the request 'Accept' headers i.e. the proxy service will do content negotiation. </p> <p>Example: RDF file with URL: http://www.w3.org/People/Berners-Lee/card</p> <div> <pre class="programlisting"> -- Access the url in order to view the result in HTML format: http://host:port/about/html/http/www.w3.org/People/Berners-Lee/card -- Access the url in order to view the result in RDF: http://host:port/about/rdf/http://www.w3.org/People/Berners-Lee/card -- or use the following proxy invocation style: http://host:port/proxy/rdf/http://www.w3.org/People/Berners-Lee/card -- or this one: http://host:port/proxy?url=http://www.w3.org/People/Berners-Lee/card&force=rdf </pre> </div> <p>Note: It is not permitted, when using the style http://host:port/proxy/rdf, to pass URL query string parameters to the proxy. </p> <p>Now go to the SPARQL endpoint, i.e. http://host:port/sparql</p> <p>For the 'Default Graph URI' enter the URL of the RDF file: http://www.w3.org/People/Berners-Lee/card</p> <p>For 'Query' enter:</p> <div> <pre class="programlisting"> SELECT * WHERE { ?s ?p ?o } </pre> </div> <p>Query result:</p> <div> <pre class="programlisting"> s p o http://www.w3.org/People/Berners-Lee/card http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://xmlns.com/foaf/0.1/PersonalProfileDocument http://www.w3.org/People/Berners-Lee/card http://purl.org/dc/elements/1.1/title Tim Berners-Lee's FOAF file http://www.w3.org/People/Berners-Lee/card http://creativecommons.org/ns#license http://creativecommons.org/licenses/by-nc/3.0/ http://www.w3.org/People/Berners-Lee/card http://xmlns.com/foaf/0.1/maker http://www.w3.org/People/Berners-Lee/card#i etc ... </pre> </div> <br /> <a name="sparqliniservice" /> <h4>14.2.3.12. SPARQL INI service</h4> <p> The <a href="sect5_ini_SPARQL.html">[SPARQL] section</a> of the virtuoso.ini configuration file sets parameters and limits for the SPARQL query web service. The values contained in the [SPARQL] section can be exposed in RDF form via the URL pattern http://cname/sparql?ini </p> <p>Example: http://demo.openlinksw.com/sparql?ini</p> <div> <pre class="programlisting"> <?xml version="1.0" encoding="utf-8" ?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:MaxQueryCostEstimationTime xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">1000</ns0pred:MaxQueryCostEstimationTime></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:ExternalXsltSource xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">1</ns0pred:ExternalXsltSource></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:DefaultQuery xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">SELECT ?Subject ?Concept WHERE {?Subject a ?Concept}</ns0pred:DefaultQuery></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:ResultSetMaxRows xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">100000</ns0pred:ResultSetMaxRows></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:MaxQueryExecutionTime xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">30</ns0pred:MaxQueryExecutionTime></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:ExternalQuerySource xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">1</ns0pred:ExternalQuerySource></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:DefaultGraph xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">http://demo.openlinksw.com/dataspace/person/demo</ns0pred:DefaultGraph></rdf:Description> <rdf:Description rdf:about="http://www.openlinksw.com/schemas/virtini#SPARQL"><ns0pred:PingService xmlns:ns0pred="http://www.openlinksw.com/schemas/virtini#">http://rpc.pingthesemanticweb.com/</ns0pred:PingService></rdf:Description> </rdf:RDF> </pre> </div> <br /> <a name="sparqlexcel" /> <h4>14.2.3.13. SPARQL Endpoint with Excel MIME Type Output Option</h4> <p>The SPARQL endpoint offers an Excel MIME type output option.</p> <p>From http://cname:host/sparql, select "Spreadsheet" for the "Display Results As:" option and click the "Run Query" button.</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL Endpoint with Excel MIME type output" src="../images/ui/Excel1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.13.1. SPARQL Endpoint with Excel MIME type output</td> </tr> </table> <p>The resulting query string contains a format parameter value of <strong>"application/vnd.ms-excel"</strong>. For example, <a href="http://demo.openlinksw.com/sparql?default-graph-uri=http%3A%2F%2Fdemo.openlinksw.com%2Fdataspace%2Fperson%2Fdemo&should-sponge=&query=select+*%0D%0Awhere+%7B%3Fs+%3Fp+%3Fo%7D%0D%0Alimit+10&format=application%2Fvnd.ms-excel&debug=on">A URL such as this one</a> will be generated, and can be opened directly with Excel.</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL Endpoint with Excel MIME type output" src="../images/ui/Excel2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.13.2. SPARQL Endpoint with Excel MIME type output</td> </tr> </table> <br /> <a name="sparqljson" /> <h4>14.2.3.14. SPARQL Endpoint with RDF+JSON Output: SPARQL UI Example</h4> <p>The SPARQL endpoint also offers a RDF+JSON output option.</p> <p>From http://cname:host/sparql select "JSON" for "Display Results As:" and click the "Run Query" button.</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL Endpoint with RDF+JSON output" src="../images/ui/JSON1.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.14.1. SPARQL Endpoint with RDF+JSON output</td> </tr> </table> <p>As result URL containing as parameter the format <strong>application/sparql-results+json</strong> will be generated and the content should look like:</p> <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="SPARQL Endpoint with JSON+RDF" src="../images/ui/JSON2.png" /> </td> </tr> <tr> <td>Figure: 14.2.3.14.2. SPARQL Endpoint with JSON+RDF</td> </tr> </table> <br /> <a name="sparqljsonp" /> <h4>14.2.3.15. SPARQL Endpoint with JSON/P Output Option: Curl Example</h4> <p>The SPARQL endpoint also offers a JSON/P output option.</p> <p>The SPARQL endpoint accepts a 'callback' URL parameter and in this case when parameter 'format' is 'json', then it will produce JSON/P output.</p> <div> <pre class="programlisting"> $ curl "http://lod.openlinksw.com/sparql?query=select+*+where+\{+%3Fx+a+%3Fz+.+\}+limit+10&format=json&debug=on&callback=func" func( { "head": { "link": [], "vars": ["x", "z"] }, "results": { "distinct": false, "ordered": true, "bindings": [ { "x": { "type": "bnode", "value": "nodeID://b196899188" } , "z": { "type": "uri", "value": "http://www.w3.org/2000/10/swap { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2005/04/sparqlette/#profile" } , "z": { "type": "uri", "value": services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/#b-profile" } , "z": { "type": "uri", aml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/#a-profile" } , "z": { "type": "uri", aml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/index.rdf#a-profile" } , "z": { "type": ://www.daml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/index.rdf#b-profile" } , "z": { "type": ://www.daml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2006/06/blogmatrix/#profile" } , "z": { "type": "uri", "value": services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/#b-profile" } , "z": { "type": "uri", aml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/#a-profile" } , "z": { "type": "uri", aml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }}, { "x": { "type": "uri", "value": "http://www.wasab.dk/morten/2003/12/nearestAirport/#b-profile" } , "z": { "type": "uri", aml.org/services/owl-s/1.1/Service.owl#ServiceProfile" }} ] } }) </pre> </div> <br /> <br /> <a name="sparqldebug" /> <h3>14.2.4. Troubleshooting SPARQL Queries</h3> <p>A short SPARQL query can be compiled into a long SQL statement, especially if data comes from many quad map patterns. A moderately sized application with 50 tables and 10 columns per table may create thousands of quad map patterns for subjects spanning hundreds of different types. An attempt to "select everything" from RDF view of that complexity may easily create 5000 lines of SQL code. Thus it is to be expected that some queries will be rejected even if the same queries would work fine if the RDF data were held as physical quads in default storage, rather than synthesized through an RDF view. </p> <p>In addition, the SQL compiler catches typos efficiently, signalling an error if a table or column name is unknown, efficiently catching typos. SPARQL uses IRIs that are long and sometimes unreadable, but there is no "closed world" schema of the data so a typo in an IRI is not an error; it is simply some other IRI. So a typo in an IRI or in a namespace prefix causes missing bindings of some triple patterns of the query and an incomplete result, but usually no errors are reported. A typo in graph or predicate IRI may cause the SPARQL compiler to generate code that accesses default (quad) storage instead of a relational source or generate empty code that accesses nothing.</p> <p>The SQL compiler does not signal casting errors when it runs the statement generated from SPARQL, because the generated SQL code contains <strong>option (QUIETCAST)</strong>. This means that mismatches between expected and actual datatypes of values stay invisible and may cause rounding errors (e.g. integer division instead of floating-point) and even empty joins (due to join conditions that silently return NULL instead of returning a comparison error).</p> <p>In other words, SPARQL queries are so laconic that there is no room for details that let the compiler distinguish between intent and a bug. This masks query complexity, misuse of names and type mismatches. One may make debugging easier by making queries longer.</p> <p>Two very helpful debugging tools are automatic void variable recognition and plain old code inspection. "Automatic" means "cheap" so the very first step of debugging is to ensure that every triple pattern of the query may in principle return something. This helps in finding typos when the query gets data from RDF views. It also helps when a query tries to join two disjoint sorts of subjects. If the <strong>define sql:signal-void-variables 1</strong> directive is placed in the preamble of the SPARQL query, the compiler will signal an error if it finds any triple pattern that cannot bind variables or any variable that is proved to be always unbound. This is especially useful when data are supposed to come from an <strong>option (exclusive)</strong> or <strong>option (soft exclusive)</strong> quad map. Without one of these options, the SPARQL compiler will usually bind variables using "physical quads"; the table of physical quads may contain any rows that match any given triple pattern; thus many errors will remain undiscovered. If the name of a quad map pattern is known then it is possible to force the SPARQL compiler to use only that quad map for the whole query or a part of the query. This is possible by using the following syntax:</p> <div> <pre class="programlisting"> QUAD MAP quad-map-name { group-pattern } </pre> </div> <p>If some triple pattern inside <strong>group-pattern</strong> cannot be bound using <strong>quad-map-name</strong> or one of its descendants then <strong>define sql:signal-void-variables 1</strong> will force the compiler to signal the error.</p> <div class="note"> <div class="notetitle">Note:</div> <p>Although it is technically possible to use <strong>QUAD MAP</strong> to improve the performance of a query that tries to access redundant Linked Data Views, it is much better to achieve the same effect by providing a more restrictive query or by changing/extending the RDF View. If an application relies on this trick then interoperable third-party SPARQL clients may experience problems because they cannot use Virtuoso-specific extensions.</p> </div> <p> If the automated query checking gives nothing, function <span class="computeroutput">sparql_to_sql_text</span> can be used in order to get the SQL text generated from the given query. Its only argument is the text of the SPARQL query to compile (without any leading SPARQL keyword or semicolon at the end). The returned value is the SQL text. The output may be long but it is the most authoritative source of diagnostic data. </p> <p> When called from ISQL or an ODBC client, the return value of <span class="computeroutput">sparql_to_sql_text</span> may be transferred as a BLOB so ISQL requires the "set blobs on" instruction to avoid data truncation. Even better, the SQL text can be saved to a file: </p> <div> <pre class="programlisting"> string_to_file ('debug.sql', sparql_to_sql_text ('SELECT * WHERE { graph ?g { ?s a ?type }}'), -2); </pre> </div> <p>(The -2 is to overwrite the previous version of the file, as this function may be called many times).</p> <div class="note"> <div class="notetitle">Note:</div> <p> When passing the query text to sparql_to_sql_text, if the query contains single quotes, each embedded single quote must be doubled up. Use double quotes in SPARQL queries to avoid this inconvenience. </p> </div> <p>As an example, let's find out why the query</p> <div> <pre class="programlisting"> SQL>SPARQL PREFIX northwind: <http://demo.openlinksw.com/schemas/northwind#> SELECT DISTINCT ?emp FROM <http://myhost.example.com/Northwind> WHERE { ?order1 northwind:has_salesrep ?emp ; northwind:shipCountry ?country1 . ?order2 northwind:has_salesrep ?emp ; northwind:shipCountry ?country2 . filter (?country1 != ?country2) } </pre> </div> <p>is much slower than a similar SQL statement. The call of <span class="computeroutput">sparql_to_sql_text</span> returns the equivalent SQL statement:</p> <div> <pre class="programlisting"> SELECT DISTINCT sprintf_iri ( 'http://myhost.example.com/Northwind/Employee/%U%U%d#this' , /*retval[*/ "s-6-1-t0"."b067b7d~FirstName~0" /* emp */ /*]retval*/ , /*retval[*/ "s-6-1-t0"."b067b7d~FirstName~1" /*]retval*/ , /*retval[*/ "s-6-1-t0"."b067b7d~FirstName~2" /*]retval*/ ) AS /*tmpl*/ "emp" FROM (SELECT "s-6-1-t0-int~orders"."OrderID" AS /*tmpl*/ "20ffecc~OrderID", "s-6-1-t0-int~employees"."FirstName" AS /*as-name-N*/ "b067b7d~FirstName~0", "s-6-1-t0-int~employees"."LastName" AS /*as-name-N*/ "b067b7d~FirstName~1", "s-6-1-t0-int~employees"."EmployeeID" AS /*as-name-N*/ "b067b7d~FirstName~2" FROM Demo.demo.Employees AS "s-6-1-t0-int~employees", Demo.demo.Orders AS "s-6-1-t0-int~orders" WHERE /* inter-alias join cond */ "s-6-1-t0-int~orders".EmployeeID = "s-6-1-t0-int~employees".EmployeeID) AS "s-6-1-t0", (SELECT "s-6-1-t1-int~orders"."OrderID" AS /*tmpl*/ "20ffecc~OrderID", "s-6-1-t1-int~orders"."ShipCountry" AS /*tmpl*/ "e45a7f~ShipCountry" FROM Demo.demo.Orders AS "s-6-1-t1-int~orders") AS "s-6-1-t1", (SELECT "s-6-1-t2-int~orders"."OrderID" AS /*tmpl*/ "20ffecc~OrderID", "s-6-1-t2-int~employees"."FirstName" AS /*as-name-N*/ "b067b7d~FirstName~0", "s-6-1-t2-int~employees"."LastName" AS /*as-name-N*/ "b067b7d~FirstName~1", "s-6-1-t2-int~employees"."EmployeeID" AS /*as-name-N*/ "b067b7d~FirstName~2" FROM Demo.demo.Employees AS "s-6-1-t2-int~employees", Demo.demo.Orders AS "s-6-1-t2-int~orders" WHERE /* inter-alias join cond */ "s-6-1-t2-int~orders".EmployeeID = "s-6-1-t2-int~employees".EmployeeID) AS "s-6-1-t2", (SELECT "s-6-1-t3-int~orders"."OrderID" AS /*tmpl*/ "20ffecc~OrderID", "s-6-1-t3-int~orders"."ShipCountry" AS /*tmpl*/ "e45a7f~ShipCountry" FROM Demo.demo.Orders AS "s-6-1-t3-int~orders") AS "s-6-1-t3" WHERE /* two fields belong to same equiv */ /*retval[*/ "s-6-1-t0"."20ffecc~OrderID" /* order1 */ /*]retval*/ = /*retval[*/ "s-6-1-t1"."20ffecc~OrderID" /* order1 */ /*]retval*/ AND /* two fields belong to same equiv */ sprintf_iri ( 'http://myhost.example.com/Northwind/Employee/%U%U%d#this' , /*retval[*/ "s-6-1-t0"."b067b7d~FirstName~0" /* emp */ /*]retval*/ , /*retval[*/ "s-6-1-t0"."b067b7d~FirstName~1" /*]retval*/ , /*retval[*/ "s-6-1-t0"."b067b7d~FirstName~2" /*]retval*/ ) = sprintf_iri ( 'http://myhost.example.com/Northwind/Employee/%U%U%d#this' , /*retval[*/ "s-6-1-t2"."b067b7d~FirstName~0" /* emp */ /*]retval*/ , /*retval[*/ "s-6-1-t2"."b067b7d~FirstName~1" /*]retval*/ , /*retval[*/ "s-6-1-t2"."b067b7d~FirstName~2" /*]retval*/ ) AND /* two fields belong to same equiv */ /*retval[*/ "s-6-1-t2"."20ffecc~OrderID" /* order2 */ /*]retval*/ = /*retval[*/ "s-6-1-t3"."20ffecc~OrderID" /* order2 */ /*]retval*/ AND /* filter */ ( /*retval[*/ "s-6-1-t1"."e45a7f~ShipCountry" /* country1 */ /*]retval*/ <> /*retval[*/ "s-6-1-t3"."e45a7f~ShipCountry" /* country2 */ /*]retval*/ ) OPTION (QUIETCAST) </pre> </div> <p>The query is next to unreadable but some comments split it into meaningful expressions. Every triple (or list of similar triples) becomes a subquery that returns fields needed to build the values of bound variables. The fields are printed wrapped by comments like <strong>/*retval[*/ expression /* original variable name */ /*]retval*/</strong>. Names like<strong>"s-6-1-t0"</strong> contain the source line number where a group pattern begins (6) and the serial number of the triple (0). Comment <strong>/* inter-alias join cond */</strong> means that the expression which follows is the condition as written in the declaration of the quad map pattern. Comment <strong>/* filter */</strong> precedes expressions for FILTER expressions in the source SPARQL. The word "equiv" means "equivalence class", i.e. a group of occurrences of variables in the source query such that all occurrences are bound to the same value. E.g. when a name repeats in many triples of a group, all its occurrences form an equivalence class. In some cases the compiler can prove that two variables are always equal even if the names differ - these variables are also placed into an "equiv".</p> <p>Looking at this query, you may notice equalities like <strong>sprintf_iri (...) = sprintf_iri (...)</strong>. That is sub-optimal because it indicates that no index will be used to optimize the join and that there will be one function call per row. When the variable <strong>?emp</strong> appears in two different triples, it means that the value of the variable is the same in both triples. The query compares IRIs instead of comparing the arguments of <a href="fn_sprintf_iri.html">sprintf_iri</a> because the format string is not proven to be a bijection. Indeed it cannot be a bijection for <strong>arbitrary</strong> strings, but the database must reflect the real world. If it is assumed that the real names of persons never start with a digit, within the <strong>%d%U</strong> format fragment, the digits will always be distinguishable from the name; so the IRI class can be declared as a bijection even if it is not true for arbitrary strings. The script can then include "suspicious" <strong>option (bijection)</strong> as follows:</p> <div> <pre class="programlisting"> create iri class sample:Employee "http://example.com/Employee/%d%U#this" (in employee_id integer not null, in employee_lastname varchar not null) option (bijection) . </pre> </div> <p>Unfortunately, attempts to use the same trick with the declaration from the Northwind example will fail:</p> <div> <pre class="programlisting"> create iri class northwind:Employee "http://^{URIQADefaultHost}^/Northwind/Employee/%U%U%d#this" (in employee_firstname varchar not null, in employee_lastname varchar not null, in employee_id integer not null) option (bijection) . </pre> </div> <p>Bijection will allow the parsing, but it will never give the proper result, because the first <strong>%U</strong> will read the whole concatenation of <strong>%U%U%d</strong>, leaving nothing before the<strong>#this</strong> for the second <strong>%U</strong> (this is an error) and leaving nothing for the <strong>%d</strong> (that is an explicit parse error, becauses the integer field cannot be empty).</p>. <p>The string parser will process the string from left to right so it will be unable to parse the string. The compiler might sometimes report an error if it can prove that the format string is not appropriate for bijection.</p> <p>The correct way of improving the Northwind example is to enable reliable bijection by adding strong delimiters:</p> <div> <pre class="programlisting"> create iri class northwind:Employee "http://^{URIQADefaultHost}^/Northwind/Employee/%U/%U/%d#this" (in employee_firstname varchar not null, in employee_lastname varchar not null, in employee_id integer not null) option (bijection) . </pre> </div> <p>After running the updated script, the query contains three comparisons of fields that were arguments of <span class="computeroutput">sprintf_iri</span> in the previous version.</p> <p> <strong>Example for casting string as IRI type</strong> </p> <div> <pre class="programlisting"> create function DB.DBA.RDF_DF_GRANTEE_ID_URI (in id integer) { declare isrole integer; isrole := coalesce ((SELECT top 1 U_IS_ROLE FROM DB.DBA.SYS_USERS WHERE U_ID = id)); if (isrole is null) return NULL; else if (isrole) return sprintf ('http://%s/sys/group?id=%d', registry_get ('URIQADefaultHost'), id); else return sprintf ('http://%s/sys/user?id=%d', registry_get ('URIQADefaultHost'), id); } ; grant execute on DB.DBA.RDF_DF_GRANTEE_ID_URI to SPARQL_SELECT ; create function DB.DBA.RDF_DF_GRANTEE_ID_URI_INVERSE (in id_iri varchar) { declare parts any; parts := sprintf_inverse (id_iri, sprintf ('http://%s/sys/user?id=%%d', registry_get ('URIQADefaultHost')), 1); if (parts is not null) { if (exists (SELECT TOP 1 1 FROM DB.DBA.SYS_USERS WHERE U_ID = parts[0] and not U_IS_ROLE)) return parts[0]; } parts := sprintf_inverse (id_iri, sprintf ('http://%s/sys/group?id=%%d', registry_get ('URIQADefaultHost')), 1); if (parts is not null) { if (exists (SELECT TOP 1 1 FROM DB.DBA.SYS_USERS WHERE U_ID = parts[0] and U_IS_ROLE)) return parts[0]; } return NULL; } ; grant execute on DB.DBA.RDF_DF_GRANTEE_ID_URI_INVERSE to SPARQL_SELECT ; create iri class oplsioc:grantee_iri using function DB.DBA.RDF_DF_GRANTEE_ID_URI (in id integer) returns varchar , function DB.DBA.RDF_DF_GRANTEE_ID_URI_INVERSE (in id_iri varchar) returns integer option ( bijection , returns "http://^{URIQADefaultHost}^/sys/group?id=%d" union "http://^{URIQADefaultHost}^/sys/user?id=%d" ) . </pre> </div> <br /> <a name="rdfsparqlinline" /> <h3>14.2.5. SPARQL Inline in SQL</h3> <p>Virtuoso extends the SQL 92 syntax with SPARQL queries and subqueries. Instead of writing a SQL SELECT query or subquery, one can write the SPARQL keyword and a SPARQL query after the keyword.</p> <div> <pre class="programlisting"> SQL>SPARQL SELECT DISTINCT ?p WHERE { graph ?g { ?s ?p ?o } }; p varchar ---------- http://example.org/ns#b http://example.org/ns#d http://xmlns.com/foaf/0.1/name http://xmlns.com/foaf/0.1/mbox ... SQL>SELECT distinct subseq ("p", strchr ("p", '#')) as fragment FROM (SPARQL SELECT DISTINCT ?p WHERE { graph ?g { ?s ?p ?o } } ) as all_predicates WHERE "p" like '%#%'; fragment varchar ---------- #query #data #name #comment ... </pre> </div> <p>Note that names of variables returned from SPARQL are always case-sensitive and no case mode rules apply to them. Depending on the CaseMode parameter in the Virtuoso configuration file, double quotes should be used if necessary to refer to them in surrounding SQL code. </p> <p> It is possible to pass parameters to a SPARQL query via a Virtuoso-specific syntax extension. <strong>??</strong> or <strong>$?</strong> indicates a positional parameter similar to <strong>?</strong> in plain SQL. <strong>??</strong> can be used in graph patterns or anywhere in place of a SPARQL variable. The value of a parameter should be passed in SQL form, i.e. this should be a number or a untyped string. An IRI ID can be passed in all cases where an absolute IRI can, except the obvious case of when the variable is an argument of a function that requires string. If the parameter is used in the 'graph', 'subject' or 'object' position of the SPARQL pattern, the string parameter is converted into an IRI automatically. In other cases an IRI string is indistinguishable from a string literal, so it is necessary to call the built-in SPARQL function <strong>iri()</strong> , e.g. <strong>iri (??)</strong>. Using this notation, any dynamic SQL client (whether ODBC, JDBC or some other) can execute parameterized SPARQL queries, binding parameters just as with dynamic SQL. </p> <div> <pre class="programlisting"> SQL> create function param_passing_demo () { declare stat, msg varchar; declare mdata, rset any; exec ('SPARQL SELECT ?s WHERE { graph ?g { ?s ?? ?? }}', stat, msg, vector ( /* Vector of two parameters */ 'http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#int1', 4 ), 10, /* Max no of rows */ mdata, /* Variable to get metadata */ rset ); /* Variable to get result-set */ if (length (rset) = 0) signal ('23000', 'No data found, try demo database with installed Virtuoso tutorials'); return rset[0][0]; } SQL> SELECT param_passing_demo (); callret VARCHAR _______________________________________________________________________________ http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#four 1 Rows. -- 00000 msec. </pre> </div> <p>Another example:</p> <div> <pre class="programlisting"> INSERT INTO GRAPH <http://localhost:8890/Northwind> { `iri($?)` <http://localhost:8890/schemas/northwind#has_province> "Valencia" }; </pre> </div> <p>An inline SPARQL query can refer to SQL variables that are in scope in the SQL query or stored procedure containing it. Virtuoso extends the SPARQL syntax with a special notation to this effect. A reference to SQL variable X can be written as <strong>?:X</strong> or <strong>$:X</strong>. A reference to column <strong>C</strong> of a table or a sub-select with alias <strong>T</strong> can be written as <strong>?:T.C</strong> or <strong>$:T.C</strong>. Both notations can be used in any place where a variable name is allowed, except the 'AS' clause described below. </p> <p>A column of a result set of a SPARQL SELECT can be used in SQL code inside a for statement just like any column from a SQL select. </p> <p>SQL rules about double-quoted names are applicable to variables that are passed to a SPARQL query or selected from one. If a variable name contains unusual characters or should not be normalized according to SQL conventions then the name should use double quotes for escaping. e.g., the notation <strong>?:"OrderLine"</strong> will always refer to variable or column titled <strong>OrderLine</strong> whereas <strong>?:OrderLine</strong> can be converted to <strong>ORDERLINE</strong> or <strong>orderline</strong>. </p> <p>It is safer to avoid using variable names that conflict with column names of RDF system tables, esp. <strong>G</strong>, <strong>S</strong>, <strong>P</strong> and <strong>O</strong>. These names are not reserved now but they may cause subtle bugs when an incorrect SPARQL subquery is compiled into SQL code that refers to identically named table columns. Some of these names may be rejected as syntax errors by future Virtuoso versions. </p> <div> <pre class="programlisting"> SQL> create procedure sql_vars_demo () { #pragma prefix sort0: <http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#> declare RES varchar; declare obj integer; result_names (RES); obj := 4; for (SPARQL SELECT ?subj WHERE { graph ?g { ?subj sort0:int1 ?:obj } } ) do result ("subj"); } SQL> sql_vars_demo (); RES VARCHAR _______________________________________________________________________________ http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#four 1 Rows. -- 00000 msec. </pre> </div> <p>The example also demonstrates the Virtuoso/PL pragma line for procedure-wide declarations of namespace prefixes. This makes the code more readable and eliminates duplicate declarations of namespace prefixes when the procedure contains many SPARQL fragments that refer to a common set of namespaces. </p> <p>A SPARQL ASK query can be used as an argument of the SQL EXISTS predicate. </p> <div> <pre class="programlisting"> create function sparql_ask_demo () returns varchar { if (exists (sparql ask where { graph ?g { ?s ?p 4}})) return 'YES'; else return 'NO'; } SQL> SELECT sparql_ask_demo (); _______________________________________________________________________________ YES </pre> </div> <a name="rdfcontrollingsparqloutputtypes" /> <h4>14.2.5.1. Controlling SPARQL Output Data Types</h4> <p>The compilation of a SPARQL query may depend on an environment that is usually provided by the SPARQL protocol and which includes the default graph URI. Environment settings that come from the SPARQL protocol may override settings in the text of a SPARQL query. To let an application configure the environment for a query, SPARQL's syntax has been extended with the 'define' clause:</p> <div> <pre class="programlisting"> define parameter-qname parameter-value </pre> </div> <p>Examples of supported parameters are <strong>output:valmode</strong> and <strong>output:format</strong> </p> <p> <strong>output:valmode</strong> specifies which data types (i.e. representation) should be used for values in the result set. The default is "SQLVAL", meaning that a query returns result set values in SQL format and behaves as a typical SQL select - IRIs and string literals are returned as strings, making the output compatible with ODBC and the standard SQL routines. To compose triple vectors in Virtuoso PL code, an application may need data in long format. A valmode of "LONG" means that IRIs are returned as IRI_IDs and string literals may be returned as special "RDF boxes" even if they are actually plain strings. This may cause problems if these new datatypes are not known to the data recipient or if IRIs come from RDF Views (in which case IRI_IDs are created on the fly and 'pollute' the database), but it can result in fewer data conversions and thus better speed if used properly. "AUTO" disables all types of conversion for the result set, so the latter can comprise a mix of values across "SQLVAL" and "LONG" value modes, as well as some internal representations. It is better to avoid using this mode in user applications because the output may change from version to version. </p> <p>If the query contains a</p> <div> <pre class="programlisting"> define output:valmode 'LONG' </pre> </div> <p>clause then all returned values are in long format. e.g., the following query returns IRI_ID's instead of IRI strings.</p> <div> <pre class="programlisting"> SQL>SPARQL define output:valmode 'LONG' SELECT distinct ?p WHERE { graph ?g { ?s ?p ?o } }; p ---------- #i1000001 #i1000003 #i1000005 #i1000006 ... </pre> </div> <p> <strong>output:format</strong> instructs the SPARQL compiler that the result of the query should be serialized into an RDF document - that document will be returned as a single column of a single row result set. <strong>output:format</strong> is especially useful if a SPARQL CONSTRUCT or SPARQL DESCRIBE query is executed directly via an ODBC or JDBC database connection and the client cannot receive the resulting dictionary of triples (there's no way to transfer such an object via ODBC). Using this option, the client can receive the document that contains the whole result set of a SELECT or the dictionary of triples of a CONSTRUCT/DESCRIBE, and parse it locally. </p> <p> Supported values for <strong>output:format</strong> are <strong>RDF/XML</strong> and <strong>TURTLE</strong> (or <strong>TTL</strong>). If both <strong>output:valmode</strong> and <strong>output:format</strong> are specified, <strong>output:format</strong> has higher priority, raising an error if <strong>output:valmode</strong> is set to a value other than <strong>LONG</strong>. </p> <p> When a SPARQL query is compiled, the compiler checks whether the result set is to be sent to a remote ODBC/JDBC client or used in some other way. The compiler will automatically set <strong>output:format</strong> to <strong>TURTLE</strong> if compiling for execution by an SQL client. </p> <p> The example below demonstrates how different values of <strong>output:format</strong> affect the result of SPARQL SELECT. Note 10 rows and 4 columns in the first result, and single LONG VARCHAR in the others. When using the ISQL client, use the 'set blobs on;' directive if fetching long texts to avoid receiving a 'data truncated' warning. </p> <div> <pre class="programlisting"> SQL> SPARQL SELECT * WHERE {graph ?g { ?s ?p ?o }} limit 10; g s p o VARCHAR VARCHAR VARCHAR VARCHAR ______________________________________________________________________ http://local.virt/DAV/bound/manifest.rdf nodeID://1000000000 http://example.com/test#query http://local.virt/DAV/bound/bound1.rq . . . http://local.virt/DAV/examples/manifest.rdf nodeID://1000000019 http://example.com/test#query http://local.virt/DAV/examples/ex11.2.3.1_1.rq 10 Rows. -- 00000 msec. SQL> SPARQL define output:format "TTL" SELECT * WHERE {graph ?g { ?s ?p ?o }} limit 10; callret-0 LONG VARCHAR _______________________________________________________________________________ @prefix :rdf <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix :rs <http://www.w3.org/2005/sparql-results#> . @prefix :xsd <http://www.w3.org/2001/XMLSchema#> . [ rdf:type rs:results ; rs:result [ rs:binding [ rs:name "g" ; rs:value <http://local.virt/DAV/bound/manifest.rdf> ] ; rs:binding [ rs:name "s" ; rs:value _:nodeID1000000000 ] ; rs:binding [ rs:name "p" ; rs:value <http://example.com/test#query> ] ; rs:binding [ rs:name "o" ; rs:value <http://local.virt/DAV/bound/bound1.rq> ] ; ] ; . . . rs:result [ rs:binding [ rs:name "g" ; rs:value <http://local.virt/DAV/examples/manifest.rdf> ] ; rs:binding [ rs:name "s" ; rs:value _:nodeID1000000019 ] ; rs:binding [ rs:name "p" ; rs:value <http://example.com/test#query> ] ; rs:binding [ rs:name "o" ; rs:value <http://local.virt/DAV/examples/ex11.2.3.1_1.rq> ] ; ] ; ] . 1 Rows. -- 00000 msec. SQL> SPARQL define output:format "RDF/XML" SELECT * WHERE {graph ?g { ?s ?p ?o }} LIMIT 10; callret-0 LONG VARCHAR _______________________________________________________________________________ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rs="http://www.w3.org/2005/sparql-results#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" > <rs:results rdf:nodeID="rset"> <rs:result rdf:nodeID="sol206"> <rs:binding rdf:nodeID="sol206-0" rs:name="g"><rs:value rdf:resource="http://local.virt/DAV/bound/manifest.rdf"/></rs:binding> <rs:binding rdf:nodeID="sol206-1" rs:name="s"><rs:value rdf:nodeID="1000000000"/></rs:binding> <rs:binding rdf:nodeID="sol206-2" rs:name="p"><rs:value rdf:resource="http://example.com/test#query"/></rs:binding> <rs:binding rdf:nodeID="sol206-3" rs:name="o"><rs:value rdf:resource="http://local.virt/DAV/bound/bound1.rq"/></rs:binding> </rs:result> . . . <rs:result rdf:nodeID="sol5737"> <rs:binding rdf:nodeID="sol5737-0" rs:name="g"><rs:value rdf:resource="http://local.virt/DAV/examples/manifest.rdf"/></rs:binding> <rs:binding rdf:nodeID="sol5737-1" rs:name="s"><rs:value rdf:nodeID="1000000019"/></rs:binding> <rs:binding rdf:nodeID="sol5737-2" rs:name="p"><rs:value rdf:resource="http://example.com/test#query"/></rs:binding> <rs:binding rdf:nodeID="sol5737-3" rs:name="o"><rs:value rdf:resource="http://local.virt/DAV/examples/ex11.2.3.1_1.rq"/></rs:binding> </rs:result> </rs:results> </rdf:RDF> 1 Rows. -- 00000 msec. </pre> </div> <p>SPARQL CONSTRUCT and SPARQL DESCRIBE results are serialized as one would expect:</p> <div> <pre class="programlisting"> SQL>SPARQL define output:format "TTL" CONSTRUCT { ?s ?p "004" } WHERE { graph ?g { ?s ?p 4 } }; callret-0 LONG VARCHAR _______________________________________________________________________________ <http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#four> <http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#int1> "004" . _:b1000000913 <http://www.w3.org/2001/sw/DataAccess/tests/result-set#index> "004" . 1 Rows. -- 00000 msec. SQL> SPARQL define output:format "RDF/XML" CONSTRUCT { ?s ?p "004" } WHERE { graph ?g { ?s ?p 4 } }; callret-0 LONG VARCHAR _______________________________________________________________________________ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description about="http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#four"><ns0pred:int1 xmlns:ns0pred="http://www.w3.org/2001/sw/DataAccess/tests/data/Sorting/sort-0#">004</ns0pred:int1></rdf:Description> <rdf:Description rdf:nodeID="b1000000913"><ns0pred:index xmlns:ns0pred="http://www.w3.org/2001/sw/DataAccess/tests/result-set#">004</ns0pred:index></rdf:Description> </rdf:RDF> 1 Rows. -- 00000 msec. </pre> </div> <p>SPARQL ASK returns a non-empty result set if a match is found for the graph pattern, an empty result set otherwise. If <strong>output:format</strong> is specified then the query makes a 'boolean result' document instead:</p> <div> <pre class="programlisting"> SQL> SPARQL ASK WHERE {graph ?g { ?s ?p 4 }}; __ask_retval INTEGER _______________________________________________________________________________ 1 1 Rows. -- 00000 msec. SQL> SPARQL ASK WHERE {graph ?g { ?s ?p "no such" }}; __ask_retval INTEGER _______________________________________________________________________________ 0 Rows. -- 00000 msec. SQL> SPARQL define output:format "TTL" ASK WHERE {graph ?g { ?s ?p 4 }}; callret VARCHAR _______________________________________________________________________________ @prefix :rdf <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix :rs <http://www.w3.org/2005/sparql-results#> . [ rdf:type rs:results ; rs:boolean TRUE ] 1 Rows. -- 00000 msec. SQL> SPARQL define output:format "RDF/XML" ASK WHERE {graph ?g { ?s ?p 4 }}; callret VARCHAR _______________________________________________________________________________ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rs="http://www.w3.org/2005/sparql-results#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" > <rs:results rdf:nodeID="rset"> <rs:boolean rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">1</rs:boolean></results></rdf:RDF> 1 Rows. -- 00000 msec. </pre> </div> <br /> <br /> <a name="rdfapi" /> <h3>14.2.6. API Functions</h3> <p> SPARQL can be used inline wherever SQL can be used. The only API functions that one needs to know are the ones for loading RDF data into the store. Dynamic SQL client applications can issue SPARQL queries against Virtuoso through the regular SQL client API, ODBC, JDBC or any other supported API, simply by prefixing the SPARQL query with the SPARQL keyword. Parameters work just as with dynamic SQL. Stored procedures can have SPARQL expressions inline and can declare cursors over SPARQL result sets. </p> <p> Value conversions between SQL and SPARQL are most often automatic and invisible. In some cases one needs to be aware of the different SPARQL value representations (valmodes). SPARQL offers declarations for specifying whether returned graphs are to be serialized as XML or Turtle, or whether these will be hash tables of triples. See <a href="fn_dict_new.html">dict_new()</a> and related functions for a description of the hash table SQL data type. The use of dict's is convenient for further programmatic processing of graphs. </p> <p>RDF-related procedures use Virtuoso/PL vectors and dictionaries to represent RDF triples and sets of triples.</p> <p> <strong>Valmode</strong> means the "format of values returned by an expression", i.e. 'short', 'long' or 'SQL value'.</p> <p> <strong>Triple vector</strong> is a vector (array) of S, P and O, where all values are in 'long' formats, i.e. IRI_ID's for IRI values, numbers or datetimes for corresponding XMLSchema types, special "RDF box" objects if O is neither string nor IRI.</p> <p> <strong>Dictionary of triples</strong> or <strong>Hash table of triples</strong> is an dictionary object made by the SQL function <strong>dict_new ()</strong> whose keys are triple vectors and values are not specified; this is a good storage format for an unordered set of distinct triples.</p> <p> <strong>Dictionary of blank node names</strong> is a dictionary used for tricky processing of a number of TURTLE or RDF /XML descriptions of subgraphs that come from a common graph. Imagine a situation where different descriptions actually refer to the same blank nodes of the original graph and, moreover, the application that generates these descriptions always generates the same blank node id string for the same node. A reader of descriptions can correctly join described subgraphs into one big subgraph by filling in a dictionary that contains blank node id strings as keys and IRI_ID's assigned to those strings as dependent data. The sharing of the same node dictionary by all readers of an application will ensure that no blank node is duplicated.</p> <a name="rdfapidataimport" /> <h4>14.2.6.1. Data Import</h4> <a name="rdfapidataimportttlp" /> <h5>14.2.6.1.1. Using TTLP</h5> <p>DB.DBA.TTLP() parses TTL (TURTLE or N3 resource) and places its triples into DB.DBA.RDF_QUAD.</p> <div> <pre class="programlisting"> create procedure DB.DBA.TTLP ( in strg any, -- text of the resource in base varchar, -- base IRI to resolve relative IRIs to absolute in graph varchar, -- target graph IRI, parsed triples will appear in that graph. in flags int) -- bitmask of flags that permit some sorts of syntax errors in resource, use 0. </pre> </div> <p>For loading a file of any great length, it is more practical to use the file_to_string_output function. </p> <p>It is important the file be accessible to the Virtuoso server. You need to have set properly set the <strong>DirsAllowed</strong> parameter value in the section [Parameters] of the Virtuoso database INI file. For example on Windows it could be: </p> <div> <pre class="programlisting"> virtuoso.ini file: [Parameters] ... DirsAllowed = .\tmp ... </pre> </div> <p>So, in the example, the file you want to import from, should be in the tmp folder or in a subfolder. Note that this example folder is a subfolder of the Virtuoso Server working directory. </p> <div> <pre class="programlisting"> SQL> DB.DBA.TTLP (file_to_string_output ('.\tmp\data.ttl'), '', 'http://my_graph', 0); </pre> </div> <br /> <a name="rdfapidataimportttlpmt" /> <h5>14.2.6.1.2. Using TTLP_MT</h5> <p>The DB.DBA.TTLP_MT() procedure is like DB.DBA.TTLP() but loads the file on multiple threads, using parallel I/O and multiprocessing if available. The function does not leave a transaction log. Hence, after a successful load, one should execute the checkpoint statement to make sure that a server restart does not wipe out the results. </p> <div> <pre class="programlisting"> create procedure DB.DBA.TTLP_MT ( in strg any, -- text of the resource in base varchar, -- base IRI to resolve relative IRIs to absolute in graph varchar, -- target graph IRI, parsed triples will appear in that graph. in flags int) -- flags, use 0 </pre> </div> <br /> <a name="rdfapidataimportxmlttlpmt" /> <h5>14.2.6.1.3. Using RDF_LOAD_RDFXML_MT</h5> <p>For loading large resources when transactional integrity is not important (loading of a single resource may take more than one transaction) you can use also the <strong>DB.DBA.RDF_LOAD_RDFXML_MT()</strong> procedure:</p> <div> <pre class="programlisting"> create procedure DB.DBA.RDF_LOAD_RDFXML_MT ( in strg varchar, -- text of the resource in base varchar, -- base IRI to resolve relative IRIs to absolute in graph varchar) -- target graph IRI, parsed triples will appear in that graph. </pre> </div> <p>The following example demonstrates importing data from the RDF resource with URI: http://www.w3.org/People/Berners-Lee/card</p> <div> <pre class="programlisting"> SQL>create procedure MY_LOAD_FILE (in full_uri varchar, in in_resultset integer := 0) { declare REPORT varchar; declare graph_uri, dattext varchar; declare app_env any; app_env := null; whenever sqlstate '*' goto err_rep; if (not in_resultset) result_names (REPORT); dattext := cast (XML_URI_GET_AND_CACHE (full_uri) as varchar); MY_SPARQL_REPORT (sprintf ('Downloading %s: %d bytes', full_uri, length (dattext) ) ); graph_uri := full_uri; DELETE FROM RDF_QUAD WHERE G = DB.DBA.RDF_MAKE_IID_OF_QNAME (graph_uri); DB.DBA.RDF_LOAD_RDFXML_MT (dattext, full_uri, graph_uri); return graph_uri; err_rep: result (sprintf ('%s: %s', __SQL_STATE, __SQL_MESSAGE)); return graph_uri; } ; Done. -- 0 msec. SQL>create procedure MY_SPARQL_REPORT(in strg varchar) { if (__tag(strg) <> 182) strg := cast (strg as varchar) || sprintf (' -- not a string, tag=%d', __tag(strg)); strg := replace (strg, 'SPARQL_DAV_DATA_URI()', '\044{SPARQL_DAV_DATA_URI()}'); strg := replace (strg, 'SPARQL_DAV_DATA_PATH()', '\044{SPARQL_DAV_DATA_PATH()}'); strg := replace (strg, 'SPARQL_FILE_DATA_ROOT()', '\044{SPARQL_FILE_DATA_ROOT()}'); result (strg); } ; Done. -- 0 msec. SQL> MY_LOAD_FILE('http://www.w3.org/People/Berners-Lee/card'); REPORT VARCHAR _______________________________________________________________________________ Downloading http://www.w3.org/People/Berners-Lee/card: 17773 bytes 1 Rows. -- 4046 msec. SQL>SPARQL SELECT * FROM <http://www.w3.org/People/Berners-Lee/card> WHERE {?s ?p ?o} ; s p o VARCHAR VARCHAR VARCHAR __________________________________________________________________________________________________________ http://bblfish.net/people/henry/card#me http://xmlns.com/foaf/0.1/name Henry Story http://www.w3.org/People/Berners-Lee/card#i http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://xmlns.com/foaf/0.1/Person http://www.w3.org/People/Berners-Lee/card#i http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://www.w3.org/2000/10/swap/pim/contact#Male http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/nick TimBL http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/nick timbl http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/mbox mailto:timbl@w3.org http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/mbox_sha1sum 965c47c5a70db7407210cef6e4e6f5374a525c5c http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://bblfish.net/people/henry/card#me http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://hometown.aol.com/chbussler/foaf/chbussler.foaf#me http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://danbri.org/foaf#danbri http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://norman.walsh.name/knows/who#norman-walsh http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://www.aaronsw.com/about.xrdf#aaronsw http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://www.ivan-herman.net/foaf.rdf#me http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://www.w3.org/People/Berners-Lee/card#amy http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/knows http://dig.csail.mit.edu/People/RRS .......... </pre> </div> <br /> <a name="rdfapidataimportttlphash" /> <h5>14.2.6.1.4. Using RDF_TTL2HASH</h5> <p>The DB.DBA.RDF_TTL2HASH() does not load TTL content, instead it returns a dictionary of triples in 'long valmode'.</p> <div> <pre class="programlisting"> create function DB.DBA.RDF_TTL2HASH ( in strg any, in base varchar, in graph varchar ) returns any </pre> </div> <p>Parameter <strong>flags</strong> is useful when the syntax of the resource is TURTLE-like, but not correct TURTLE. By default, use zero value. Add 1 to let string literals contain end-of-line characters. Add 2 to suppress error messages on blank node verbs. Add 4 to allow variables instead of blank nodes. Add 8 to silently skip triples with literal subjects. </p> <br /> <a name="rdfapidataimportloadrdfxml" /> <h5>14.2.6.1.5. Using RDF_LOAD_RDFXML</h5> <p>The DB.DBA.RDF_LOAD_RDFXML() procedure parses RDF/XML and places its triples into DB.DBA.RDF_QUAD.</p> <div> <pre class="programlisting"> create procedure DB.DBA.RDF_LOAD_RDFXML ( in strg any, -- text of and XML document in base_iri varchar, -- base IRI to resolve relative IRIs in graph_iri varchar ) -- the IRI of destination graph </pre> </div> <p>See <a href="sparqlextensions.html#rdfsparqlrulespecifywhatindexexample">example</a> </p>. <br /> <a name="rdfapidataimportloadrdfuri" /> <h5>14.2.6.1.6. Using RDF_QUAD_URI, RDF_QUAD_URI_L and RDF_QUAD_URI_L_TYPED</h5> <p>To insert a single quad into DB.DBA.RDF_QUAD() table, use one of these procedures:</p> <div> <pre class="programlisting"> -- Simple insertion of a quad where the object is a node create procedure DB.DBA.RDF_QUAD_URI ( in g_uri varchar, in s_uri varchar, in p_uri varchar, in o_uri varchar ) -- IRI string or IRI_ID -- Simple insertion of a quad where the object is a literal value in 'SQL valmode' create procedure DB.DBA.RDF_QUAD_URI_L ( in g_uri varchar, in s_uri varchar, in p_uri varchar, in o_lit any ) -- string, number or datetime, NULL is not allowed create procedure DB.DBA.RDF_QUAD_URI_L_TYPED ( in g_uri varchar, in s_uri varchar, in p_uri varchar, in o_lit any, -- string value of the literal in dt any, -- datatype as IRI string or IRI_ID, can be NULL in lang varchar ) -- language as string or NULL </pre> </div> <br /> <p>Arguments g_uri, s_uri and p_uri of these three functions should be IRI strings or IRI_IDs. All string arguments should be in UTF-8 encoding, otherwise they will be stored but are not queryable via SPARQL.</p> <br /> <a name="rdfapidataexport" /> <h4>14.2.6.2. Data Export</h4> <p>These two procedures serialize a vector of triples into a session, in TURTLE or RDF/XML syntax. In their current versions, every triple is printed in a separate top-level record (say, in an rdf:Description tag), without any pretty-printing or nesting optimization. </p> <div> <pre class="programlisting"> create procedure DB.DBA.RDF_TRIPLES_TO_TTL ( inout triples any, -- vector of triples in 'long valmode'. inout ses any ) -- an output stream in server default encoding create procedure DB.DBA.RDF_TRIPLES_TO_RDF_XML_TEXT ( inout triples any, -- vector of triples in 'long valmode'. in print_top_level integer, -- zero if only rdf:Description tags should be written, -- non-zero if the rdf:RDF top-level element should also be written inout ses any ) -- an output stream in server default encoding </pre> </div> <br /> <a name="rdfapidataquery" /> <h4>14.2.6.3. Data query</h4> <div> <pre class="programlisting"> -- Local execution of SPARQL via SPARQL protocol, produces a result set of SQL values. create procedure DB.DBA.SPARQL_EVAL ( in query varchar, -- text of SPARQL query to execute in dflt_graph varchar, -- default graph IRI, if not NULL then this overrides what's specified in query in maxrows integer ) -- limit on numbers of rows that should be returned. -- Similar to SPARQL_EVAL, but returns a vector of vectors of SQL values. create function DB.DBA.SPARQL_EVAL_TO_ARRAY ( in query varchar, -- text of SPARQL query to execute in dflt_graph varchar, -- default graph IRI, if not NULL then this overrides what's specified in query in maxrows integer ) -- limit on numbers of rows that should be returned. returns any </pre> </div> <div> <pre class="programlisting"> -- Remote execution of SPARQL via SPARQL protocol, produces a result set of SQL values. create procedure DB.DBA.SPARQL_REXEC ( in service varchar, -- service URI to call via HTTP in query varchar, -- text of SPARQL query to execute in dflt_graph varchar, -- default graph IRI, if not NULL then this overrides what's specified in query in named_graphs any, -- vector of named graph IRIs, if not NULL then this overrides what's specified in query in req_hdr any, -- additional HTTP header lines that should be passed to the service; 'Host: ...' is most popular. in maxrows integer, -- limit on numbers of rows that should be returned. in bnode_dict any ) -- dictionary of bnode ID references. -- Similar to SPARQL_REXEC (), but returns a vector of vectors of SQL values. -- All arguments are the same. create function DB.DBA.SPARQL_REXEC_TO_ARRAY ( in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any, in req_hdr any, in maxrows integer, in bnode_dict any) returns any -- Similar to SPARQL_REXEC (), but fills in output parameters with metadata (like exec metadata) and a vector of vector s of 'long valmode' values. -- First seven arguments are the same. create procedure DB.DBA.SPARQL_REXEC_WITH_META ( in service varchar, in query varchar, in dflt_graph varchar, in named_graphs any, in req_hdr any, in maxrows integer, in bnode_dict any, out metadata any, -- metadata like exec () returns. out resultset any) -- results as 'long valmode' value. </pre> </div> <p>If the query is a CONSTRUCT or DESCRIBE then the result set consists of a single row and column, the value inside is a dictionary of triples in 'long valmode'.</p> <br /> <br /> <a name="rdfinternalfunctions" /> <h3>14.2.7. Useful Internal Functions</h3> <a name="rdfinternalconversion" /> <h4>14.2.7.1. Conversion Functions for XMLSchema/RDF Data Serialization Syntax</h4> <p>These functions emulate constructor functions from XQuery Core Function Library.</p> <div> <pre class="programlisting"> create function DB.DBA."http://www.w3.org/2001/XMLSchema#boolean" (in strg any) returns integer create function DB.DBA."http://www.w3.org/2001/XMLSchema#dateTime" (in strg any) returns datetime create function DB.DBA."http://www.w3.org/2001/XMLSchema#double" (in strg varchar) returns double precision create function DB.DBA."http://www.w3.org/2001/XMLSchema#float" (in strg varchar) returns float create function DB.DBA."http://www.w3.org/2001/XMLSchema#integer" (in strg varchar) returns integer </pre> </div> <br /> <a name="rdfinternalpredicates" /> <h4>14.2.7.2. RDF-specific Predicates</h4> <div> <pre class="programlisting"> -- Returns 1 if string s matches pattern p, 0 otherwise create function DB.DBA.RDF_REGEX ( in s varchar, -- source string to check in p varchar, -- regular expression pattern string in coll varchar := null) -- unused for now (modes are not yet implemented) -- Returns 1 if language identifier r matches lang pattern t create function DB.DBA.RDF_LANGMATCHES ( in r varchar, -- language identifies (string or NULL) in t varchar) -- language pattern (exact name, first two letters or '*') </pre> </div> <br /> <br /> <a name="rdfdefaultgraph" /> <h3>14.2.8. Default and Named Graphs</h3> <p>Sometimes the default graph IRI is not known when the SPARQL query is composed. It can be added at the very last moment by providing the IRI in a 'define' clause as follows:</p> <div> <pre class="programlisting"> define input:default-graph-uri &lt;http://example.com&gt </pre> </div> <p>Such a definition overrides the default graph URI set in query by the 'FROM ...' clause (if any).</p> <p>The query may contain more than one <strong>define input:default-graph-uri</strong>. The set of values of <strong>input:default-graph-uri</strong> has the highest possible priority and cannot be redefined in the rest of the text of the query by FROM clauses.</p> <p>FROM NAMED clauses can be used multiple times in one query:</p> <div> <pre class="programlisting"> SPARQL SELECT ?id FROM NAMED <http://example.com/user1.ttl> OPTION (get:soft "soft", get:method "GET") FROM NAMED <http://example.com/user2.ttl> OPTION (get:soft "soft", get:method "GET") WHERE { GRAPH ?g { ?id a ?o } } </pre> </div> <p>Similarly, <strong>define input:named-graph-uri <http://example.com></strong> is a replacement for a FROM NAMED clause</p> <p> When Virtuoso receives a SPARQL request via HTTP, the value of the default graph can be set in the protocol using a <strong>default-graph-uri</strong> HTTP parameter. Multiple occurrences of this parameter are allowed. This HTTP parameter is converted into <strong>define input:default-graph-uri</strong>. There's similar support for <strong>named-graph-uri</strong> HTTP parameter. For debugging purposes, graph names set in the protocol are sent back in the reply header as <strong>X-SPARQL-default-graph: ...</strong> and <strong>X-SPARQL-named-graph: ...</strong> header lines, one line per graph. </p> <p> A web service endpoint may provide different default configurations for different host names mentioned in HTTP requests. This facility is configured via table <strong>DB.DBA.SYS_SPARQL_HOST</strong>. </p> <div> <pre class="programlisting"> create table DB.DBA.SYS_SPARQL_HOST ( SH_HOST varchar not null primary key, -- host mask SH_GRAPH_URI varchar, -- 'default default' graph uri SH_USER_URI varchar, -- reserved for any use in applications SH_DEFINES long varchar -- additional defines for requests ) </pre> </div> <p> When the SPARQL web service endpoint receives a request it checks the <strong>Host</strong> HTTP header line. This line contains zero or more target host names, delimited by commas. For every host name in the line, the service scans the <strong>DB.DBA.SYS_SPARQL_HOST</strong> table in search of a row containing a matching host name in <strong>SH_HOST</strong>. The <strong>SH_HOST</strong> field acts as 'pattern' argument for the SQL string operator LIKE. If a matching row is found, the text of SPARQL request is extended. If a default graph is not explicitly set by the HTTP parameters and <strong>SH_GRAPH_URI</strong> is not null then the default graph is set to <strong>SH_GRAPH_URI</strong>. If <strong>SH_DEFINES</strong> is not null then it is added in front of the query; so this field is a good place for the text for any <strong>define</strong> options. </p> <p>SH_USER_URI is for arbitrary user data and can be used in any way by the application that is "responsible" for the declared host.</p> <p> The search of <strong>DB.DBA.SYS_SPARQL_HOST</strong> stops at the first found row, other possible matches are silently ignored. </p> <br /> <a name="rdfsqlfromsparql" /> <h3>14.2.9. Calling SQL from SPARQL</h3> <p>A SPARQL expression can contain calls to Virtuoso/PL functions and built-in SQL functions in both the WHERE clause and in the result set. Two namespace prefixes, <strong>bif</strong> and <strong>sql</strong> are reserved for these purposes. When a function name starts with the <strong>bif:</strong> namespace prefix, the rest of the name is treated as the name of a SQL BIF (Built-In Function). When a function name starts with the <strong>sql:</strong> namespace prefix, the rest of the name is treated as the name of a Virtuoso/PL function owned by DBA with database qualifier DB, e.g. <strong>sql:example(...)</strong> is converted into <strong>DB.DBA."example"(...)</strong>.</p> <p>In both cases, the function receives arguments in SQL format ('SQL valmode') and also returns the result in SQL format. The SPARQL compiler will automatically add code for format conversion into the resulting SQL code so SQL functions can be used even if <strong>define output:valmode 'LONG'</strong> forces the use of RDF representation in the result set.</p> <a name="rdfsqlfromsparqlex1" /> <h4>14.2.9.1. Example with sql: namespace prefix</h4> <div> <pre class="programlisting"> SQL>create procedure DB.DBA.ComposeInfo ( in pname varchar, in pnick varchar := '', in pbox varchar := '') { declare ss varchar; ss := concat(pname, ' ', pnick, ' ', pbox); ss := rtrim (ss, ' '); return ss; }; Done. -- 0 msec. SQL>SPARQL PREFIX foaf: <http://xmlns.com/foaf/0.1/> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> SELECT (sql:ComposeInfo (?name, ?nick, ?box)) FROM <http://www.w3.org/People/Berners-Lee/card> WHERE { ?s rdf:type foaf:Person . optional{?s foaf:name ?name }. optional{?s foaf:nick ?nick }. optional{?s foaf:box ?box }. filter (?nick like '%TimBL%') . }; callret-0 VARCHAR _______________________________________________________________________________ Timothy Berners-Lee TimBL 1 Rows. -- 30 msec. </pre> </div> <div class="tip"> <div class="tiptitle">See Also:</div> <ul> <li> <a href="rdfsparqlgeospat.html#rdfsparqlgeospatexmp11">Example "Things around highly populated places"</a> </li> <li> <a href="virtuosospongerfacent.html">Virtuoso Faceted Web Service Examples</a> </li> <li> <a href="figure_VirtFacetUsage6.html">Virtuoso Faceted Usage Statistics Examples</a> </li> </ul> </div> <br /> <a name="rdfsqlfromsparqlex1" /> <h4>14.2.9.2. Example with sql: namespace prefix and bif:contains</h4> <div> <pre class="programlisting"> SQL>SPARQL SELECT DISTINCT ?cityUri ?cityName (sql:BEST_LANGMATCH (?cityName, 'en, en-gb;q=0.8, fr;q=0.7, *;q=0.1', '')) as ?bestCityName WHERE { ?cityUri ?predicate ?value. ?cityUri a <http://dbpedia.org/ontology/City>. ?value bif:contains "London". OPTIONAL { ?cityUri rdfs:label ?cityName } }; cityUri cityName bestCityName ANY ANY ANY ______________________________________________________________________________________________________________ http://dbpedia.org/resource/Anerley Anerley Anerley http://dbpedia.org/resource/Felixstowe Felixstowe Felixstowe http://dbpedia.org/resource/Chesham Chesham Chesham http://dbpedia.org/resource/Stratford%2C_London Stratford, London Stratford, London http://dbpedia.org/resource/Ashford%2C_Surrey Ashford (Surrey) A shford (Surrey) http://dbpedia.org/resource/Newmarket%2C_Suffolk Newmarket (Suffolk) Newmarket (Suffolk) http://dbpedia.org/resource/North_Rhine-Westphalia Renania d'o Norte-Westfalia Renania d'o Norte-Westfalia http://dbpedia.org/resource/West_Bromwich West Bromwich West Bromwich .... </pre> </div> <br /> <a name="rdfsqlfromsparqlex2" /> <h4>14.2.9.3. Example with bif: namespace prefix</h4> <div> <pre class="programlisting"> SQL>SPARQL SELECT * FROM <http://www.w3.org/people#> WHERE { ?s ?p ?o . ?o bif:contains '"Timo*"'}; s p o VARCHAR VARCHAR VARCHAR _______________________________________________________________________________ http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/name Timothy Berners-Lee http://www.w3.org/People/Berners-Lee/card#i http://xmlns.com/foaf/0.1/givenname Timothy 2 Rows. -- 2 msec. </pre> </div> <div class="tip"> <div class="tiptitle">See Also:</div> <ul> <li> <a href="rdfsparql.html#rdfpredicatessparqlexamples">Example filtering RDF objects triples by a given predicate</a> </li> <li> <a href="rdfsparql.html#rdfsparqlendpointexamples6">Example with extraction part of literal as variable</a> </li> <li> <a href="sparqlextensions.html#rdfsparulexamples5">Example for various expressions usage</a> </li> <li> <a href="sparqlextensions.html#rdfsparulexamples8">Example for generating RDF information resource URI</a> </li> </ul> </div> <br /> <br /> <a name="rdfsqlfromsparqldescribe" /> <h3>14.2.10. SPARQL DESCRIBE</h3> <p>The SPARQL specification does not define the precise output of DESCRIBE, so different applications may need different results for the same subject. Some applications need quick generation of short and incomplete results whereas others may need detailed reports composed from multiple sources. </p> <p>If define <strong>sql:describe-mode "xxx"</strong> is specified then the generated SQL code will use the procedures named: </p> <div> <pre class="programlisting"> DB.DBA.SPARQL_DESC_DICT_xxx (in subj_dict any, in consts any, in graphs any, in storage_name any, in options any) </pre> </div> <p>and </p> <div> <pre class="programlisting"> DB.DBA.SPARQL_DESC_DICT_xxx_PHYSICAL (in subj_dict any, in consts any, in graphs any, in storage_name any, in options any) </pre> </div> <p>In a new blank database, only two such pairs of procedures are created. Procedures <strong>DB.DBA.SPARQL_DESC_DICT_SPO</strong> and <strong>DB.DBA.SPARQL_DESC_DICT_SPO_PHYSICAL</strong> are for <strong>sql:describe-mode "SPO"</strong>. This pair of procedures searches for all triples where the input IRIs are used as subjects; they are faster than the default routine which searches for all triples where the input IRIs are used as subjects or objects. Similarly, <strong>DB.DBA.SPARQL_DESC_DICT_CBD</strong> and <strong>DB.DBA.SPARQL_DESC_DICT_CBD_PHYSICAL</strong> are for <strong>sql:describe-mode "CBD"</strong>. CBD stands for Concise Bounded Description, Nokia-style. </p> <p> <strong>Example:</strong> </p> <div> <pre class="programlisting"> SQL>SPARQL DEFINE sql:describe-mode "CBD" PREFIX foaf: <http://xmlns.com/foaf/0.1/> DESCRIBE ?friend WHERE { ?s foaf:knows ?friend . ?friend foaf:nick ?nick. filter (?s=<http://www.advogato.org/person/rmorgan/foaf.rdf#me>) } ; @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix ns1: <http://www.advogato.org/person/chrisd/foaf.rdf#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . ns1:me rdf:type foaf:Person . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . ns1:me rdfs:seeAlso <http://www.advogato.org/person/chrisd/foaf.rdf> ; foaf:name "Chris DiBona" ; foaf:nick "chrisd" ; foaf:homepage <http://www.dibona.com> ; foaf:mbox_sha1sum "e8231d19ac0d11ccbdc565485054461e5d71f0d3" . @prefix ns4: <http://www.advogato.org/person/schoen/foaf.rdf#> . ns1:me foaf:knows ns4:me . @prefix ns5: <http://www.advogato.org/person/jpick/foaf.rdf#> . ns1:me foaf:knows ns5:me . @prefix ns6: <http://www.advogato.org/person/benson/foaf.rdf#> . ns1:me foaf:knows ns6:me . @prefix ns7: <http://www.advogato.org/person/conrad/foaf.rdf#> . ns1:me foaf:knows ns7:me . @prefix ns8: <http://www.advogato.org/person/starshine/foaf.rdf#> . ns1:me foaf:knows ns8:me . @prefix ns9: <http://www.advogato.org/person/chip/foaf.rdf#> . ns1:me foaf:knows ns9:me . @prefix ns10: <http://www.advogato.org/person/crackmonkey/foaf.rdf#> . ..... </pre> </div> <p>In each pair, both procedures have the same semantics but the second one is used if and only if the SPARQL compiler can prove that all subjects to process are from physical storage <strong>(DB.DBA.RDF_QUAD)</strong>. Thus the second procedure will not search for subjects in RDF Views. </p> <p>Each procedure should return a dictionary with triples as keys and integer 1 as values. So the dictionary is filled by calls like: </p> <div> <pre class="programlisting"> dict_put (resulting_dict, vector (subj_iri_id, pred_iri_id, obj_iri_id_or_rdf_box), 1); </pre> </div> <p>Procedure arguments are as follows: </p> <ul> <li> <strong>subj_dict</strong> - a dictionary whose keys are IRI IDs and maybe values of other types, esp. RDF boxes. Keys are subjects to be described, so values other than IRI IDs should usually be ignored. Values should be ignored.</li> <li> <strong>consts</strong> - a vector of IRI IDs and values of other types. The items contained in the vector are subjects to be described, as with the keys of subj_dict.</li> <li> <strong>graphs</strong> - a vector of IRI IDs of graphs that can be used for DESCRIBE. The vector may contain garbage, like in the two previous cases. A NULL can be passed instead of a vector indicating that the source graphs are not specified in the source query.</li> <li> <strong>storage_name</strong> - the value of "define input:storage" from the original SPARQL query, NULL if missing.</li> <li> <strong>options</strong> - reserved for future use and can be ignored.</li> </ul> <p>One should grant execute permission on both procedures to SPARQL_SELECT before referring to them in SPARQL.</p> <p> <strong>Example:</strong> </p> <div> <pre class="programlisting"> SQL>set blobs on; SQL>SPARQL define sql:describe-mode "SPO" PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX sioct: <http://rdfs.org/sioc/types#> DESCRIBE ?forum FROM <http://demo.openlinksw.com/dataspace> WHERE { ?forum rdf:type sioct:Weblog . } LIMIT 1; callret-0 LONG VARCHAR _______________________________________________________________________________ <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://rdfs.org/sioc/types#Weblog> , <http://atomowl.org/ontologies/atomrdf#Feed> ; <http://rdfs.org/sioc/ns#description> "XML templates demo's Weblog" ; <http://rdfs.org/sioc/ns#has_space> <http://demo.openlinksw.com/dataspace/bloguser/space#this> ; <http://rdfs.org/sioc/ns#container_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/20> , <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/21> ; <http://rdfs.org/sioc/ns#id> "bloguser_blog" ; <http://xmlns.com/foaf/0.1/maker> <http://demo.openlinksw.com/dataspace/person/bloguser#this> ; <http://rdfs.org/sioc/ns#link> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> ; <http://atomowl.org/ontologies/atomrdf#entry> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/20> , <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/21> ; <http://atomowl.org/ontologies/atomrdf#contains> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/21> , <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/20> ; <http://atomowl.org/ontologies/atomrdf#title> "bloguser_blog" ; <http://www.w3.org/2000/01/rdf-schema#label> "XML templates demo's Weblog" ; <http://rdfs.org/sioc/ns#scope_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog#owner> ; <http://rdfs.org/sioc/ns#has_owner> <http://demo.openlinksw.com/dataspace/bloguser#this> ; <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/sioc.rdf> ; <http://purl.org/dc/elements/1.1/identifier> "62"^^<http://www.w3.org/2001/XMLSchema#integer> ; <http://rdfs.org/sioc/services#has_service> <http://demo.openlinksw.com/RPC2> , <http://demo.openlinksw.com/mt-tb> , <http://demo.openlinksw.com/Atom/bloguser-blog-0> , <http://demo.openlinksw.com/GData/bloguser-blog-0> . <http://demo.openlinksw.com/RPC2> <http://rdfs.org/sioc/services#service_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/mt-tb> <http://rdfs.org/sioc/services#service_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog#owner> <http://rdfs.org/sioc/ns#has_scope> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/20> <http://rdfs.org/sioc/ns#has_container> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> ; <http://atomowl.org/ontologies/atomrdf#source> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog/21> <http://rdfs.org/sioc/ns#has_container> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> ; <http://atomowl.org/ontologies/atomrdf#source> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/dataspace/bloguser#this> <http://rdfs.org/sioc/ns#owner_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/dataspace/bloguser/space#this> <http://rdfs.org/sioc/ns#space_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/dataspace/person/bloguser#this> <http://xmlns.com/foaf/0.1/made> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/Atom/bloguser-blog-0> <http://rdfs.org/sioc/services#service_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . <http://demo.openlinksw.com/GData/bloguser-blog-0> <http://rdfs.org/sioc/services#service_of> <http://demo.openlinksw.com/dataspace/bloguser/weblog/bloguser_blog> . 1 Rows. -- 240 msec. </pre> </div> <br /> <a name="rdfsparqlimplementatiotrans" /> <h3>14.2.11. Transitivity in SPARQL</h3> <p>Virtuoso SPARQL allows access to Virtuoso's SQL transitivity extension. Read the <a href="transitivityinsQL.html">SQL section</a> for a definition of the options.</p> <p>The SPARQL syntax is slightly different from the SQL, although the option names and meanings are the same.</p> <p>In SPARQL, the transitive options occur after a subquery enclosed in braces:</p> <p>The below produces all the IRI's that are the same as <alice>.</p> <div> <pre class="programlisting"> SPARQL SELECT ?syn where { { SELECT ?x ?syn where { { ?x owl:sameAs ?syn } union { ?syn owl:sameAs ?x } } } option ( transitive, t_in (?x), t_out (?syn), t_distinct, t_min (0) ) filter (?x = <Alice>) . } </pre> </div> <p>In this case, we provide a binding for ?x in the filter outside of the transitive subquery. The subquery therefore is made to run from in to out. The same effect would be accomplished if we bound ?syn and SELECT ?x, the designations of in and out are arbitrary and for transitive steps that can be evaluated equally well in both directions this makes no difference. </p> <p>The transitive subquery in the above is </p> <div> <pre class="programlisting"> {SELECT ?syn WHERE { { SELECT ?x ?syn WHERE {{ ?x owl:sameAs ?syn } UNION { ?syn owl:sameAs ?x}} } OPTION (TRANSITIVE, t_in (?x), t_out (?syn), t_distinct, t_min (0) ) } } . </pre> </div> <p>Leaving out the option would just look for one step of owl:sameAs. Making it transitive will apply the subquery to all bindings it produces until all are visited at least once (the t_distinct modifier). </p> <p>If the transitive step consists of a single triple pattern, there is a shorthand:</p> <div> <pre class="programlisting"> <alice> foaf:knows ?friend option (transitive t_min (1)) </pre> </div> <p>will bind ?friend to all directly and indirectly found foaf:known individuals. If t_min had been 0, Malice> would have also been in the generated bindings.</p> <p>The syntax is</p> <div> <pre class="programlisting"> option (transitive transitivity_option[,...]) transitivity_option ::= t_in (<variable_list>) | t_out (<variable_list>) | t_distinct | t_shortest_only | t_no_cycles | t_cycles_only | t_min (INTNUM) | t_max (INTNUM) | t_end_flag (<variable>) | t_step (<variiable_or_step>) | t_direction INTNUM variable_list ::= <variable> [,...] variable_or_step ::= <variable> | path_id' | 'step_no' </pre> </div> <p>Unlike SQL, variable names are used instead of column numbers. Otherwise all the options have the same meaning.</p> <p>Some examples of the use of transitivity are:</p> <a name="rdfsparqlimplementatiotransexamples" /> <h4>14.2.11.1. Collection of Transitivity Option Demo Queries for SPARQL</h4> <a name="rdfsparqlimplementatiotransexamples1" /> <h5>14.2.11.1.1. Example for finding out what graphs contain owl:sameAs for "New York"</h5> <p>To find out what graphs contain owl:sameAs for Dan York, we do</p> <div> <pre class="programlisting"> SELECT ?g ?x count (*) as ?count WHERE { {SELECT ?x ?alias ?g WHERE { { GRAPH ?g {?x owl:sameAs ?alias } } UNION {GRAPH ?g {?alias owl:sameAs ?x}}}} OPTION (TRANSITIVE, t_in (?x), t_out (?alias), t_distinct, t_min (1)) . FILTER (?x = <http://dbpedia.org/resource/New_York> ) . } </pre> </div> <p>Here we select all paths that start with the initial URI and pass through one or more sameAs statements. Each step produces a result of the transitive subquery. The graph where the sameAs triple was found is returned and used as the grouping column. In this way we see how many times each graph is used. Note that graphs are counted many times since the graphs containing immediate sameAs statements are counted for paths of length 1, then again as steps on paths that reach to their aliases and so on.</p> <br /> <a name="rdfsparqlimplementatiotransexamples2" /> <h5>14.2.11.1.2. Example for query that takes all the people known by Tim Berners-Lee, to a depth between 1 and 4 applications of the subquery</h5> <p>This query takes all the people known by kidehen, to a depth between 1 and 4 applications of the subquery. It then sorts them by the distance and the descending count of connections of each found connection. This is equivalent to the default connections list shown by LinkedIn.</p> <div> <pre class="programlisting"> SPARQL SELECT ?o ?dist ((SELECT COUNT (*) WHERE {?o foaf:knows ?xx})) WHERE { { SELECT ?s ?o WHERE { ?s foaf:knows ?o } } OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_min (1), t_max (4), t_step ('step_no') as ?dist) . FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i>) } ORDER BY ?dist DESC 3 LIMIT 50 </pre> </div> <br /> <a name="rdfsparqlimplementatiotransexamples4" /> <h5>14.2.11.1.3. Example for finding how two people know each other and what graphs are involved in the connection</h5> <p>To find how two people know each other and what graphs are involved in the connection, we do:</p> <div> <pre class="programlisting"> SPARQL SELECT ?link ?g ?step ?path WHERE { { SELECT ?s ?o ?g WHERE { graph ?g {?s foaf:knows ?o } } } OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_no_cycles, T_shortest_only, t_step (?s) as ?link, t_step ('path_id') as ?path, t_step ('step_no') as ?step, t_direction 3) . FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i> && ?o = <http://www.advogato.org/person/mparaz/foaf.rdf#me>) } LIMIT 20 </pre> </div> <p>This query binds both the t_in and t_out variables. The ?g is left as a free variable. Also, specifying ?s and the system defined constants step_no and path_id as with t_step, we get for each transitive step a row of results with the intermediate binding of ?s, the count of steps from the initial ?s and a distinct identifier for the individual path, since there can be many distinct paths that link the ?s and ?o specified in the filter.</p> <p>See the SQL transitive option section for details on the meaning of step_no and path_id.</p> <br /> <a name="rdfsparqlimplementatiotransexamples5" /> <h5>14.2.11.1.4. Example for TBox Subsumption</h5> <p>Subsumption Demo Using Transitivity Clause</p> <p>Yago Class Hierarchy (TBox) Subsumption</p> <p>AlphaReceptors</p> <div> <pre class="programlisting"> SELECT ?y FROM <http://dbpedia.org/resource/classes/yago#> WHERE { { SELECT * WHERE { ?x rdfs:subClassOf ?y . } } OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?y) ) . FILTER (?x = <http://dbpedia.org/class/yago/AlphaReceptor105609111>) } </pre> </div> <br /> <a name="rdfsparqlimplementatiotransexamples6" /> <h5>14.2.11.1.5. Example for Receptors</h5> <div> <pre class="programlisting"> SELECT ?x FROM <http://dbpedia.org/resource/classes/yago#> WHERE { { SELECT * WHERE { ?x rdfs:subClassOf ?y . } } OPTION (transitive, t_distinct, t_in (?x), t_out (?y) ) . FILTER (?y = <http://dbpedia.org/class/yago/Receptor105608868>) } </pre> </div> <br /> <a name="rdfsparqlimplementatiotransexamples7" /> <h5>14.2.11.1.6. Inference Rule example using transitive properties from SKOS vocabulary</h5> The following example demostrates the steps how to retrieve the skos ontology, add triples for skos:broaderTransitiveinto the graph, define inference rule, and at the and execute sparql query with inference rule and transitivity option. The queries were executed against the LOD instance (http://lod.openlinksw.com): <ol> <li>Make the Context graph, assuming you don't want to load entire SKOS vocabulary into our Quad Store: <div> <pre class="programlisting"> SQL>SPARQL PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> INSERT INTO GRAPH <urn:rules.skos> { skos:broader rdfs:subPropertyOf skos:broaderTransitive . skos:narrower rdfs:subPropertyOf skos:narrowerTransitive }; </pre> </div> </li> <li>OR Load entire SKOS ontology into Quad Store via iSQL interface (commandline or HTML based Conductor): <div> <pre class="programlisting"> SQL>DB.DBA.RDF_LOAD_RDFXML (http_get ('http://www.w3.org/2009/08/skos-reference/skos-owl1-dl.rdf'), 'no', 'urn:rules.skos'); Done. </pre> </div> </li> <li>Make Context Rule: <div> <pre class="programlisting"> SQL>rdfs_rule_set ('skos-trans', 'urn:rules.skos'); Done. </pre> </div> </li> <li>Go to SPARQL endpoint, for ex. http://lod.openlinksw.com/sparql</li> <li>Use inference rule pragma to set context rule for SPARQL query, i.e: <div> <pre class="programlisting"> SPARQL DEFINE input:inference "skos-trans" PREFIX p: <http://dbpedia.org/property/> PREFIX dbpedia: <http://dbpedia.org/resource/> PREFIX category: <http://dbpedia.org/resource/Category:> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX geo: <http://www.georss.org/georss/> SELECT DISTINCT ?m ?n ?p ?d WHERE { ?m rdfs:label ?n. ?m skos:subject ?c. ?c skos:broaderTransitive category:Churches_in_Paris OPTION (TRANSITIVE) . ?m p:abstract ?d. ?m geo:point ?p FILTER ( lang(?n) = "fr" ) FILTER ( lang(?d) = "fr" ) } </pre> </div> </li> <li>You will get 22 rows returned from the query. Note that for comparison, if the option (transitive) is ommitted, then only 2 rows will be returned in our example query: <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Transitive option" src="../images/ui/trs1.png" /> </td> </tr> <tr> <td>Figure: 14.2.11.1.6.1. Transitive option</td> </tr> </table> </li> </ol> <br /> <a name="rdfsparqlimplementatiotransexamples8" /> <h5>14.2.11.1.7. Inference Rule example using transitive properties from SKOS vocabulary: Variant II</h5> This example shows how to find entities that are subcategories of Protestant Churches, no deeper than 3 levels within the concept scheme hierarchy, filtered by a specific subcategory. It demonstrates use of inference rules, sub-queries, and filter to obtain entities associated with category: Protestant_churches combined with the use of the transitivitve closure, sets to a maximum of 3 steps down a SKOS based concept scheme hierarchy: <ol> <li>Make sure the inference rule "skos-trans" is created as described in the previous <a href="rdfsparql.html#rdfsparqlimplementatiotransexamples7">example</a> </li> <li>Go to SPARQL endpoint, for ex. http://lod.openlinksw.com/sparql</li> <li>Use inference rule pragma to set context rule for SPARQL query, i.e: <div> <pre class="programlisting"> DEFINE input:inference "skos-trans" PREFIX p: <http://dbpedia.org/property/> PREFIX dbpedia: <http://dbpedia.org/resource/> PREFIX category: <http://dbpedia.org/resource/Category:> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX geo: <http://www.georss.org/georss/> SELECT DISTINCT ?c AS ?skos_broader ?trans AS ?skos_narrower ?dist AS ?skos_level ?m ?n ?p AS ?geo_point WHERE { { SELECT ?c ?m ?n ?p ?trans ?dist WHERE { ?m rdfs:label ?n. ?m skos:subject ?c. ?c skos:broaderTransitive category:Protestant_churches . ?c skos:broaderTransitive ?trans OPTION ( TRANSITIVE, t_distinct, t_in (?c), t_out (?trans), t_max (3), t_step ( 'step_no' ) as ?dist ) . ?m p:abstract ?d. ?m geo:point ?p FILTER ( lang(?n) = "en" ) FILTER ( lang(?d) = "en" ) } } FILTER ( ?trans = <http://dbpedia.org/resource/Category:Churches_in_London> ) } ORDER BY ASC (?dist) </pre> </div> </li> <li>You will get 22 rows returned from the query. <table class="figure" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <img alt="Transitive option" src="../images/ui/trs2.png" /> </td> </tr> <tr> <td>Figure: 14.2.11.1.7.1. Transitive option</td> </tr> </table> </li> </ol> <br /> <br /> <br /> <a name="rdfsparqlimplementatioptragmas" /> <h3>14.2.12. Supported SPARQL-BI "define" pragmas</h3> <p>SPARQL-BI compiler and run-time support are not isolated from environment and some used heuristics are not perfect and sometimes different use cases require different behavior within same standard. These reasons are seen frequently in the industry, and the solution is well known: compiler pragmas. So we allow them at the beginning of any SPARQL query in form: </p> <div> <pre class="programlisting"> define QName value </pre> </div> <a name="rdfsparqlimplementatioptragmascinp" /> <h4>14.2.12.1. Pragmas to control the input data set for the query</h4> <div> <pre class="programlisting"> input:default-graph-uri works like "FROM" clause; input:named-graph-uri works like "FROM NAMED" clause; input:default-graph-exclude works like "NOT FROM" clause; input:named-graph-exclude works like "NOT FROM NAMED" clause. </pre> </div> <p>The difference is that these pragmas have higher priority and they can be used for security restrictions in combination with define input:freeze that blocks further changes in the list of source graphs. The web service endpoint (or similar non-web application) can edit the incoming query by placing list of pragmas ended with input:freeze in front of query text. Even if the intruder will try to place some graph names, it will get compilation error, not an access to the data. input:freeze disables all input:grab-... pragmas as well. </p> <ul> <li>input:ifp: adds IFP keyword in OPTION (QUIETCAST, ...) clause in the generated SQL. The value of this define is not used ATM, an empty string is safe for future extensions.</li> <li>input:same-as: works like input:ifp but adds SAME_AS keyword.</li> <li>input:storage: selects quad map storage to use. The value is an IRI of storage, the default value is, of course, virtrdf:DefaultQuadStorage. If the value is an empty string then only quads from RDF_VIEW are used. This is a good choice for low-level admin procedures, for two reasons: they will not interfere with any changes in virtrdf:DefaultQuadStorage and they will continue to work even if all compiler's metadata are corrupted, including the description of virtrdf:DefaultQuadStorage (define input:storage "" switches the SPARQL compiler to a small set of metadata that are built in server C code and thus are very hard to corrupt by users).</li> <li>input:inference: specifies the name of inference rule set to use.</li> <li>input:param (and synonyms input:params, sql:param, sql:params): declares a variable name as a protocol parameter. The SPARQL query can refer to protocol parameter X via variable with special syntax of name ?::X . If a query text should be made by query builder that does not understand SPARQL-BI extensions then the text may contain variable ?X and define input:param "X" . This does not work for positional parameters, one can not replace a reference to ?::3 with ?3 and define input:param "3".</li> <li>input:grab-var: sponge values of variable;</li> <li>input:grab-iri: sponge the constant IRI;</li> <li>input:grab-all: sponge all constants and variables of the query;</li> <li>input:grab-seealso (and synonym input:grab-follow-predicate): sets predicate that tells where to sponge more data about a subject;</li> <li>input:grab-limit: how many resources can be sponged;</li> <li>input:grab-depth: how many iterations can be done, sponging additional data on each iteration;</li> <li>input:grab-base: base to resolve relative IRIs before passing to sponge;</li> <li>input:grab-resolver: IRI resolving procedure (i.e., one that turns base and relative IRI to an absolute IRI);</li> <li>input:grab-destination: single resource that should be filled in with results of all sponges;</li> <li>input:grab-loader: a name of procedure that retrieve the resource via HTTP, parse it and store it.</li> </ul> <p>All these pragmas are described in more details <a href="rdfiridereferencing.html#rdfinputgrab">here</a>, but in addition there are some experimental: </p> <ul> <li>input:grab-intermediate: extends the set of IRIs to sponge, useful in combination with input:grab-seealso. If present then for a given subject, sponge will retrieve not only values of see-also predicates for that subject but the subject itself. The define value is not used in current implementation.</li> <li>input:grab-group-destination: resembles input:grab-destination but sponges will create individual graphs for sponge results, and in additional to this common routine, a copy of each sponge result is added to the resource specified by the value of input:grab-group-destination. input:grab-destination redirects loadings, input:grab-group-destination duplicates them.</li> <li>get:soft: "soft" or "replacing", depending on mode of loading source graph; </li> <li>get:uri: an URI of web resource where the graph should come from (e.g., a local mirror);</li> <li>get:method: "GET" or "MGET", depending on loading the resource itself or loading metadata about the resource;</li> <li>get:refresh: limits the lifetime of a local cached copy of the source, the value is in seconds;</li> <li>get:proxy: the proxy server to use, as "host:port" string.</li> </ul> <p>These defines are described also <a href="rdfiridereferencing.html#rdfinputgrab">here</a>. Note that all of them can be used in option list of "FROM ... OPTION (get:... )" extended SPARQL-BI syntax for FROM/FROM NAMED clause. </p> <p>Note that all of them can be used in option list of "FROM ... OPTION (get:... )" extended SPARQL-BI syntax for FROM/FROM NAMED clause. </p> <br /> <a name="rdfsparqlimplementatioptragmasccg" /> <h4>14.2.12.2. Pragmas to control code generation</h4> <ul> <li>sql:assert-user: defines the user who is supposed to be the single "proper" use for the query. If the compiler is launched by other user, an error is signaled. The typical use is define sql:assist-user "dba". This is too weak to be a security measure, but may help in debugging of security issues.</li> <li>sql:gs-app-callback: application-specific callback that returns permission bits of a given graph;</li> <li>sql:gs-app-uid: application-specific user id to use in callback. <div class="tip"> <div class="tiptitle">See Also:</div> <p> <a href="rdfgraphsecurity.html#rdfgraphsecurityappcallb">RDF Graph Security</a> </p> </div> </li> <li>sql:globals-mode: tells how to print names of global variables, supported values are "XSLT" (print colon before name of global variable and "SQL" (print as usual).</li> <li>sql:log-enable: value that will be passed to SPARUL procedures and there it will be passed to log_enable() BIF. Thus define sql:log-enable N will result in log_enable(N, 1) at the beginning of the operation and other log_enable() call will restore previous mode of transaction log at exit from the procedure or at any error signalled from it.</li> <li>sql:table-option: value will be added as an option to each triple in the query and later it will be printed in TABLE OPTION (...) clause of source table clause. This works only for SQL code for plain triples from RDF_QUAD, fragments of queries related to RDF Views will remain unchanged.</li> <li>sql:select-option: value will be added as an global OPTION () clause of the generated SQL SELECT. This clause is always printed, it is always at least OPTION (QUIETCAST, ...). The most popular use case is define sql:table-option "ORDER" to tell the SQL compiler execute joins in the order of their use in the query (this can make query compilation much faster but the compilation result can be terrible if you do not know precisely what you're doing and not inspected execution plan of the generated SQL query).</li> <li>sql:describe-mode: sets procedures that will produce the result of a DESCRIBE query. The pragma is ignored for other types of SPARQL queries. In the default mode, the result contains all X ?p ?o and all ?s ?p X triples for each given X. In "SPO" mode, the result contains X ?p ?o triples only. In "CBD" mode, the result contains concise bound descriptions of given subjects. Application developers may add more modes.</li> <li>sql:signal-void-variables: the most useful debugging variable if Linked Data Views are in use. It tells the SPARQL compiler to signal an error if it can prove that some variable can never be bound. Usually it means error in query, like typo in IRI or totally wrong triple pattern.</li> </ul> <br /> <a name="rdfsparqlimplementatioptragmasctr" /> <h4>14.2.12.3. Pragmas to control the type of the result</h4> <ul> <li>output:valmode: tells the compiler which SQL datatypes should be used for output values. ODBC clients and the like known nothing about RDF and expect plain SQL values, so the appropriate value for them is "SQLVAL" and that's the default. When a Virtuoso/PL procedure is RDF-aware and keeps results for further passing to other SPARQL queries or some low-level RDF routines, the value "LONG" tells the compiler to preserve RDF boxes as is and to return IRI IDs instead of IRI string value. Third possible value, "AUTO", is for dirty hackers that do not want any conversion of any sort at the output to read the SQL output of SPARQL front-end, find the format of each column and add the needed conversions later. You will probably never need it.</li> <li>output:format: tells the compiler that the query should produce a string output with the serialization of the result, not a result set. There are three of them because the caller, like SPARQL web service endpoint, may not know the actual type of the query that should be executed. The value of output:format is used for SELECT and data manipulation queries, if specified, it can also be used for CONSTRUCT, DESCRIBE or ASK, if it is specified but related output:dict-format or output:scalar-format is not.</li> <li>output:scalar-format: tells the compiler that the query should produce a string output with the serialization of the result, not a result set. There are three of them because the caller, like SPARQL web service endpoint, may not know the actual type of the query that should be executed. The value of output:scalar-format is used for ASK queries only, if specified.</li> <li>output:dict-format: tells the compiler that the query should produce a string output with the serialization of the result, not a result set. There are three of them because the caller, like SPARQL web service endpoint, may not know the actual type of the query that should be executed. The value of output:dict-format is used for CONSTRUCT and DESCRIBE queries only, if specified.</li> </ul> <br /> <a name="rdfsparqlimplementatioptragmassfs" /> <h4>14.2.12.4. Supported formats that return a string session</h4> <ul> <li>"RDF/XML",</li> <li>"TURTLE" (and "TTL" is a synonym),</li> <li>"JSON" (canonical JSON for result sets, Talis-style JSON for CONSTRUCT and DESCRIBE),</li> <li>"JSON;ODATA" (oData-style JSON for CONSTRUCT and DESCRIBE, error otherwise),</li> <li>"RDFA;XHTML" (only for CONSTRUCT and DESCRIBE, error otherwise),</li> <li>"ATOM;XML" (only for CONSTRUCT and DESCRIBE as well).</li> </ul> <br /> <a name="rdfsparqlimplementatioptragmassdfs" /> <h4>14.2.12.5. Supported formats that do not return a string session to the caller</h4> <p>Supported formats that do not return a string session to the caller, but form an HTTP response instead and send it directly to the client HTTP connection with an appropriate HTTP header: </p> <ul> <li>"HTTP+XML mime/type",</li> <li>"HTTP+TTL mime/type",</li> <li>"HTTP+NT mime/type". A MIME type in value will be placed in the returned header, it should be separated from the starting keyword with one white space.</li> </ul> <br /> <a name="rdfsparqlimplementatioptragmassspfs" /> <h4>14.2.12.6. Supported Special formats</h4> <p>A special format "_JAVA_" is for SPARQL queries sent via JDBC. It changes only the output of ASK queries. </p> <p>Note: Pragmas output:valmode and output:format may conflict if used together, and if they're not in conflict then output:valmode is redundant: the compiler knows for sure which output:valmode-s are needed by various output:format-s. </p> <ul> <li>output:route: works only for SPARUL operators and tells the SPARQL compiler to generate procedure names that differ from default. As a result, the effect of operator will depend on application. That is for tricks. E.g., consider an application that extracts metadata from DAV resources stored in the Virtuoso and put them to RDF storage to make visible from outside. When a web application has permissions and credentials to execute a SPARUL query, the changed metadata can be written to the DAV resource (and after that the trigger will update them in the RDF storage), transparently for all other parts of application.</li> <li>output:maxrows: limits the number of rows in the returned result set. The integer value is expected, the positive integer value is obviously recommended.</li> </ul> <br /> <a name="rdfsparqlimplementatioptragmasmnotes" /> <h4>14.2.12.7. Minor notes</h4> <p>Values of most pragmas are strings. Exceptions are: </p> <ul> <li>input:grab-depth,</li> <li>input:grab-limit,</li> <li>output:maxrows,</li> <li>sql:log-enable,</li> <li>sql:signal-void-variables</li> </ul> <p>that have integer values. </p> <p>Values of some pragmas a passed through the compiler to the run-time so they are seen in the generated SQL code as arguments of procedures: </p> <ul> <li>get:method,</li> <li>get:proxy,</li> <li>get:query,</li> <li>get:refresh,</li> <li>get:soft,</li> <li>get:uri</li> </ul> <p>so sometimes you may meet them in SQL debuggers output and the like. </p> <br /> <br /> <a name="rdfsparqlbif" /> <h3>14.2.13. Built-in bif functions</h3> <ul> <li> <strong>bif:__rdf_long_from_batch_params(i_nt integer, st_value, st2_value)</strong> <ul> <li>For value URI, the params values should be: 1, value.stringValue(), NULL</li> <li>For value BNODE, the params values should be: 1, "_:"+((BNode)value).getID(), NULL</li> <li>For value Literal with Language!=NULL, the params values should be: 5, lit.stringValue(), lit.getLanguage()</li> <li>For value Literal with Datatype!=NULL, the params values should be: 4, lit.stringValue(), lit.getDatatype().toString()</li> <li>For value Literal with Datatype==NULL && Language==NULL, the params values should be: 3, lit.stringValue(), NULL</li> <li>For value any value exclude above, the params values should be: 3, value.stringValue(), NULL</li> <li>For string value (without Datatype and Language), the params values should be: 3, value.stringValue(), NULL</li> </ul> <p> <strong>Example:</strong> </p> <div> <pre class="programlisting"> SPARQL SELECT * WHERE { graph ?g { `iri(??)` `iri(??)` `bif:__rdf_long_from_batch_params(3,value.stringValue(),NULL)` } } </pre> </div> </li> </ul> <br /> <table border="0" width="90%" id="navbarbottom"> <tr> <td align="left" width="33%"> <a href="rdfdatarepresentation.html" title="Data Representation">Previous</a> <br />Data Representation</td> <td align="center" width="34%"> <a href="rdfandsparql.html">Chapter Contents</a> </td> <td align="right" width="33%"> <a href="sparqlextensions.html" title="Extensions">Next</a> <br />Extensions</td> </tr> </table> </div> <div id="footer"> <div>Copyright© 1999 - 2009 OpenLink Software All rights reserved.</div> <div id="validation"> <a href="http://validator.w3.org/check/referer"> <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /> </a> <a href="http://jigsaw.w3.org/css-validator/"> <img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88" /> </a> </div> </div> </body> </html>