/**
	 * Parse a query string given in SMW's query language to create
	 * an SMWQuery. Parameters are given as key-value-pairs in the
	 * given array. The parameter $context defines in what context the
	 * query is used, which affects ceretain general settings.
	 * An object of type SMWQuery is returned.
	 *
	 * The format string is used to specify the output format if already
	 * known. Otherwise it will be determined from the parameters when
	 * needed. This parameter is just for optimisation in a common case.
	 *
	 * @param string $querystring
	 * @param array $params These need to be the result of a list fed to getProcessedParams
	 * @param $context
	 * @param string $format
	 * @param array $extraprintouts
	 *
	 * @return SMWQuery
	 */
	static public function createQuery( $querystring, array $params, $context = self::INLINE_QUERY, $format = '', array $extraprintouts = array() ) {
		global $smwgQDefaultNamespaces, $smwgQFeatures, $smwgQConceptFeatures;
		
		// parse query:
		$queryfeatures = ( $context == self::CONCEPT_DESC ) ? $smwgQConceptFeatures : $smwgQFeatures;
		$qp = new SMWQueryParser( $queryfeatures );
		$qp->setDefaultNamespaces( $smwgQDefaultNamespaces );
		$desc = $qp->getQueryDescription( $querystring );

		if ( $format === '' || is_null( $format ) ) {
			$format = $params['format'];
		}
		
		if ( $format == 'count' ) {
			$querymode = SMWQuery::MODE_COUNT;
		} elseif ( $format == 'debug' ) {
			$querymode = SMWQuery::MODE_DEBUG;
		} else {
			$printer = self::getResultPrinter( $format, $context );
			$querymode = $printer->getQueryMode( $context );
		}

		$query = new SMWQuery( $desc, ( $context != self::SPECIAL_PAGE ), ( $context == self::CONCEPT_DESC ) );
		$query->setQueryString( $querystring );
		$query->setExtraPrintouts( $extraprintouts );
		$query->setMainLabel( $params['mainlabel'] );
		$query->addErrors( $qp->getErrors() ); // keep parsing errors for later output

		// set mode, limit, and offset:
		$query->querymode = $querymode;
		if ( ( array_key_exists( 'offset', $params ) ) && ( is_int( $params['offset'] + 0 ) ) ) {
			$query->setOffset( max( 0, trim( $params['offset'] ) + 0 ) );
		}

		if ( $query->querymode == SMWQuery::MODE_COUNT ) { // largest possible limit for "count", even inline
			global $smwgQMaxLimit;
			$query->setOffset( 0 );
			$query->setLimit( $smwgQMaxLimit, false );
		} else {
			if ( ( array_key_exists( 'limit', $params ) ) && ( is_int( trim( $params['limit'] ) + 0 ) ) ) {
				$query->setLimit( max( 0, trim( $params['limit'] ) + 0 ) );
				if ( ( trim( $params['limit'] ) + 0 ) < 0 ) { // limit < 0: always show further results link only
					$query->querymode = SMWQuery::MODE_NONE;
				}
			} else {
				global $smwgQDefaultLimit;
				$query->setLimit( $smwgQDefaultLimit );
			}
		}

		$defaultSort = $format === 'rss' ? 'DESC' : 'ASC';
		$sort = self::getSortKeys( $params['sort'], $params['order'], $defaultSort );
		
		$query->sortkeys = $sort['keys'];
		$query->addErrors( $sort['errors'] );
		$query->sort = count( $query->sortkeys ) > 0; // TODO: Why would we do this here?
		
		return $query;
	}
Exemplo n.º 2
0
 /**
  * Function not called anywhere but code kept for reference before
  * migrating it to SMWExporter.
  */
 private function getExportData()
 {
     if ($this->isValid()) {
         $qp = new SMWQueryParser();
         $desc = $qp->getQueryDescription(str_replace(array('&lt;', '&gt;', '&amp;'), array('<', '>', '&'), $this->m_dataitem->getConceptQuery()));
         $exact = true;
         $owldesc = $this->descriptionToExpData($desc, $exact);
         if (!$exact) {
             $result = new SMWExpData(new SMWExpResource(''));
             $result->addPropertyObjectValue(SMWExporter::getSpecialNsResource('rdf', 'type'), new SMWExpData(SMWExporter::getSpecialNsResource('owl', 'Class')));
             $result->addPropertyObjectValue(SMWExporter::getSpecialNsResource('rdfs', 'subClassOf'), $owldesc);
             return $result;
         } else {
             return $owldesc;
         }
     } else {
         return null;
     }
 }
 /**
  * @param string $conceptDescriptionText
  *
  * @return QuerySegment|null
  */
 public function prepareQuerySegmentFor($conceptDescriptionText)
 {
     QuerySegment::$qnum = 0;
     $querySegmentListBuilder = $this->queryEngine->getQuerySegmentListBuilder();
     $querySegmentListBuilder->setSortKeys(array());
     $qp = new QueryParser($this->conceptFeatures);
     $querySegmentListBuilder->getQuerySegmentFrom($qp->getQueryDescription($conceptDescriptionText));
     $qid = $querySegmentListBuilder->getLastQuerySegmentId();
     $querySegmentList = $querySegmentListBuilder->getQuerySegmentList();
     if ($qid < 0) {
         return null;
     }
     // execute query tree, resolve all dependencies
     $querySegmentListProcessor = $this->queryEngine->getQuerySegmentListProcessor();
     $querySegmentListProcessor->setQueryMode(Query::MODE_INSTANCES);
     $querySegmentListProcessor->setQuerySegmentList($querySegmentList);
     $querySegmentListProcessor->doResolveQueryDependenciesById($qid);
     return $querySegmentList[$qid];
 }
 /**
  * @param string $conceptDescriptionText
  *
  * @return QuerySegment|null
  */
 public function prepareQuerySegmentFor($conceptDescriptionText)
 {
     $querySegements = array();
     QuerySegment::$qnum = 0;
     $queryBuilder = $this->queryEngine->getQueryBuilder();
     $queryBuilder->setSortKeys(array());
     $qp = new QueryParser($this->conceptFeatures);
     $queryBuilder->buildQuerySegmentFor($qp->getQueryDescription($conceptDescriptionText));
     $qid = $queryBuilder->getLastQuerySegmentId();
     $querySegements = $queryBuilder->getQuerySegments();
     if ($qid < 0) {
         return null;
     }
     // execute query tree, resolve all dependencies
     $querySegmentListResolver = $this->queryEngine->getQuerySegmentListResolver();
     $querySegmentListResolver->setQueryMode(Query::MODE_INSTANCES);
     $querySegmentListResolver->setQuerySegmentList($querySegements);
     $querySegmentListResolver->resolveForSegmentId($qid);
     return $querySegements[$qid];
 }
 private function createQuery($queryString, $mode, array $printouts = array())
 {
     $description = $this->queryParser->getQueryDescription($queryString);
     foreach ($printouts as $printout) {
         $property = DIProperty::newFromUserLabel($printout);
         $propertyValue = new PropertyValue('__pro');
         $propertyValue->setDataItem($property);
         $description->addPrintRequest(new PrintRequest(PrintRequest::PRINT_PROP, null, $propertyValue));
     }
     $query = new Query($description, false, false);
     $query->setUnboundlimit($this->queryLimit);
     $query->setOffset($this->queryOffset);
     $query->querymode = $mode;
     return $query;
 }
Exemplo n.º 6
0
 /**
  * Compute an SMWDescription from a query string. Returns whatever descriptions could be
  * wrestled from the given string (the most general result being SMWThingDescription if
  * no meaningful condition was extracted).
  */
 public function getQueryDescription($querystring)
 {
     if (stripos($querystring, "select") === 0) {
         wfProfileIn('SMWSPARQLQueryParser::getQueryDescription (SMW)');
         $this->m_errors = array();
         $this->m_label = '';
         $this->m_curstring = $querystring;
         $this->m_sepstack = array();
         $setNS = false;
         $result = new SMWSPARQLDescription();
         wfProfileOut('SMWSPARQLQueryParser::getQueryDescription (SMW)');
         return $result;
     } else {
         return parent::getQueryDescription($querystring);
     }
 }
Exemplo n.º 7
0
 /**
  * Create a new SMWSQLStore3Query object that can be used to obtain results
  * for the given description. The result is stored in $this->m_queries
  * using a numeric key that is returned as a result of the function.
  * Returns -1 if no query was created.
  * @todo The case of nominal classes (top-level SMWValueDescription) still
  * makes some assumptions about the table structure, especially about the
  * name of the joinfield (o_id). Better extend
  * compilePropertyValueDescription to deal with this case.
  *
  * @param SMWDescription $description
  *
  * @return integer
  */
 protected function compileQueries(SMWDescription $description)
 {
     $query = new SMWSQLStore3Query();
     if ($description instanceof SMWSomeProperty) {
         $this->compileSomePropertyDescription($query, $description);
     } elseif ($description instanceof SMWNamespaceDescription) {
         // TODO: One instance of the SMW IDs table on s_id always suffices (swm_id is KEY)! Doable in execution ... (PERFORMANCE)
         $query->jointable = SMWSql3SmwIds::tableName;
         $query->joinfield = "{$query->alias}.smw_id";
         $query->where = "{$query->alias}.smw_namespace=" . $this->m_dbs->addQuotes($description->getNamespace());
     } elseif ($description instanceof SMWConjunction || $description instanceof SMWDisjunction) {
         $query->type = $description instanceof SMWConjunction ? SMWSQLStore3Query::Q_CONJUNCTION : SMWSQLStore3Query::Q_DISJUNCTION;
         foreach ($description->getDescriptions() as $subdesc) {
             $sub = $this->compileQueries($subdesc);
             if ($sub >= 0) {
                 $query->components[$sub] = true;
             }
         }
         // All subconditions failed, drop this as well.
         if (count($query->components) == 0) {
             $query->type = SMWSQLStore3Query::Q_NOQUERY;
         }
     } elseif ($description instanceof SMWClassDescription) {
         $cqid = SMWSQLStore3Query::$qnum;
         $cquery = new SMWSQLStore3Query();
         $cquery->type = SMWSQLStore3Query::Q_CLASS_HIERARCHY;
         $cquery->joinfield = array();
         foreach ($description->getCategories() as $cat) {
             $cid = $this->m_store->smwIds->getSMWPageID($cat->getDBkey(), NS_CATEGORY, $cat->getInterwiki(), '');
             if ($cid != 0) {
                 $cquery->joinfield[] = $cid;
             }
         }
         if (count($cquery->joinfield) == 0) {
             // Empty result.
             $query->type = SMWSQLStore3Query::Q_VALUE;
             $query->jointable = '';
             $query->joinfield = '';
         } else {
             // Instance query with disjunction of classes (categories)
             $query->jointable = $this->m_dbs->tableName($this->m_store->findPropertyTableID(new SMWDIProperty('_INST')));
             $query->joinfield = "{$query->alias}.s_id";
             $query->components[$cqid] = "{$query->alias}.o_id";
             $this->m_queries[$cqid] = $cquery;
         }
     } elseif ($description instanceof SMWValueDescription) {
         // Only type '_wpg' objects can appear on query level (essentially as nominal classes).
         if ($description->getDataItem() instanceof SMWDIWikiPage) {
             if ($description->getComparator() == SMW_CMP_EQ) {
                 $query->type = SMWSQLStore3Query::Q_VALUE;
                 $oid = $this->m_store->smwIds->getSMWPageID($description->getDataItem()->getDBkey(), $description->getDataItem()->getNamespace(), $description->getDataItem()->getInterwiki(), $description->getDataItem()->getSubobjectName());
                 $query->joinfield = array($oid);
             } else {
                 // Join with SMW IDs table needed for other comparators (apply to title string).
                 $query->jointable = SMWSql3SmwIds::tableName;
                 $query->joinfield = "{$query->alias}.smw_id";
                 $value = $description->getDataItem()->getSortKey();
                 switch ($description->getComparator()) {
                     case SMW_CMP_LEQ:
                         $comp = '<=';
                         break;
                     case SMW_CMP_GEQ:
                         $comp = '>=';
                         break;
                     case SMW_CMP_LESS:
                         $comp = '<';
                         break;
                     case SMW_CMP_GRTR:
                         $comp = '>';
                         break;
                     case SMW_CMP_NEQ:
                         $comp = '!=';
                         break;
                     case SMW_CMP_LIKE:
                     case SMW_CMP_NLKE:
                         $comp = ' LIKE ';
                         if ($description->getComparator() == SMW_CMP_NLKE) {
                             $comp = " NOT{$comp}";
                         }
                         $value = str_replace(array('%', '_', '*', '?'), array('\\%', '\\_', '%', '_'), $value);
                         break;
                 }
                 $query->where = "{$query->alias}.smw_sortkey{$comp}" . $this->m_dbs->addQuotes($value);
             }
         }
     } elseif ($description instanceof SMWConceptDescription) {
         // fetch concept definition and insert it here
         $cid = $this->m_store->smwIds->getSMWPageID($description->getConcept()->getDBkey(), SMW_NS_CONCEPT, '', '');
         // We bypass the storage interface here (which is legal as we control it, and safe if we are careful with changes ...)
         // This should be faster, but we must implement the unescaping that concepts do on getWikiValue()
         $row = $this->m_dbs->selectRow('smw_fpt_conc', array('concept_txt', 'concept_features', 'concept_size', 'concept_depth', 'cache_date'), array('s_id' => $cid), 'SMWSQLStore3Queries::compileQueries');
         if ($row === false) {
             // No description found, concept does not exist.
             // keep the above query object, it yields an empty result
             // TODO: announce an error here? (maybe not, since the query processor can check for
             // non-existing concept pages which is probably the main reason for finding nothing here)
         } else {
             global $smwgQConceptCaching, $smwgQMaxSize, $smwgQMaxDepth, $smwgQFeatures, $smwgQConceptCacheLifetime;
             $may_be_computed = $smwgQConceptCaching == CONCEPT_CACHE_NONE || $smwgQConceptCaching == CONCEPT_CACHE_HARD && ~(~($row->concept_features + 0) | $smwgQFeatures) == 0 && $smwgQMaxSize >= $row->concept_size && $smwgQMaxDepth >= $row->concept_depth;
             if ($row->cache_date && ($row->cache_date > strtotime("now") - $smwgQConceptCacheLifetime * 60 || !$may_be_computed)) {
                 // Cached concept, use cache unless it is dead and can be revived.
                 $query->jointable = SMWSQLStore3::CONCEPT_CACHE_TABLE;
                 $query->joinfield = "{$query->alias}.s_id";
                 $query->where = "{$query->alias}.o_id=" . $this->m_dbs->addQuotes($cid);
             } elseif ($row->concept_txt) {
                 // Parse description and process it recursively.
                 if ($may_be_computed) {
                     $qp = new SMWQueryParser();
                     // No defaultnamespaces here; If any, these are already in the concept.
                     // Unescaping is the same as in SMW_DV_Conept's getWikiValue().
                     $desc = $qp->getQueryDescription(str_replace(array('&lt;', '&gt;', '&amp;'), array('<', '>', '&'), $row->concept_txt));
                     $qid = $this->compileQueries($desc);
                     if ($qid != -1) {
                         $query = $this->m_queries[$qid];
                     } else {
                         // somehow the concept query is no longer valid; maybe some syntax changed (upgrade) or global settings were modified since storing it
                         $this->m_errors[] = wfMessage('smw_emptysubquery')->text();
                         // not quite the right message, but this case is very rare; let us not make detailed messages for this
                     }
                 } else {
                     $this->m_errors[] = wfMessage('smw_concept_cache_miss', $description->getConcept()->getText())->text();
                 }
             }
             // else: no cache, no description (this may happen); treat like empty concept
         }
     } else {
         // (e.g. SMWThingDescription)
         $query->type = SMWSQLStore3Query::Q_NOQUERY;
         // no condition
     }
     $this->registerQuery($query);
     if ($query->type != SMWSQLStore3Query::Q_NOQUERY) {
         return $query->queryNumber;
     } else {
         return -1;
     }
 }
	static public function addNotify( $rawquery, $name, $rep_all, $show_all, $delegate ) {
		global $wgTitle;
		// Take care at least of some templates -- for better template support use #ask
		$parser = new Parser();
		$parserOptions = new ParserOptions();
		$rawquery = $parser->transformMsg( $rawquery, $parserOptions, $wgTitle );

		wfProfileIn( 'SMWNotifyProcessor::createNotify (SMW)' );
		$sStore = NMStorage::getDatabase();
		global $wgUser;
		$user_id = $wgUser->getId();
		if ( $user_id == 0 ) {
			wfProfileOut( 'SMWNotifyProcessor::createNotify (SMW)' );
			return wfMsg( 'smw_nm_proc_notlogin' );
		}

		// check notify query first, use QueryParser from SMW
		SMWQueryProcessor::processFunctionParams( SMWNotifyProcessor::getQueryRawParams( $rawquery ), $querystring, $params, $printouts );

		$qp = new SMWQueryParser();
		$qp->setDefaultNamespaces( $smwgQDefaultNamespaces );
		$desc = $qp->getQueryDescription( $querystring );

		if ( count( $qp->getErrors() ) > 0 ) {
			wfProfileOut( 'SMWNotifyProcessor::createNotify (SMW)' );
			return wfMsg( 'smw_nm_proc_createfail', implode( "\n", $qp->getErrors() ) );
		}

		$notify_id = $sStore->addNotifyQuery( $user_id, $rawquery, $name, $rep_all, $show_all, $delegate );
		if ( $notify_id == 0 ) {
			wfProfileOut( 'SMWNotifyProcessor::createNotify (SMW)' );
			return wfMsg( 'smw_nm_proc_savefail' );
		}
		wfProfileOut( 'SMWNotifyProcessor::createNotify (SMW)' );

		wfProfileIn( 'SMWNotifyProcessor::enableNotify (SMW)' );
		$msg = '';
		$result  = SMWNotifyProcessor::enableNotify( $notify_id, $rawquery, $msg );
		wfProfileOut( 'SMWNotifyProcessor::enableNotify (SMW)' );
		return "1" . ( $result ? "1":"0" ) . "$notify_id,$msg";
	}
Exemplo n.º 9
0
    static function addAutocomplete()
    {
        global $smwgNMDelegateQuery, $smwgNMDelegateUserGroup;
        if (!$smwgNMDelegateQuery && !$smwgNMDelegateUserGroup) {
            return;
        }
        global $wgOut, $smwgNMScriptPath;
        $nmScriptPath = $smwgNMScriptPath . '/specials/SMWNotifyMe';
        $nmYUIBase = "http://yui.yahooapis.com/2.7.0/build/";
        $wgOut->addLink(array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => "screen, projection", 'href' => $nmScriptPath . '/skins/NM_yui_autocompletion.css'));
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'yahoo/yahoo-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'dom/dom-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'event/event-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'get/get-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'connection/connection-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'json/json-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'datasource/datasource-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmYUIBase . 'autocomplete/autocomplete-min.js"></script>' . "\n");
        $wgOut->addScript('<script type="text/javascript" src="' . $nmScriptPath . '/libs/NM_yui_autocompletion.js"></script>' . "\n");
        $pages = array();
        if ($smwgNMDelegateUserGroup) {
            if ($smwgNMDelegateUserGroup != "*" && !is_array($smwgNMDelegateUserGroup)) {
                $groups = split(",", $smwgNMDelegateUserGroup);
                for ($i = count($groups) - 1; $i >= 0; --$i) {
                    $groups[$i] = strtolower(trim(str_replace("\\'", "\\\\'", $groups[$i])));
                }
            }
            $pages = NMStorage::getDatabase()->getGroupedUsers($groups);
            for ($i = count($pages) - 1; $i >= 0; --$i) {
                $pages[$i] = "['" . str_replace("\\'", "\\\\'", $pages[$i]) . "']";
            }
        }
        if ($smwgNMDelegateQuery) {
            global $smwgQDefaultNamespaces, $smwgQFeatures;
            $qp = new SMWQueryParser($smwgQFeatures);
            $qp->setDefaultNamespaces($smwgQDefaultNamespaces);
            $desc = $qp->getQueryDescription($smwgNMDelegateQuery);
            $desc->prependPrintRequest(new SMWPrintRequest(SMWPrintRequest::PRINT_THIS, ""));
            $query = new SMWQuery($desc, true);
            $query_result = smwfGetStore()->getQueryResult($query);
            while ($res = $query_result->getNext()) {
                $pages[] = "['" . str_replace("\\'", "\\\\'", $res[0]->getNextObject()->getWikiValue()) . "']";
            }
        }
        global $smwgNMMaxAutocompleteValues;
        if ($smwgNMMaxAutocompleteValues <= 0) {
            $smwgNMMaxAutocompleteValues = 10;
        }
        $wgOut->addScript('<script type="text/javascript">
		nmautocompletestrings = [' . join(',', $pages) . '];
		nmMaxResultsDisplayed = ' . $smwgNMMaxAutocompleteValues . ';
		</script>');
    }
 /**
  * Create a new SMWSQLStore2Query object that can be used to obtain results
  * for the given description. The result is stored in $this->m_queries
  * using a numeric key that is returned as a result of the function.
  * Returns -1 if no query was created.
  * @todo The case of nominal classes (top-level SMWValueDescription) still
  * makes some assumptions about the table structure, especially about the
  * name of the joinfield (o_id). Better extend compileAttributeWhere to
  * deal with this case.
  *
  * @param SMWDescription $description
  *
  * @return integer
  */
 protected function compileQueries(SMWDescription $description)
 {
     $qid = SMWSQLStore2Query::$qnum;
     $query = new SMWSQLStore2Query();
     if ($description instanceof SMWSomeProperty) {
         $this->compilePropertyCondition($query, $description->getProperty(), $description->getDescription());
         // Compilation has set type to NOQUERY: drop condition.
         if ($query->type == SMW_SQL2_NOQUERY) {
             $qid = -1;
         }
     } elseif ($description instanceof SMWNamespaceDescription) {
         // TODO: One instance of smw_ids on s_id always suffices (swm_id is KEY)! Doable in execution ... (PERFORMANCE)
         $query->jointable = 'smw_ids';
         $query->joinfield = "{$query->alias}.smw_id";
         $query->where = "{$query->alias}.smw_namespace=" . $this->m_dbs->addQuotes($description->getNamespace());
     } elseif ($description instanceof SMWConjunction || $description instanceof SMWDisjunction) {
         $query->type = $description instanceof SMWConjunction ? SMW_SQL2_CONJUNCTION : SMW_SQL2_DISJUNCTION;
         foreach ($description->getDescriptions() as $subdesc) {
             $sub = $this->compileQueries($subdesc);
             if ($sub >= 0) {
                 $query->components[$sub] = true;
             }
         }
         // All subconditions failed, drop this as well.
         if (count($query->components) == 0) {
             $qid = -1;
         }
     } elseif ($description instanceof SMWClassDescription) {
         $cqid = SMWSQLStore2Query::$qnum;
         $cquery = new SMWSQLStore2Query();
         $cquery->type = SMW_SQL2_CLASS_HIERARCHY;
         $cquery->joinfield = array();
         foreach ($description->getCategories() as $cat) {
             $cid = $this->m_store->getSMWPageID($cat->getDBkey(), NS_CATEGORY, $cat->getInterwiki());
             if ($cid != 0) {
                 $cquery->joinfield[] = $cid;
             }
         }
         if (count($cquery->joinfield) == 0) {
             // Empty result.
             $query->type = SMW_SQL2_VALUE;
             $query->jointable = '';
             $query->joinfield = '';
         } else {
             // Instance query with dicjunction of classes (categories)
             $query->jointable = 'smw_inst2';
             $query->joinfield = "{$query->alias}.s_id";
             $query->components[$cqid] = "{$query->alias}.o_id";
             $this->m_queries[$cqid] = $cquery;
         }
     } elseif ($description instanceof SMWValueDescription) {
         // Only type '_wpg' objects can appear on query level (essentially as nominal classes).
         if ($description->getDatavalue()->getTypeID() == '_wpg') {
             if ($description->getComparator() == SMW_CMP_EQ) {
                 $query->type = SMW_SQL2_VALUE;
                 $oid = $this->m_store->getSMWPageID($description->getDatavalue()->getDBkey(), $description->getDatavalue()->getNamespace(), $description->getDatavalue()->getInterwiki());
                 $query->joinfield = array($oid);
             } else {
                 // Join with smw_ids needed for other comparators (apply to title string).
                 $query->jointable = 'smw_ids';
                 $query->joinfield = "{$query->alias}.smw_id";
                 $value = $description->getDatavalue()->getSortkey();
                 switch ($description->getComparator()) {
                     case SMW_CMP_LEQ:
                         $comp = '<=';
                         break;
                     case SMW_CMP_GEQ:
                         $comp = '>=';
                         break;
                     case SMW_CMP_NEQ:
                         $comp = '!=';
                         break;
                     case SMW_CMP_LIKE:
                     case SMW_CMP_NLKE:
                         $comp = ' LIKE ';
                         if ($description->getComparator() == SMW_CMP_NLKE) {
                             $comp = " NOT{$comp}";
                         }
                         $value = str_replace(array('%', '_', '*', '?'), array('\\%', '\\_', '%', '_'), $value);
                         break;
                 }
                 $query->where = "{$query->alias}.smw_sortkey{$comp}" . $this->m_dbs->addQuotes($value);
             }
         }
     } elseif ($description instanceof SMWConceptDescription) {
         // fetch concept definition and insert it here
         $cid = $this->m_store->getSMWPageID($description->getConcept()->getDBkey(), SMW_NS_CONCEPT, '');
         $row = $this->m_dbs->selectRow('smw_conc2', array('concept_txt', 'concept_features', 'concept_size', 'concept_depth', 'cache_date'), array('s_id' => $cid), 'SMWSQLStore2Queries::compileQueries');
         if ($row === false) {
             // No description found, concept does not exist.
             // keep the above query object, it yields an empty result
             // TODO: announce an error here? (maybe not, since the query processor can check for
             // non-existing concept pages which is probably the main reason for finding nothing here)
         } else {
             global $smwgQConceptCaching, $smwgQMaxSize, $smwgQMaxDepth, $smwgQFeatures, $smwgQConceptCacheLifetime;
             $may_be_computed = $smwgQConceptCaching == CONCEPT_CACHE_NONE || $smwgQConceptCaching == CONCEPT_CACHE_HARD && ~(~($row->concept_features + 0) | $smwgQFeatures) == 0 && $smwgQMaxSize >= $row->concept_size && $smwgQMaxDepth >= $row->concept_depth;
             if ($row->cache_date && ($row->cache_date > strtotime("now") - $smwgQConceptCacheLifetime * 60 || !$may_be_computed)) {
                 // Cached concept, use cache unless it is dead and can be revived.
                 $query->jointable = 'smw_conccache';
                 $query->joinfield = "{$query->alias}.s_id";
                 $query->where = "{$query->alias}.o_id=" . $this->m_dbs->addQuotes($cid);
             } elseif ($row->concept_txt) {
                 // Parse description and process it recursively.
                 if ($may_be_computed) {
                     $qp = new SMWQueryParser();
                     // No defaultnamespaces here; If any, these are already in the concept.
                     $desc = $qp->getQueryDescription($row->concept_txt);
                     $qid = $this->compileQueries($desc);
                     if ($qid != -1) {
                         $query = $this->m_queries[$qid];
                     } else {
                         // somehow the concept query is no longer valid; maybe some syntax changed (upgrade) or global settings were modified since storing it
                         smwfLoadExtensionMessages('SemanticMediaWiki');
                         $this->m_errors[] = wfMsg('smw_emptysubquery');
                         // not quite the right message, but this case is very rare; let us not make detailed messages for this
                     }
                 } else {
                     smwfLoadExtensionMessages('SemanticMediaWiki');
                     $this->m_errors[] = wfMsg('smw_concept_cache_miss', $description->getConcept()->getText());
                 }
             }
             // else: no cache, no description (this may happen); treat like empty concept
         }
     } else {
         // (e.g. SMWThingDescription)
         $qid = -1;
         // no condition
     }
     if ($qid >= 0) {
         // Success, keep query object, propagate sortkeys from subqueries.
         $this->m_queries[$qid] = $query;
         if ($query->type != SMW_SQL2_DISJUNCTION) {
             // Sortkeys are killed by disjunctions (not all parts may have them),
             // NOTE: preprocessing might try to push disjunctions downwards to safe sortkey, but this seems to be minor
             foreach ($query->components as $cid => $field) {
                 $query->sortfields = array_merge($this->m_queries[$cid]->sortfields, $query->sortfields);
             }
         }
     }
     return $qid;
 }
 /**
  * No defaultnamespaces here; If any, these are already in the concept.
  * Unescaping is the same as in SMW_DV_Conept's getWikiValue().
  */
 private function getConceptQueryDescriptionFrom($conceptQuery)
 {
     $queryParser = new QueryParser();
     return $queryParser->getQueryDescription(str_replace(array('&lt;', '&gt;', '&amp;'), array('<', '>', '&'), $conceptQuery));
 }