Bug #22640 » 14372_v3.diff
class.ux_t3lib_db.php (working copy) | ||
---|---|---|
protected function map_assocArray($input, $tables, $rev = FALSE) {
|
||
// Traverse tables from query (hopefully only one table):
|
||
foreach ($tables as $tableCfg) {
|
||
if (is_array($this->mapping[$tableCfg['table']]['mapFieldNames'])) {
|
||
$tableKey = $this->getMappingKey($tableCfg['table']);
|
||
if (is_array($this->mapping[$tableKey]['mapFieldNames'])) {
|
||
// Get the map (reversed if needed):
|
||
if ($rev) {
|
||
$theMap = array_flip($this->mapping[$tableCfg['table']]['mapFieldNames']);
|
||
$theMap = array_flip($this->mapping[$tableKey]['mapFieldNames']);
|
||
} else {
|
||
$theMap = $this->mapping[$tableCfg['table']]['mapFieldNames'];
|
||
$theMap = $this->mapping[$tableKey]['mapFieldNames'];
|
||
}
|
||
// Traverse selected record, map fieldnames:
|
||
... | ... | |
* @see exec_SELECTquery()
|
||
*/
|
||
protected function map_remapSELECTQueryParts(&$select_fields, &$from_table, &$where_clause, &$groupBy, &$orderBy) {
|
||
// Backup current mapping as it may be altered if aliases on mapped tables are found
|
||
$backupMapping = $this->mapping;
|
||
// Tables:
|
||
$tables = $this->SQLparser->parseFromTables($from_table);
|
||
$defaultTable = $tables[0]['table'];
|
||
// Prepare mapping for aliased tables. This will copy the definition of the original table name.
|
||
// The alias is prefixed with a database-incompatible character to prevent naming clash with real table name
|
||
// Further access to $this->mapping should be made through $this->getMappingKey() method
|
||
foreach ($tables as $k => $v) {
|
||
if ($this->mapping[$v['table']]['mapTableName']) {
|
||
$tables[$k]['table'] = $this->mapping[$v['table']]['mapTableName'];
|
||
if ($v['as'] && is_array($this->mapping[$v['table']]['mapFieldNames'])) {
|
||
$mappingKey = $this->getFreeMappingKey($v['as']);
|
||
$this->mapping[$mappingKey]['mapFieldNames'] =& $this->mapping[$v['table']]['mapFieldNames'];
|
||
}
|
||
if (is_array($v['JOIN'])) {
|
||
foreach ($v['JOIN'] as $joinCnt => $join) {
|
||
if ($join['as'] && is_array($this->mapping[$join['withTable']]['mapFieldNames'])) {
|
||
$mappingKey = $this->getFreeMappingKey($join['as']);
|
||
$this->mapping[$mappingKey]['mapFieldNames'] =& $this->mapping[$join['withTable']]['mapFieldNames'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
foreach ($tables as $k => $v) {
|
||
$tableKey = $this->getMappingKey($v['table']);
|
||
if ($this->mapping[$tableKey]['mapTableName']) {
|
||
$tables[$k]['table'] = $this->mapping[$tableKey]['mapTableName'];
|
||
}
|
||
// Mapping JOINS
|
||
if (is_array($v['JOIN'])) {
|
||
foreach($v['JOIN'] as $joinCnt => $join) {
|
||
// Mapping withTable of the JOIN
|
||
if ($this->mapping[$join['withTable']]['mapTableName']) {
|
||
$tables[$k]['JOIN'][$joinCnt]['withTable'] = $this->mapping[$join['withTable']]['mapTableName'];
|
||
$withTableKey = $this->getMappingKey($join['withTable']);
|
||
if ($this->mapping[$withTableKey]['mapTableName']) {
|
||
$tables[$k]['JOIN'][$joinCnt]['withTable'] = $this->mapping[$withTableKey]['mapTableName'];
|
||
}
|
||
$onPartsArray = array();
|
||
// Mapping ON parts of the JOIN
|
||
if (is_array($tables[$k]['JOIN'][$joinCnt]['ON'])) {
|
||
foreach ($tables[$k]['JOIN'][$joinCnt]['ON'] as &$condition) {
|
||
// Left side of the comparator
|
||
if (isset($this->mapping[$condition['left']['table']]['mapFieldNames'][$condition['left']['field']])) {
|
||
$condition['left']['field'] = $this->mapping[$condition['left']['table']]['mapFieldNames'][$condition['left']['field']];
|
||
$leftTableKey = $this->getMappingKey($condition['left']['table']);
|
||
if (isset($this->mapping[$leftTableKey]['mapFieldNames'][$condition['left']['field']])) {
|
||
$condition['left']['field'] = $this->mapping[$leftTableKey]['mapFieldNames'][$condition['left']['field']];
|
||
}
|
||
if (isset($this->mapping[$condition['left']['table']]['mapTableName'])) {
|
||
$condition['left']['table'] = $this->mapping[$condition['left']['table']]['mapTableName'];
|
||
if (isset($this->mapping[$leftTableKey]['mapTableName'])) {
|
||
$condition['left']['table'] = $this->mapping[$leftTableKey]['mapTableName'];
|
||
}
|
||
// Right side of the comparator
|
||
if (isset($this->mapping[$condition['right']['table']]['mapFieldNames'][$condition['right']['field']])) {
|
||
$condition['right']['field'] = $this->mapping[$condition['right']['table']]['mapFieldNames'][$condition['right']['field']];
|
||
$rightTableKey = $this->getMappingKey($condition['right']['table']);
|
||
if (isset($this->mapping[$rightTableKey]['mapFieldNames'][$condition['right']['field']])) {
|
||
$condition['right']['field'] = $this->mapping[$rightTableKey]['mapFieldNames'][$condition['right']['field']];
|
||
}
|
||
if (isset($this->mapping[$condition['right']['table']]['mapTableName'])) {
|
||
$condition['right']['table'] = $this->mapping[$condition['right']['table']]['mapTableName'];
|
||
if (isset($this->mapping[$rightTableKey]['mapTableName'])) {
|
||
$condition['right']['table'] = $this->mapping[$rightTableKey]['mapTableName'];
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
$expFields = $this->SQLparser->parseFieldList($orderBy);
|
||
$this->map_sqlParts($expFields,$defaultTable);
|
||
$orderBy = $this->SQLparser->compileFieldList($expFields);
|
||
// Restore the original mapping
|
||
$this->mapping = $backupMapping;
|
||
}
|
||
/**
|
||
* Returns the key to be used when retrieving information from $this->mapping. This ensures
|
||
* that mapping from aliased tables is properly retrieved.
|
||
*
|
||
* @param string $tableName
|
||
* @return string
|
||
*/
|
||
protected function getMappingKey($tableName) {
|
||
// Search deepest alias mapping
|
||
while (isset($this->mapping['*' . $tableName])) {
|
||
$tableName = '*' . $tableName;
|
||
}
|
||
return $tableName;
|
||
}
|
||
/**
|
||
* Returns a free key to be used to store mapping information in $this->mapping.
|
||
*
|
||
* @param string $tableName
|
||
* @return string
|
||
*/
|
||
protected function getFreeMappingKey($tableName) {
|
||
while (isset($this->mapping[$tableName])) {
|
||
$tableName = '*' . $tableName;
|
||
}
|
||
return $tableName;
|
||
}
|
||
/**
|
||
* Generic mapping of table/field names arrays (as parsed by tx_dbal_sqlengine)
|
||
*
|
||
* @param array Array with parsed SQL parts; Takes both fields, tables, where-parts, group and order-by. Passed by reference.
|
||
... | ... | |
* @see map_remapSELECTQueryParts()
|
||
*/
|
||
protected function map_sqlParts(&$sqlPartArray, $defaultTable) {
|
||
$defaultTableKey = $this->getMappingKey($defaultTable);
|
||
// Traverse sql Part array:
|
||
if (is_array($sqlPartArray)) {
|
||
foreach ($sqlPartArray as $k => $v) {
|
||
... | ... | |
case 'CASE':
|
||
if (isset($sqlPartArray[$k]['case_field'])) {
|
||
$fieldArray = explode('.', $sqlPartArray[$k]['case_field']);
|
||
if (count($fieldArray) == 1 && is_array($this->mapping[$defaultTable]['mapFieldNames']) && isset($this->mapping[$defaultTable]['mapFieldNames'][$fieldArray[0]])) {
|
||
$sqlPartArray[$k]['case_field'] = $this->mapping[$defaultTable]['mapFieldNames'][$fieldArray[0]];
|
||
if (count($fieldArray) == 1 && is_array($this->mapping[$defaultTableKey]['mapFieldNames']) && isset($this->mapping[$defaultTableKey]['mapFieldNames'][$fieldArray[0]])) {
|
||
$sqlPartArray[$k]['case_field'] = $this->mapping[$defaultTableKey]['mapFieldNames'][$fieldArray[0]];
|
||
}
|
||
elseif (count($fieldArray) == 2) {
|
||
// Map the external table
|
||
$table = $fieldArray[0];
|
||
if (isset($this->mapping[$fieldArray[0]]['mapTableName'])) {
|
||
$table = $this->mapping[$fieldArray[0]]['mapTableName'];
|
||
$tableKey = $this->getMappingKey($table);
|
||
if (isset($this->mapping[$tableKey]['mapTableName'])) {
|
||
$table = $this->mapping[$tableKey]['mapTableName'];
|
||
}
|
||
// Map the field itself
|
||
$field = $fieldArray[1];
|
||
if (is_array($this->mapping[$fieldArray[0]]['mapFieldNames']) && isset($this->mapping[$fieldArray[0]]['mapFieldNames'][$fieldArray[1]])) {
|
||
$field = $this->mapping[$fieldArray[0]]['mapFieldNames'][$fieldArray[1]];
|
||
if (is_array($this->mapping[$tableKey]['mapFieldNames']) && isset($this->mapping[$tableKey]['mapFieldNames'][$fieldArray[1]])) {
|
||
$field = $this->mapping[$tableKey]['mapFieldNames'][$fieldArray[1]];
|
||
}
|
||
$sqlPartArray[$k]['case_field'] = $table . '.' . $field;
|
||
}
|
||
... | ... | |
} elseif (isset($sqlPartArray[$k]['func'])) {
|
||
switch ($sqlPartArray[$k]['func']['type']) {
|
||
case 'EXISTS':
|
||
$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);
|
||
$this->map_subquery($sqlPartArray[$k]['func']['subquery']);
|
||
break;
|
||
case 'IFNULL':
|
||
case 'LOCATE':
|
||
// For the field, look for table mapping (generic):
|
||
$t = $sqlPartArray[$k]['func']['table'] ? $sqlPartArray[$k]['func']['table'] : $defaultTable;
|
||
$t = $this->getMappingKey($t);
|
||
if (is_array($this->mapping[$t]['mapFieldNames']) && $this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['func']['field']]) {
|
||
$sqlPartArray[$k]['func']['field'] = $this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['func']['field']];
|
||
}
|
||
... | ... | |
} else {
|
||
// For the field, look for table mapping (generic):
|
||
$t = $sqlPartArray[$k]['table'] ? $sqlPartArray[$k]['table'] : $defaultTable;
|
||
$t = $this->getMappingKey($t);
|
||
// Mapping field name, if set:
|
||
if (is_array($this->mapping[$t]['mapFieldNames']) && isset($this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['field']])) {
|
||
... | ... | |
elseif (count($fieldArray) == 2) {
|
||
// Map the external table
|
||
$table = $fieldArray[0];
|
||
if (isset($this->mapping[$fieldArray[0]]['mapTableName'])) {
|
||
$table = $this->mapping[$fieldArray[0]]['mapTableName'];
|
||
$tableKey = $this->getMappingKey($table);
|
||
if (isset($this->mapping[$tableKey]['mapTableName'])) {
|
||
$table = $this->mapping[$tableKey]['mapTableName'];
|
||
}
|
||
// Map the field itself
|
||
$field = $fieldArray[1];
|
||
if (is_array($this->mapping[$fieldArray[0]]['mapFieldNames']) && isset($this->mapping[$fieldArray[0]]['mapFieldNames'][$fieldArray[1]])) {
|
||
$field = $this->mapping[$fieldArray[0]]['mapFieldNames'][$fieldArray[1]];
|
||
if (is_array($this->mapping[$tableKey]['mapFieldNames']) && isset($this->mapping[$tableKey]['mapFieldNames'][$fieldArray[1]])) {
|
||
$field = $this->mapping[$tableKey]['mapFieldNames'][$fieldArray[1]];
|
||
}
|
||
$sqlPartArray[$k]['func_content.'][0]['func_content'] = $table . '.' . $field;
|
||
$sqlPartArray[$k]['func_content'] = $table . '.' . $field;
|
||
... | ... | |
// Do we have a function (e.g., CONCAT)
|
||
if (isset($v['value']['operator'])) {
|
||
foreach ($sqlPartArray[$k]['value']['args'] as $argK => $fieldDef) {
|
||
if (isset($this->mapping[$fieldDef['table']]['mapTableName'])) {
|
||
$sqlPartArray[$k]['value']['args'][$argK]['table'] = $this->mapping[$fieldDef['table']]['mapTableName'];
|
||
$tableKey = $this->getMappingKey($fieldDef['table']);
|
||
if (isset($this->mapping[$tableKey]['mapTableName'])) {
|
||
$sqlPartArray[$k]['value']['args'][$argK]['table'] = $this->mapping[$tableKey]['mapTableName'];
|
||
}
|
||
if (is_array($this->mapping[$fieldDef['table']]['mapFieldNames']) && isset($this->mapping[$fieldDef['table']]['mapFieldNames'][$fieldDef['field']])) {
|
||
$sqlPartArray[$k]['value']['args'][$argK]['field'] = $this->mapping[$fieldDef['table']]['mapFieldNames'][$fieldDef['field']];
|
||
if (is_array($this->mapping[$tableKey]['mapFieldNames']) && isset($this->mapping[$tableKey]['mapFieldNames'][$fieldDef['field']])) {
|
||
$sqlPartArray[$k]['value']['args'][$argK]['field'] = $this->mapping[$tableKey]['mapFieldNames'][$fieldDef['field']];
|
||
}
|
||
}
|
||
}
|
||
// 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);
|
||
$this->map_subquery($sqlPartArray[$k]['subquery']);
|
||
}
|
||
// do we have a field name in the value?
|
||
... | ... | |
} elseif (count($fieldArray) == 2) {
|
||
// Map the external table
|
||
$table = $fieldArray[0];
|
||
if (isset($this->mapping[$fieldArray[0]]['mapTableName'])) {
|
||
$table = $this->mapping[$fieldArray[0]]['mapTableName'];
|
||
$tableKey = $this->getMappingKey($table);
|
||
if (isset($this->mapping[$tableKey]['mapTableName'])) {
|
||
$table = $this->mapping[$tableKey]['mapTableName'];
|
||
}
|
||
// Map the field itself
|
||
$field = $fieldArray[1];
|
||
if (is_array($this->mapping[$fieldArray[0]]['mapFieldNames']) && isset($this->mapping[$fieldArray[0]]['mapFieldNames'][$fieldArray[1]])) {
|
||
$field = $this->mapping[$fieldArray[0]]['mapFieldNames'][$fieldArray[1]];
|
||
if (is_array($this->mapping[$tableKey]['mapFieldNames']) && isset($this->mapping[$tableKey]['mapFieldNames'][$fieldArray[1]])) {
|
||
$field = $this->mapping[$tableKey]['mapFieldNames'][$fieldArray[1]];
|
||
}
|
||
$sqlPartArray[$k]['value'][0] = $table . '.' . $field;
|
||
}
|
||
}
|
||
// Map table?
|
||
if ($sqlPartArray[$k]['table'] && $this->mapping[$sqlPartArray[$k]['table']]['mapTableName']) {
|
||
$sqlPartArray[$k]['table'] = $this->mapping[$sqlPartArray[$k]['table']]['mapTableName'];
|
||
$tableKey = $this->getMappingKey($sqlPartArray[$k]['table']);
|
||
if ($sqlPartArray[$k]['table'] && $this->mapping[$tableKey]['mapTableName']) {
|
||
$sqlPartArray[$k]['table'] = $this->mapping[$tableKey]['mapTableName'];
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
}
|
||
/**
|
||
* Maps table and field names in a subquery.
|
||
*
|
||
* @param array $parsedQuery
|
||
* @return void
|
||
*/
|
||
protected function map_subquery(&$parsedQuery) {
|
||
// Backup current mapping as it may be altered
|
||
$backupMapping = $this->mapping;
|
||
foreach ($parsedQuery['FROM'] as $k => $v) {
|
||
$mappingKey = $v['table'];
|
||
if ($v['as'] && is_array($this->mapping[$v['table']]['mapFieldNames'])) {
|
||
$mappingKey = $this->getFreeMappingKey($v['as']);
|
||
} else {
|
||
// Should ensure that no alias is defined in the external query
|
||
// which would correspond to a real table name in the subquery
|
||
if ($this->getMappingKey($v['table']) !== $v['table']) {
|
||
$mappingKey = $this->getFreeMappingKey($v['table']);
|
||
// This is the only case when 'mapTableName' should be copied
|
||
$this->mapping[$mappingKey]['mapTableName'] =& $this->mapping[$v['table']]['mapTableName'];
|
||
}
|
||
}
|
||
if ($mapping !== $v['table']) {
|
||
$this->mapping[$mappingKey]['mapFieldNames'] =& $this->mapping[$v['table']]['mapFieldNames'];
|
||
}
|
||
}
|
||
// Perform subquery's remapping
|
||
$defaultTable = $parsedQuery['FROM'][0]['table'];
|
||
$this->map_sqlParts($parsedQuery['SELECT'], $defaultTable);
|
||
$this->map_sqlParts($parsedQuery['FROM'], $defaultTable);
|
||
$this->map_sqlParts($parsedQuery['WHERE'], $defaultTable);
|
||
// Restore the mapping
|
||
$this->mapping = $backupMapping;
|
||
}
|
||
/**
|
||
* Will do table/field mapping on a general tx_dbal_sqlengine-compliant SQL query
|
||
* (May still not support all query types...)
|
||
*
|
tests/fixtures/oci8.config.php (working copy) | ||
---|---|---|
'pid' => 'page_id',
|
||
),
|
||
),
|
||
'pages' => array(
|
||
'mapTableName' => 'my_pages',
|
||
'mapFieldNames' => array(
|
||
'uid' => 'page_uid',
|
||
),
|
||
),
|
||
'tt_news' => array(
|
||
'mapTableName' => 'ext_tt_news',
|
||
'mapFieldNames' => array(
|
tests/db_oracle_testcase.php (working copy) | ||
---|---|---|
$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 "cpg_categories"."uid", "cpg_categories"."name" FROM "cpg_categories", "pages" WHERE "pages"."uid" = "cpg_categories"."page_id"';
|
||
$expected .= ' AND "pages"."deleted" = 0 AND 1 = 1 ORDER BY "cpg_categories"."pos"';
|
||
$expected = 'SELECT "cpg_categories"."uid", "cpg_categories"."name" FROM "cpg_categories", "my_pages" WHERE "my_pages"."page_uid" = "cpg_categories"."page_id"';
|
||
$expected .= ' AND "my_pages"."deleted" = 0 AND 1 = 1 ORDER BY "cpg_categories"."pos"';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function fieldFromAliasIsRemapped() {
|
||
$selectFields = 'news.uid';
|
||
$fromTables = 'tt_news AS news';
|
||
$whereClause = 'news.uid = 1';
|
||
$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 "news"."news_uid" FROM "ext_tt_news" AS "news" WHERE "news"."news_uid" = 1';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* Trick here is that we already have a mapping for both table tt_news and table tt_news_cat
|
||
* (see tests/fixtures/oci8.config.php) which is used as alias name.
|
||
*
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function fieldFromAliasIsRemappedWithoutBeingTricked() {
|
||
$selectFields = 'tt_news_cat.uid';
|
||
$fromTables = 'tt_news AS tt_news_cat';
|
||
$whereClause = 'tt_news_cat.uid = 1';
|
||
$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 "tt_news_cat"."news_uid" FROM "ext_tt_news" AS "tt_news_cat" WHERE "tt_news_cat"."news_uid" = 1';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function aliasRemappingDoesNotAlterFurtherQueries() {
|
||
$selectFields = 'foo.uid';
|
||
$fromTables = 'tt_news AS foo';
|
||
$whereClause = 'foo.uid = 1';
|
||
$groupBy = '';
|
||
$orderBy = '';
|
||
// First call to possibly alter (in memory) the mapping from localconf.php
|
||
$GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
|
||
$selectFields = 'uid';
|
||
$fromTables = 'foo';
|
||
$whereClause = 'uid = 1';
|
||
$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 "uid" FROM "foo" WHERE "uid" = 1';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function fieldFromAliasInJoinIsRemapped() {
|
||
$selectFields = 'cat.uid, cat_mm.uid_local, news.uid';
|
||
$fromTables = 'tt_news_cat AS cat' .
|
||
' INNER JOIN tt_news_cat_mm AS cat_mm ON cat.uid = cat_mm.uid_foreign' .
|
||
' INNER JOIN tt_news AS news ON news.uid = cat_mm.uid_local';
|
||
$whereClause = '1=1';
|
||
$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 "cat"."cat_uid", "cat_mm"."local_uid", "news"."news_uid"';
|
||
$expected .= ' FROM "ext_tt_news_cat" AS "cat"';
|
||
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" AS "cat_mm" ON "cat"."cat_uid"="cat_mm"."uid_foreign"';
|
||
$expected .= ' INNER JOIN "ext_tt_news" AS "news" ON "news"."news_uid"="cat_mm"."local_uid"';
|
||
$expected .= ' WHERE 1 = 1';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function aliasRemappingWithInSubqueryDoesNotAffectMainQuery() {
|
||
$selectFields = 'foo.uid';
|
||
$fromTables = 'tt_news AS foo INNER JOIN tt_news_cat_mm ON tt_news_cat_mm.uid_local = foo.uid';
|
||
$whereClause = 'tt_news_cat_mm.uid_foreign IN (SELECT foo.uid FROM tt_news_cat AS foo WHERE foo.hidden = 0)';
|
||
$groupBy = '';
|
||
$orderBy = 'foo.uid';
|
||
$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 "foo"."news_uid" FROM "ext_tt_news" AS "foo"';
|
||
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" ON "ext_tt_news_cat_mm"."local_uid"="foo"."news_uid"';
|
||
$expected .= ' WHERE "ext_tt_news_cat_mm"."uid_foreign" IN (';
|
||
$expected .= 'SELECT "foo"."cat_uid" FROM "ext_tt_news_cat" AS "foo" WHERE "foo"."hidden" = 0';
|
||
$expected .= ')';
|
||
$expected .= ' ORDER BY "foo"."news_uid"';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function aliasRemappingWithExistsSubqueryDoesNotAffectMainQuery() {
|
||
$selectFields = 'foo.uid';
|
||
$fromTables = 'tt_news AS foo INNER JOIN tt_news_cat_mm ON tt_news_cat_mm.uid_local = foo.uid';
|
||
$whereClause = 'EXISTS (SELECT foo.uid FROM tt_news_cat AS foo WHERE foo.hidden = 0)';
|
||
$groupBy = '';
|
||
$orderBy = 'foo.uid';
|
||
$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 "foo"."news_uid" FROM "ext_tt_news" AS "foo"';
|
||
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" ON "ext_tt_news_cat_mm"."local_uid"="foo"."news_uid"';
|
||
$expected .= ' WHERE EXISTS (';
|
||
$expected .= 'SELECT "foo"."cat_uid" FROM "ext_tt_news_cat" AS "foo" WHERE "foo"."hidden" = 0';
|
||
$expected .= ')';
|
||
$expected .= ' ORDER BY "foo"."news_uid"';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function aliasRemappingSupportsNestedSubqueries() {
|
||
$selectFields = 'foo.uid';
|
||
$fromTables = 'tt_news AS foo';
|
||
$whereClause = 'uid IN (' .
|
||
'SELECT foobar.uid_local FROM tt_news_cat_mm AS foobar WHERE uid_foreign IN (' .
|
||
'SELECT uid FROM tt_news_cat WHERE 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 "foo"."news_uid" FROM "ext_tt_news" AS "foo"';
|
||
$expected .= ' WHERE "news_uid" IN (';
|
||
$expected .= 'SELECT "foobar"."local_uid" FROM "ext_tt_news_cat_mm" AS "foobar" WHERE "uid_foreign" IN (';
|
||
$expected .= 'SELECT "cat_uid" FROM "ext_tt_news_cat" WHERE "deleted" = 0';
|
||
$expected .= ')';
|
||
$expected .= ')';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
/**
|
||
* @test
|
||
* @see http://bugs.typo3.org/view.php?id=14372
|
||
*/
|
||
public function remappingDoesNotMixUpAliasesInSubquery() {
|
||
$selectFields = 'pages.uid';
|
||
$fromTables = 'tt_news AS pages INNER JOIN tt_news_cat_mm AS cat_mm ON cat_mm.uid_local = pages.uid';
|
||
$whereClause = 'pages.pid IN (SELECT uid FROM pages WHERE deleted = 0 AND cat_mm.uid_local != 100)';
|
||
$groupBy = '';
|
||
$orderBy = 'pages.uid';
|
||
$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 "pages"."news_uid" FROM "ext_tt_news" AS "pages"';
|
||
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" AS "cat_mm" ON "cat_mm"."local_uid"="pages"."news_uid"';
|
||
$expected .= ' WHERE "pages"."pid" IN (';
|
||
$expected .= 'SELECT "page_uid" FROM "my_pages" WHERE "deleted" = 0 AND "cat_mm"."local_uid" != 100';
|
||
$expected .= ')';
|
||
$expected .= ' ORDER BY "pages"."news_uid"';
|
||
$this->assertEquals($expected, $query);
|
||
}
|
||
///////////////////////////////////////
|
||
// Tests concerning DB management
|
||
///////////////////////////////////////
|
- « Previous
- 1
- 2
- 3
- Next »