ENH Add index for default_sort on many_many tables#11785
ENH Add index for default_sort on many_many tables#11785emteknetnz merged 1 commit intosilverstripe:6from
Conversation
| /** | ||
| * Derive the index spec for default_sort, e.g. for a DataObject table or for a many_many join table. | ||
| */ | ||
| public function deriveIndexFromSort(string $tableName, array $fieldNames, string|array $sort, string $indexMode): array |
There was a problem hiding this comment.
Logic for this method is just all pulled out of buildSortDatabaseIndexes() so we can reuse it in DataObject for many_many join tables
4cfba15 to
4b579f8
Compare
4b579f8 to
3b8814a
Compare
| // Indexes aren't included in transactions, which means they aren't reset after the test is torn down. | ||
| // Because of that, we need to reset the index manually by rebuilding the table. | ||
| Config::inst()->set('ManyManyListTest_ExtraFields_Clients', 'default_sort', null); | ||
| DB::get_schema()->schemaUpdate(fn () => $obj->requireTable()); |
emteknetnz
left a comment
There was a problem hiding this comment.
Could you also rebase framework on to this? I attempted to do a kitchen sink CI run (just this PR, not any of the others) to double check this, though it complained that "Class Generated does not exist" - since there is no Generated class, instead DBGenerated, something's go wrong. I also go the same issue trying to run this PR locally.
|
fc52832 to
4a1c447
Compare
4a1c447 to
18cf152
Compare
There was a problem hiding this comment.
I'm just having a little trouble validating this works, though it's probably more my lack on understanding rather than any thing in this PR
Seems like the DB indexes are the same whether or not this PR is present or not?
// app/MyDataObject.php
use SilverStripe\ORM\DataObject;
class MyDataObject extends DataObject
{
private static $table_name = 'MyDataObject';
private static $db = [
'Foo' => 'Varchar'
];
private static $many_many = [
'MyOtherDataObjects' => MyOtherDataObject::class
];
private static $default_sort = 'Foo ASC';
}// app/MyOtherDataObject.php
use SilverStripe\ORM\DataObject;
class MyDataObject extends DataObject
{
private static $table_name = 'MyDataObject';
private static $db = [
'Bar' => 'Varchar'
];
private static $many_many = [
'MyOtherDataObjects' => MyOtherDataObject::class
];
private static $default_sort = 'Title ASC';
}
```text
# show indexes from MyDataObject;
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Ignored |
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| MyDataObject | 0 | PRIMARY | 1 | ID | A | 0 | NULL | NULL | | BTREE | | | NO |
| MyDataObject | 1 | Foo | 1 | Foo | A | 0 | NULL | NULL | YES | BTREE | | | NO |
| MyDataObject | 1 | ClassName | 1 | ClassName | A | 0 | NULL | NULL | YES | BTREE | | | NO |
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
# show indexes from MyOtherDataObject;
+-------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Ignored |
+-------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| MyOtherDataObject | 0 | PRIMARY | 1 | ID | A | 0 | NULL | NULL | | BTREE | | | NO |
| MyOtherDataObject | 1 | Bar | 1 | Bar | A | 0 | NULL | NULL | YES | BTREE | | | NO |
| MyOtherDataObject | 1 | ClassName | 1 | ClassName | A | 0 | NULL | NULL | YES | BTREE | | | NO |
+-------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
# show indexes from MyDataObject_MyOtherDataObjects;
+---------------------------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Ignored |
+---------------------------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| MyDataObject_MyOtherDataObjects | 0 | PRIMARY | 1 | ID | A | 0 | NULL | NULL | | BTREE | | | NO |
| MyDataObject_MyOtherDataObjects | 1 | MyDataObjectID | 1 | MyDataObjectID | A | 0 | NULL | NULL | | BTREE | | | NO |
| MyDataObject_MyOtherDataObjects | 1 | MyOtherDataObjectID | 1 | MyOtherDataObjectID | A | 0 | NULL | NULL | | BTREE | | | NO |
+---------------------------------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+|
It's not the default sort for either model, it's for the many_many join table itself. It's documented in https://docs.silverstripe.org/en/6/developer_guides/model/relations/#:~:text=To%20ensure%20this,to%20your%20config You need to add some YAML config (the extrafields can be in your PHP class but the sort has to be in YAML) MyDataObject:
many_many_extraFields:
MyOtherDataObjects:
SomeField: 'Int'
MyDataObject_MyOtherDataObjects:
default_sort: 'SomeField ASC' |
|
Can you please also merge the other PRs which have been approved? None of them except the docs PR rely on this in any way. |
emteknetnz
left a comment
There was a problem hiding this comment.
Cool thanks, index now shows up with this PR
default_sorton aDataObjectresults in an index being added. The same should happen with the join table formany_manyrelations.Note that because MySQL (and probably others) can only use a single index at a time, I've opted to add the sort index columns into the existing child and parent ID indexes. This means we can filter by ID and sort by the default sort all using the same index.
If a different sort is applied, the first column (the parent or child ID) in the index can still be used for filtering.
Issue