/// <summary> /// Gets the Algebra representation of the Graph Pattern /// </summary> /// <returns></returns> public ISparqlAlgebra ToAlgebra() { if (_isUnion) { // If this Graph Pattern represents a UNION of Graph Patterns turn into a series of UNIONs ISparqlAlgebra union = new Union(_graphPatterns[0].ToAlgebra(), _graphPatterns[1].ToAlgebra()); if (_graphPatterns.Count > 2) { for (int i = 2; i < _graphPatterns.Count; i++) { union = new Union(union, _graphPatterns[i].ToAlgebra()); } } // Apply Inline Data if (HasInlineData) { union = Join.CreateJoin(union, new Bindings(_data)); } // If there's a FILTER apply it over the Union if (_isFiltered && (_filter != null || _unplacedFilters.Count > 0)) { return(new Filter(union, Filter)); } return(union); } // Terminal graph pattern if (_graphPatterns.Count == 0) { // If there are no Child Graph Patterns then this is a BGP ISparqlAlgebra bgp = new Bgp(_triplePatterns); if (_unplacedAssignments.Count > 0) { // If we have any unplaced LETs these get Extended onto the BGP foreach (IAssignmentPattern p in _unplacedAssignments) { bgp = new Extend(bgp, p.AssignExpression, p.VariableName); } } if (IsGraph) { bgp = Algebra.Graph.ApplyGraph(bgp, GraphSpecifier); } else if (IsService) { bgp = new Service(GraphSpecifier, this, IsSilent); } // Apply Inline Data if (HasInlineData) { bgp = Join.CreateJoin(bgp, new Bindings(_data)); } if (_isFiltered && (_filter != null || _unplacedFilters.Count > 0)) { if (_isOptional && !(_isExists || _isNotExists)) { // If we contain an unplaced FILTER and we're an OPTIONAL then the FILTER // applies over the LEFT JOIN and will have been added elsewhere in the Algebra transform return(bgp); } // If we contain an unplaced FILTER and we're not an OPTIONAL the FILTER // applies here return(new Filter(bgp, Filter)); } // We're not filtered (or all FILTERs were placed in the BGP) so we're just a BGP return(bgp); } // Create a basic BGP to start with ISparqlAlgebra complex = new Bgp(); if (_triplePatterns.Count > 0) { complex = new Bgp(_triplePatterns); } // Apply Inline Data // If this Graph Pattern had child patterns before this Graph Pattern then we would // have broken the BGP and not added the Inline Data here so it's always safe to apply this here if (HasInlineData) { complex = Join.CreateJoin(complex, new Bindings(_data)); } // Then Join each of the Graph Patterns as appropriate foreach (GraphPattern gp in _graphPatterns) { if (gp.IsGraph) { // A GRAPH clause means a Join of the current pattern to a Graph clause ISparqlAlgebra gpAlgebra = gp.ToAlgebra(); complex = Join.CreateJoin(complex, Algebra.Graph.ApplyGraph(gpAlgebra, gp.GraphSpecifier)); } else if (gp.IsOptional) { if (gp.IsExists || gp.IsNotExists) { // An EXISTS/NOT EXISTS means an Exists Join of the current pattern to the EXISTS/NOT EXISTS clause complex = new ExistsJoin(complex, gp.ToAlgebra(), gp.IsExists); } else { // An OPTIONAL means a Left Join of the current pattern to the OPTIONAL clause // with a possible FILTER applied over the LeftJoin if (gp.IsFiltered && gp.Filter != null) { // If the OPTIONAL clause has an unplaced FILTER it applies over the Left Join complex = new LeftJoin(complex, gp.ToAlgebra(), gp.Filter); } else { complex = new LeftJoin(complex, gp.ToAlgebra()); } } } else if (gp.IsMinus) { // Always introduce a Minus here even if the Minus is disjoint since during evaluation we'll choose // not to execute it if it's disjoint complex = new Minus(complex, gp.ToAlgebra()); } else if (gp.IsService) { complex = Join.CreateJoin(complex, new Service(gp.GraphSpecifier, gp, gp.IsSilent)); } else { // Otherwise we just join the pattern to the existing pattern complex = Join.CreateJoin(complex, gp.ToAlgebra()); } } if (_unplacedAssignments.Count > 0) { // Unplaced assignments get Extended over the algebra so far here // complex = Join.CreateJoin(complex, new Bgp(this._unplacedAssignments.OfType<ITriplePattern>())); foreach (IAssignmentPattern p in _unplacedAssignments) { complex = new Extend(complex, p.AssignExpression, p.VariableName); } } if (IsGraph) { complex = Algebra.Graph.ApplyGraph(complex, GraphSpecifier); } if (_isFiltered && (_filter != null || _unplacedFilters.Count > 0)) { if (_isOptional && !(_isExists || _isNotExists)) { // If there's an unplaced FILTER and we're an OPTIONAL then the FILTER will // apply over the LeftJoin and is applied elsewhere in the Algebra transform return(complex); } else { if (_filter != null || _unplacedFilters.Count > 0) { // If there's an unplaced FILTER and we're not an OPTIONAL pattern we apply // the FILTER here return(new Filter(complex, Filter)); } else { return(complex); } } } else { // If no FILTER just return the transform return(complex); } }
/// <summary> /// Gets the Algebra representation of the Graph Pattern /// </summary> /// <returns></returns> public ISparqlAlgebra ToAlgebra() { if (this._isUnion) { //If this Graph Pattern represents a UNION of Graph Patterns turn into a series of UNIONs ISparqlAlgebra union = new Union(this._graphPatterns[0].ToAlgebra(), this._graphPatterns[1].ToAlgebra()); if (this._graphPatterns.Count > 2) { for (int i = 2; i < this._graphPatterns.Count; i++) { union = new Union(union, this._graphPatterns[i].ToAlgebra()); } } //If there's a FILTER apply it over the Union if (this._isFiltered && (this._filter != null || this._unplacedFilters.Count > 0)) { return(new Filter(union, this.Filter)); } else { return(union); } } else if (this._graphPatterns.Count == 0) { //If there are no Child Graph Patterns then this is a BGP ISparqlAlgebra bgp = new Bgp(this._triplePatterns); if (this._unplacedAssignments.Count > 0) { //If we have any unplaced LETs these get Joined onto the BGP bgp = Join.CreateJoin(bgp, new Bgp(this._unplacedAssignments)); } if (this._isFiltered && (this._filter != null || this._unplacedFilters.Count > 0)) { if (this._isOptional && !(this._isExists || this._isNotExists)) { //If we contain an unplaced FILTER and we're an OPTIONAL then the FILTER //applies over the LEFT JOIN and will have been added elsewhere in the Algebra transform return(bgp); } else { ISparqlAlgebra complex = bgp; //If we contain an unplaced FILTER and we're not an OPTIONAL the FILTER //applies here return(new Filter(bgp, this.Filter)); } } else { //We're not filtered (or all FILTERs were placed in the BGP) so we're just a BGP return(bgp); } } else { //Create a basic BGP to start with ISparqlAlgebra complex = new Bgp(); if (this._triplePatterns.Count > 0) { complex = new Bgp(this._triplePatterns); } //Then Join each of the Graph Patterns as appropriate foreach (GraphPattern gp in this._graphPatterns) { if (gp.IsGraph) { //A GRAPH clause means a Join of the current pattern to a Graph clause complex = Join.CreateJoin(complex, new Algebra.Graph(gp.ToAlgebra(), gp.GraphSpecifier)); } else if (gp.IsOptional) { if (gp.IsExists || gp.IsNotExists) { //An EXISTS/NOT EXISTS means an Exists Join of the current pattern to the EXISTS/NOT EXISTS clause complex = new ExistsJoin(complex, gp.ToAlgebra(), gp.IsExists); } else { //An OPTIONAL means a Left Join of the current pattern to the OPTIONAL clause //with a possible FILTER applied over the LeftJoin if (gp.IsFiltered && gp.Filter != null) { //If the OPTIONAL clause has an unplaced FILTER it applies over the Left Join complex = new LeftJoin(complex, gp.ToAlgebra(), gp.Filter); } else { complex = new LeftJoin(complex, gp.ToAlgebra()); } } } else if (gp.IsMinus) { //Always introduce a Minus here even if the Minus is disjoint since during evaluation we'll choose //not to execute it if it's disjoint complex = new Minus(complex, gp.ToAlgebra()); } else if (gp.IsService) { complex = Join.CreateJoin(complex, new Service(gp.GraphSpecifier, gp, gp.IsSilent)); } else { //Otherwise we just join the pattern to the existing pattern complex = Join.CreateJoin(complex, gp.ToAlgebra()); } } if (this._unplacedAssignments.Count > 0) { //Unplaced assignments get Joined as a BGP here complex = Join.CreateJoin(complex, new Bgp(this._unplacedAssignments)); } if (this._isFiltered && (this._filter != null || this._unplacedFilters.Count > 0)) { if (this._isOptional && !(this._isExists || this._isNotExists)) { //If there's an unplaced FILTER and we're an OPTIONAL then the FILTER will //apply over the LeftJoin and is applied elsewhere in the Algebra transform return(complex); } else { if (this._filter != null || this._unplacedFilters.Count > 0) { //If there's an unplaced FILTER and we're not an OPTIONAL pattern we apply //the FILTER here return(new Filter(complex, this.Filter)); } else { return(complex); } } } else { //If no FILTER just return the transform return(complex); } } }