/** * Recursively create an SMWSparqlCondition from an SMWDisjunction. * * @param $description SMWDisjunction * @param $joinVariable string name, see buildSparqlCondition() * @param $orderByProperty mixed SMWDIProperty or null, see buildSparqlCondition() * @return SMWSparqlCondition */ protected function buildDisjunctionCondition(SMWDisjunction $description, $joinVariable, $orderByProperty) { $subDescriptions = $description->getDescriptions(); if (count($subDescriptions) == 0) { // empty disjunction: false return new SMWSparqlFalseCondition(); } elseif (count($subDescriptions) == 1) { // disjunction with one element return $this->buildSparqlCondition(reset($subDescriptions), $joinVariable, $orderByProperty); } // else: proper disjunction; note that orderVariables found in subconditions cannot be used for the whole disjunction $unionCondition = ''; $filter = ''; $namespaces = $weakConditions = array(); $hasSafeSubconditions = false; foreach ($subDescriptions as $subDescription) { $subCondition = $this->buildSparqlCondition($subDescription, $joinVariable, null); if ($subCondition instanceof SMWSparqlFalseCondition) { // empty parts in a disjunction can be ignored } elseif ($subCondition instanceof SMWSparqlTrueCondition) { return $this->buildTrueCondition($joinVariable, $orderByProperty); } elseif ($subCondition instanceof SMWSparqlWhereCondition) { $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe(); $unionCondition .= ($unionCondition ? ' UNION ' : '') . "{\n" . $subCondition->condition . "}"; } elseif ($subCondition instanceof SMWSparqlFilterCondition) { $filter .= ($filter ? ' || ' : '') . $subCondition->filter; } elseif ($subCondition instanceof SMWSparqlSingletonCondition) { $hasSafeSubconditions = $hasSafeSubconditions || $subCondition->isSafe(); $matchElement = $subCondition->matchElement; $matchElementName = SMWTurtleSerializer::getTurtleNameForExpElement($matchElement); if ($matchElement instanceof SMWExpNsResource) { $namespaces[$matchElement->getNamespaceId()] = $matchElement->getNamespace(); } if ($subCondition->condition === '') { $filter .= ($filter ? ' || ' : '') . "?{$joinVariable} = {$matchElementName}"; } else { $unionCondition .= ($unionCondition ? ' UNION ' : '') . "{\n" . $subCondition->condition . " FILTER( ?{$joinVariable} = {$matchElementName} ) }"; } } $namespaces = array_merge($namespaces, $subCondition->namespaces); $weakConditions = array_merge($weakConditions, $subCondition->weakConditions); } if ($unionCondition === '' && $filter === '') { return new SMWSparqlFalseCondition(); } elseif ($unionCondition === '') { $result = new SMWSparqlFilterCondition($filter, $namespaces); } elseif ($filter === '') { $result = new SMWSparqlWhereCondition($unionCondition, $hasSafeSubconditions, $namespaces); } else { $subJoinVariable = $this->getNextVariable(); $unionCondition = str_replace("?{$joinVariable} ", "?{$subJoinVariable} ", $unionCondition); $filter .= " || ?{$joinVariable} = ?{$subJoinVariable}"; $result = new SMWSparqlWhereCondition("OPTIONAL { {$unionCondition} }\n FILTER( {$filter} )\n", false, $namespaces); } $result->weakConditions = $weakConditions; $this->addOrderByDataForProperty($result, $joinVariable, $orderByProperty); return $result; }
public function prune( &$maxsize, &$maxdepth, &$log ) { if ( $maxsize <= 0 ) { $log[] = $this->getQueryString(); return new SMWThingDescription(); } $prunelog = array(); $newdepth = $maxdepth; $result = new SMWDisjunction(); foreach ( $this->m_descriptions as $desc ) { $restdepth = $maxdepth; $result->addDescription( $desc->prune( $maxsize, $restdepth, $prunelog ) ); $newdepth = min( $newdepth, $restdepth ); } if ( count( $result->getDescriptions() ) > 0 ) { $log = array_merge( $log, $prunelog ); $maxdepth = $newdepth; if ( count( $result->getDescriptions() ) == 1 ) { // simplify unary disjunctions! $descriptions = $result->getDescriptions(); $result = array_shift( $descriptions ); } $result->setPrintRequests( $this->getPrintRequests() ); return $result; } else { $log[] = $this->getQueryString(); $result = new SMWThingDescription(); $result->setPrintRequests( $this->getPrintRequests() ); return $result; } }