diff options
author | Thomas Steur <tsteur@users.noreply.github.com> | 2020-08-17 22:52:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-17 22:52:28 +0300 |
commit | ef881fdb46502bfefd2b564c6f7e649d8e5db60b (patch) | |
tree | 2d6372fbb0c628442081c4ef4ff42956221faf23 /core | |
parent | 4451f99ddbba5169678dd6d9f127e87c8dc2ae03 (diff) |
Fix error when primary key is required (#16290)
Diffstat (limited to 'core')
-rw-r--r-- | core/DataAccess/LogAggregator.php | 22 | ||||
-rw-r--r-- | core/Updater/Migration/Db.php | 10 |
2 files changed, 30 insertions, 2 deletions
diff --git a/core/DataAccess/LogAggregator.php b/core/DataAccess/LogAggregator.php index 7697f6b9e4..a4850ebe71 100644 --- a/core/DataAccess/LogAggregator.php +++ b/core/DataAccess/LogAggregator.php @@ -282,7 +282,8 @@ class LogAggregator if (defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE) { $engine = 'ENGINE=MEMORY'; } - $createTableSql = 'CREATE TEMPORARY TABLE ' . $table . ' (idvisit BIGINT(10) UNSIGNED NOT NULL) ' . $engine; + $tempTableIdVisitColumn = 'idvisit BIGINT(10) UNSIGNED NOT NULL'; + $createTableSql = 'CREATE TEMPORARY TABLE ' . $table . ' (' . $tempTableIdVisitColumn . ') ' . $engine; // we do not insert the data right away using create temporary table ... select ... // to avoid metadata lock see eg https://www.percona.com/blog/2018/01/10/why-avoid-create-table-as-select-statement/ @@ -292,8 +293,25 @@ class LogAggregator } catch (\Exception $e) { if ($readerDb->isErrNo($e, \Piwik\Updater\Migration\Db::ERROR_CODE_TABLE_EXISTS)) { return; + } elseif ($readerDb->isErrNo($e, \Piwik\Updater\Migration\Db::ERROR_CODE_REQUIRES_PRIMARY_KEY) + || $readerDb->isErrNo($e, \Piwik\Updater\Migration\Db::ERROR_CODE_UNABLE_CREATE_TABLE_WITHOUT_PRIMARY_KEY + || stripos($e->getMessage(), 'requires a primary key') !== false + || stripos($e->getMessage(), 'table without a primary key') !== false) + ) { + $createTableSql = str_replace($tempTableIdVisitColumn, $tempTableIdVisitColumn . ', PRIMARY KEY (`idvisit`)', $createTableSql); + + try { + $readerDb->query($createTableSql); + } catch (\Exception $e) { + if ($readerDb->isErrNo($e, \Piwik\Updater\Migration\Db::ERROR_CODE_TABLE_EXISTS)) { + return; + } else { + throw $e; + } + } + } else { + throw $e; } - throw $e; } $transactionLevel = new Db\TransactionLevel($readerDb); diff --git a/core/Updater/Migration/Db.php b/core/Updater/Migration/Db.php index b2039c4beb..6cab6233de 100644 --- a/core/Updater/Migration/Db.php +++ b/core/Updater/Migration/Db.php @@ -68,6 +68,16 @@ abstract class Db extends Migration const ERROR_CODE_TABLE_NOT_EXISTS = 1146; /** + * This table type requires a primary key SQL: CREATE TEMPORARY TABLE %s + */ + const ERROR_CODE_REQUIRES_PRIMARY_KEY = 1173; + + /** + * General error: 3750 Unable to create or change a table without a primary key, when the system variable 'sql_require_primary_key' is set. + */ + const ERROR_CODE_UNABLE_CREATE_TABLE_WITHOUT_PRIMARY_KEY = 3750; + + /** * Query execution was interrupted, maximum statement execution time exceeded */ const ERROR_CODE_MAX_EXECUTION_TIME_EXCEEDED_QUERY_INTERRUPTED = 3024; |