Virtuoso's RDF support is at an early implementation stage. The SPARQL language is fairly complete but none of the support functions such as data loading or triple storage are optimized. Many pieces of the present implementation that are written in Virtuoso/PL will be rewritten in C for performance.
Also, the triple store has no specific security model. Thus access rights of the tables and stored procedures involved in the process dictate who can access these features.
All triples of all graphs are stored in a single default system table called DB.DBA.RDF_QUAD. This will change in the next release, where a complex meta-schema system will be introduced for allowing graphs to be stored in different tables, potentially having different index structures, optionally also full text index on long object values. The meta-schema support will also make it possible to map native SQL tables into the RDF SPARQL-queriable space, as well as introduce finer-grained security.
Hence the RDF subsystem is offered for review but is not a productized whole. Benchmark results obtained with it are tentative and reflect a non-optimized state.
The current implementation does not support some SPARQL features.
On the other hand, Virtuoso implements some extensions to SPARQL. One extension, DEFINE ... clause, e.g., define output:valmode "LONG" is described above.
Virtuoso also allows use of expressions in some places where SPARQL only allows constant expressions or variables. For example, the values list of SELECT may contain arbitrary expressions in parenthesis as well as variable names. Expressions may also appear in triples of CONSTRUCT pattern or WHERE pattern: an expression can be used instead of constant or variable name for subject, predicate or object. In this case, an expression is surrounded by backquotes.
The following return all distinct 'fragment' parts of all subjects in all graphs that have some predicate whose value is equal to 2+2.
SQL>sparql select distinct (bif:subseq (?s, bif:strchr (?s, '#'))) where { graph ?g { ?s ?p `2+2` . filter (! bif:isnull (bif:strchr (?s, '#') ) ) } }; callret VARCHAR ---------- #four
This is BNF grammar of SPARQL with all Virtuoso extensions, but without rules for syntax of lexems. Rule numbers in square brackets are from W3C normative SPARQL grammar, asterick means that the rule differs from W3C grammar due to Virtuoso extensions, [Virt] means that the rule is Virtuoso-specific. [DML] stands for data manipulation language extensions from SPARUL.
[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 [7]* DescribeQuery ::= 'DESCRIBE' ( VarOrIRIrefOrBackquoted+ | '*' ) 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 can not *) [13] WhereClause ::= 'WHERE'? GroupGraphPattern [14] SolutionModifier ::= OrderClause? LimitClause? OffsetClause? [15] OrderClause ::= 'ORDER' 'BY' OrderCondition+ [16]* OrderCondition ::= ( 'ASC' | 'DESC' )? ( FunctionCall | Var | ( '(' Expn ')' ) | ( '[' Expn ']' ) ) [17] LimitClause ::= 'LIMIT' INTEGER [18] OffsetClause ::= 'OFFSET' INTEGER [19] GroupGraphPattern ::= '{' GraphPattern '}' [20] GraphPattern ::= Triples? ( GraphPatternNotTriples '.'? GraphPattern )? [21] GraphPatternNotTriples ::= OptionalGraphPattern | GroupOrUnionGraphPattern | GraphGraphPattern | Constraint [22] OptionalGraphPattern ::= 'OPTIONAL' 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+ ')' [32] ObjectList ::= GraphNode ( ',' ObjectList )? [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 [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 ')' ) | ( '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 | DeleteAction | ModifyAction | ClearAction [DML]* CreateAction ::= 'CREATE' 'SILENT' ? 'GRAPH' ( 'IDENTIFIED' 'BY' )? PrecodeExpn [DML]* InsertAction ::= 'INSERT' ( ( 'IN' | 'INTO ) 'GRAPH' ( 'IDENTIFIED' 'BY' )? )? PrecodeExpn ConstructTemplate ( DatasetClause* WhereClause SolutionModifier )? [DML]* DeleteAction ::= 'DELETE' ( 'FROM' 'GRAPH' ( 'IDENTIFIED' 'BY' )? )? PrecodeExpn ConstructTemplate ( DatasetClause* WhereClause SolutionModifier )? [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]* 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' | 'RETURNS' STRING ('UNION' STRING)* [Virt] QmLiteralClassOptions ::= 'OPTION' '(' QmLiteralClassOption (',' QmLiteralClassOption)* ')' [Virt] QmLiteralClassOption ::= ( 'DATATYPE' QmIRIrefConst ) | ( 'LANG' STRING ) | ( 'LANG' STRING ) | 'BIJECTION' | '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 ::= '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 ')' )
In the current implementation, the XQuery Function Library is not available from SPARQL .
As a temporary workaround, string parsing functions are made available, because they are widely used in W3C DAWG examples and the like. They are:
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
(assuming that the query contains declaration 'PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>')
Previous
RDF Views -- Mapping Relational Data to RDF |
Chapter Contents |
Next
RDF Inference in Virtuoso |