mod_storage_sql: Change prosodyarchive_index to be non-unique (fixes #1087)
authorMatthew Wild <mwild1@gmail.com>
Thu, 11 Oct 2018 19:23:21 +0100
changeset 9496 55b40f3fa659
parent 9495 c03c60a2dede
child 9497 b19f676203fd
mod_storage_sql: Change prosodyarchive_index to be non-unique (fixes #1087) MySQL requires that the first 20 bytes are unique, even if they differ after the first 20 bytes. This breaks e.g. pubsub/PEP nodes longer than 20 characters that have common prefixes.
plugins/mod_storage_sql.lua
--- a/plugins/mod_storage_sql.lua	Thu Oct 11 19:15:46 2018 +0100
+++ b/plugins/mod_storage_sql.lua	Thu Oct 11 19:23:21 2018 +0100
@@ -496,7 +496,7 @@
 		Column { name="with", type="TEXT", nullable=false }; -- related id
 		Column { name="type", type="TEXT", nullable=false };
 		Column { name="value", type="MEDIUMTEXT", nullable=false };
-		Index { name="prosodyarchive_index", unique = true, "host", "user", "store", "key" };
+		Index { name="prosodyarchive_index", "host", "user", "store", "key" };
 		Index { name="prosodyarchive_with_when", "host", "user", "store", "with", "when" };
 		Index { name="prosodyarchive_when", "host", "user", "store", "when" };
 	};
@@ -509,13 +509,30 @@
 	local changes = false;
 	if params.driver == "MySQL" then
 		local success,err = engine:transaction(function()
-			local result = engine:execute("SHOW COLUMNS FROM \"prosody\" WHERE \"Field\"='value' and \"Type\"='text'");
-			if result:rowcount() > 0 then
-				changes = true;
-				if apply_changes then
-					module:log("info", "Upgrading database schema...");
-					engine:execute("ALTER TABLE \"prosody\" MODIFY COLUMN \"value\" MEDIUMTEXT");
-					module:log("info", "Database table automatically upgraded");
+			do
+				local result = engine:execute("SHOW COLUMNS FROM \"prosody\" WHERE \"Field\"='value' and \"Type\"='text'");
+				if result:rowcount() > 0 then
+					changes = true;
+					if apply_changes then
+						module:log("info", "Upgrading database schema (value column size)...");
+						engine:execute("ALTER TABLE \"prosody\" MODIFY COLUMN \"value\" MEDIUMTEXT");
+						module:log("info", "Database table automatically upgraded");
+					end
+				end
+			end
+
+			do
+				-- Ensure index is not unique (issue #1087)
+				local result = assert(engine:execute([[SHOW INDEX FROM prosodyarchive WHERE key_name='prosodyarchive_index' and non_unique=0]]));
+				if result:rowcount() > 0 then
+					changes = true;
+					if apply_changes then
+						module:log("info", "Upgrading database schema (prosodyarchive_index)...");
+						engine:execute[[ALTER TABLE "prosodyarchive" DROP INDEX prosodyarchive_index;]];
+						local new_index = sql.Index { table = "prosodyarchive", name="prosodyarchive_index", "host", "user", "store", "key" };
+						engine:_create_index(new_index);
+						module:log("info", "Database table automatically upgraded");
+					end
 				end
 			end
 			return true;