Support INSERT IGNORE

MySQL supports the IGNORE modifier on INSERT statements, which ignores
uniqueness errors resulting from the INSERT.  This causes syntax errors
in PostgreSQL such as the following:

Error running :
INSERT IGNORE INTO `wp_options` ( `option_name`, `option_value`, `autoload` ) VALUES ('auto_updater.lock', '1433306517', 'no') /* LOCK */
---- converted to ----
INSERT IGNORE INTO wp_options ( option_name, option_value, autoload ) VALUES ('auto_updater.lock', '1433306517', 'no') /* LOCK */
----> ERROR:  syntax error at or near "IGNORE"
LINE 1: INSERT IGNORE INTO wp_options ( option_name, option_value, a...
               ^

Provide support for INSERT IGNORE using a PostgreSQL DO statement with
an exception handler for uniqueness errors.

This has the drawback that it requires PostgreSQL 9.0 or later, support
for plpgsql, and USAGE privileges for plpgsql for the current user.  But
these are all common, and it allows us to support INSERT IGNORE
statements generically.  If this is later found to be too much of a
problem, it is possible to rewrite the query on a query-specific basis
to an INSERT SELECT statement without a FROM clause.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This commit is contained in:
Kevin Locke
2015-06-06 20:58:03 -06:00
parent 6d55670e42
commit e5353f70d6

View File

@ -355,6 +355,13 @@
$sql = 'DELETE FROM '.$table.' WHERE '.$matches[2].' = '.$matches[3].';'.$sql;
}
}
elseif( 0 === strpos($sql, 'INSERT IGNORE'))
{
// Note: Requires PostgreSQL 9.0 and USAGE privilege.
// Could do query-specific rewrite using SELECT without FROM
// as in http://stackoverflow.com/a/13342031
$sql = 'DO $$BEGIN INSERT'.substr($sql, 13).'; EXCEPTION WHEN unique_violation THEN END;$$;';
}
// To avoid Encoding errors when inserting data coming from outside
if( preg_match('/^.{1}/us',$sql,$ar) != 1)