The quoting of identifiers which contain "ID" can match things other
than identifiers, such as strings which contain "ID" and subsequently
"=". An example of this occurring in practice is:
Error running :
UPDATE `wp_ngg_pictures` SET `pid` = '42', `post_id` = 0, `galleryid` = '3', `filename` = 'img_0683.jpg', `description` = '', `alttext` = 'img_0683', `imagedate` = '2011-02-05 11:52:31', `exclude` = '0', `sortorder` = '0', `meta_data` = 'eyIwIjpmYWxzZSwiYXBlcnR1cmUiOiJGIDUuNiIsImNyZWRpdCI6ZmFsc2UsImNhbWVyYSI6IkNhbm9uIEVPUyBSRUJFTCBUMWkiLCJjYXB0aW9uIjpmYWxzZSwiY3JlYXRlZF90aW1lc3RhbXAiOiJGZWJydWFyeSA1LCAyMDExIDExOjUyIGFtIiwiY29weXJpZ2h0IjpmYWxzZSwiZm9jYWxfbGVuZ3RoIjoiNTUgbW0iLCJpc28iOjQwMCwic2h1dHRlcl9zcGVlZCI6IjFcLzYwIHNlYyIsImZsYXNoIjoiRmlyZWQiLCJ0aXRsZSI6ZmFsc2UsImtleXdvcmRzIjpmYWxzZSwid2lkdGgiOjE2MDAsImhlaWdodCI6MTA2Nywic2F2ZWQiOnRydWUsInRodW1ibmFpbCI6eyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjc1fSwibmdnMGR5bi0weDI1MC0wMGYwdzAxMWMwMTByMTEwZjExMHIwMTB0MDEwIjp7IndpZHRoIjozNzUsImhlaWdodCI6MjUwLCJmaWxlbmFtZSI6ImltZ18wNjgzLmpwZy1uZ2dpZDAyNDItbmdnMGR5bi0weDI1MC0wMGYwdzAxMWMwMTByMTEwZjExMHIwMTB0MDEwLmpwZyIsImdlbmVyYXRlZCI6IjAuNjczMzIxMDAgMTQzMzYyOTQxMiJ9fQ==', `image_slug` = 'img_0683', `extras_post_id` = '310', `updated_at` = '1433629412' WHERE `pid` = '42'
---- converted to ----
UPDATE wp_ngg_pictures SET pid = '42', post_id = 0, galleryid = '3', filename = 'img_0683.jpg', description = '', alttext = 'img_0683', imagedate = '2011-02-05 11:52:31', exclude = '0', sortorder = '0', meta_data = "'eyIwIjpmYWxzZSwiYXBlcnR1cmUiOiJGIDUuNiIsImNyZWRpdCI6ZmFsc2UsImNhbWVyYSI6IkNhbm9uIEVPUyBSRUJFTCBUMWkiLCJjYXB0aW9uIjpmYWxzZSwiY3JlYXRlZF90aW1lc3RhbXAiOiJGZWJydWFyeSA1LCAyMDExIDExOjUyIGFtIiwiY29weXJpZ2h0IjpmYWxzZSwiZm9jYWxfbGVuZ3RoIjoiNTUgbW0iLCJpc28iOjQwMCwic2h1dHRlcl9zcGVlZCI6IjFcLzYwIHNlYyIsImZsYXNoIjoiRmlyZWQiLCJ0aXRsZSI6ZmFsc2UsImtleXdvcmRzIjpmYWxzZSwid2lkdGgiOjE2MDAsImhlaWdodCI6MTA2Nywic2F2ZWQiOnRydWUsInRodW1ibmFpbCI6eyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjc1fSwibmdnMGR5bi0weDI1MC0wMGYwdzAxMWMwMTByMTEwZjExMHIwMTB0MDEwIjp7IndpZHRoIjozNzUsImhlaWdodCI6MjUwLCJmaWxlbmFtZSI6ImltZ18wNjgzLmpwZy1uZ2dpZDAyNDItbmdnMGR5bi0weDI1MC0wMGYwdzAxMWMwMTByMTEwZjExMHIwMTB0MDEwLmpwZyIsImdlbmVyYXRlZCI6IjAuNjczMzIxMDAgMTQzMzYyOTQxMiJ9fQ=" =', image_slug = 'img_0683', extras_post_id = '310', updated_at = '1433629412' WHERE pid = '42'
----> ERROR: syntax error at or near "img_0683"
LINE 1: ...jczMzIxMDAgMTQzMzYyOTQxMiJ9fQ=" =', image_slug = 'img_0683',...
To avoid this, ensure that the matched substring is not part of a SQL
string literal.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
[Work In Progress] MySQL performs prefix indexing on a few columns.
PostgreSQL lacks support for prefix indexing (although it does support
expression indexing, which can be used to similar effect), which results
in the following error message:
Error running :
ALTER TABLE wp_comments ADD KEY comment_author_email (comment_author_email(10))
---- converted to ----
CREATE INDEX wp_comments_comment_author_email ON wp_comments (comment_author_email(10)
----> ERROR: syntax error at end of input
LINE 1: ...omment_author_email ON wp_comments (comment_author_email(10)
Since the prefix indexing does not currently appear to be advantageous
(other than working around MySQL row index size limitations), convert
these to full-column indexes.
FIXME: SHOW INDEX needs to be updated so that it returns the requested
prefix length in order to avoid attempted index recreation during schema
upgrades. This could be accomplished by storing the length as a comment
or some other ancillary metadata. This is not implemented yet.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
The order of rows returned from SHOW INDEX is significant, and it is
used to determine the column order in multi-column indexes. Update the
query to return rows in the expected order to avoid errors during
upgrade (e.g. in wp_term_taxonomy_term_id_taxonomy where the column
order is not alphabetical).
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This appears as both "SELECT @@SESSION.sql_mode" checked from wp-db.php
in Wordpress core during startup and as "SHOW VARIABLES LIKE 'sql_mode'"
in several extensions (all-in-one-seo-pack, flash-album-gallery, and
nextgen-gallery on my system). Support both by returning the empty
string, which reports the default MySQL behavior (and avoids attempts to
change the mode, since all current code expects this).
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
Wordpress 4 makes use of SHOW COLUMNS and SHOW TABLES in addition to
SHOW INDEX, both with and without the FULL modifier. Implement support
for these statements using queries against INFORMATION_SCHEMA.
Some of these queries use lower-case versions of these statements,
such as "show tables like 'wp_flag_pictures'", so we make sure to
recognize both the upper- and lower-case versions.
This is based, in part, on the work of raptorz in the support forum at
https://wordpress.org/support/topic/upgrade-to-wp421-fail?replies=3#post-6886123
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
The current rewriting changes "default '0000-00-00 00:00:00'" when it
appears in CREATE TABLE statements, but does not handle the case that a
column default value is modified. This results in errors such as the
following during schema upgrade:
Error running :
ALTER TABLE wp_users ALTER COLUMN user_registered SET DEFAULT '0000-00-00 00:00:00'
---- converted to ----
ALTER TABLE wp_users ALTER COLUMN user_registered SET DEFAULT '0000-00-00 00:00:00'
----> ERROR: date/time field value out of range: "0000-00-00 00:00:00"
Apply the conversion to ALTER TABLE statements as well.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
During schema upgrade, populate_options() deletes all expired transients
and their corresponding transient timeouts. The queries produce the
following errors:
Error running :
DELETE a, b FROM wp_options a, wp_options b
WHERE a.option_name LIKE '\_transient\_%'
AND a.option_name NOT LIKE '\_transient\_timeout\_%'
AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
AND b.option_value < 1433110465
---- converted to ----
DELETE a, b FROM wp_options a, wp_options b
WHERE a.option_name LIKE '\_transient\_%'
AND a.option_name NOT LIKE '\_transient\_timeout\_%'
AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
AND b.option_value < 1433110465
----> ERROR: syntax error at or near "a"
LINE 1: DELETE a, b FROM wp_options a, wp_options b
^
---------------------
Error running :
DELETE a, b FROM wp_options a, wp_options b
WHERE a.option_name LIKE '\_site\_transient\_%'
AND a.option_name NOT LIKE '\_site\_transient\_timeout\_%'
AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
AND b.option_value < 1433110465
---- converted to ----
DELETE a, b FROM wp_options a, wp_options b
WHERE a.option_name LIKE '\_site\_transient\_%'
AND a.option_name NOT LIKE '\_site\_transient\_timeout\_%'
AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
AND b.option_value < 1433110465
----> ERROR: syntax error at or near "a"
LINE 1: DELETE a, b FROM wp_options a, wp_options b
^
---------------------
Since PostgreSQL does not support multi-table DELETE statements,
significant rewriting must be done. Since I could not think of a good
generic way to perform this rewriting, recognize this statement
specifically and provide an alternative version.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
Wordpress 4 defaults to using mysqli_* functions in preference to
mysql_*. Since pg4wp only provides replacements for mysql_ functions,
we need to ensure that the mysql_* functions are called. Do this by
defining WP_USE_EXT_MYSQL to true.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>