* Thomas Bleher <[EMAIL PROTECTED]> [2007-11-15 20:36]:
> * Thomas Bleher <[EMAIL PROTECTED]> [2007-11-14 08:48]:
> > 1) Implement negations in queries - then I could ask "(NOT maxTeilnehmer <=
> > 9) AND (NOT minTeilnehmer >= 11)". I used this solution with SMW 0.7
> > (patch below), but looking at the 1.0RC2 code, I'm not quite sure how
> > to implement it cleanly.
>
> I looked at the code again and tried to implement negation support. The
> patch below adds a <n> </n> pair which negates the query in between. It
> also adds a SMWNegation class (derived from SMWDescription), which
> encapsulates the negation.
OK, I took another stab at this, and in my limited tests the code works
correctly now :)
The code is online at http://pwiki.j-crew.de/wiki/Test, feel free to
play around with it (it's just a test-wiki).
Technical details:
To work around the problems with INNER JOINs and negations, all INNER
JOINs of the form "SELECT a INNER JOIN b ON a.c=b.d" are replaced by
"SELECT a,b WHERE a.c=b.d". This may not be the most elegant solution,
but the only workable I found.
To make this work, addJoin now has an additional $where parameter.
Beware: I still don't understand all the internals of query processing,
so no guarantees for this code. I would really appreciate it if someone
more knowledgeable than me would look over the code.
Regards,
Thomas
--- a/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php
+++ b/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php
@@ -296,7 +296,14 @@ class SMWQueryParser {
$conjunction = $this->addDescription($conjunction, $this->getSubqueryDescription($setsubNS, $label));
/// TODO: print requests from subqueries currently are ignored, should be moved down
break;
- case '||': case '': case '</q>': // finish disjunction and maybe subquery
+ case '<n>': // negated subquery
+ $this->pushDelimiter('</n>');
+ $setsubsubNS = false;
+ $sublabel = '';
+ $conjunction = $this->addDescription($conjunction, new SMWNegation($this->getSubqueryDescription($setsubsubNS, $sublabel)));
+ /// TODO: print requests from negations currently are ignored, should be moved down
+ break;
+ case '||': case '': case '</q>': case '</n>': // finish disjunction and maybe subquery
if ($this->m_defaultns !== NULL) { // possibly add namespace restrictions
if ( $hasNamespaces && !$mustSetNS) {
// add ns restrictions to all earlier conjunctions (all of which did not have them yet)
@@ -323,6 +330,13 @@ class SMWQueryParser {
$this->m_errors[] = wfMsgForContent('smw_toomanyclosing', $chunk);
return NULL;
}
+ } elseif ($chunk == '</n>') {
+ if ($this->popDelimiter('</n>')) {
+ $continue = false; // leave the loop
+ } else {
+ $this->m_errors[] = wfMsgForContent('smw_toomanyclosing', $chunk);
+ return NULL;
+ }
} elseif ($chunk == '') {
$continue = false;
}
@@ -489,6 +503,18 @@ class SMWQueryParser {
}
$chunk = $this->readChunk();
break;
+ case '<n>': // subquery, set default namespaces
+ if ($typeid == '_wpg') {
+ $this->pushDelimiter('</n>');
+ $setsubNS = true;
+ $sublabel = '';
+ $innerdesc = $this->addDescription($innerdesc, new SMWNegation($this->getSubqueryDescription($setsubNS, $sublabel)), false);
+ } else { // no subqueries allowed for non-pages
+ $this->m_errors[] = wfMsgForContent('smw_valuesubquery', $propertyname);
+ $innerdesc = $this->addDescription($innerdesc, new SMWThingDescription(), false);
+ }
+ $chunk = $this->readChunk();
+ break;
default: //normal object value or print statement
// read value(s), possibly with inner [[...]]
$open = 1;
@@ -738,7 +764,7 @@ class SMWQueryParser {
*/
protected function readChunk($stoppattern = '', $consume=true) {
if ($stoppattern == '') {
- $stoppattern = '\[\[|\]\]|::|:=|<q>|<\/q>|^' . $this->m_categoryprefix . '|\|\||\|';
+ $stoppattern = '\[\[|\]\]|::|:=|<q>|<\/q>|<n>|<\/n>|^' . $this->m_categoryprefix . '|\|\||\|';
}
$chunks = preg_split('/[\s]*(' . $stoppattern . ')[\s]*/', $this->m_curstring, 2, PREG_SPLIT_DELIM_CAPTURE);
if (count($chunks) == 1) { // no matches anymore, strip spaces and finish
--- a/extensions/SemanticMediaWiki/includes/storage/SMW_Description.php
+++ b/extensions/SemanticMediaWiki/includes/storage/SMW_Description.php
@@ -763,3 +763,31 @@ class SMWSomeProperty extends SMWDescription {
}
}
+/**
+ * Description of a negation of a description.
+ */
+class SMWNegation extends SMWDescription {
+ protected $m_description;
+
+ public function SMWNegation(SMWDescription $description) {
+ $this->m_description = $description;
+ }
+
+ public function getDescription() {
+ return $this->m_description;
+ }
+
+
+ public function getQueryString() {
+ return '<n>' . $this->m_description->getQueryString() . '</n>';
+ }
+
+ public function isSingleton() {
+ return false;
+ }
+
+ public function getDepth() {
+ return $this->m_description->getDepth() + 1;
+ }
+
+}
--- a/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php
+++ b/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php
@@ -352,7 +352,8 @@ class SMWSQLStore extends SMWStore {
case '__nry':
$values = $value->getDVs();
$narytable = $db->tableName('smw_nary');
- $where = "$narytable.attribute_title=" . $db->addQuotes($property->getDBKey());
+ if ($where != '') $where .= ' AND ';
+ $where .= "$narytable.attribute_title=" . $db->addQuotes($property->getDBKey());
$from = $narytable;
$count = 0;
foreach ($values as $dv) {
@@ -364,14 +365,14 @@ class SMWSQLStore extends SMWStore {
case '_txt': // not supported
break;
case '_wpg':
- $from .= ' INNER JOIN ' . $db->tableName('smw_nary_relations') . ' AS nary' . $count .
- " ON ($narytable.subject_id=nary$count.subject_id AND $narytable.nary_key=nary$count.nary_key)";
+ $from .= ', ' . $db->tableName('smw_nary_relations') . ' AS nary' . $count;
+ $where .= " AND ($narytable.subject_id=nary$count.subject_id AND $narytable.nary_key=nary$count.nary_key)";
$where .= " AND nary$count.object_title=" . $db->addQuotes($dv->getDBKey()) .
" AND nary$count.object_namespace=" . $db->addQuotes($dv->getNamespace());
break;
default:
- $from .= ' INNER JOIN ' . $db->tableName('smw_nary_attributes') . ' AS nary' . $count .
- " ON ($narytable.subject_id=nary$count.subject_id AND $narytable.nary_key=nary$count.nary_key)";
+ $from .= ', ' . $db->tableName('smw_nary_attributes') . ' AS nary' . $count;
+ $where .= " AND ($narytable.subject_id=nary$count.subject_id AND $narytable.nary_key=nary$count.nary_key)";
$where .= " AND nary$count.value_xsd=" . $db->addQuotes($dv->getXSDValue()) .
" AND nary$count.value_unit=" . $db->addQuotes($dv->getUnit());
}
@@ -1234,11 +1235,11 @@ class SMWSQLStore extends SMWStore {
* relevant page id. This can be a field from a (possibly auxilliary) page table or
* from one of SMW's relation tables. If no field is available, return false.
*/
- protected function getCurrentIDField(&$from, &$db, &$curtables, $nary_pos = '') {
+ protected function getCurrentIDField(&$from, &$where, &$db, &$curtables, $nary_pos = '') {
$id = false;
- if ($this->addJoin('pRELS', $from, $db, $curtables, $nary_pos)) {
+ if ($this->addJoin('pRELS', $from, $where, $db, $curtables, $nary_pos)) {
$id = $curtables['pRELS'] . '.object_id';
- } elseif ($this->addJoin('PAGE', $from, $db, $curtables, $nary_pos)) { // fallback
+ } elseif ($this->addJoin('PAGE', $from, $where, $db, $curtables, $nary_pos)) { // fallback
$id = $curtables['PAGE'] . '.page_id';
}
return $id;
@@ -1408,83 +1409,95 @@ class SMWSQLStore extends SMWStore {
* That's all. The method can be read and modified case by case, each of which is
* rather short and completely independent from the other cases.
*/
- protected function addJoin($tablename, &$from, &$db, &$curtables, $nary_pos = '') {
+ protected function addJoin($tablename, &$from, &$where, &$db, &$curtables, $nary_pos = '') {
global $smwgQEqualitySupport;
if (array_key_exists($tablename, $curtables)) { // table already present
return $curtables[$tablename];
}
if ($tablename == 'PAGE') {
- if ($this->addJoin('pRELS', $from, $db, $curtables, $nary_pos)) {
+ if ($this->addJoin('pRELS', $from, $where, $db, $curtables, $nary_pos)) {
$curtables['PAGE'] = 'p' . SMWSQLStore::$m_tablenum++;
- $from .= ' INNER JOIN ' . $db->tableName('page') . ' AS ' . $curtables['PAGE'] . ' ON (' .
+ $from .= ', ' . $db->tableName('page') . ' AS ' . $curtables['PAGE'];
+ if ($where != '') $where .= ' AND ';
+ $where .= '(' .
$curtables['PAGE'] . '.page_title=' . $curtables['pRELS'] . '.object_title AND ' .
$curtables['PAGE'] . '.page_namespace=' . $curtables['pRELS'] . '.object_namespace)';
return $curtables['PAGE'];
}
} elseif ($tablename == 'CATS') {
- if ($id = $this->getCurrentIDField($from, $db, $curtables, $nary_pos)) {
+ if ($id = $this->getCurrentIDField($from, $where, $db, $curtables, $nary_pos)) {
$curtables['CATS'] = 'cl' . SMWSQLStore::$m_tablenum++;
$cond = $curtables['CATS'] . '.cl_from=' . $id;
/// TODO: slow, introduce another parameter to activate this
if ($smwgQEqualitySupport && (array_key_exists('pRELS', $curtables))) {
// only do this at inner queries (pRELS set)
- $this->addJoin('REDIPAGE', $from, $db, $curtables, $nary_pos);
+ $this->addJoin('REDIPAGE', $from, $where, $db, $curtables, $nary_pos);
$cond = '((' . $cond . ') OR (' .
$curtables['REDIPAGE'] . '.page_id=' . $curtables['CATS'] . '.cl_from))';
}
- $from .= ' INNER JOIN ' . $db->tableName('categorylinks') . ' AS ' . $curtables['CATS'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('categorylinks') . ' AS ' . $curtables['CATS'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['CATS'];
}
} elseif ($tablename == 'RELS') {
- if ($id = $this->getCurrentIDField($from, $db, $curtables, $nary_pos)) {
+ if ($id = $this->getCurrentIDField($from, $where, $db, $curtables, $nary_pos)) {
$curtables['RELS'] = 'rel' . SMWSQLStore::$m_tablenum++;
$cond = $curtables['RELS'] . '.subject_id=' . $id;
/// TODO: slow, introduce another parameter to activate this
if ($smwgQEqualitySupport && (array_key_exists('pRELS', $curtables))) {
// only do this at inner queries (pRELS set)
- $this->addJoin('REDIRECT', $from, $db, $curtables, $nary_pos);
+ $this->addJoin('REDIRECT', $from, $where, $db, $curtables, $nary_pos);
$cond = '((' . $cond . ') OR (' .
$curtables['REDIRECT'] . '.rd_title=' . $curtables['RELS'] . '.subject_title AND ' .
$curtables['REDIRECT'] . '.rd_namespace=' . $curtables['RELS'] . '.subject_namespace))';
}
- $from .= ' INNER JOIN ' . $db->tableName('smw_relations') . ' AS ' . $curtables['RELS'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('smw_relations') . ' AS ' . $curtables['RELS'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['RELS'];
}
} elseif ($tablename == 'ATTS') {
- if ($id = $this->getCurrentIDField($from, $db, $curtables, $nary_pos)) {
+ if ($id = $this->getCurrentIDField($from, $where, $db, $curtables, $nary_pos)) {
$curtables['ATTS'] = 'att' . SMWSQLStore::$m_tablenum++;
$cond = $curtables['ATTS'] . '.subject_id=' . $id;
/// TODO: slow, introduce another parameter to activate this
if ($smwgQEqualitySupport && (array_key_exists('pRELS', $curtables))) {
// only do this at inner queries (pREL set)
- $this->addJoin('REDIRECT', $from, $db, $curtables, $nary_pos);
+ $this->addJoin('REDIRECT', $from, $where, $db, $curtables, $nary_pos);
$cond = '((' . $cond . ') OR (' .
$curtables['REDIRECT'] . '.rd_title=' . $curtables['ATTS'] . '.subject_title AND ' .
$curtables['REDIRECT'] . '.rd_namespace=' . $curtables['ATTS'] . '.subject_namespace))';
}
- $from .= ' INNER JOIN ' . $db->tableName('smw_attributes') . ' AS ' . $curtables['ATTS'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('smw_attributes') . ' AS ' . $curtables['ATTS'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['ATTS'];
}
} elseif ($tablename == 'TEXT') {
- if ($id = $this->getCurrentIDField($from, $db, $curtables, $nary_pos)) {
+ if ($id = $this->getCurrentIDField($from, $where, $db, $curtables, $nary_pos)) {
$curtables['TEXT'] = 'txt' . SMWSQLStore::$m_tablenum++;
- $from .= ' INNER JOIN ' . $db->tableName('smw_longstrings') . ' AS ' . $curtables['TEXT'] . ' ON ' . $curtables['TEXT'] . '.subject_id=' . $id;
+ $from .= ', ' . $db->tableName('smw_longstrings') . ' AS ' . $curtables['TEXT'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $curtables['TEXT'] . '.subject_id=' . $id;
return $curtables['TEXT'];
}
} elseif ($tablename == 'NARY') {
- if ($id = $this->getCurrentIDField($from, $db, $curtables, $nary_pos)) {
+ if ($id = $this->getCurrentIDField($from, $where, $db, $curtables, $nary_pos)) {
$curtables['NARY'] = 'nary' . SMWSQLStore::$m_tablenum++;
$cond = $curtables['NARY'] . '.subject_id=' . $id;
/// TODO: slow, introduce another parameter to activate this
if ($smwgQEqualitySupport && (array_key_exists('pRELS', $curtables))) {
// only do this at inner queries (pRELS set)
- $this->addJoin('REDIRECT', $from, $db, $curtables, $nary_pos);
+ $this->addJoin('REDIRECT', $from, $where, $db, $curtables, $nary_pos);
$cond = '((' . $cond . ') OR (' .
$curtables['REDIRECT'] . '.rd_title=' . $curtables['RELS'] . '.subject_title AND ' .
$curtables['REDIRECT'] . '.rd_namespace=' . $curtables['RELS'] . '.subject_namespace))';
}
- $from .= ' INNER JOIN ' . $db->tableName('smw_nary') . ' AS ' . $curtables['NARY'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('smw_nary') . ' AS ' . $curtables['NARY'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['NARY'];
}
} elseif ($tablename == 'pATTS') {
@@ -1494,8 +1507,10 @@ class SMWSQLStore extends SMWStore {
$curtables['pATTS'] . '.subject_id=' . $curtables['pNARY'] . '.subject_id AND ' .
$curtables['pATTS'] . '.nary_key=' . $curtables['pNARY'] . '.nary_key AND ' .
$curtables['pATTS'] . '.nary_pos=' . $db->addQuotes($nary_pos) . ')';
- $from .= ' INNER JOIN ' . $db->tableName('smw_nary_attributes') . ' AS ' .
- $curtables['pATTS'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('smw_nary_attributes') . ' AS ' .
+ $curtables['pATTS'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['pATTS'];
}
} elseif ($tablename == 'pRELS') {
@@ -1505,7 +1520,9 @@ class SMWSQLStore extends SMWStore {
$curtables['pRELS'] . '.subject_id=' . $curtables['pNARY'] . '.subject_id AND ' .
$curtables['pRELS'] . '.nary_key=' . $curtables['pNARY'] . '.nary_key AND ' .
$curtables['pRELS'] . '.nary_pos=' . $db->addQuotes($nary_pos) . ')';
- $from .= ' INNER JOIN ' . $db->tableName('smw_nary_relations') . ' AS ' . $curtables['pRELS'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('smw_nary_relations') . ' AS ' . $curtables['pRELS'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['pRELS'];
}
} elseif ($tablename == 'pTEXT') {
@@ -1515,17 +1532,19 @@ class SMWSQLStore extends SMWStore {
$curtables['pTEXT'] . '.subject_id=' . $curtables['pNARY'] . '.subject_id AND ' .
$curtables['pTEXT'] . '.nary_key=' . $curtables['pNARY'] . '.nary_key AND ' .
$curtables['pTEXT'] . '.nary_pos=' . $db->addQuotes($nary_pos) . ')';
- $from .= ' INNER JOIN ' . $db->tableName('smw_nary_longstrings') . ' AS ' . $curtables['pTEXT'] . ' ON ' . $cond;
+ $from .= ', ' . $db->tableName('smw_nary_longstrings') . ' AS ' . $curtables['pTEXT'];
+ if ($where != '') $where .= ' AND ';
+ $where .= $cond;
return $curtables['pTEXT'];
}
} elseif ($tablename == 'REDIRECT') {
- if ($id = $this->getCurrentIDField($from, $db, $curtables, $nary_pos)) {
+ if ($id = $this->getCurrentIDField($from, $where, $db, $curtables, $nary_pos)) {
$curtables['REDIRECT'] = 'rd' . SMWSQLStore::$m_tablenum++;
$from .= ' LEFT JOIN ' . $db->tableName('redirect') . ' AS ' . $curtables['REDIRECT'] . ' ON ' . $curtables['REDIRECT'] . '.rd_from=' . $id;
return $curtables['REDIRECT'];
}
} elseif ($tablename == 'REDIPAGE') { // +another copy of page for getting ids of redirect targets; *ouch*
- if ($this->addJoin('REDIRECT', $from, $db, $curtables, $nary_pos)) {
+ if ($this->addJoin('REDIRECT', $from, $where, $db, $curtables, $nary_pos)) {
$curtables['REDIPAGE'] = 'rp' . SMWSQLStore::$m_tablenum++;
$from .= ' LEFT JOIN ' . $db->tableName('page') . ' AS ' . $curtables['REDIPAGE'] . ' ON (' .
$curtables['REDIRECT'] . '.rd_title=' . $curtables['REDIPAGE'] . '.page_title AND ' .
@@ -1570,12 +1589,13 @@ class SMWSQLStore extends SMWStore {
if ($description instanceof SMWThingDescription) {
// nothing to check
} elseif ($description instanceof SMWClassDescription) {
- if ($table = $this->addJoin('CATS', $from, $db, $curtables, $nary_pos)) {
+ if ($table = $this->addJoin('CATS', $from, $where, $db, $curtables, $nary_pos)) {
global $smwgQSubcategoryDepth;
if ($smwgQSubcategoryDepth > 0) {
$ct = $this->getCategoryTable($description->getCategories(), $db);
$from = '`' . $ct . '`, ' . $from;
- $where = "$ct.title=" . $table . '.cl_to';
+ if ($where != '') $where .= ' AND ';
+ $where .= " $ct.title=" . $table . '.cl_to ';
} else {
foreach ($description->getCategories() as $cat) {
if ($subwhere != '') {
@@ -1590,15 +1610,17 @@ class SMWSQLStore extends SMWStore {
}
}
} elseif ($description instanceof SMWNamespaceDescription) {
- if ($table = $this->addJoin('pRELS', $from, $db, $curtables, $nary_pos)) {
+ if ($table = $this->addJoin('pRELS', $from, $where, $db, $curtables, $nary_pos)) {
+ if ($where != '') $where .= ' AND ';
$where .= $table . '.object_namespace=' . $db->addQuotes($description->getNamespace());
- } elseif ($table = $this->addJoin('PAGE', $from, $db, $curtables, $nary_pos)) {
+ } elseif ($table = $this->addJoin('PAGE', $from, $where, $db, $curtables, $nary_pos)) {
+ if ($where != '') $where .= ' AND ';
$where .= $table . '.page_namespace=' . $db->addQuotes($description->getNamespace());
}
} elseif ($description instanceof SMWValueDescription) {
switch ($description->getDatavalue()->getTypeID()) {
case '_txt': // possibly pull in longstring table (for naries)
- $this->addJoin('pTEXT', $from, $db, $curtables, $nary_pos);
+ $this->addJoin('pTEXT', $from, $where, $db, $curtables, $nary_pos);
break;
case '_wpg':
global $smwgQEqualitySupport;
@@ -1607,24 +1629,26 @@ class SMWSQLStore extends SMWStore {
} else {
$page = $description->getDatavalue();
}
- if ($table = $this->addJoin('pRELS', $from, $db, $curtables, $nary_pos)) {
+ if ($table = $this->addJoin('pRELS', $from, $where, $db, $curtables, $nary_pos)) {
$cond = $table . '.object_title=' .
$db->addQuotes($page->getDBKey()) . ' AND ' .
$table . '.object_namespace=' . $page->getNamespace();
if ( $smwgQEqualitySupport &&
- ($this->addJoin('REDIRECT', $from, $db, $curtables, $nary_pos)) ) {
+ ($this->addJoin('REDIRECT', $from, $where, $db, $curtables, $nary_pos)) ) {
$cond = '(' . $cond . ') OR (' .
$curtables['REDIRECT'] . '.rd_title=' . $db->addQuotes($page->getDBKey()) . ' AND ' .
$curtables['REDIRECT'] . '.rd_namespace=' . $page->getNamespace() . ')';
}
+ if ($where != '') $where .= ' AND ';
$where .= $cond;
- } elseif ($table = $this->addJoin('PAGE', $from, $db, $curtables, $nary_pos)) {
+ } elseif ($table = $this->addJoin('PAGE', $from, $where, $db, $curtables, $nary_pos)) {
+ if ($where != '') $where .= ' AND ';
$where .= $table . '.page_title=' . $db->addQuotes($page->getDBKey()) . ' AND ' .
$table . '.page_namespace=' . $page->getNamespace();
}
break;
default:
- if ( $table = $this->addJoin('pATTS', $from, $db, $curtables, $nary_pos) ) {
+ if ( $table = $this->addJoin('pATTS', $from, $where, $db, $curtables, $nary_pos) ) {
switch ($description->getComparator()) {
case SMW_CMP_LEQ: $op = '<='; break;
case SMW_CMP_GEQ: $op = '>='; break;
@@ -1638,6 +1662,7 @@ class SMWSQLStore extends SMWStore {
$valuefield = 'value_xsd';
$value = $description->getDatavalue()->getXSDValue();
}
+ if ($where != '') $where .= ' AND ';
///TODO: implement check for unit
$where .= $table . '.' . $valuefield . $op . $db->addQuotes($value);
}
@@ -1664,7 +1689,7 @@ class SMWSQLStore extends SMWStore {
if ( array_key_exists('PAGE', $curtables) ) {
$nexttables['PAGE'] = $curtables['PAGE'];
}
- if ($this->addJoin('pRELS', $from, $db, $curtables, $nary_pos)) {
+ if ($this->addJoin('pRELS', $from, $where, $db, $curtables, $nary_pos)) {
$nexttables['pRELS'] = $curtables['pRELS'];
}
$this->createSQLQuery($subdesc, $from, $subwhere, $db, $nexttables, $nary_pos);
@@ -1687,6 +1712,16 @@ class SMWSQLStore extends SMWStore {
$subwhere = '';
}
}
+ } elseif ($description instanceof SMWNegation) {
+ $intfrom = $db->tableName('page');
+ $intwhere = '';
+ $this->createSQLQuery($description->getDescription(), $intfrom, $subwhere, $db, $curtables, $nary_pos);
+ if ($subwhere != '') {
+ if ($where != '') $where .= ' AND ';
+ // $intfrom includes `page`, but we want to take the page ref from the outer query, so we remove it from the inner one
+ $cleansed_from = str_replace($db->tableName('page').',', '', $intfrom);
+ $where .= 'NOT EXISTS (SELECT 1 FROM '.$cleansed_from.' WHERE ' . $subwhere . ')';
+ }
} elseif ($description instanceof SMWSomeProperty) {
$id = SMWDataValueFactory::getPropertyObjectTypeID($description->getProperty());
$sort = false;
@@ -1721,12 +1756,13 @@ class SMWSQLStore extends SMWStore {
}
}
}
- if ($table = $this->addJoin($tablename, $from, $db, $curtables, $nary_pos)) {
+ if ($table = $this->addJoin($tablename, $from, $where, $db, $curtables, $nary_pos)) {
global $smwgQSubpropertyDepth;
if ($smwgQSubpropertyDepth > 0) {
$pt = $this->getPropertyTable($description->getProperty()->getDBKey(), $db);
$from = '`' . $pt . '`, ' . $from;
- $where = "$pt.title=" . $table . '.' . $pcolumn;
+ if ($where != '') $where .= ' AND ';
+ $where .= "$pt.title=" . $table . '.' . $pcolumn;
} else {
$where .= $table . '.' . $pcolumn . '=' .
$db->addQuotes($description->getProperty()->getDBKey());
@@ -1739,7 +1775,8 @@ class SMWSQLStore extends SMWStore {
$this->m_sortfield = "$table.$sort";
}
if ( $subwhere != '') {
- $where .= ' AND (' . $subwhere . ')';
+ if ($where != '') $where .= ' AND ';
+ $where .= '(' . $subwhere . ')';
}
}
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Semediawiki-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/semediawiki-devel