From 32da29b965693fca85e91d178d514c8f3634da9e Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Mar 2021 14:28:41 -0800 Subject: [PATCH] Provide more help around GRANT errors, particularly for missing TEMPORARY TABLE permission Summary: Fixes T13622. Figuring out what permissions we have seems difficult, so address this a bit more narrowly: - Make the "access denied" error message a bit more helpful. - Tailor error handling for the "CREATE TEMPORARY TABLE" statement. Test Plan: - Created a new user, granted them "SELECT ON *.*" but not "CREATE TEMPORARY TABLE", ran `bin/storage upgrade --force --apply phabricator:20210215.changeset.02.phid-populate.php`. - Before: fairly opaque error. - After: fairly useful error. Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam Maniphest Tasks: T13622 Differential Revision: https://secure.phabricator.com/D21608 --- .../20210215.changeset.02.phid-populate.php | 20 +++++++++++++------ .../AphrontBaseMySQLDatabaseConnection.php | 11 +++++++++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/resources/sql/autopatches/20210215.changeset.02.phid-populate.php b/resources/sql/autopatches/20210215.changeset.02.phid-populate.php index 2f35a18172..93f886c7b0 100644 --- a/resources/sql/autopatches/20210215.changeset.02.phid-populate.php +++ b/resources/sql/autopatches/20210215.changeset.02.phid-populate.php @@ -11,12 +11,20 @@ $chunk_size = 4096; $temporary_table = 'tmp_20210215_changeset_id_map'; -queryfx( - $conn, - 'CREATE TEMPORARY TABLE %T ( - changeset_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - changeset_phid VARBINARY(64) NOT NULL)', - $temporary_table); +try { + queryfx( + $conn, + 'CREATE TEMPORARY TABLE %T ( + changeset_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + changeset_phid VARBINARY(64) NOT NULL)', + $temporary_table); +} catch (AphrontAccessDeniedQueryException $ex) { + throw new PhutilProxyException( + pht( + 'Failed to "CREATE TEMPORARY TABLE". You may need to "GRANT" the '. + 'current MySQL user this permission.'), + $ex); +} $table_iterator = id(new LiskRawMigrationIterator($conn, $table_name)) ->setPageSize($chunk_size); diff --git a/src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php b/src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php index 6faf10e2c6..db52eebe8e 100644 --- a/src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php +++ b/src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php @@ -347,7 +347,16 @@ abstract class AphrontBaseMySQLDatabaseConnection case 1142: // Access denied to table case 1143: // Access denied to column case 1227: // Access denied (e.g., no SUPER for SHOW SLAVE STATUS). - throw new AphrontAccessDeniedQueryException($message); + + // See T13622. Try to help users figure out that this is a GRANT + // problem. + + $more = pht( + 'This error usually indicates that you need to "GRANT" the '. + 'MySQL user additional permissions. See "GRANT" in the MySQL '. + 'manual for help.'); + + throw new AphrontAccessDeniedQueryException("{$message}\n\n{$more}"); case 1045: // Access denied (auth) throw new AphrontInvalidCredentialsQueryException($message); case 1146: // No such table -- 2.51.2