summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rothstein <drothstein@gmail.com>2013-12-25 14:57:44 -0500
committerDavid Rothstein <drothstein@gmail.com>2013-12-25 14:57:44 -0500
commitcbabb1a24bf40e74363efbf0401ba8d37b8c9799 (patch)
tree6bee867bdb60e2ceacf02ca670026f7dd2bcdd83
parent6c89f3924e7e375e634b52f539520b9125789431 (diff)
downloadbrdo-cbabb1a24bf40e74363efbf0401ba8d37b8c9799.tar.gz
brdo-cbabb1a24bf40e74363efbf0401ba8d37b8c9799.tar.bz2
Issue #2056363 by yched, Sweetchuck, chx: INSERT INTO table SELECT * FROM ... not supported.
-rw-r--r--CHANGELOG.txt2
-rw-r--r--includes/database/mysql/query.inc3
-rw-r--r--includes/database/pgsql/query.inc3
-rw-r--r--includes/database/query.inc9
-rw-r--r--includes/database/sqlite/query.inc3
-rw-r--r--modules/simpletest/tests/database_test.install3
-rw-r--r--modules/simpletest/tests/database_test.test26
7 files changed, 40 insertions, 9 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index e7817422b..0397e258a 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,8 @@
Drupal 7.25, xxxx-xx-xx (development version)
-----------------------
+- Changed the database API to allow inserts based on a SELECT * query to work
+ correctly.
- Changed the database schema of the {file_managed} table to allow Drupal to
manage files larger than 4 GB.
- Changed the File module's hook_field_load() implementation to prevent file
diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc
index fa698d90c..d3d2d9eec 100644
--- a/includes/database/mysql/query.inc
+++ b/includes/database/mysql/query.inc
@@ -51,7 +51,8 @@ class InsertQuery_mysql extends InsertQuery {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
- return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
+ $insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
+ return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
}
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
diff --git a/includes/database/pgsql/query.inc b/includes/database/pgsql/query.inc
index f3783a9ca..9902b1643 100644
--- a/includes/database/pgsql/query.inc
+++ b/includes/database/pgsql/query.inc
@@ -112,7 +112,8 @@ class InsertQuery_pgsql extends InsertQuery {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
- return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
+ $insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
+ return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
}
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 66495273e..ce242beb7 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -710,10 +710,11 @@ class InsertQuery extends Query {
// first call to fields() does have an effect.
$this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
}
-
- // Don't execute query without fields.
- if (count($this->insertFields) + count($this->defaultFields) == 0) {
- throw new NoFieldsException('There are no fields available to insert with.');
+ else {
+ // Don't execute query without fields.
+ if (count($this->insertFields) + count($this->defaultFields) == 0) {
+ throw new NoFieldsException('There are no fields available to insert with.');
+ }
}
// If no values have been added, silently ignore this query. This can happen
diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc
index 1bf609db1..1c6289bd7 100644
--- a/includes/database/sqlite/query.inc
+++ b/includes/database/sqlite/query.inc
@@ -41,7 +41,8 @@ class InsertQuery_sqlite extends InsertQuery {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
- return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') ' . $this->fromQuery;
+ $insert_fields_string = $this->insertFields ? ' (' . implode(', ', $this->insertFields) . ') ' : ' ';
+ return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
}
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
diff --git a/modules/simpletest/tests/database_test.install b/modules/simpletest/tests/database_test.install
index 867d81323..11361151f 100644
--- a/modules/simpletest/tests/database_test.install
+++ b/modules/simpletest/tests/database_test.install
@@ -87,6 +87,9 @@ function database_test_schema() {
),
);
+ $schema['test_people_copy'] = $schema['test_people'];
+ $schema['test_people_copy']['description'] = 'A duplicate version of the test_people table, used for additional tests.';
+
$schema['test_one_blob'] = array(
'description' => 'A simple table including a BLOB field for testing BLOB behavior.',
'fields' => array(
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index b58578e99..aa390bd43 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -23,6 +23,7 @@ class DatabaseTestCase extends DrupalWebTestCase {
$schema['test'] = drupal_get_schema('test');
$schema['test_people'] = drupal_get_schema('test_people');
+ $schema['test_people_copy'] = drupal_get_schema('test_people_copy');
$schema['test_one_blob'] = drupal_get_schema('test_one_blob');
$schema['test_two_blobs'] = drupal_get_schema('test_two_blobs');
$schema['test_task'] = drupal_get_schema('test_task');
@@ -603,9 +604,9 @@ class DatabaseInsertTestCase extends DatabaseTestCase {
}
/**
- * Test that the INSERT INTO ... SELECT ... syntax works.
+ * Test that the INSERT INTO ... SELECT (fields) ... syntax works.
*/
- function testInsertSelect() {
+ function testInsertSelectFields() {
$query = db_select('test_people', 'tp');
// The query builder will always append expressions after fields.
// Add the expression first to test that the insert fields are correctly
@@ -627,6 +628,27 @@ class DatabaseInsertTestCase extends DatabaseTestCase {
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Meredith'))->fetchField();
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
}
+
+ /**
+ * Tests that the INSERT INTO ... SELECT * ... syntax works.
+ */
+ function testInsertSelectAll() {
+ $query = db_select('test_people', 'tp')
+ ->fields('tp')
+ ->condition('tp.name', 'Meredith');
+
+ // The resulting query should be equivalent to:
+ // INSERT INTO test_people_copy
+ // SELECT *
+ // FROM test_people tp
+ // WHERE tp.name = 'Meredith'
+ db_insert('test_people_copy')
+ ->from($query)
+ ->execute();
+
+ $saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', array(':name' => 'Meredith'))->fetchField();
+ $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
+ }
}
/**