Browse Source

Fix insert queries failing with expression objects.

Insert queries should support expression objects as values. This allows
geo features from MySQL to be used, and enables other platform specific
SQL functions.

Refs #4671
mark_story 11 years ago
parent
commit
bbbe6a9abe

+ 3 - 0
src/Database/Expression/ValuesExpression.php

@@ -149,6 +149,9 @@ class ValuesExpression implements ExpressionInterface {
 		foreach ($this->_values as $row) {
 			$row = array_merge($defaults, $row);
 			foreach ($row as $column => $value) {
+				if ($value instanceof ExpressionInterface) {
+					$value = $value->sql($generator);
+				}
 				$type = $this->typeMap()->type($column);
 				$generator->bind($i++, $value, $type);
 			}

+ 21 - 0
tests/TestCase/Database/QueryTest.php

@@ -2295,6 +2295,27 @@ class QueryTest extends TestCase {
 	}
 
 /**
+ * Test that insert can use expression objects as values.
+ *
+ * @return void
+ */
+	public function testInsertExpressionValues() {
+		$query = new Query($this->connection);
+		$query->insert(['title'])
+			->into('articles')
+			->values(['title' => $query->newExpr("SELECT 'jose'")]);
+
+		$result = $query->sql();
+		$this->assertQuotedQuery(
+			"INSERT INTO <articles> \(<title>\) VALUES (?)",
+			$result,
+			true
+		);
+		$result = $query->execute();
+		$this->assertCount(1, $result);
+	}
+
+/**
  * Tests that functions are correctly transformed and their parameters are bound
  *
  * @group FunctionExpression

+ 13 - 0
tests/TestCase/ORM/QueryRegressionTest.php

@@ -293,6 +293,19 @@ class QueryRegressionTest extends TestCase {
 	}
 
 /**
+ * Test that save() works with entities containing expressions
+ * as properties.
+ *
+ * @return void
+ */
+	public function testSaveWithExpressionProperty() {
+		$articles = TableRegistry::get('Articles');
+		$article = $articles->newEntity();
+		$article->title = new \Cake\Database\Expression\QueryExpression("SELECT 'jose'");
+		$this->assertSame($article, $articles->save($article));
+	}
+
+/**
  * Tests that whe saving deep associations for a belongsToMany property,
  * data is not removed becuase of excesive associations filtering.
  *