Skip to content

[3.0] Lets table_sql read a column that has no default - #9651

Open
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/pg-table-sql-null-default
Open

[3.0] Lets table_sql read a column that has no default#9651
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/pg-table-sql-null-default

Conversation

@albertlast

Copy link
Copy Markdown
Collaborator

Description

table_sql() cannot run on PostgreSQL. It ends on the first column that has no default, which every table has:

PHP Fatal error:  Uncaught TypeError: trim(): Argument #1 ($string) must be of type string, null given in Sources/Db/APIs/PostgreSQL.php:1145
#0 Sources/Db/APIs/PostgreSQL.php(1145): trim(NULL)
#1 ...: SMF\Db\APIs\PostgreSQL->table_sql('smf_boards')

information_schema.columns.column_default is null for a column that has no default, and the code asks trim() about it before looking:

if (trim($row['column_default']) != '') {

trim(null) has been deprecated since PHP 8.1, and the file declares strict_types, so it is a TypeError rather than a notice. The intent is already there in the comparison against ''; only the null has to reach it.

Nothing in SMF calls table_sql(), which is why this has gone unnoticed. It is public API and reachable through the db_table_sql alias in DatabaseApi::$db_function_map, so a mod calling it on PostgreSQL gets a fatal.

With the null handled, the method does what it says. For smf_boards:

CREATE SEQUENCE smf_boards_seq START WITH 25;

DROP TABLE IF EXISTS smf_boards;

CREATE TABLE smf_boards (
 "id_board" smallint NOT NULL default nextval('smf_boards_seq'::regclass),
 "id_cat" smallint NOT NULL default 0,
 ...
 "posts_count" smallint NOT NULL default 1
);
CREATE UNIQUE INDEX smf_boards_idx_categories ON public.smf_boards USING btree (id_cat, id_board);
CREATE INDEX smf_boards_idx_id_parent ON public.smf_boards USING btree (id_parent);
CREATE INDEX smf_boards_idx_id_msg_updated ON public.smf_boards USING btree (id_msg_updated);
CREATE INDEX smf_boards_idx_member_groups ON public.smf_boards USING btree (member_groups varchar_pattern_ops);
ALTER TABLE smf_boards ADD PRIMARY KEY (id_board);

How this was verified

Against a PostgreSQL forum upgraded from the 2.1.7 baseline, calling Db::$db->table_sql() through SSI: fatal on every table before, and the definition above after. The sequence, the defaults, the indexes and the primary key are all in it, and START WITH 25 matches the 24 boards the baseline holds.

MySQL reaches the same information through table_structure() and does not read column_default this way, so it is unaffected.

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] Keeps a backup table from depending on the live table's sequence #9650. A definition dump is a candidate for what a backup should keep, and this is what stops one being taken on PostgreSQL today.

information_schema.columns.column_default is null for a column without
one, and trim() has not taken null since PHP 8.1. The file declares
strict_types, so the first such column ends the method rather than
being passed over, and every table has one.

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