Fixed bug #6196: IFNULL operator cannot be parsed
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_sqlparser.php
index 03e2a99..e9561c0 100644 (file)
@@ -134,7 +134,7 @@ class t3lib_sqlparser {
 
                        // Finding starting keyword of string:
                $_parseString = $parseString;   // Protecting original string...
-               $keyword = $this->nextPart($_parseString, '^(SELECT|UPDATE|INSERT[[:space:]]+INTO|DELETE[[:space:]]+FROM|EXPLAIN|DROP[[:space:]]+TABLE|CREATE[[:space:]]+TABLE|CREATE[[:space:]]+DATABASE|ALTER[[:space:]]+TABLE)[[:space:]]+');
+               $keyword = $this->nextPart($_parseString, '^(SELECT|UPDATE|INSERT[[:space:]]+INTO|DELETE[[:space:]]+FROM|EXPLAIN|DROP[[:space:]]+TABLE|CREATE[[:space:]]+TABLE|CREATE[[:space:]]+DATABASE|ALTER[[:space:]]+TABLE|TRUNCATE[[:space:]]+TABLE)[[:space:]]+');
                $keyword = strtoupper(str_replace(array(' ',"\t","\r","\n"),'',$keyword));
 
                switch($keyword)        {
@@ -174,6 +174,10 @@ class t3lib_sqlparser {
                                        // Parsing CREATE DATABASE query:
                                $result = $this->parseCREATEDATABASE($parseString);
                        break;
+                       case 'TRUNCATETABLE':
+                                       // Parsing TRUNCATE TABLE query:
+                               $result = $this->parseTRUNCATETABLE($parseString);
+                       break;
                        default:
                                $result = $this->parseError('"'.$keyword.'" is not a keyword',$parseString);
                        break;
@@ -664,6 +668,38 @@ class t3lib_sqlparser {
                } else return $this->parseError('No database found!',$parseString);
        }
 
+       /**
+        * Parsing TRUNCATE TABLE query
+        * 
+        * @param       string          SQL string starting with TRUNCATE TABLE
+        * @return      mixed           Returns array with components of TRUNCATE TABLE query on success, otherwise an error message string.
+        */
+       protected function parseTRUNCATETABLE($parseString) {
+
+                       // Removing TRUNCATE TABLE
+               $parseString = $this->trimSQL($parseString);
+               $parseString = ltrim(substr(ltrim(substr($parseString, 8)), 5));
+
+                       // Init output variable:
+               $result = array();
+               $result['type'] = 'TRUNCATETABLE';
+
+                       // Get table:
+               $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+');
+
+               if ($result['TABLE']) {
+
+                               // Should be no more content now:
+                       if ($parseString) {
+                               return $this->parseError('Still content in clause after parsing!', $parseString);
+                       }
+
+                       return $result;
+               } else {
+                       return $this->parseError('No table found!', $parseString);
+               }
+       }
+
 
 
 
@@ -1030,7 +1066,30 @@ class t3lib_sqlparser {
                                                }
                                                if (!$this->nextPart($parseString, '^([)])')) {
                                                        return $this->parseError('No ) parenthesis at end of function');
-                                               }                                               
+                                               }
+                                       } elseif (preg_match('/^IFNULL[[:space:]]*[(]/i', $parseString)) {
+                                               $stack[$level][$pnt[$level]]['func']['type'] = $this->nextPart($parseString, '^(IFNULL)[[:space:]]*');
+                                               $parseString = trim(substr($parseString, 1));   // Strip of "("
+                                               if ($fieldName = $this->nextPart($parseString, '^([[:alnum:]\*._]+)[[:space:]]*')) {
+                                                               // Parse field name into field and table:
+                                                       $tableField = explode('.', $fieldName, 2);
+                                                       if (count($tableField) == 2) {
+                                                               $stack[$level][$pnt[$level]]['func']['table'] = $tableField[0];
+                                                               $stack[$level][$pnt[$level]]['func']['field'] = $tableField[1];
+                                                       } else {
+                                                               $stack[$level][$pnt[$level]]['func']['table'] = '';
+                                                               $stack[$level][$pnt[$level]]['func']['field'] = $tableField[0];
+                                                       }
+                                               } else {
+                                                       return $this->parseError('No field name found as expected in parseWhereClause()', $parseString);
+                                               }
+                                               if ($this->nextPart($parseString, '^(,)')) {
+                                                       $stack[$level][$pnt[$level]]['func']['default'] = $this->getValue($parseString);
+                                               }
+                                               if (!$this->nextPart($parseString, '^([)])')) {
+                                                       return $this->parseError('No ) parenthesis at end of function');
+                                               }
                                        } else {
 
                                                        // Support calculated value only for:
@@ -1460,6 +1519,9 @@ class t3lib_sqlparser {
                        case 'ALTERTABLE':
                                $query = $this->compileALTERTABLE($components);
                        break;
+                       case 'TRUNCATETABLE':
+                               $query = $this->compileTRUNCATETABLE($components);
+                       break;
                }
 
                return $query;
@@ -1652,6 +1714,22 @@ class t3lib_sqlparser {
                return $query;
        }
 
+       /**
+        * Compiles a TRUNCATE TABLE statement from components array
+        * 
+        * @param       array           Array of SQL query components
+        * @return      string          SQL TRUNCATE TABLE query
+        * @see parseTRUNCATETABLE()
+        */
+       protected function compileTRUNCATETABLE(array $components) {
+
+                       // Make query:
+               $query = 'TRUNCATE TABLE ' . $components['TABLE'];
+
+                       // Return query
+               return $query;
+       }
+
 
 
 
@@ -1830,6 +1908,11 @@ class t3lib_sqlparser {
                                                $output .= ', ' . ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
                                                $output .= isset($v['func']['pos']) ? ', ' . $v['func']['pos'][0] : '';
                                                $output .= ')';
+                                       } elseif (isset($v['func']) && $v['func']['type'] === 'IFNULL') {
+                                               $output = ' ' . trim($v['modifier']) . ' IFNULL(';
+                                               $output .= ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+                                               $output .= ', ' . $v['func']['default'][1] . $this->compileAddslashes($v['func']['default'][0]) . $v['func']['default'][1];
+                                               $output .= ')';
                                        } else {
                                                
                                                        // Set field/table with modifying prefix if any: