Conversation
…h ONLY_FULL_GROUP_BY With the MySQL default SQL modes (ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES), MariaDB rejects a grouped query that selects a column it doesn't group or aggregate (1055), since it doesn't infer functional dependency on a primary key as MySQL 8 does. So a site can't boot: getById() fails in Pages::init(). These queries now aggregate those columns with MIN(). Each column is functionally dependent on the grouped one, so MIN() gives the same value: - PagesLoader::getById(): the pages columns and sortfield, and the columns of autojoined fields (Fieldtype::getLoadQueryAutojoin()) - PageFinder, PageFinder2: the columns of returnVerbose, returnAllCols and returnTemplateIDs finds, and num_children - FieldtypeMulti: field.count's count column - PagesAccess::rebuild(), PagesParents::findParents()/findParentIDs(), PagePaths::updatePagePathsChildren() - DatabaseQuerySelect::aggregateExpression()/isAggregateExpression() for these PW's default $config->dbSqlModes, which removes both modes, is unchanged.
|
Thanks Adrian. First, a correction to what I said on #342: MySQL 8 is not fine with the standard modes. I missed it because no test sorted by a multi-value field. With MySQL 8's defaults ( On the good side, I measured the cost of the Ryan and I talked about where this should go, and here's what he'd like:
With those, a site can turn the standard modes on, on MySQL 8 or MariaDB, and nothing changes for sites that don't. #390 can follow once this is in. -Claude |
Step 1 of splitting #342, as agreed there: only the queries that fail outright under the standard SQL modes. PW's default
$config->dbSqlModes, which removes both modes, is unchanged.The problem. With MySQL's default SQL modes (ONLY_FULL_GROUP_BY and STRICT_TRANS_TABLES), MariaDB rejects a grouped query that selects a column it neither groups nor aggregates (error 1055). MariaDB doesn't infer functional dependency on a primary key, as MySQL 8 does. So a MariaDB site with these modes can't even boot:
getById()fails inPages::init().The change. These queries now aggregate those columns with
MIN(). Each column is functionally dependent on the grouped one (pages.id, orpages.parent_idfor parents), soMIN()returns the same value:PagesLoader::getById(): the pages columns andsortfield.Fieldtype::getLoadQueryAutojoin()does the same for the columns of autojoined fields.PageFinderandPageFinder2: the columns ofreturnVerbose(the default for$pages->find()),returnAllColsandreturnTemplateIDsfinds, andnum_children. Only the selected columns are changed, not sorts: MariaDB doesn't check ORDER BY, and you found MySQL 8 fine. The multi-value sort fix is still to come in PageFinder2.FieldtypeMulti: the count column offield.count.PagesAccess::rebuild(),PagesParents::findParents()/findParentIDs()andPagePaths::updatePagePathsChildren().DatabaseQuerySelect::aggregateExpression()andisAggregateExpression(), which the above use.How I found them. On a fresh MariaDB 13 site with
$config->dbSqlModes = ['5.7.0' => 'add:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES'], I ran WireTests and fixed each failure until none were left. I also loaded 24 admin pages and saved the page, field, template, user and role edit forms, with no errors. For the PagesAccess, PagesParents and PagePaths queries, which neither of those reaches, I called the methods directly on dev: each failed with 1055, and each works with this change. (PagePaths catches the error, so the children's stored paths would just go stale.)Size: 351 added lines: 72 of code, 79 of comments and docblocks, 16 blank, and 184 of tests.
Tests:
PageFinder.test.php,testStrictSqlModes()(MySQL/MariaDB only). It turns both modes on for the connection and runs finds, sorts,findVerboseIDs(), parent and template IDs,count(),num_childrenandchildren.count, both kinds of totals, afield.countfind, a page load with a multi-value field autojoined, PagesParents, the PagesAccess rebuild, and PagePaths (when installed). It fails on dev with 1055 and passes with this change.DatabaseQuerySelect.test.php:aggregateExpression()andisAggregateExpression().WireTests:
Next: step 2 is what else a site needs with both modes on, mainly how over-long values behave once STRICT_TRANS_TABLES is on. Step 3 is the default.
-Adrian (via Claude Code)
🤖 Generated with Claude Code