Feature #21688 » 12758-dbal_v2.diff
class.ux_t3lib_sqlparser.php (working copy) | ||
---|---|---|
*
|
||
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
|
||
* @author Karsten Dambekalns <k.dambekalns@fishfarm.de>
|
||
* @author Xavier Perseguers <typo3@perseguers.ch>
|
||
*/
|
||
... | ... | |
$stack[$level] = array(); // Reset stack for this level
|
||
} else { // If no new level is started, just parse the current level:
|
||
// Find "modifyer", eg. "NOT or !"
|
||
// Find "modifier", eg. "NOT or !"
|
||
$stack[$level][$pnt[$level]]['modifier'] = trim($this->nextPart($parseString, '^(!|NOT[[:space:]]+)'));
|
||
// Support calculated value only for:
|
||
// - "&" (boolean AND)
|
||
// - "+" (addition)
|
||
// - "-" (substraction)
|
||
// - "*" (multiplication)
|
||
// - "/" (division)
|
||
// - "%" (modulo)
|
||
$calcOperators = '&|\+|-|\*|\/|%';
|
||
// Fieldname:
|
||
if ($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)([[:space:]]+|' . $calcOperators . '|<=|>=|<|>|=|!=|IS)')) {
|
||
// Parse field name into field and table:
|
||
$tableField = explode('.', $fieldName, 2);
|
||
if (count($tableField) == 2) {
|
||
$stack[$level][$pnt[$level]]['table'] = $tableField[0];
|
||
$stack[$level][$pnt[$level]]['field'] = $tableField[1];
|
||
} else {
|
||
$stack[$level][$pnt[$level]]['table'] = '';
|
||
$stack[$level][$pnt[$level]]['field'] = $tableField[0];
|
||
// See if condition is EXISTS with a subquery
|
||
if (preg_match('/^EXISTS[[:space:]]*[(]/', $parseString)) {
|
||
$stack[$level][$pnt[$level]]['func']['type'] = $this->nextPart($parseString, '^(EXISTS)');
|
||
$this->nextPart($parseString, '^([(])');
|
||
$stack[$level][$pnt[$level]]['func']['subquery'] = $this->parseSELECT($parseString);
|
||
// Seek to new position in parseString after parsing of the subquery
|
||
$parseString = $stack[$level][$pnt[$level]]['func']['subquery']['parseString'];
|
||
unset($stack[$level][$pnt[$level]]['func']['subquery']['parseString']);
|
||
if (!$this->nextPart($parseString, '^([)])')) {
|
||
return 'No ) parenthesis at end of subquery';
|
||
}
|
||
} else {
|
||
return $this->parseError('No field name found as expected in parseWhereClause()', $parseString);
|
||
}
|
||
// See if the value is calculated:
|
||
$stack[$level][$pnt[$level]]['calc'] = $this->nextPart($parseString, '^(' . $calcOperators . ')');
|
||
if (strlen($stack[$level][$pnt[$level]]['calc'])) {
|
||
// Finding value for calculation:
|
||
$stack[$level][$pnt[$level]]['calc_value'] = $this->getValue($parseString);
|
||
}
|
||
// Find "comparator":
|
||
$stack[$level][$pnt[$level]]['comparator'] = $this->nextPart($parseString, '^(<=|>=|<|>|=|!=|NOT[[:space:]]+IN|IN|NOT[[:space:]]+LIKE|LIKE|IS[[:space:]]+NOT|IS)');
|
||
if (strlen($stack[$level][$pnt[$level]]['comparator'])) {
|
||
if (preg_match('/^CONCAT[[:space:]]*\(/', $parseString)) {
|
||
$this->nextPart($parseString, '^(CONCAT[[:space:]]?[(])');
|
||
$values = array(
|
||
'operator' => 'CONCAT',
|
||
'args' => array(),
|
||
);
|
||
$cnt = 0;
|
||
while ($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)')) {
|
||
// Parse field name into field and table:
|
||
$tableField = explode('.', $fieldName, 2);
|
||
if (count($tableField) == 2) {
|
||
$values['args'][$cnt]['table'] = $tableField[0];
|
||
$values['args'][$cnt]['field'] = $tableField[1];
|
||
} else {
|
||
$values['args'][$cnt]['table'] = '';
|
||
$values['args'][$cnt]['field'] = $tableField[0];
|
||
}
|
||
// Looking for comma:
|
||
$this->nextPart($parseString, '^(,)');
|
||
$cnt++;
|
||
// Support calculated value only for:
|
||
// - "&" (boolean AND)
|
||
// - "+" (addition)
|
||
// - "-" (substraction)
|
||
// - "*" (multiplication)
|
||
// - "/" (division)
|
||
// - "%" (modulo)
|
||
$calcOperators = '&|\+|-|\*|\/|%';
|
||
|
||
// Fieldname:
|
||
if ($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)([[:space:]]+|' . $calcOperators . '|<=|>=|<|>|=|!=|IS)')) {
|
||
|
||
// Parse field name into field and table:
|
||
$tableField = explode('.', $fieldName, 2);
|
||
if (count($tableField) == 2) {
|
||
$stack[$level][$pnt[$level]]['table'] = $tableField[0];
|
||
$stack[$level][$pnt[$level]]['field'] = $tableField[1];
|
||
} else {
|
||
$stack[$level][$pnt[$level]]['table'] = '';
|
||
$stack[$level][$pnt[$level]]['field'] = $tableField[0];
|
||
}
|
||
// Look for ending parenthesis:
|
||
$this->nextPart($parseString, '([)])');
|
||
$stack[$level][$pnt[$level]]['value'] = $values;
|
||
} else {
|
||
// Finding value for comparator:
|
||
$stack[$level][$pnt[$level]]['value'] = $this->getValue($parseString, $stack[$level][$pnt[$level]]['comparator']);
|
||
if ($this->parse_error) {
|
||
return $this->parse_error;
|
||
return $this->parseError('No field name found as expected in parseWhereClause()', $parseString);
|
||
}
|
||
|
||
// See if the value is calculated:
|
||
$stack[$level][$pnt[$level]]['calc'] = $this->nextPart($parseString, '^(' . $calcOperators . ')');
|
||
if (strlen($stack[$level][$pnt[$level]]['calc'])) {
|
||
// Finding value for calculation:
|
||
$stack[$level][$pnt[$level]]['calc_value'] = $this->getValue($parseString);
|
||
}
|
||
|
||
// Find "comparator":
|
||
$stack[$level][$pnt[$level]]['comparator'] = $this->nextPart($parseString, '^(<=|>=|<|>|=|!=|NOT[[:space:]]+IN|IN|NOT[[:space:]]+LIKE|LIKE|IS[[:space:]]+NOT|IS)');
|
||
if (strlen($stack[$level][$pnt[$level]]['comparator'])) {
|
||
if (preg_match('/^CONCAT[[:space:]]*\(/', $parseString)) {
|
||
$this->nextPart($parseString, '^(CONCAT[[:space:]]?[(])');
|
||
$values = array(
|
||
'operator' => 'CONCAT',
|
||
'args' => array(),
|
||
);
|
||
$cnt = 0;
|
||
while ($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)')) {
|
||
// Parse field name into field and table:
|
||
$tableField = explode('.', $fieldName, 2);
|
||
if (count($tableField) == 2) {
|
||
$values['args'][$cnt]['table'] = $tableField[0];
|
||
$values['args'][$cnt]['field'] = $tableField[1];
|
||
} else {
|
||
$values['args'][$cnt]['table'] = '';
|
||
$values['args'][$cnt]['field'] = $tableField[0];
|
||
}
|
||
// Looking for comma:
|
||
$this->nextPart($parseString, '^(,)');
|
||
$cnt++;
|
||
}
|
||
// Look for ending parenthesis:
|
||
$this->nextPart($parseString, '([)])');
|
||
$stack[$level][$pnt[$level]]['value'] = $values;
|
||
} elseif (in_array($stack[$level][$pnt[$level]]['comparator'], array('IN', 'NOT IN')) && preg_match('/^[(][[:space:]]*SELECT[[:space:]]+/', $parseString)) {
|
||
$this->nextPart($parseString, '^([(])');
|
||
$stack[$level][$pnt[$level]]['subquery'] = $this->parseSELECT($parseString);
|
||
// Seek to new position in parseString after parsing of the subquery
|
||
$parseString = $stack[$level][$pnt[$level]]['subquery']['parseString'];
|
||
unset($stack[$level][$pnt[$level]]['subquery']['parseString']);
|
||
if (!$this->nextPart($parseString, '^([)])')) {
|
||
return 'No ) parenthesis at end of subquery';
|
||
}
|
||
} else {
|
||
// Finding value for comparator:
|
||
$stack[$level][$pnt[$level]]['value'] = $this->getValue($parseString, $stack[$level][$pnt[$level]]['comparator']);
|
||
if ($this->parse_error) {
|
||
return $this->parse_error;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
// Finished, increase pointer:
|
||
$pnt[$level]++;
|
||
// Checking if we are back to level 0 and we should still decrease level,
|
||
// meaning we were probably parsing a subquery and should return here:
|
||
if ($level === 0 && preg_match('/^[)]/', $parseString)) {
|
||
// Return the stacks lowest level:
|
||
return $stack[0];
|
||
}
|
||
// Checking if the current level is ended, in that case do stack management:
|
||
while ($this->nextPart($parseString,'^([)])')) {
|
||
$level--; // Decrease level:
|
||
... | ... | |
// Look for sublevel:
|
||
if (is_array($v['sub'])) {
|
||
$output .= ' (' . trim($this->nativeCompileWhereClause($v['sub'])) . ')';
|
||
} elseif (isset($v['func'])) {
|
||
$output .= ' ' . trim($v['modifier']) . ' ' . $v['func']['type'] . ' (' . $this->compileSELECT($v['func']['subquery']) . ')';
|
||
} else {
|
||
// Set field/table with modifying prefix if any:
|
||
... | ... | |
// Detecting value type; list or plain:
|
||
if (t3lib_div::inList('NOTIN,IN', strtoupper(str_replace(array(' ', "\t", "\r", "\n"), '', $v['comparator'])))) {
|
||
$valueBuffer = array();
|
||
foreach ($v['value'] as $realValue) {
|
||
$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
|
||
if (isset($v['subquery'])) {
|
||
$output .= ' (' . $this->compileSELECT($v['subquery']) . ')';
|
||
} else {
|
||
$valueBuffer = array();
|
||
foreach ($v['value'] as $realValue) {
|
||
$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
|
||
}
|
||
$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
|
||
}
|
||
$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
|
||
} else if (isset($v['value']['operator'])) {
|
||
} elseif (isset($v['value']['operator'])) {
|
||
$values = array();
|
||
foreach ($v['value']['args'] as $fieldDef) {
|
||
$values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
|
||
... | ... | |
// Look for sublevel:
|
||
if (is_array($v['sub'])) {
|
||
$output .= ' (' . trim($this->compileWhereClause($v['sub'], $functionMapping)) . ')';
|
||
} elseif (isset($v['func'])) {
|
||
$output .= ' ' . trim($v['modifier']) . ' ' . $v['func']['type'] . ' (' . $this->compileSELECT($v['func']['subquery']) . ')';
|
||
} else {
|
||
// Set field/table with modifying prefix if any:
|
||
... | ... | |
// Detecting value type; list or plain:
|
||
if (t3lib_div::inList('NOTIN,IN', strtoupper(str_replace(array(' ', "\t", "\r", "\n"), '', $v['comparator'])))) {
|
||
$valueBuffer = array();
|
||
foreach ($v['value'] as $realValue) {
|
||
$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
|
||
if (isset($v['subquery'])) {
|
||
$output .= ' (' . $this->compileSELECT($v['subquery']) . ')';
|
||
} else {
|
||
$valueBuffer = array();
|
||
foreach ($v['value'] as $realValue) {
|
||
$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
|
||
}
|
||
$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
|
||
}
|
||
$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
|
||
} else if (isset($v['value']['operator'])) {
|
||
} elseif (isset($v['value']['operator'])) {
|
||
$values = array();
|
||
foreach ($v['value']['args'] as $fieldDef) {
|
||
$values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
|
class.ux_t3lib_db.php (working copy) | ||
---|---|---|
**************************************/
|
||
/**
|
||
* Quotes components of a SELECT subquery.
|
||
*
|
||
* @param array $components Array of SQL query components
|
||
* @return array
|
||
*/
|
||
protected function quoteSELECTsubquery(array $components) {
|
||
$components['SELECT'] = $this->_quoteFieldNames($components['SELECT']);
|
||
$components['FROM'] = $this->_quoteFromTables($components['FROM']);
|
||
$components['WHERE'] = $this->_quoteWhereClause($components['WHERE']);
|
||
return $components;
|
||
}
|
||
/**
|
||
* Quotes field (and table) names with the quote character suitable for the DB being used
|
||
* Use quoteFieldNames instead!
|
||
*
|
||
... | ... | |
if ($this->runningNative()) return $select_fields;
|
||
$select_fields = $this->SQLparser->parseFieldList($select_fields);
|
||
$select_fields = $this->_quoteFieldNames($select_fields);
|
||
return $this->SQLparser->compileFieldList($select_fields);
|
||
}
|
||
/**
|
||
* Quotes field (and table) names in a SQL SELECT clause acccording to DB rules
|
||
*
|
||
* @param array $select_fields The parsed fields to quote
|
||
* @return array
|
||
* @see quoteFieldNames()
|
||
*/
|
||
protected function _quoteFieldNames(array $select_fields) {
|
||
foreach ($select_fields as $k => $v) {
|
||
if ($select_fields[$k]['field'] != '' && $select_fields[$k]['field'] != '*') {
|
||
$select_fields[$k]['field'] = $this->quoteName($select_fields[$k]['field']);
|
||
... | ... | |
}
|
||
}
|
||
return $this->SQLparser->compileFieldList($select_fields);
|
||
return $select_fields;
|
||
}
|
||
/**
|
||
... | ... | |
if ($this->runningNative()) return $from_table;
|
||
$from_table = $this->SQLparser->parseFromTables($from_table);
|
||
$from_table = $this->_quoteFromTables($from_table);
|
||
return $this->SQLparser->compileFromTables($from_table);
|
||
}
|
||
/**
|
||
* Quotes table names in a SQL FROM clause acccording to DB rules
|
||
*
|
||
* @param array $from_table The parsed FROM clause to quote
|
||
* @return array
|
||
* @see quoteFromTables()
|
||
*/
|
||
protected function _quoteFromTables(array $from_table) {
|
||
foreach ($from_table as $k => $v) {
|
||
$from_table[$k]['table'] = $this->quoteName($from_table[$k]['table']);
|
||
if ($from_table[$k]['as'] != '') {
|
||
... | ... | |
}
|
||
}
|
||
}
|
||
return $this->SQLparser->compileFromTables($from_table);
|
||
return $from_table;
|
||
}
|
||
/**
|
||
... | ... | |
* @return array
|
||
* @see quoteWhereClause()
|
||
*/
|
||
protected function _quoteWhereClause($where_clause) {
|
||
protected function _quoteWhereClause(array $where_clause) {
|
||
foreach ($where_clause as $k => $v) {
|
||
// Look for sublevel:
|
||
if (is_array($where_clause[$k]['sub'])) {
|
||
$where_clause[$k]['sub'] = $this->_quoteWhereClause($where_clause[$k]['sub']);
|
||
} else if (isset($v['func'])) {
|
||
$where_clause[$k]['func']['subquery'] = $this->quoteSELECTsubquery($v['func']['subquery']);
|
||
} else {
|
||
if ($where_clause[$k]['table'] != '') {
|
||
$where_clause[$k]['table'] = $this->quoteName($where_clause[$k]['table']);
|
||
... | ... | |
}
|
||
} else {
|
||
// Detecting value type; list or plain:
|
||
if ((!isset($where_clause[$k]['value'][1]) || $where_clause[$k]['value'][1] == '') && is_string($where_clause[$k]['value'][0]) && strstr($where_clause[$k]['value'][0], '.') && !t3lib_div::inList('NOTIN,IN',strtoupper(str_replace(array(" ","\n","\r","\t"),'',$where_clause[$k]['comparator'])))) {
|
||
$where_clause[$k]['value'][0] = $this->quoteFieldNames($where_clause[$k]['value'][0]);
|
||
if (t3lib_div::inList('NOTIN,IN', strtoupper(str_replace(array(' ',"\n", "\r", "\t"), '', $where_clause[$k]['comparator'])))) {
|
||
if (isset($v['subquery'])) {
|
||
$where_clause[$k]['subquery'] = $this->quoteSELECTsubquery($v['subquery']);
|
||
}
|
||
} else {
|
||
if ((!isset($where_clause[$k]['value'][1]) || $where_clause[$k]['value'][1] == '') && is_string($where_clause[$k]['value'][0]) && strstr($where_clause[$k]['value'][0], '.')) {
|
||
$where_clause[$k]['value'][0] = $this->quoteFieldNames($where_clause[$k]['value'][0]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
// Look for sublevel (WHERE parts only)
|
||
if (is_array($sqlPartArray[$k]['sub'])) {
|
||
$this->map_sqlParts($sqlPartArray[$k]['sub'], $defaultTable); // Call recursively!
|
||
} else if (isset($sqlPartArray[$k]['func'])) {
|
||
$subqueryDefaultTable = $sqlPartArray[$k]['func']['subquery']['FROM'][0]['table'];
|
||
$this->map_sqlParts($sqlPartArray[$k]['func']['subquery']['SELECT'], $subqueryDefaultTable);
|
||
$this->map_sqlParts($sqlPartArray[$k]['func']['subquery']['FROM'], $subqueryDefaultTable);
|
||
$this->map_sqlParts($sqlPartArray[$k]['func']['subquery']['WHERE'], $subqueryDefaultTable);
|
||
} else {
|
||
// For the field, look for table mapping (generic):
|
||
$t = $sqlPartArray[$k]['table'] ? $sqlPartArray[$k]['table'] : $defaultTable;
|
||
... | ... | |
}
|
||
}
|
||
// Do we have a subquery (WHERE parts only)?
|
||
if (isset($sqlPartArray[$k]['subquery'])) {
|
||
$subqueryDefaultTable = $sqlPartArray[$k]['subquery']['FROM'][0]['table'];
|
||
$this->map_sqlParts($sqlPartArray[$k]['subquery']['SELECT'], $subqueryDefaultTable);
|
||
$this->map_sqlParts($sqlPartArray[$k]['subquery']['FROM'], $subqueryDefaultTable);
|
||
$this->map_sqlParts($sqlPartArray[$k]['subquery']['WHERE'], $subqueryDefaultTable);
|
||
}
|
||
// do we have a field name in the value?
|
||
// this is a very simplistic check, beware
|
||
if (!is_numeric($sqlPartArray[$k]['value'][0]) && !isset($sqlPartArray[$k]['value'][1])) {
|
tests/fixtures/oci8.config.php (working copy) | ||
---|---|---|
'uid_local' => 'local_uid',
|
||
),
|
||
),
|
||
'tx_crawler_process' => array(
|
||
'mapTableName' => 'tx_crawler_ps',
|
||
'mapFieldNames' => array(
|
||
'process_id' => 'ps_id',
|
||
'active' => 'is_active',
|
||
),
|
||
),
|
||
'tx_dam_file_tracking' => array(
|
||
'mapFieldNames' => array(
|
||
'file_name' => 'filename',
|
tests/sqlparser_general_testcase.php (working copy) | ||
---|---|---|
$createTables = $this->fixture->_callRef('parseCREATETABLE', $parseString);
|
||
$this->assertTrue(is_array($createTables), $createTables);
|
||
}
|
||
///////////////////////////////////////
|
||
// Tests concerning subqueries
|
||
///////////////////////////////////////
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function inWhereClauseSupportsSubquery() {
|
||
$parseString = 'process_id IN (SELECT process_id FROM tx_crawler_process WHERE active=0 AND deleted=0)';
|
||
$whereParts = $this->fixture->parseWhereClause($parseString);
|
||
$this->assertTrue(is_array($whereParts), $whereParts);
|
||
$this->assertTrue(empty($parseString), 'parseString is not empty');
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function inWhereClauseWithSubqueryIsProperlyCompiled() {
|
||
$sql = 'SELECT * FROM tx_crawler_queue WHERE 1 = 1 AND process_id IN (SELECT process_id FROM tx_crawler_process WHERE active=0 AND deleted=0)';
|
||
$expected = 'SELECT * FROM tx_crawler_queue WHERE 1 = 1 AND process_id IN (SELECT process_id FROM tx_crawler_process WHERE active = 0 AND deleted = 0)';
|
||
$actual = $this->cleanSql($this->fixture->debug_testSQL($sql));
|
||
$this->assertEquals($expected, $actual);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function whereClauseSupportsExistsKeyword() {
|
||
$parseString = 'EXISTS (SELECT * FROM tx_crawler_queue WHERE tx_crawler_queue.process_id = tx_crawler_process.process_id AND tx_crawler_queue.exec_time = 0)';
|
||
$whereParts = $this->fixture->parseWhereClause($parseString);
|
||
$this->assertTrue(is_array($whereParts), $whereParts);
|
||
$this->assertTrue(empty($parseString), 'parseString is not empty');
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function existsClauseIsProperlyCompiled() {
|
||
$sql = 'SELECT * FROM tx_crawler_process WHERE active = 0 AND NOT EXISTS (SELECT * FROM tx_crawler_queue WHERE tx_crawler_queue.process_id = tx_crawler_process.process_id AND tx_crawler_queue.exec_time = 0)';
|
||
$expected = 'SELECT * FROM tx_crawler_process WHERE active = 0 AND NOT EXISTS (SELECT * FROM tx_crawler_queue WHERE tx_crawler_queue.process_id = tx_crawler_process.process_id AND tx_crawler_queue.exec_time = 0)';
|
||
$actual = $this->cleanSql($this->fixture->debug_testSQL($sql));
|
||
$this->assertEquals($expected, $actual);
|
||
}
|
||
}
|
||
?>
|
tests/db_oracle_testcase.php (working copy) | ||
---|---|---|
)
|
||
');
|
||
$this->assertEquals($expected, $this->cleanSql($sqlCommands[0]));
|
||
}
|
||
}
|
||
///////////////////////////////////////
|
||
// Tests concerning subqueries
|
||
///////////////////////////////////////
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function inWhereClauseWithSubqueryIsProperlyQuoted() {
|
||
$query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
|
||
'*',
|
||
'tx_crawler_queue',
|
||
'process_id IN (SELECT process_id FROM tx_crawler_process WHERE active=0 AND deleted=0)'
|
||
));
|
||
$expected = 'SELECT * FROM "tx_crawler_queue" WHERE "process_id" IN (SELECT "process_id" FROM "tx_crawler_process" WHERE "active" = 0 AND "deleted" = 0)';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function subqueryIsRemappedForInWhereClause() {
|
||
$selectFields = '*';
|
||
$fromTables = 'tx_crawler_queue';
|
||
$whereClause = 'process_id IN (SELECT process_id FROM tx_crawler_process WHERE active=0 AND deleted=0)';
|
||
$groupBy = '';
|
||
$orderBy = '';
|
||
$GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
|
||
$query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
|
||
$expected = 'SELECT * FROM "tx_crawler_queue" WHERE "process_id" IN (SELECT "ps_id" FROM "tx_crawler_ps" WHERE "is_active" = 0 AND "deleted" = 0)';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function existsWhereClauseIsProperlyQuoted() {
|
||
$query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
|
||
'*',
|
||
'tx_crawler_process',
|
||
'active = 0 AND NOT EXISTS (SELECT * FROM tx_crawler_queue WHERE tx_crawler_queue.process_id = tx_crawler_process.process_id AND tx_crawler_queue.exec_time = 0)'
|
||
));
|
||
$expected = 'SELECT * FROM "tx_crawler_process" WHERE "active" = 0 AND NOT EXISTS (SELECT * FROM "tx_crawler_queue" WHERE "tx_crawler_queue"."process_id" = "tx_crawler_process"."process_id" AND "tx_crawler_queue"."exec_time" = 0)';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=12758
|
||
*/
|
||
public function subqueryIsRemappedForExistsWhereClause() {
|
||
$selectFields = '*';
|
||
$fromTables = 'tx_crawler_process';
|
||
$whereClause = 'active = 0 AND NOT EXISTS (SELECT * FROM tx_crawler_queue WHERE tx_crawler_queue.process_id = tx_crawler_process.process_id AND tx_crawler_queue.exec_time = 0)';
|
||
$groupBy = '';
|
||
$orderBy = '';
|
||
$GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
|
||
$query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
|
||
$expected = 'SELECT * FROM "tx_crawler_ps" WHERE "is_active" = 0 AND NOT EXISTS (SELECT * FROM "tx_crawler_queue" WHERE "tx_crawler_queue"."process_id" = "tx_crawler_ps"."ps_id" AND "tx_crawler_queue"."exec_time" = 0)';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
}
|
||
?>
|