/**
  * Given an SMWDescription that is just a conjunction or disjunction of
  * SMWValueDescription objects, create and return a plain WHERE condition
  * string for it.
  *
  * @param $query
  * @param SMWDescription $description
  * @param SMWSQLStore2Table $proptable
  * @param integer $valueIndex
  * @param string $operator
  */
 protected function compileAttributeWhere($query, SMWDescription $description, SMWSQLStore2Table $proptable, $valueIndex, $operator = 'AND')
 {
     $where = '';
     if ($description instanceof SMWValueDescription) {
         $dv = $description->getDatavalue();
         $keys = $dv->getDBkeys();
         // Try comparison based on value field and comparator.
         if ($valueIndex >= 0) {
             // Find field name for comparison.
             $smwidjoinfield = false;
             $fieldName = $this->getDBFieldsForDVIndex($proptable->objectfields, $valueIndex, $smwidjoinfield);
             // Do not support smw_id joined data for now.
             if ($fieldName && !$smwidjoinfield) {
                 $comparator = false;
                 $customSQL = false;
                 // See if the getSQLCondition method exists and call it if this is the case.
                 if (method_exists($description, 'getSQLCondition')) {
                     $customSQL = $description->getSQLCondition($query->alias, array_keys($proptable->objectfields), $this->m_dbs);
                 }
                 if ($customSQL) {
                     $where = $customSQL;
                 } else {
                     $value = $keys[$valueIndex];
                     switch ($description->getComparator()) {
                         case SMW_CMP_EQ:
                             $comparator = '=';
                             break;
                         case SMW_CMP_LEQ:
                             $comparator = '<=';
                             break;
                         case SMW_CMP_GEQ:
                             $comparator = '>=';
                             break;
                         case SMW_CMP_NEQ:
                             $comparator = '!=';
                             break;
                         case SMW_CMP_LIKE:
                         case SMW_CMP_NLKE:
                             $comparator = ' LIKE ';
                             if ($description->getComparator() == SMW_CMP_NLKE) {
                                 $comparator = " NOT{$comparator}";
                             }
                             $value = str_replace(array('%', '_', '*', '?'), array('\\%', '\\_', '%', '_'), $value);
                     }
                     if ($comparator) {
                         $where = "{$query->alias}.{$fieldName}{$comparator}" . $this->m_dbs->addQuotes($value);
                     }
                 }
             }
         }
         if ($where == '') {
             // comparators did not apply; match all fields
             $i = 0;
             foreach ($proptable->objectfields as $fname => $ftype) {
                 if ($i >= count($keys)) {
                     break;
                 }
                 if ($ftype == 'p') {
                     // Special case: page id, resolve this in advance
                     $oid = $this->getSMWPageID($keys[$i], $keys[$i + 1], $keys[$i + 2]);
                     $i += 3;
                     // skip these additional values (sortkey not needed here)
                     $where .= ($where ? ' AND ' : '') . "{$query->alias}.{$fname}=" . $this->m_dbs->addQuotes($oid);
                 } elseif ($ftype != 'l') {
                     // plain value, but not a text blob
                     $where .= ($where ? ' AND ' : '') . "{$query->alias}.{$fname}=" . $this->m_dbs->addQuotes($keys[$i]);
                 }
                 $i++;
             }
         }
     } elseif ($description instanceof SMWConjunction || $description instanceof SMWDisjunction) {
         $op = $description instanceof SMWConjunction ? 'AND' : 'OR';
         foreach ($description->getDescriptions() as $subdesc) {
             $this->compileAttributeWhere($query, $subdesc, $proptable, $valueIndex, $op);
         }
     }
     if ($where != '') {
         $query->where .= ($query->where ? " {$operator} " : '') . "({$where})";
     }
 }
	public function addDescription( SMWDescription $description ) {
		if ( ! ( $description instanceof SMWThingDescription ) ) {
			if ( $description instanceof SMWConjunction ) { // absorb sub-conjunctions
				foreach ( $description->getDescriptions() as $subdesc ) {
					$this->m_descriptions[] = $subdesc;
				}
			} else {
				$this->m_descriptions[] = $description;
			}
			
			// move print descriptions downwards
			///TODO: This may not be a good solution, since it does modify $description and since it does not react to future changes
			$this->m_printreqs = array_merge( $this->m_printreqs, $description->getPrintRequests() );
			$description->setPrintRequests( array() );
		}
	}
 /**
  * Given an SMWDescription that is just a conjunction or disjunction of
  * SMWValueDescription objects, create a plain WHERE condition string for it.
  */
 protected function compileAttributeWhere(SMWDescription $description, $jointable)
 {
     if ($description instanceof SMWValueDescription) {
         $dv = $description->getDatavalue();
         if (SMWSQLStore2::getStorageMode($dv->getTypeID()) == SMW_SQL2_SPEC2) {
             $keys = $dv->getDBkeys();
             $value = $keys[0];
             $field = "{$jointable}.value_string";
         } else {
             // should be SMW_SQL2_ATTS2
             if ($dv->isNumeric()) {
                 $value = $dv->getNumericValue();
                 $field = "{$jointable}.value_num";
             } else {
                 $keys = $dv->getDBkeys();
                 $value = $keys[0];
                 $field = "{$jointable}.value_xsd";
             }
         }
         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:
                 if ($dv->getTypeID() == '_str') {
                     $comp = ' LIKE ';
                     $value = str_replace(array('%', '_', '*', '?'), array('\\%', '\\_', '%', '_'), $value);
                 } else {
                     // LIKE only supported for strings
                     $comp = '=';
                 }
                 break;
             case SMW_CMP_EQ:
             default:
                 $comp = '=';
                 break;
         }
         $result = "{$field}{$comp}" . $this->m_dbs->addQuotes($value);
     } elseif ($description instanceof SMWConjunction || $description instanceof SMWDisjunction) {
         $op = $description instanceof SMWConjunction ? ' AND ' : ' OR ';
         $result = '';
         foreach ($description->getDescriptions() as $subdesc) {
             $result = $result . ($result != '' ? $op : '') . $this->compileAttributeWhere($subdesc, $jointable);
         }
         $result = "({$result})";
     } else {
         $result = '';
     }
     return $result;
 }