diff --git a/includes/database/database.inc b/includes/database/database.inc
index b375aa4..c53c5bf 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -267,6 +267,13 @@ abstract class DatabaseConnection extends PDO {
   protected $connectionOptions = array();
 
   /**
+   * The quote character for quoted identifiers.
+   *
+   * @var string
+   */
+  protected $quoteChar = '"';
+
+  /**
    * The schema object for this connection.
    *
    * @var object
@@ -419,8 +426,14 @@ abstract class DatabaseConnection extends PDO {
       if ($key != 'default') {
         $this->prefixSearch[] = '{' . $key . '}';
         $this->prefixReplace[] = $val . $key;
+        // And quoted tables
+        $this->prefixSearch[] = '{' . $this->quoteChar . $key . $this->quoteChar . '}';
+        $this->prefixReplace[] = $this->quoteChar . $val . $key . $this->quoteChar;
       }
     }
+    // Then replace quoted tables with the default prefix.
+    $this->prefixSearch[] = '{' . $this->quoteChar;
+    $this->prefixReplace[] = $this->quoteChar . $this->prefixes['default'];
     // Then replace remaining tables with the default prefix.
     $this->prefixSearch[] = '{';
     $this->prefixReplace[] = $this->prefixes['default'];
@@ -428,6 +441,10 @@ abstract class DatabaseConnection extends PDO {
     $this->prefixReplace[] = '';
   }
 
+  protected function setQuoteChar($char) {
+    $this->quoteChar = $char;
+  }
+
   /**
    * Appends a database prefix to all tables in a query.
    *
@@ -921,7 +938,9 @@ abstract class DatabaseConnection extends PDO {
    *   The sanitized table name string.
    */
   public function escapeTable($table) {
-    return preg_replace('/[^A-Za-z0-9_.]+/', '', $table);
+    $quote = $this->quoteChar;
+    $escaped_quote = $this->quoteChar . $this->quoteChar;
+    return $quote . str_replace($quote, $escaped_quote, $table) . $quote;
   }
 
   /**
@@ -935,7 +954,15 @@ abstract class DatabaseConnection extends PDO {
    *   The sanitized field name string.
    */
   public function escapeField($field) {
-    return preg_replace('/[^A-Za-z0-9_.]+/', '', $field);
+    $quote = $this->quoteChar;
+    $escaped_quote = $this->quoteChar . $this->quoteChar;
+    $parts = explode('.', $field);
+    foreach ($parts as &$part) {
+      if (strlen($part) != 0) {
+        $part = $quote . str_replace($quote, $escaped_quote, $part) . $quote;
+      }
+    }
+    return implode('.', $parts);
   }
 
   /**
@@ -950,7 +977,13 @@ abstract class DatabaseConnection extends PDO {
    *   The sanitized field name string.
    */
   public function escapeAlias($field) {
-    return preg_replace('/[^A-Za-z0-9_]+/', '', $field);
+    $quote = $this->quoteChar;
+    $escaped_quote = $this->quoteChar . $this->quoteChar;
+    $quoted_field = '';
+    if (strlen($field) != 0) {
+      $quoted_field = $quote . str_replace($quote, $escaped_quote, $field) . $quote;
+    }
+    return $quoted_field;
   }
 
   /**
diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc
index 00d81f4..56dc2d0 100644
--- a/includes/database/mysql/database.inc
+++ b/includes/database/mysql/database.inc
@@ -20,6 +20,8 @@ class DatabaseConnection_mysql extends DatabaseConnection {
   protected $needsCleanup = FALSE;
 
   public function __construct(array $connection_options = array()) {
+    // Set the quote char
+    $this->setQuoteChar('`');
     // This driver defaults to transaction support, except if explicitly passed FALSE.
     $this->transactionSupport = !isset($connection_options['transactions']) || ($connection_options['transactions'] !== FALSE);
 
@@ -90,7 +92,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
 
   public function queryTemporary($query, array $args = array(), array $options = array()) {
     $tablename = $this->generateTemporaryTableName();
-    $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} Engine=MEMORY SELECT', $query), $args, $options);
+    $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $this->escapeTable($tablename) . '} Engine=MEMORY SELECT', $query), $args, $options);
     return $tablename;
   }
 
@@ -102,6 +104,26 @@ class DatabaseConnection_mysql extends DatabaseConnection {
     return 'mysql';
   }
 
+  /**
+   * Escapes a table name string.
+   *
+   * Force all table names to be strictly alphanumeric-plus-underscore.
+   * For some database drivers, it may also wrap the table name in
+   * database-specific escape characters.
+   *
+   * @return
+   *   The sanitized table name string.
+   */
+  public function escapeTable($table) {
+    $quote = $this->quoteChar;
+    $escaped_quote = $this->quoteChar . $this->quoteChar;
+    $parts = explode('.', $table);
+    foreach ($parts as &$part) {
+      $part = $quote . str_replace($quote, $escaped_quote, $part) . $quote;
+    }
+    return implode('.', $parts);
+  }
+
   public function mapConditionOperator($operator) {
     // We don't want to override any of the defaults.
     return NULL;
diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc
index d3d2d9e..f3f22ec 100644
--- a/includes/database/mysql/query.inc
+++ b/includes/database/mysql/query.inc
@@ -45,17 +45,19 @@ class InsertQuery_mysql extends InsertQuery {
     // Create a sanitized comment string to prepend to the query.
     $comments = $this->connection->makeComment($this->comments);
 
+    $default_fields = array_map(array($this->connection, 'escapeField'), $this->defaultFields);
+    $insert_fields = array_map(array($this->connection, 'escapeField'), $this->insertFields);
     // Default fields are always placed first for consistency.
-    $insert_fields = array_merge($this->defaultFields, $this->insertFields);
+    $insert_fields = array_merge($default_fields, $insert_fields);
 
     // 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)) {
       $insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
-      return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
+      return $comments . 'INSERT INTO {' .$this->connection->escapeTable($this->table) . '}' . $insert_fields_string . $this->fromQuery;
     }
 
-    $query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
+    $query = $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '} (' . implode(', ', $insert_fields) . ') VALUES ';
 
     $max_placeholder = 0;
     $values = array();
diff --git a/includes/database/mysql/schema.inc b/includes/database/mysql/schema.inc
index 949cf4e..afb7600 100644
--- a/includes/database/mysql/schema.inc
+++ b/includes/database/mysql/schema.inc
@@ -84,7 +84,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       'mysql_character_set' => 'utf8',
     );
 
-    $sql = "CREATE TABLE {" . $name . "} (\n";
+    $sql = "CREATE TABLE {" . $this->connection->escapeTable($name) . "} (\n";
 
     // Add the SQL statement for each field.
     foreach ($table['fields'] as $field_name => $field) {
@@ -129,7 +129,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
    *   The field specification, as per the schema data structure format.
    */
   protected function createFieldSql($name, $spec) {
-    $sql = "`" . $name . "` " . $spec['mysql_type'];
+    $sql = $this->connection->escapeField($name) . ' ' . $spec['mysql_type'];
 
     if (in_array($spec['mysql_type'], array('VARCHAR', 'CHAR', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'TEXT'))) {
       if (isset($spec['length'])) {
@@ -261,12 +261,12 @@ class DatabaseSchema_mysql extends DatabaseSchema {
     }
     if (!empty($spec['unique keys'])) {
       foreach ($spec['unique keys'] as $key => $fields) {
-        $keys[] = 'UNIQUE KEY `' . $key . '` (' . $this->createKeysSqlHelper($fields) . ')';
+        $keys[] = 'UNIQUE KEY ' . $this->connection->escapeField($key) . ' (' . $this->createKeysSqlHelper($fields) . ')';
       }
     }
     if (!empty($spec['indexes'])) {
       foreach ($spec['indexes'] as $index => $fields) {
-        $keys[] = 'INDEX `' . $index . '` (' . $this->createKeysSqlHelper($fields) . ')';
+        $keys[] = 'INDEX ' . $this->connection->escapeField($index) . ' (' . $this->createKeysSqlHelper($fields) . ')';
       }
     }
 
@@ -277,10 +277,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
     $return = array();
     foreach ($fields as $field) {
       if (is_array($field)) {
-        $return[] = '`' . $field[0] . '`(' . $field[1] . ')';
+        $return[] = $this->connection->escapeField($field[0]) . '(' . $field[1] . ')';
       }
       else {
-        $return[] = '`' . $field . '`';
+        $return[] = $this->connection->escapeField($field);
       }
     }
     return implode(', ', $return);
@@ -290,10 +290,10 @@ class DatabaseSchema_mysql extends DatabaseSchema {
     $return = array();
     foreach ($fields as $field) {
       if (is_array($field)) {
-        $return[] = '`' . $field[0] . '`(' . $field[1] . ')';
+        $return[] = $this->connection->escapeField($field[0]) . '(' . $field[1] . ')';
       }
       else {
-        $return[] = '`' . $field . '`';
+        $return[] = $this->connection->escapeField($field);
       }
     }
     return implode(', ', $return);
@@ -308,7 +308,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
     }
 
     $info = $this->getPrefixInfo($new_name);
-    return $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO `' . $info['table'] . '`');
+    return $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} RENAME TO ' . $this->connection->escapeTable($info['table']));
   }
 
   public function dropTable($table) {
@@ -316,7 +316,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('DROP TABLE {' . $table . '}');
+    $this->connection->query('DROP TABLE {' . $this->connection->escapeTable($table) . '}');
     return TRUE;
   }
 
@@ -333,7 +333,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       $fixnull = TRUE;
       $spec['not null'] = FALSE;
     }
-    $query = 'ALTER TABLE {' . $table . '} ADD ';
+    $query = 'ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD ';
     $query .= $this->createFieldSql($field, $this->processField($spec));
     if ($keys_sql = $this->createKeysSql($keys_new)) {
       $query .= ', ADD ' . implode(', ADD ', $keys_sql);
@@ -355,7 +355,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP `' . $field . '`');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP ' . $this->connection->escapeField($field));
     return TRUE;
   }
 
@@ -371,7 +371,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       $default = is_string($default) ? "'$default'" : $default;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` SET DEFAULT ' . $default);
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER COLUMN ' . $this->connection->escapeField($field) . ' SET DEFAULT ' . $default);
   }
 
   public function fieldSetNoDefault($table, $field) {
@@ -379,13 +379,13 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` DROP DEFAULT');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER COLUMN ' . $this->connection->escapeField($field) . ' DROP DEFAULT');
   }
 
   public function indexExists($table, $name) {
     // Returns one row for each column in the index. Result is string or FALSE.
     // Details at http://dev.mysql.com/doc/refman/5.0/en/show-index.html
-    $row = $this->connection->query('SHOW INDEX FROM {' . $table . "} WHERE key_name = '$name'")->fetchAssoc();
+    $row = $this->connection->query('SHOW INDEX FROM {' . $this->connection->escapeTable($table) . "} WHERE key_name = '$name'")->fetchAssoc();
     return isset($row['Key_name']);
   }
 
@@ -397,7 +397,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
   }
 
   public function dropPrimaryKey($table) {
@@ -405,7 +405,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP PRIMARY KEY');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP PRIMARY KEY');
     return TRUE;
   }
 
@@ -417,7 +417,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD UNIQUE KEY `' . $name . '` (' . $this->createKeySql($fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD UNIQUE KEY ' . $this->connection->escapeField($name) . ' (' . $this->createKeySql($fields) . ')');
   }
 
   public function dropUniqueKey($table, $name) {
@@ -425,7 +425,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP KEY `' . $name . '`');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP KEY ' . $this->connection->escapeField($name));
     return TRUE;
   }
 
@@ -437,7 +437,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", array('%table' => $table, '%name' => $name)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD INDEX ' . $this->connection->escapeField($name) . ' (' . $this->createKeySql($fields) . ')');
   }
 
   public function dropIndex($table, $name) {
@@ -445,7 +445,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP INDEX `' . $name . '`');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP INDEX ' . $this->connection->escapeField($field));
     return TRUE;
   }
 
@@ -457,7 +457,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
     }
 
-    $sql = 'ALTER TABLE {' . $table . '} CHANGE `' . $field . '` ' . $this->createFieldSql($field_new, $this->processField($spec));
+    $sql = 'ALTER TABLE {' . $this->connection->escapeTable($table) . '} CHANGE ' . $this->connection->escapeField($field) . ' ' . $this->createFieldSql($field_new, $this->processField($spec));
     if ($keys_sql = $this->createKeysSql($keys_new)) {
       $sql .= ', ADD ' . implode(', ADD ', $keys_sql);
     }
@@ -504,7 +504,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
     // @todo: This override should be removed once we require a version of MySQL
     // that has that bug fixed.
     try {
-      $this->connection->queryRange("SELECT 1 FROM {" . $table . "}", 0, 1);
+      $this->connection->queryRange("SELECT 1 FROM {" . $this->connection->escapeTable($table) . "}", 0, 1);
       return TRUE;
     }
     catch (Exception $e) {
@@ -521,7 +521,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
     // @todo: This override should be removed once we require a version of MySQL
     // that has that bug fixed.
     try {
-      $this->connection->queryRange("SELECT $column FROM {" . $table . "}", 0, 1);
+      $this->connection->queryRange("SELECT " . $this->connection->escapeField($column) . " FROM {" . $this->connection->escapeTable($table) . "}", 0, 1);
       return TRUE;
     }
     catch (Exception $e) {
diff --git a/includes/database/pgsql/database.inc b/includes/database/pgsql/database.inc
index 00ed799..0883dee 100644
--- a/includes/database/pgsql/database.inc
+++ b/includes/database/pgsql/database.inc
@@ -146,7 +146,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
 
   public function queryTemporary($query, array $args = array(), array $options = array()) {
     $tablename = $this->generateTemporaryTableName();
-    $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $tablename . '} AS SELECT', $query), $args, $options);
+    $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE {' . $this->escapeTable($tablename) . '} AS SELECT', $query), $args, $options);
     return $tablename;
   }
 
diff --git a/includes/database/pgsql/query.inc b/includes/database/pgsql/query.inc
index 9902b16..4f51ba7 100644
--- a/includes/database/pgsql/query.inc
+++ b/includes/database/pgsql/query.inc
@@ -60,7 +60,7 @@ class InsertQuery_pgsql extends InsertQuery {
             // used twice. However, trying to insert a value into a serial
             // column should only be done in very rare cases and is not thread
             // safe by definition.
-            $this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', GREATEST(MAX(" . $serial_field . "), :serial_value)) FROM {" . $this->table . "}", array(':serial_value' => (int)$serial_value));
+            $this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', GREATEST(MAX(" . $serial_field . "), :serial_value)) FROM {" . $this->connection->escapeTable($this->table) . "}", array(':serial_value' => (int)$serial_value));
           }
         }
       }
@@ -106,17 +106,19 @@ class InsertQuery_pgsql extends InsertQuery {
     // Create a sanitized comment string to prepend to the query.
     $comments = $this->connection->makeComment($this->comments);
 
+    $default_fields = array_map(array($this->connection, 'escapeField'), $this->defaultFields);
+    $insert_fields = array_map(array($this->connection, 'escapeField'), $this->insertFields);
     // Default fields are always placed first for consistency.
-    $insert_fields = array_merge($this->defaultFields, $this->insertFields);
+    $insert_fields = array_merge($default_fields, $insert_fields);
 
     // 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)) {
       $insert_fields_string = $insert_fields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
-      return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
+      return $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '}' . $insert_fields_string . $this->fromQuery;
     }
 
-    $query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
+    $query = $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '} (' . implode(', ', $insert_fields) . ') VALUES ';
 
     $max_placeholder = 0;
     $values = array();
diff --git a/includes/database/pgsql/schema.inc b/includes/database/pgsql/schema.inc
index 49adbf9..a0fcb1c 100644
--- a/includes/database/pgsql/schema.inc
+++ b/includes/database/pgsql/schema.inc
@@ -38,7 +38,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
    */
   public function queryTableInformation($table) {
     // Generate a key to reference this table's information on.
-    $key = $this->connection->prefixTables('{' . $table . '}');
+    $key = $this->connection->prefixTables('{' . $this->connection->escapeTable($table) . '}');
     if (!strpos($key, '.')) {
       $key = 'public.' . $key;
     }
@@ -124,15 +124,15 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
 
     $sql_keys = array();
     if (isset($table['primary key']) && is_array($table['primary key'])) {
-      $sql_keys[] = 'PRIMARY KEY (' . implode(', ', $table['primary key']) . ')';
+      $sql_keys[] = 'PRIMARY KEY (' . implode(', ', array_map(array($this->connection, 'escapeField'), $table['primary key'])) . ')';
     }
     if (isset($table['unique keys']) && is_array($table['unique keys'])) {
       foreach ($table['unique keys'] as $key_name => $key) {
-        $sql_keys[] = 'CONSTRAINT ' . $this->prefixNonTable($name, $key_name, 'key') . ' UNIQUE (' . implode(', ', $key) . ')';
+        $sql_keys[] = 'CONSTRAINT ' . $this->prefixNonTable($name, $key_name, 'key') . ' UNIQUE (' . implode(', ', array_map(array($this->connection, 'escapeField'), $key)) . ')';
       }
     }
 
-    $sql = "CREATE TABLE {" . $name . "} (\n\t";
+    $sql = "CREATE TABLE {" . $this->connection->escapeTable($name) . "} (\n\t";
     $sql .= implode(",\n\t", $sql_fields);
     if (count($sql_keys) > 0) {
       $sql .= ",\n\t";
@@ -149,13 +149,13 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
 
     // Add table comment.
     if (!empty($table['description'])) {
-      $statements[] = 'COMMENT ON TABLE {' . $name . '} IS ' . $this->prepareComment($table['description']);
+      $statements[] = 'COMMENT ON TABLE {' . $this->connection->escapeTable($name) . '} IS ' . $this->prepareComment($table['description']);
     }
 
     // Add column comments.
     foreach ($table['fields'] as $field_name => $field) {
       if (!empty($field['description'])) {
-        $statements[] = 'COMMENT ON COLUMN {' . $name . '}.' . $field_name . ' IS ' . $this->prepareComment($field['description']);
+        $statements[] = 'COMMENT ON COLUMN {' . $this->connection->escapeTable($name) . '}.' . $this->connection->escapeField($field_name) . ' IS ' . $this->prepareComment($field['description']);
       }
     }
 
@@ -175,7 +175,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
    *    The field specification, as per the schema data structure format.
    */
   protected function createFieldSql($name, $spec) {
-    $sql = $name . ' ' . $spec['pgsql_type'];
+    $sql = $this->connection->escapeField($name) . ' ' . $spec['pgsql_type'];
 
     if (isset($spec['type']) && $spec['type'] == 'serial') {
       unset($spec['not null']);
@@ -189,7 +189,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     }
 
     if (!empty($spec['unsigned'])) {
-      $sql .= " CHECK ($name >= 0)";
+      $sql .= " CHECK (" . $this->connection->escapeField($name) . " >= 0)";
     }
 
     if (isset($spec['not null'])) {
@@ -303,10 +303,10 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     $return = array();
     foreach ($fields as $field) {
       if (is_array($field)) {
-        $return[] = 'substr(' . $field[0] . ', 1, ' . $field[1] . ')';
+        $return[] = 'substr(' . $this->connection->escapeField($field[0]) . ', 1, ' . $field[1] . ')';
       }
       else {
-        $return[] = '"' . $field . '"';
+        $return[] = $this->connection->escapeField($field);
       }
     }
     return implode(', ', $return);
@@ -321,7 +321,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     }
 
     // Get the schema and tablename for the old table.
-    $old_full_name = $this->connection->prefixTables('{' . $table . '}');
+    $old_full_name = $this->connection->prefixTables('{' . $this->connection->escapeTable($table) . '}');
     list($old_schema, $old_table_name) = strpos($old_full_name, '.') ? explode('.', $old_full_name) : array('public', $old_full_name);
 
     // Index names and constraint names are global in PostgreSQL, so we need to
@@ -337,7 +337,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     // Now rename the table.
     // Ensure the new table name does not include schema syntax.
     $prefixInfo = $this->getPrefixInfo($new_name);
-    $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $prefixInfo['table']);
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} RENAME TO ' . $this->connection->escapeTable($prefixInfo['table']));
   }
 
   public function dropTable($table) {
@@ -345,7 +345,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('DROP TABLE {' . $table . '}');
+    $this->connection->query('DROP TABLE {' . $this->connection->escapeTable($table) . '}');
     return TRUE;
   }
 
@@ -362,7 +362,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       $fixnull = TRUE;
       $spec['not null'] = FALSE;
     }
-    $query = 'ALTER TABLE {' . $table . '} ADD COLUMN ';
+    $query = 'ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD COLUMN ';
     $query .= $this->createFieldSql($field, $this->processField($spec));
     $this->connection->query($query);
     if (isset($spec['initial'])) {
@@ -371,14 +371,14 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
         ->execute();
     }
     if ($fixnull) {
-      $this->connection->query("ALTER TABLE {" . $table . "} ALTER $field SET NOT NULL");
+      $this->connection->query("ALTER TABLE {" . $this->connection->escapeTable($table) . "} ALTER " . $this->connection->escapeField($field) . " SET NOT NULL");
     }
     if (isset($new_keys)) {
       $this->_createKeys($table, $new_keys);
     }
     // Add column comment.
     if (!empty($spec['description'])) {
-      $this->connection->query('COMMENT ON COLUMN {' . $table . '}.' . $field . ' IS ' . $this->prepareComment($spec['description']));
+      $this->connection->query('COMMENT ON COLUMN {' . $this->connection->escapeTable($table) . '}.' . $this->connection->escapeField($field) . ' IS ' . $this->prepareComment($spec['description']));
     }
   }
 
@@ -387,7 +387,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP COLUMN "' . $field . '"');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP COLUMN ' . $this->connection->escapeField($field));
     return TRUE;
   }
 
@@ -403,7 +403,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       $default = is_string($default) ? "'$default'" : $default;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" SET DEFAULT ' . $default);
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER COLUMN ' . $this->connection->escapeField($field) . ' SET DEFAULT ' . $default);
   }
 
   public function fieldSetNoDefault($table, $field) {
@@ -411,7 +411,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot remove default value of field %table.%field: field doesn't exist.", array('%table' => $table, '%field' => $field)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" DROP DEFAULT');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER COLUMN ' . $this->connection->escapeField($field) . ' DROP DEFAULT');
   }
 
   public function indexExists($table, $name) {
@@ -441,7 +441,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . implode(',', $fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD PRIMARY KEY (' . implode(',', array_map(array($this->connection, 'escapeField'), $fields)) . ')');
   }
 
   public function dropPrimaryKey($table) {
@@ -449,7 +449,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
     return TRUE;
   }
 
@@ -461,7 +461,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', array_map(array($this->connection, 'escapeField'), $fields)) . ')');
   }
 
   public function dropUniqueKey($table, $name) {
@@ -469,7 +469,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '"');
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '"');
     return TRUE;
   }
 
@@ -524,13 +524,13 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     $field_info = $this->queryFieldInformation($table, $field);
 
     foreach ($field_info as $check) {
-      $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $check . '"');
+      $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} DROP CONSTRAINT "' . $check . '"');
     }
 
     // Remove old default.
     $this->fieldSetNoDefault($table, $field);
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" TYPE ' . $typecast . ' USING "' . $field . '"::' . $typecast);
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER ' . $this->connection->escapeField($field) . ' TYPE ' . $typecast . ' USING ' . $this->connection->escapeField($table) . '::' . $typecast);
 
     if (isset($spec['not null'])) {
       if ($spec['not null']) {
@@ -539,7 +539,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       else {
         $nullaction = 'DROP NOT NULL';
       }
-      $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" ' . $nullaction);
+      $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER ' . $this->connection->escapeField($field) . ' ' . $nullaction);
     }
 
     if (in_array($spec['pgsql_type'], array('serial', 'bigserial'))) {
@@ -550,18 +550,18 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       $this->connection->query("CREATE SEQUENCE " . $seq);
       // Set sequence to maximal field value to not conflict with existing
       // entries.
-      $this->connection->query("SELECT setval('" . $seq . "', MAX(\"" . $field . '")) FROM {' . $table . "}");
-      $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" SET DEFAULT nextval(\'' . $seq . '\')');
+      $this->connection->query("SELECT setval('" . $seq . "', MAX(" . $this->connection->escapeField($field) . ')) FROM {' . $this->connection->escapeTable($table) . "}");
+      $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ALTER ' . $this->connection->escapeField($field) . ' SET DEFAULT nextval(\'' . $seq . '\')');
     }
 
     // Rename the column if necessary.
     if ($field != $field_new) {
-      $this->connection->query('ALTER TABLE {' . $table . '} RENAME "' . $field . '" TO "' . $field_new . '"');
+      $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} RENAME ' . $this->connection->escapeField($field) . ' TO ' . $this->connection->escapeField($field_new));
     }
 
     // Add unsigned check if necessary.
     if (!empty($spec['unsigned'])) {
-      $this->connection->query('ALTER TABLE {' . $table . '} ADD CHECK ("' . $field_new . '" >= 0)');
+      $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD CHECK (' . $this->connection->escapeField($field_new) . ' >= 0)');
     }
 
     // Add default if necessary.
@@ -571,7 +571,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
 
     // Change description if necessary.
     if (!empty($spec['description'])) {
-      $this->connection->query('COMMENT ON COLUMN {' . $table . '}."' . $field_new . '" IS ' . $this->prepareComment($spec['description']));
+      $this->connection->query('COMMENT ON COLUMN {' . $this->connection->escapeTable($table) . '}.' . $this->connection->escapeField($field_new) . ' IS ' . $this->prepareComment($spec['description']));
     }
 
     if (isset($new_keys)) {
@@ -580,7 +580,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
   }
 
   protected function _createIndexSql($table, $name, $fields) {
-    $query = 'CREATE INDEX "' . $this->prefixNonTable($table, $name, 'idx') . '" ON {' . $table . '} (';
+    $query = 'CREATE INDEX "' . $this->prefixNonTable($table, $name, 'idx') . '" ON {' . $this->connection->escapeTable($table) . '} (';
     $query .= $this->_createKeySql($fields) . ')';
     return $query;
   }
diff --git a/includes/database/pgsql/select.inc b/includes/database/pgsql/select.inc
index f6a83db..90fe6a5 100644
--- a/includes/database/pgsql/select.inc
+++ b/includes/database/pgsql/select.inc
@@ -89,13 +89,6 @@ class SelectQuery_pgsql extends SelectQuery {
       }
     }
 
-    // If $field contains an characters which are not allowed in a field name
-    // it is considered an expression, these can't be handeld automatically
-    // either.
-    if ($this->connection->escapeField($field) != $field) {
-      return $return;
-    }
-
     // This is a case that can be handled automatically, add the field.
     $this->addField(NULL, $field);
     return $return;
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 8af91c2..5ed6823 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -669,11 +669,13 @@ class InsertQuery extends Query {
     // Create a sanitized comment string to prepend to the query.
     $comments = $this->connection->makeComment($this->comments);
 
+    $default_fields = array_map(array($this->connection, 'escapeField'), $this->defaultFields);
+    $insert_fields = array_map(array($this->connection, 'escapeField'), $this->insertFields);
     // Default fields are always placed first for consistency.
-    $insert_fields = array_merge($this->defaultFields, $this->insertFields);
+    $insert_fields = array_merge($default_fields, $insert_fields);
 
     if (!empty($this->fromQuery)) {
-      return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
+      return $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
     }
 
     // For simplicity, we will use the $placeholders array to inject
@@ -683,7 +685,7 @@ class InsertQuery extends Query {
     $placeholders = array_pad($placeholders, count($this->defaultFields), 'default');
     $placeholders = array_pad($placeholders, count($this->insertFields), '?');
 
-    return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES (' . implode(', ', $placeholders) . ')';
+    return $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '} (' . implode(', ', $insert_fields) . ') VALUES (' . implode(', ', $placeholders) . ')';
   }
 
   /**
@@ -1192,13 +1194,13 @@ class UpdateQuery extends Query implements QueryConditionInterface {
     $fields = $this->fields;
     $update_fields = array();
     foreach ($this->expressionFields as $field => $data) {
-      $update_fields[] = $field . '=' . $data['expression'];
+      $update_fields[] = $this->connection->escapeField($field) . '=' . $data['expression'];
       unset($fields[$field]);
     }
 
     $max_placeholder = 0;
     foreach ($fields as $field => $value) {
-      $update_fields[] = $field . '=:db_update_placeholder_' . ($max_placeholder++);
+      $update_fields[] = $this->connection->escapeField($field) . '=:db_update_placeholder_' . ($max_placeholder++);
     }
 
     $query = $comments . 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields);
diff --git a/includes/database/select.inc b/includes/database/select.inc
index e036904..748ddd5 100644
--- a/includes/database/select.inc
+++ b/includes/database/select.inc
@@ -1552,7 +1552,7 @@ class SelectQuery extends Query implements SelectQueryInterface {
 
     // GROUP BY
     if ($this->group) {
-      $query .= "\nGROUP BY " . implode(', ', $this->group);
+      $query .= "\nGROUP BY " . implode(', ', array_map(array($this->connection, 'escapeField'), $this->group));
     }
 
     // HAVING
@@ -1566,7 +1566,7 @@ class SelectQuery extends Query implements SelectQueryInterface {
       $query .= "\nORDER BY ";
       $fields = array();
       foreach ($this->order as $field => $direction) {
-        $fields[] = $field . ' ' . $direction;
+        $fields[] = $this->connection->escapeField($field) . ' ' . $direction;
       }
       $query .= implode(', ', $fields);
     }
diff --git a/includes/database/sqlite/database.inc b/includes/database/sqlite/database.inc
index b302b3e..922f8d9 100644
--- a/includes/database/sqlite/database.inc
+++ b/includes/database/sqlite/database.inc
@@ -250,7 +250,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
     $prefixes[$tablename] = '';
     $this->setPrefix($prefixes);
 
-    $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $tablename . ' AS SELECT', $query), $args, $options);
+    $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $this->escapeTable($tablename) . ' AS SELECT', $query), $args, $options);
     return $tablename;
   }
 
diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc
index 1c6289b..c07e2ce 100644
--- a/includes/database/sqlite/query.inc
+++ b/includes/database/sqlite/query.inc
@@ -27,7 +27,7 @@ class InsertQuery_sqlite extends InsertQuery {
       return parent::execute();
     }
     else {
-      return $this->connection->query('INSERT INTO {' . $this->table . '} DEFAULT VALUES', array(), $this->queryOptions);
+      return $this->connection->query('INSERT INTO {' . $this->connection->escapeTable($this->table) . '} DEFAULT VALUES', array(), $this->queryOptions);
     }
   }
 
@@ -35,17 +35,19 @@ class InsertQuery_sqlite extends InsertQuery {
     // Create a sanitized comment string to prepend to the query.
     $comments = $this->connection->makeComment($this->comments);
 
+    $insert_fields = array_map(array($this->connection, 'escapeField'), $this->insertFields);
+
     // Produce as many generic placeholders as necessary.
     $placeholders = array_fill(0, count($this->insertFields), '?');
 
     // 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)) {
-      $insert_fields_string = $this->insertFields ? ' (' . implode(', ', $this->insertFields) . ') ' : ' ';
-      return $comments . 'INSERT INTO {' . $this->table . '}' . $insert_fields_string . $this->fromQuery;
+      $insert_fields_string = $this->insertFields ? ' (' . implode(', ', $insert_fields) . ') ' : ' ';
+      return $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '}' . $insert_fields_string . $this->fromQuery;
     }
 
-    return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
+    return $comments . 'INSERT INTO {' . $this->connection->escapeTable($this->table) . '} (' . implode(', ', $insert_fields) . ') VALUES (' . implode(', ', $placeholders) . ')';
   }
 
 }
diff --git a/includes/database/sqlite/schema.inc b/includes/database/sqlite/schema.inc
index c5882f1..436c41d 100644
--- a/includes/database/sqlite/schema.inc
+++ b/includes/database/sqlite/schema.inc
@@ -42,7 +42,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
    */
   public function createTableSql($name, $table) {
     $sql = array();
-    $sql[] = "CREATE TABLE {" . $name . "} (\n" . $this->createColumsSql($name, $table) . "\n);\n";
+    $sql[] = "CREATE TABLE {" . $this->connection->escapeTable($name) . "} (\n" . $this->createColumsSql($name, $table) . "\n);\n";
     return array_merge($sql, $this->createIndexSql($name, $table));
   }
 
@@ -54,12 +54,12 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
     $info = $this->getPrefixInfo($tablename);
     if (!empty($schema['unique keys'])) {
       foreach ($schema['unique keys'] as $key => $fields) {
-        $sql[] = 'CREATE UNIQUE INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $key . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . "); \n";
+        $sql[] = 'CREATE UNIQUE INDEX ' . $this->connection->escapeField($info['schema'] . '.' . $info['table'] . '_' . $key) . ' ON ' . $this->connection->escapeTable($info['table']) . ' (' . $this->createKeySql($fields) . "); \n";
       }
     }
     if (!empty($schema['indexes'])) {
       foreach ($schema['indexes'] as $key => $fields) {
-        $sql[] = 'CREATE INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $key . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . "); \n";
+        $sql[] = 'CREATE INDEX ' . $this->connection->escapeField($info['schema'] . '.' . $info['table'] . '_' . $key) . ' ON ' . $this->connection->escapeTable($info['table']) . ' (' . $this->createKeySql($fields) . "); \n";
       }
     }
     return $sql;
@@ -96,10 +96,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
     $return = array();
     foreach ($fields as $field) {
       if (is_array($field)) {
-        $return[] = $field[0];
+        $return[] = $this->connection->escapeField($field[0]);
       }
       else {
-        $return[] = $field;
+        $return[] = $this->connection->escapeField($field);
       }
     }
     return implode(', ', $return);
@@ -146,13 +146,13 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
    */
   protected function createFieldSql($name, $spec) {
     if (!empty($spec['auto_increment'])) {
-      $sql = $name . " INTEGER PRIMARY KEY AUTOINCREMENT";
+      $sql = $this->connection->escapeField($name) . " INTEGER PRIMARY KEY AUTOINCREMENT";
       if (!empty($spec['unsigned'])) {
-        $sql .= ' CHECK (' . $name . '>= 0)';
+        $sql .= ' CHECK (' . $this->connection->escapeField($name) . '>= 0)';
       }
     }
     else {
-      $sql = $name . ' ' . $spec['sqlite_type'];
+      $sql = $this->connection->escapeField($name) . ' ' . $spec['sqlite_type'];
 
       if (in_array($spec['sqlite_type'], array('VARCHAR', 'TEXT')) && isset($spec['length'])) {
         $sql .= '(' . $spec['length'] . ')';
@@ -168,7 +168,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       }
 
       if (!empty($spec['unsigned'])) {
-        $sql .= ' CHECK (' . $name . '>= 0)';
+        $sql .= ' CHECK (' . $this->connection->escapeField($name) . '>= 0)';
       }
 
       if (isset($spec['default'])) {
@@ -246,7 +246,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
     // the table with curly braces incase the db_prefix contains a reference
     // to a database outside of our existsing database.
     $info = $this->getPrefixInfo($new_name);
-    $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
+    $this->connection->query('ALTER TABLE {' . $this->connection->escapeTable($table) . '} RENAME TO ' . $this->connection->escapeTable($info['table']));
 
     // Drop the indexes, there is no RENAME INDEX command in SQLite.
     if (!empty($schema['unique keys'])) {
@@ -272,7 +272,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       return FALSE;
     }
     $this->connection->tableDropped = TRUE;
-    $this->connection->query('DROP TABLE {' . $table . '}');
+    $this->connection->query('DROP TABLE {' . $this->connection->escapeTable($table) . '}');
     return TRUE;
   }
 
@@ -290,7 +290,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
     if (empty($keys_new) && (empty($specification['not null']) || isset($specification['default']))) {
       // When we don't have to create new keys and we are not creating a
       // NOT NULL column without a default value, we can use the quicker version.
-      $query = 'ALTER TABLE {' . $table . '} ADD ' . $this->createFieldSql($field, $this->processField($specification));
+      $query = 'ALTER TABLE {' . $this->connection->escapeTable($table) . '} ADD ' . $this->createFieldSql($field, $this->processField($specification));
       $this->connection->query($query);
 
       // Apply the initial value if set.
@@ -386,8 +386,8 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       ->from($select)
       ->execute();
 
-    $old_count = $this->connection->query('SELECT COUNT(*) FROM {' . $table . '}')->fetchField();
-    $new_count = $this->connection->query('SELECT COUNT(*) FROM {' . $new_table . '}')->fetchField();
+    $old_count = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($table) . '}')->fetchField();
+    $new_count = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($new_table) . '}')->fetchField();
     if ($old_count == $new_count) {
       $this->dropTable($table);
       $this->renameTable($new_table, $table);
@@ -417,7 +417,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
     );
 
     $info = $this->getPrefixInfo($table);
-    $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.table_info(' . $info['table'] . ')');
+    $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.table_info(' . $this->connection->escapeTable($info['table']) . ')');
     foreach ($result as $row) {
       if (preg_match('/^([^(]+)\((.*)\)$/', $row->type, $matches)) {
         $type = $matches[1];
@@ -447,7 +447,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       }
     }
     $indexes = array();
-    $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_list(' . $info['table'] . ')');
+    $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_list(' . $this->connection->escapeTable($info['table']) . ')');
     foreach ($result as $row) {
       if (strpos($row->name, 'sqlite_autoindex_') !== 0) {
         $indexes[] = array(
@@ -460,7 +460,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       $name = $index['name'];
       // Get index name without prefix.
       $index_name = substr($name, strlen($info['table']) + 1);
-      $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $name . ')');
+      $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $this->connection->escapeTable($name) . ')');
       foreach ($result as $row) {
         $schema[$index['schema_key']][$index_name][] = $row->name;
       }
@@ -575,7 +575,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
   public function indexExists($table, $name) {
     $info = $this->getPrefixInfo($table);
 
-    return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $info['table'] . '_' . $name . ')')->fetchField() != '';
+    return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' .$this->connection->escapeTable($info['table'] . '_' . $name) . ')')->fetchField() != '';
   }
 
   public function dropIndex($table, $name) {
@@ -585,7 +585,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
 
     $info = $this->getPrefixInfo($table);
 
-    $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name);
+    $this->connection->query('DROP INDEX ' . $this->connection->escapeField($info['schema'] . '.' . $info['table'] . '_' . $name));
     return TRUE;
   }
 
@@ -611,7 +611,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
 
     $info = $this->getPrefixInfo($table);
 
-    $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name);
+    $this->connection->query('DROP INDEX ' . $this->connection->escapeField($info['schema'] . '.' . $info['table'] . '_' . $name));
     return TRUE;
   }
 
diff --git a/modules/simpletest/tests/database_test.install b/modules/simpletest/tests/database_test.install
index 1136115..b35597a 100644
--- a/modules/simpletest/tests/database_test.install
+++ b/modules/simpletest/tests/database_test.install
@@ -190,6 +190,50 @@ function database_test_schema() {
     ),
   );
 
+  $schema['test-reserved'] = array(
+    'description' => 'Basic test table for quoted and reserved word identifiers.',
+    'fields' => array(
+      'id' => array(
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'select' => array(
+        'description' => "A column called a reserved word.",
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'back`tick' => array(
+        'description' => "A column with a backtick.",
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'single\'quote' => array(
+        'description' => "A column with a single quote.",
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'double"quote' => array(
+        'description' => "A column with a double quote.",
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'hyp-hen' => array(
+        'description' => "A column with a hyphen.",
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+    ),
+    'primary key' => array('id'),
+    'unique keys' => array(
+      'select' => array('select'),
+      'back`tick' => array('back`tick'),
+      'single\'quote' => array('single\'quote'),
+      'double"quote' => array('double"quote'),
+      'hyp-hen' => array('hyp-hen'),
+    ),
+  );
+
   $schema['test_serialized'] = array(
     'description' => 'Basic test table for NULL value handling.',
     'fields' => array(
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index aa390bd..159888e 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -25,6 +25,7 @@ class DatabaseTestCase extends DrupalWebTestCase {
     $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-reserved'] = drupal_get_schema('test-reserved');
     $schema['test_two_blobs'] = drupal_get_schema('test_two_blobs');
     $schema['test_task'] = drupal_get_schema('test_task');
 
@@ -1393,10 +1394,10 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
     }
 
     $query = (string)$query;
-    $expected = "/* Testing query comments */ SELECT test.name AS name, test.age AS age\nFROM \n{test} test";
+    $expected_comment = '/* Testing query comments */';
 
     $this->assertEqual($num_records, 4, 'Returned the correct number of rows.');
-    $this->assertEqual($query, $expected, 'The flattened query contains the comment string.');
+    $this->assertTrue(strstr($query, $expected_comment), 'The flattened query contains the comment string.');
   }
 
   /**
@@ -1414,10 +1415,10 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
     }
 
     $query = (string)$query;
-    $expected = "/* Testing query comments SELECT nid FROM {node}; -- */ SELECT test.name AS name, test.age AS age\nFROM \n{test} test";
+    $expected_comment = '/* Testing query comments SELECT nid FROM {node}; -- */';
 
     $this->assertEqual($num_records, 4, 'Returned the correct number of rows.');
-    $this->assertEqual($query, $expected, 'The flattened query contains the sanitised comment string.');
+    $this->assertTrue(strstr($query, $expected_comment), 'The flattened query contains the sanitised comment string.');
   }
 
   /**
