Skip to content

[3.0] Puts an index prefix length outside the column's quoting - #9652

Open
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/mysql-table-sql-prefix-index
Open

[3.0] Puts an index prefix length outside the column's quoting#9652
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/mysql-table-sql-prefix-index

Conversation

@albertlast

Copy link
Copy Markdown
Collaborator

Description

On MySQL, table_sql() returns SQL that MySQL will not accept for any table carrying an index on part of a column:

ERROR 1072 (42000): Key column 'member_groups(48)' doesn't exist in table

A column can be indexed by its first so many characters, and list_indexes() reports that the way MySQL states it, as member_groups(48). table_sql() then quotes each index column whole:

$line .= ' (`' . implode('`, `', $index['columns']) . '`)';

which puts the count inside the name and asks for a column called member_groups(48). What MySQL wants is `member_groups`(48), with the count outside the quoting.

Twelve indexes on a forum with nothing added to it are affected, and two of them are primary keys:

table index column
admin_info_files idx_filename filename(191)
boards idx_member_groups member_groups(191)
log_packages filename, idx_filename, idx_hash filename(191), filename(15), sha256_hash(191)
members idx_active_real_name, idx_email_address_ci, idx_lngfile, idx_spoofdetector_name, idx_spoofdetector_name_id real_name(191), email_address_ci(191), lngfile(30), spoofdetector_name(191)
settings PRIMARY variable(191)
themes PRIMARY variable(191)

Nothing in SMF calls table_sql(), which is why this has gone unnoticed. It is public API, reachable through the db_table_sql alias in DatabaseApi::$db_function_map, so a mod using it to record or copy a table gets SQL it cannot run.

PostgreSQL is unaffected: its table_sql() asks the server for each index with pg_get_indexdef() rather than assembling one.

How this was verified

Against a MySQL forum upgraded from the 2.1.7 baseline, by taking Db::$db->table_sql('smf_boards') and running it into an empty database, which is the only thing the output is for:

before after
replaying the output ERROR 1072, no table created runs, exit 0
rebuilt table vs the original columns and keys identical

The comparison is SHOW CREATE TABLE on both, with AUTO_INCREMENT= removed since it records how many rows a table has held rather than its shape.

Not reachable from the unit suite

table_sql() is a database driver method and needs a connection.

Issues References (Fixes|Related|Closes)

  1. Related: [3.0] Lets table_sql read a column that has no default #9651, the same method failing on PostgreSQL for a different reason.

A column can be indexed by its first so many characters, and
list_indexes reports that as part of the column, so table_sql was
quoting "member_groups(48)" whole and naming a column that does not
exist. MySQL refuses the CREATE TABLE it produced:

  ERROR 1072 (42000): Key column 'member_groups(48)' doesn't exist in table

Every table with a prefixed index was affected, which on a stock forum
is boards, members, messages and log_packages.

Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant