Просмотр исходного кода

Merge pull request #441 from Mayflower/nested-sql-functions

Loosen regex to allow nested function calls in SQL
Frank Brückner 11 лет назад
Родитель
Сommit
e78669d5a5
2 измененных файлов с 23 добавлено и 3 удалено
  1. 3 3
      library/Zend/Db/Select.php
  2. 20 0
      tests/Zend/Db/Select/StaticTest.php

+ 3 - 3
library/Zend/Db/Select.php

@@ -509,7 +509,7 @@ class Zend_Db_Select
         }
 
         foreach ($spec as $val) {
-            if (preg_match('/^[\w]*\([^\)]*\)$/', (string) $val)) {
+            if (preg_match('/^([\w]*\(([^\)]|(?1))*\))$/', (string) $val)) {
                 $val = new Zend_Db_Expr($val);
             }
             $this->_parts[self::GROUP][] = $val;
@@ -601,7 +601,7 @@ class Zend_Db_Select
                     $val = trim($matches[1]);
                     $direction = $matches[2];
                 }
-                if (preg_match('/^[\w]*\([^\)]*\)$/', $val)) {
+                if (preg_match('/^([\w]*\(([^\)]|(?1))*\))$/', (string) $val)) {
                     $val = new Zend_Db_Expr($val);
                 }
                 $this->_parts[self::ORDER][] = array($val, $direction);
@@ -943,7 +943,7 @@ class Zend_Db_Select
                     $alias = $m[2];
                 }
                 // Check for columns that look like functions and convert to Zend_Db_Expr
-                if (preg_match('/^[\w]*\([^\)]*\)$/', $col)) {
+                if (preg_match('/^([\w]*\(([^\)]|(?1))*\))$/', (string) $col)) {
                     $col = new Zend_Db_Expr($col);
                 } elseif (preg_match('/(.+)\.(.+)/', $col, $m)) {
                     $currentCorrelationName = $m[1];

+ 20 - 0
tests/Zend/Db/Select/StaticTest.php

@@ -854,6 +854,26 @@ class Zend_Db_Select_StaticTest extends Zend_Db_Select_TestCommon
         $this->assertEquals('SELECT "p"."MD5(1); drop table products; -- )" FROM "products" AS "p"', $select->assemble());
     }
 
+    public function testIfInColumn()
+    {
+        $select = $this->_db->select();
+        $select->from('table1', '*');
+        $select->join(array('table2'),
+                      'table1.id = table2.id',
+                      array('bar' => 'IF(table2.id IS NOT NULL, 1, 0)'));
+        $this->assertEquals("SELECT \"table1\".*, IF(table2.id IS NOT NULL, 1, 0) AS \"bar\" FROM \"table1\"\n INNER JOIN \"table2\" ON table1.id = table2.id", $select->assemble());
+    }
+
+    public function testNestedIfInColumn()
+    {
+        $select = $this->_db->select();
+        $select->from('table1', '*');
+        $select->join(array('table2'),
+            'table1.id = table2.id',
+            array('bar' => 'IF(table2.id IS NOT NULL, IF(table2.id2 IS NOT NULL, 1, 2), 0)'));
+        $this->assertEquals("SELECT \"table1\".*, IF(table2.id IS NOT NULL, IF(table2.id2 IS NOT NULL, 1, 2), 0) AS \"bar\" FROM \"table1\"\n INNER JOIN \"table2\" ON table1.id = table2.id", $select->assemble());
+    }
+
     /**
      * @group ZF-378
      */