Fixed bug #11022: DBAL does not support SQL having "+" (used in cache management)
authorSteffen Kamper <info@sk-typo3.de>
Thu, 21 May 2009 07:59:05 +0000 (07:59 +0000)
committerSteffen Kamper <info@sk-typo3.de>
Thu, 21 May 2009 07:59:05 +0000 (07:59 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@5465 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/cache/backend/class.t3lib_cache_backend_dbbackend.php
t3lib/class.t3lib_sqlparser.php
typo3/sysext/dbal/class.ux_t3lib_sqlparser.php

index c306cb0..c061dcc 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2009-05-20  Steffen Kamper  <info@sk-typo3.de>
 
+       * Fixed bug #11022: DBAL does not support SQL having "+" (used in cache management)
        * Fixed bug #8231: DBAL's bug admin_get_charsets() on a non-object
 
 2009-05-20  Oliver Hader  <oliver@typo3.org>
index 51652cb..796a3e4 100644 (file)
@@ -93,7 +93,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
                        'content',
                        $this->cacheTable,
                        'identifier = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($entryIdentifier, $this->cacheTable) . ' '
-                               . 'AND ((crdate + lifetime) >= ' . time() . ' OR lifetime = 0)'
+                               . 'AND (crdate + lifetime >= ' . time() . ' OR lifetime = 0)'
                );
 
                if (count($cacheEntries) == 1) {
@@ -117,7 +117,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
                        'content',
                        $this->cacheTable,
                        'identifier = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($entryIdentifier, $this->cacheTable) . ' '
-                               . 'AND (crdate + lifetime) >= ' . time()
+                               . 'AND crdate + lifetime >= ' . time()
                );
 
                if (count($cacheEntries) == 1) {
@@ -163,7 +163,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
                $cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
                        'identifier',
                        $this->cacheTable,
-                       $this->getListQueryForTag($tag) . ' AND ((crdate + lifetime) >= ' . time() . ' OR lifetime = 0)'
+                       $this->getListQueryForTag($tag) . ' AND (crdate + lifetime >= ' . time() . ' OR lifetime = 0)'
                );
 
                foreach ($cacheEntryIdentifierRows as $cacheEntryIdentifierRow) {
@@ -188,7 +188,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
                foreach ($tags as $tag) {
                        $whereClause[] = $this->getListQueryForTag($tag);
                }
-               $whereClause[] = '((crdate + lifetime) >= ' . time() . ' OR lifetime = 0)';
+               $whereClause[] = '(crdate + lifetime >= ' . time() . ' OR lifetime = 0)';
 
                $cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
                        'identifier',
@@ -248,7 +248,7 @@ class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend
        public function collectGarbage() {
                $GLOBALS['TYPO3_DB']->exec_DELETEquery(
                        $this->cacheTable,
-                       '(crdate + lifetime) < ' . time()
+                       'crdate + lifetime < ' . time()
                );
        }
 
index ab71b8f..e2078c4 100644 (file)
@@ -905,8 +905,17 @@ class t3lib_sqlparser {
                                        // Find "modifyer", 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:]]+|&|<=|>=|<|>|=|!=|IS)'))   {
+                               if ($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)([[:space:]]+|' . $calcOperators . '|<=|>=|<|>|=|!=|IS)')) {
 
                                                // Parse field name into field and table:
                                        $tableField = explode('.',$fieldName,2);
@@ -921,8 +930,8 @@ class t3lib_sqlparser {
                                        return $this->parseError('No field name found as expected in parseWhereClause()',$parseString);
                                }
 
-                                       // See if the value is calculated. Support only for "&" (boolean AND) at the moment:
-                               $stack[$level][$pnt[$level]]['calc'] = $this->nextPart($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);
@@ -953,8 +962,10 @@ class t3lib_sqlparser {
                                }
 
                                        // Detecting the operator for the next level:
-                               $op = $this->nextPart($parseString,'^(AND[[:space:]]+NOT|OR[[:space:]]+NOT|AND|OR)(\(|[[:space:]]+)');
+                               $op = $this->nextPart($parseString, '^(AND[[:space:]]+NOT|&&[[:space:]]+NOT|OR[[:space:]]+NOT|OR[[:space:]]+NOT|\|\|[[:space:]]+NOT|AND|&&|OR|\|\|)(\(|[[:space:]]+)');
                                if ($op)        {
+                                               // Normalize boolean operator
+                                       $op = str_replace(array('&&', '||'), array('AND', 'OR'), $op);
                                        $stack[$level][$pnt[$level]]['operator'] = $op;
                                } elseif (strlen($parseString)) {
 
index e0f343e..226d693 100644 (file)
@@ -302,8 +302,13 @@ class ux_t3lib_sqlparser extends t3lib_sqlparser {
        /**
         * Implodes an array of WHERE clause configuration into a WHERE clause.
         *
-        * DBAL-specific: The only(!) handled "calc" operator supported by parseWhereClause() is the bitwise
-        * logical and (&), and only this one is supported here!
+        * DBAL-specific: The only(!) handled "calc" operators supported by parseWhereClause() are:
+        * - the bitwise logical and (&)
+        * - the addition (+)
+        * - the substraction (-)
+        * - the multiplication (*)
+        * - the division (/)
+        * - the modulo (%)
         *
         * @param       array           WHERE clause configuration
         * @return      string          WHERE clause as string.
@@ -334,7 +339,7 @@ class ux_t3lib_sqlparser extends t3lib_sqlparser {
                                                        $output.=' '.trim($v['modifier']).' ';
 
                                                        // DBAL-specific: Set calculation, if any:
-                                                       if ($v['calc'] && $functionMapping)     {
+                                                       if ($v['calc'] === '&' && $functionMapping) {
                                                                switch(true) {
                                                                        case $GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8'):
                                                                                        // Oracle only knows BITAND(x,y) - sigh