[Rt-commit] rt branch 4.4/mysql-8 created. rt-4.4.6-17-g79f9995346

BPS Git Server git at git.bestpractical.com
Wed Jul 20 13:03:11 UTC 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 4.4/mysql-8 has been created
        at  79f99953464fc5c18c3369348fc56a85727b9c90 (commit)

- Log -----------------------------------------------------------------
commit 79f99953464fc5c18c3369348fc56a85727b9c90
Author: Brian Conry <bconry at bestpractical.com>
Date:   Wed Jul 20 08:01:10 2022 -0500

    Make github actions prove recursively
    
    Previously the github actions were not operating recursively, causing
    some tests to be missed in the automated testing.

diff --git a/.github/workflows/github-action.yml b/.github/workflows/github-action.yml
index f2ec94c2a3..a6a25db38a 100644
--- a/.github/workflows/github-action.yml
+++ b/.github/workflows/github-action.yml
@@ -29,7 +29,7 @@ jobs:
           docker exec rt bash -c "cd /rt && ./configure.ac --with-db-type=SQLite --with-my-user-group --enable-layout=inplace --enable-developer --enable-externalauth --enable-gpg --enable-smime && mkdir -p /rt/var && make testdeps"
       - name: Run RT tests
         shell: bash
-        run: docker exec -e RT_TEST_PARALLEL=1 rt bash -c "cd /rt && prove -lj6 t/*"
+        run: docker exec -e RT_TEST_PARALLEL=1 rt bash -c "cd /rt && prove -rlj6 t/"
       - name: Get run time
         shell: bash
         run: |
@@ -85,7 +85,7 @@ jobs:
           RT_DBA_PASSWORD: password
           DB_VERSION_TAG: 10.3
         shell: bash
-        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=root -e RT_DBA_PASSWORD=password rt bash -c "cd /rt && prove -lj6 t/*"
+        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=root -e RT_DBA_PASSWORD=password rt bash -c "cd /rt && prove -rlj6 t/"
       - name: Get run time
         shell: bash
         run: |
@@ -141,7 +141,7 @@ jobs:
           RT_DBA_PASSWORD: password
           DB_VERSION_TAG: 8.0
         shell: bash
-        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=root -e RT_DBA_PASSWORD=password rt bash -c "cd /rt && prove -lj6 t/*"
+        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=root -e RT_DBA_PASSWORD=password rt bash -c "cd /rt && prove -rlj6 t/"
       - name: Get run time
         shell: bash
         run: |
@@ -202,7 +202,7 @@ jobs:
           RT_TEST_APACHE: /usr/sbin/apache2
           RT_TEST_APACHE_MODULES: /usr/lib/apache2/modules
         shell: bash
-        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=postgres -e RT_DBA_PASSWORD=password -u rt-user rt bash -c "cd /rt && prove -lj6 t/*"
+        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=postgres -e RT_DBA_PASSWORD=password -u rt-user rt bash -c "cd /rt && prove -rlj6 t/"
       - name: Get run time
         shell: bash
         run: |
@@ -263,7 +263,7 @@ jobs:
           RT_TEST_APACHE: /usr/sbin/apache2
           RT_TEST_APACHE_MODULES: /usr/lib/apache2/modules
         shell: bash
-        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=postgres -e RT_DBA_PASSWORD=password -u rt-user rt bash -c "cd /rt && prove -lj6 t/*"
+        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=postgres -e RT_DBA_PASSWORD=password -u rt-user rt bash -c "cd /rt && prove -rlj6 t/"
       - name: Get run time
         shell: bash
         run: |

commit 8bc889e71b724fd7ec69156b7fa25d37af2eb653
Author: Brian Conry <bconry at bestpractical.com>
Date:   Mon Jul 18 13:12:51 2022 -0500

    Add github actions for new databases
    
    This adds a github action for testing with mysql8 using the latest
    version of the official image, and also an action for testing with
    PostgreSQL 10, also using the latest version of the official image.

diff --git a/.github/workflows/github-action.yml b/.github/workflows/github-action.yml
index f706368ad6..f2ec94c2a3 100644
--- a/.github/workflows/github-action.yml
+++ b/.github/workflows/github-action.yml
@@ -111,6 +111,62 @@ jobs:
           fields: |
             [{ "title": "Configuration", "value": "RT Server, MariaDB 10.3", "short": true },
             { "title": "URL", "value": "${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}?check_suite_focus=true", "short": true }]
+  rt_test_mysql8:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Set up for tests
+        shell: bash
+        run: |
+          echo "RT_BRANCH_NAME=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
+          echo "RT_GA_START_TIME=$(date +%s)" >> $GITHUB_ENV
+      - name: Checkout RT
+        uses: actions/checkout at v2
+      - name: Build RT
+        env:
+          RT_TEST_PARALLEL: 1
+          RT_DBA_USER: root
+          RT_DBA_PASSWORD: password
+          DB_VERSION_TAG: 8.0
+        shell: bash
+        run: |
+          docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:$DB_VERSION_TAG  --default-authentication-plugin=mysql_native_password
+          docker build -t rt-base .
+          docker run -d -v $GITHUB_WORKSPACE:/rt --name rt --link mysql:db rt-base
+          docker ps -a
+          docker exec rt bash -c "cd /rt && ./configure.ac --with-db-type=mysql --with-my-user-group --enable-layout=inplace --enable-developer --enable-externalauth --enable-gpg --enable-smime && mkdir -p /rt/var && make testdeps"
+      - name: Run RT tests
+        env:
+          RT_TEST_PARALLEL: 1
+          RT_DBA_USER: root
+          RT_DBA_PASSWORD: password
+          DB_VERSION_TAG: 8.0
+        shell: bash
+        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=root -e RT_DBA_PASSWORD=password rt bash -c "cd /rt && prove -lj6 t/*"
+      - name: Get run time
+        shell: bash
+        run: |
+          export RT_GA_END_TIME=$(date +%s)
+          echo RT_GA_START_TIME ${{ env.RT_GA_START_TIME }}
+          echo RT_GA_END_TIME $RT_GA_END_TIME
+          echo "RT_GA_END_TIME=$RT_GA_END_TIME" >> $GITHUB_ENV
+          export RT_GA_TEST_TIME=$(( RT_GA_END_TIME - ${{ env.RT_GA_START_TIME }} ))
+          # Convert seconds to HH::MM::SS
+          export RT_GA_TEST_TIME=$(date -u -d @"$RT_GA_TEST_TIME" +"%T")
+          echo "RT_GA_TEST_TIME=$RT_GA_TEST_TIME" >> $GITHUB_ENV
+      - name: Post results to Slack
+        if: always()
+        uses: edge/simple-slack-notify at v1.1.1
+        env:
+          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_NOTIFICATIONS }}
+        with:
+          channel: '#github'
+          status: ${{ job.status }}
+          success_text: '${env.RT_BRANCH_NAME} (${env.GITHUB_RUN_NUMBER}) tests completed successfully in ${env.RT_GA_TEST_TIME}'
+          failure_text: '${env.RT_BRANCH_NAME} (${env.GITHUB_RUN_NUMBER}) tests failed in ${env.RT_GA_TEST_TIME}'
+          cancelled_text: '${env.RT_BRANCH_NAME} (${env.GITHUB_RUN_NUMBER}) tests cancelled in ${env.RT_GA_TEST_TIME}'
+          fields: |
+            [{ "title": "Configuration", "value": "RT Server, MySQL 8.0", "short": true },
+            { "title": "URL", "value": "${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}?check_suite_focus=true", "short": true }]
   rt_test_postgresql_apache_mod_fcgid:
     runs-on: ubuntu-latest
     steps:
@@ -172,3 +228,64 @@ jobs:
           fields: |
             [{ "title": "Configuration", "value": "Apache mod_fcgid, PostgreSQL 9.6", "short": true },
             { "title": "URL", "value": "${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}?check_suite_focus=true", "short": true }]
+  rt_test_postgresql10_apache_mod_fcgid:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Set up for tests
+        shell: bash
+        run: |
+          echo "RT_BRANCH_NAME=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
+          echo "RT_GA_START_TIME=$(date +%s)" >> $GITHUB_ENV
+      - name: Checkout RT
+        uses: actions/checkout at v2
+      - name: Build RT
+        env:
+          DB_VERSION_TAG: 10
+          RT_TEST_PARALLEL: 1
+          RT_TEST_WEB_HANDLER: apache+fcgid
+          HTTPD_ROOT: /etc/apache2
+          RT_TEST_APACHE: /usr/sbin/apache2
+          RT_TEST_APACHE_MODULES: /usr/lib/apache2/modules
+        shell: bash
+        run: |
+          docker run --name postgresql10 --mount type=tmpfs,destination=/var/lib/postgresql/data -e POSTGRES_PASSWORD=password -d postgres:$DB_VERSION_TAG
+          docker build -t rt-base .
+          docker run -d -v $GITHUB_WORKSPACE:/rt --name rt --link postgresql10:db rt-base
+          docker ps -a
+          docker exec rt bash -c "chown -R rt-user /rt; touch /etc/apache2/mime.types"
+          docker exec -e USER=rt-user -u rt-user rt bash -c "cd /rt && ./configure.ac --with-db-type=Pg --with-my-user-group --enable-layout=inplace --with-web-handler=fcgid --enable-developer --enable-externalauth --enable-gpg --enable-smime && mkdir -p /rt/var && make testdeps && chmod a+rX /rt/sbin/*"
+      - name: Run RT tests
+        env:
+          DB_VERSION_TAG: 9.6
+          RT_TEST_PARALLEL: 1
+          RT_TEST_WEB_HANDLER: apache+fcgid
+          HTTPD_ROOT: /etc/apache2
+          RT_TEST_APACHE: /usr/sbin/apache2
+          RT_TEST_APACHE_MODULES: /usr/lib/apache2/modules
+        shell: bash
+        run: docker exec -e RT_TEST_PARALLEL=1 -e RT_DBA_USER=postgres -e RT_DBA_PASSWORD=password -u rt-user rt bash -c "cd /rt && prove -lj6 t/*"
+      - name: Get run time
+        shell: bash
+        run: |
+          export RT_GA_END_TIME=$(date +%s)
+          echo RT_GA_START_TIME ${{ env.RT_GA_START_TIME }}
+          echo RT_GA_END_TIME $RT_GA_END_TIME
+          echo "RT_GA_END_TIME=$RT_GA_END_TIME" >> $GITHUB_ENV
+          export RT_GA_TEST_TIME=$(( RT_GA_END_TIME - ${{ env.RT_GA_START_TIME }} ))
+          # Convert seconds to HH::MM::SS
+          export RT_GA_TEST_TIME=$(date -u -d @"$RT_GA_TEST_TIME" +"%T")
+          echo "RT_GA_TEST_TIME=$RT_GA_TEST_TIME" >> $GITHUB_ENV
+      - name: Post results to Slack
+        if: always()
+        uses: edge/simple-slack-notify at v1.1.1
+        env:
+          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_NOTIFICATIONS }}
+        with:
+          channel: '#github'
+          status: ${{ job.status }}
+          success_text: '${env.RT_BRANCH_NAME} (${env.GITHUB_RUN_NUMBER}) tests completed successfully in ${env.RT_GA_TEST_TIME}'
+          failure_text: '${env.RT_BRANCH_NAME} (${env.GITHUB_RUN_NUMBER}) tests failed in ${env.RT_GA_TEST_TIME}'
+          cancelled_text: '${env.RT_BRANCH_NAME} (${env.GITHUB_RUN_NUMBER}) tests cancelled in ${env.RT_GA_TEST_TIME}'
+          fields: |
+            [{ "title": "Configuration", "value": "Apache mod_fcgid, PostgreSQL 10", "short": true },
+            { "title": "URL", "value": "${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}?check_suite_focus=true", "short": true }]

commit 32a35ef0207f4d352d95b70e3d7772d51f93e36b
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jan 21 05:19:42 2021 +0800

    Update DBIx::SearchBuilder to 1.69 to work with MySQL 8

diff --git a/sbin/rt-test-dependencies.in b/sbin/rt-test-dependencies.in
index 941af7834d..1a5eb434b0 100644
--- a/sbin/rt-test-dependencies.in
+++ b/sbin/rt-test-dependencies.in
@@ -249,7 +249,7 @@ FCGI 0.74
 .
 
 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
-DBIx::SearchBuilder 1.68
+DBIx::SearchBuilder 1.69
 DBD::mysql 2.1018
 .
 

commit 8294129c3b54db785963680df1fcf8adeec9624d
Author: Aaron Trevena <ast at bestpractical.com>
Date:   Tue Sep 1 16:19:56 2020 +0100

    Make RT work with MySQL 8
    
    Update code for the following changes in MySQL 8:
    
    * "Groups" is a reversed word
    
    We need to quote it accordingly.
    
    * Can't create user using GRANT any more
    
    We need to create user first and then grant privileges.

diff --git a/etc/acl.mysql b/etc/acl.mysql
index 26e27fbfbc..da148bde66 100644
--- a/etc/acl.mysql
+++ b/etc/acl.mysql
@@ -1,5 +1,6 @@
 
 sub acl {
+    my $dbh = shift;
     my $db_name = RT->Config->Get('DatabaseName');
     my $db_rthost = RT->Config->Get('DatabaseRTHost');
     my $db_user = RT->Config->Get('DatabaseUser');
@@ -13,6 +14,19 @@ sub acl {
         return;
     }
     $db_name =~ s/([_%\\])/\\$1/g;
+
+    if ( my $version = ( $dbh->selectrow_array("show variables like 'version'") )[1] ) {
+        if ( $version !~ /mariadb/i && $version =~ /^(\d+)\./ ) {
+            # run 2 part acl update for mysql 8 or higher
+            if ( $1 >= 8 ) {
+                return (
+                    "CREATE USER IF NOT EXISTS '$db_user'\@'$db_rthost' IDENTIFIED BY '$db_pass';",
+                    "GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE ON `$db_name`.* TO '$db_user'\@'$db_rthost';",
+                );
+            }
+        }
+    }
+
     return (
         "GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE
                ON `$db_name`.*
diff --git a/etc/schema.mysql b/etc/schema.mysql
index 21975aba55..a2d361c866 100644
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@ -70,7 +70,7 @@ CREATE TABLE Principals (
 ) ENGINE=InnoDB CHARACTER SET ascii;
 
 
-CREATE TABLE Groups (
+CREATE TABLE `Groups` (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   Name varchar(200) NULL  ,
   Description varchar(255) NULL  ,
@@ -83,8 +83,8 @@ CREATE TABLE Groups (
   PRIMARY KEY (id)
 ) ENGINE=InnoDB CHARACTER SET utf8;
 
-CREATE INDEX Groups1 ON Groups (Domain, Name, Instance);
-CREATE INDEX Groups2 On Groups (Instance);
+CREATE INDEX Groups1 ON `Groups` (Domain, Name, Instance);
+CREATE INDEX Groups2 On `Groups` (Instance);
 
 CREATE TABLE ScripConditions (
   id INTEGER NOT NULL  AUTO_INCREMENT,
diff --git a/etc/upgrade/3.9.5/schema.mysql b/etc/upgrade/3.9.5/schema.mysql
index 83f2f4087f..2a40f46414 100644
--- a/etc/upgrade/3.9.5/schema.mysql
+++ b/etc/upgrade/3.9.5/schema.mysql
@@ -6,7 +6,7 @@ AND CustomFieldValues.id = Attributes.ObjectId);
 
 DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue';
 
-ALTER TABLE Groups
+ALTER TABLE `Groups`
     ADD COLUMN Creator integer NOT NULL DEFAULT 0,
     ADD COLUMN Created DATETIME NULL,
     ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
diff --git a/etc/upgrade/4.1.13/backcompat b/etc/upgrade/4.1.13/backcompat
index 0dc53d224f..1126995277 100644
--- a/etc/upgrade/4.1.13/backcompat
+++ b/etc/upgrade/4.1.13/backcompat
@@ -22,6 +22,12 @@ if ( $groups->Next ) {
             WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal')
                 OR LOWER(Domain) LIKE '%-role'"
         );
+    } elsif ( $db_type eq 'mysql' ) {
+        $dbh->do(
+            "UPDATE `Groups` SET Name = Type
+            WHERE Domain IN ('ACLEquivalence', 'SystemInternal')
+                OR Domain LIKE '%-Role'"
+        );
     } else {
         $dbh->do(
             "UPDATE Groups SET Name = Type
diff --git a/etc/upgrade/4.1.13/schema.mysql b/etc/upgrade/4.1.13/schema.mysql
index a429007e30..33e162fca2 100644
--- a/etc/upgrade/4.1.13/schema.mysql
+++ b/etc/upgrade/4.1.13/schema.mysql
@@ -1,2 +1,2 @@
-UPDATE Groups SET Name = Type
-WHERE Domain IN ('ACLEquivalence', 'SystemInternal') OR Domain LIKE '%-Role';
\ No newline at end of file
+UPDATE `Groups` SET Name = Type
+WHERE Domain IN ('ACLEquivalence', 'SystemInternal') OR Domain LIKE '%-Role';
diff --git a/etc/upgrade/4.1.4/schema.mysql b/etc/upgrade/4.1.4/schema.mysql
index e530ede81d..8a727b5eef 100644
--- a/etc/upgrade/4.1.4/schema.mysql
+++ b/etc/upgrade/4.1.4/schema.mysql
@@ -1 +1 @@
-UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0;
+UPDATE `Groups` SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0;
diff --git a/etc/upgrade/4.3.13/schema.mysql b/etc/upgrade/4.3.13/schema.mysql
index 31328a030b..d7ade7e2a7 100644
--- a/etc/upgrade/4.3.13/schema.mysql
+++ b/etc/upgrade/4.3.13/schema.mysql
@@ -15,6 +15,6 @@ ALTER TABLE Users
 ALTER TABLE Principals
   DROP COLUMN ObjectId;
 
-ALTER TABLE Groups
+ALTER TABLE `Groups`
    DROP COLUMN Type;
 
diff --git a/etc/upgrade/4.4.2/content b/etc/upgrade/4.4.2/content
index 790342ddf8..e9998e54f1 100644
--- a/etc/upgrade/4.4.2/content
+++ b/etc/upgrade/4.4.2/content
@@ -22,9 +22,10 @@ our @Initial = (
 
     # fix up inconsistent denormalized owner vs owner-role group members (#32381)
     sub {
-        my $sth = RT->DatabaseHandle->dbh->prepare(q[
+        my $groups_table = RT->Config->Get('DatabaseType') eq 'mysql' ? '`Groups`' : 'Groups';
+        my $sth = RT->DatabaseHandle->dbh->prepare(qq[
             SELECT Tickets.Id, Tickets.Owner, GroupMembers.MemberId
-            FROM Groups
+            FROM $groups_table
             JOIN GroupMembers ON Groups.Id = GroupMembers.GroupId
             JOIN Tickets ON Tickets.Id = Groups.Instance
             WHERE Groups.Name = 'Owner'
diff --git a/etc/upgrade/upgrade-mysql-schema.pl b/etc/upgrade/upgrade-mysql-schema.pl
index 6ef9247e08..f50572be9b 100755
--- a/etc/upgrade/upgrade-mysql-schema.pl
+++ b/etc/upgrade/upgrade-mysql-schema.pl
@@ -306,7 +306,7 @@ sub convert_table {
     }
     for my $conversiontype (qw(char_to_binary binary_to_char)) {
         next unless @{$alter_aggregator{$conversiontype}};
-        push @sql_commands, qq{ALTER TABLE $table\n   }.
+        push @sql_commands, qq{ALTER TABLE `$table`\n   }.
             join(",\n   ",@{$alter_aggregator{$conversiontype}});
     }
 }
diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index 9f1da0cdec..2f7c8caa14 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -1765,7 +1765,7 @@ sub DropIndex {
     if ( $db_type eq 'mysql' ) {
         $args{'Table'} = $self->_CanonicTableNameMysql( $args{'Table'} );
         $res = $dbh->do(
-            'drop index '. $dbh->quote_identifier($args{'Name'}) ." on $args{'Table'}",
+            'drop index '. $dbh->quote_identifier($args{'Name'}) ." on ". $dbh->quote_identifier($args{'Table'}),
         );
     }
     elsif ( $db_type eq 'Pg' ) {
@@ -1824,8 +1824,9 @@ sub CreateIndex {
     my $self = shift;
     my %args = ( Table => undef, Name => undef, Columns => [], CaseInsensitive => {}, @_ );
 
-    $args{'Table'} = $self->_CanonicTableNameMysql( $args{'Table'} )
-        if RT->Config->Get('DatabaseType') eq 'mysql';
+    if (RT->Config->Get('DatabaseType') eq 'mysql') {
+        $args{'Table'} = $self->QuoteName( $self->_CanonicTableNameMysql( $args{'Table'} ));
+    }
 
     my $name = $args{'Name'};
     unless ( $name ) {
diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm
index 7489a02eca..18dde5caaf 100644
--- a/lib/RT/Principal.pm
+++ b/lib/RT/Principal.pm
@@ -615,8 +615,9 @@ sub _HasRoleRightQuery {
     $groups->LimitToUserDefinedGroups;
     $groups->WithMember( PrincipalId => $self->id, Recursively => 1 );
 
+    my $groups_table = $self->can('QuotedTableName') ? $self->QuotedTableName('Groups') : 'Groups';
     my $query =
-        " FROM Groups, Principals, CachedGroupMembers WHERE "
+        " FROM $groups_table, Principals, CachedGroupMembers WHERE "
 
         # Never find disabled things
         . "Principals.Disabled = 0 " . "AND CachedGroupMembers.Disabled = 0 "
diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index 7189125a8b..6dc972542a 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -1601,6 +1601,7 @@ entire database.
 sub LockForUpdate {
     my $self = shift;
 
+    my $table = $self->can('QuotedTableName') ? $self->QuotedTableName($self->Table) : $self->Table;
     my $pk = $self->_PrimaryKey;
     my $id = @_ ? $_[0] : $self->$pk;
     $self->_expire if $self->isa("DBIx::SearchBuilder::Record::Cachable");
@@ -1609,12 +1610,11 @@ sub LockForUpdate {
         # "RESERVED" on the first UPDATE/INSERT/DELETE.  Do a no-op
         # UPDATE to force the upgade.
         return RT->DatabaseHandle->dbh->do(
-            "UPDATE " .$self->Table.
-                " SET $pk = $pk WHERE 1 = 0");
+            "UPDATE $table SET $pk = $pk WHERE 1 = 0"
+        );
     } else {
         return $self->_LoadFromSQL(
-            "SELECT * FROM ".$self->Table
-                ." WHERE $pk = ? FOR UPDATE",
+            "SELECT * FROM $table WHERE $pk = ? FOR UPDATE",
             $id,
         );
     }
diff --git a/sbin/rt-validator.in b/sbin/rt-validator.in
index 14cb5f3df6..5b4771bc5b 100644
--- a/sbin/rt-validator.in
+++ b/sbin/rt-validator.in
@@ -97,6 +97,7 @@ END
 
 my $dbh = $RT::Handle->dbh;
 my $db_type = RT->Config->Get('DatabaseType');
+my $groups_table = $db_type eq 'mysql' ? '`Groups`' : 'Groups' ;
 
 my %TYPE = (
     'Transactions.Field'    => 'text',
@@ -608,7 +609,7 @@ FROM
         AND cgm3.MemberId          = gm2.MemberId
         AND cgm3.Via               = cgm1.id
         AND cgm3.ImmediateParentId = cgm1.MemberId )
-    LEFT JOIN Groups g ON (
+    LEFT JOIN $groups_table g ON (
         cgm1.GroupId = g.id
     )
 WHERE cgm1.GroupId != cgm1.MemberId
@@ -680,7 +681,7 @@ push @CHECKS, 'Tickets -> other' => sub {
     {
         my $query = <<END;
 SELECT Tickets.Id, Tickets.Owner
-FROM Groups
+FROM $groups_table
 JOIN Tickets ON Tickets.Id = Groups.Instance
 LEFT JOIN GroupMembers ON Groups.Id = GroupMembers.GroupId
 WHERE Groups.Name = 'Owner'
@@ -717,7 +718,7 @@ END
     {
         my $query = <<END;
 SELECT Tickets.Id, Tickets.Owner, GroupMembers.MemberId
-FROM Groups
+FROM $groups_table
 JOIN GroupMembers ON Groups.Id = GroupMembers.GroupId
 JOIN Tickets ON Tickets.Id = Groups.Instance
 WHERE Groups.Name = 'Owner'
@@ -1006,10 +1007,11 @@ push @CHECKS, 'FIX: LastUpdatedBy and Creator' => sub {
             next unless $object->_Accessible( $column, 'auto' );
 
             my $table = m2t($model);
+            $table = "`$table`" if $db_type eq 'mysql';
             my $query = <<END;
 SELECT m.id, g.id, g.Instance
 FROM
-    Groups g JOIN $table m ON g.id = m.$column
+    $groups_table g JOIN $table m ON g.id = m.$column
 WHERE
     g.Domain = ?
     AND g.Name = ?
@@ -1230,17 +1232,18 @@ push @CHECKS, 'Links: missing object' => sub {
 
         foreach my $use ( @URI_USES ) {
             my $stable = m2t( $use->{'model'} );
+            my $stablename = $db_type eq 'mysql' ? "`$stable`" : $stable;
             my $scolumn = $use->{'column'};
 
             foreach my $tmodel ( @models ) {
                 my $tclass = 'RT::'. $tmodel;
                 my $ttable = m2t($tmodel);
-
+                my $ttablename = ($db_type eq 'mysql') ? "`$ttable`" : $ttable;
                 my $tprefix = $prefix .'/'. ($tclass eq 'RT::Ticket'? 'ticket' : $tclass) .'/';
 
                 $tprefix = $prefix . '/article/' if $tclass eq 'RT::Article';
 
-                my $query = "SELECT s.id FROM $stable s LEFT JOIN $ttable t "
+                my $query = "SELECT s.id FROM $stablename s LEFT JOIN $ttablename t "
                   ." ON t.id = ". sql_str2int("SUBSTR(s.$scolumn, ?)")
                     ." WHERE s.$scolumn LIKE ? AND t.id IS NULL";
                 my @binds = (length($tprefix) + 1, sql_escape_like($tprefix).'%');
@@ -1310,6 +1313,9 @@ sub check_integrity {
     my ($ttable, @tcols) = (shift, shift);
     my %args = @_;
 
+    my $stablename = $db_type eq 'mysql' ? "`$stable`" : $stable;
+    my $ttablename = $db_type eq 'mysql' ? "`$ttable`" : $ttable;
+
     @scols = @{ $scols[0] } if ref $scols[0];
     @tcols = @{ $tcols[0] } if ref $tcols[0];
 
@@ -1317,7 +1323,7 @@ sub check_integrity {
         if $opt{'verbose'};
 
     my $query = "SELECT s.id, ". join(', ', map "s.$_", @scols)
-        ." FROM $stable s LEFT JOIN $ttable t"
+        ." FROM $stablename s LEFT JOIN $ttablename t"
         ." ON (". join(
             ' AND ', map columns_eq_cond('s', $stable, $scols[$_] => 't', $ttable, $tcols[$_]), (0..(@scols-1))
         ) .")"
@@ -1387,6 +1393,7 @@ sub check_uniqueness {
     my $on = shift;
     my %args = @_;
 
+    $on = "`$on`" if $db_type eq 'mysql';
     my @columns = @{ $args{'columns'} };
 
     print "Checking uniqueness of ( ", join(', ', map "'$_'", @columns )," ) in table '$on'\n"
@@ -1427,14 +1434,16 @@ sub check_uniqueness {
 
 sub load_record {
     my ($table, $id) = @_;
-    my $sth = execute_query( "SELECT * FROM $table WHERE id = ?", $id );
+    my $tablename = $db_type eq 'mysql' ? "`$table`" : $table;
+    my $sth = execute_query( "SELECT * FROM $tablename WHERE id = ?", $id );
     return $sth->fetchrow_hashref('NAME_lc');
 }
 
 sub delete_record {
     my ($table, $id) = (@_);
     print "Deleting record #$id in $table\n" if $opt{'verbose'};
-    my $query = "DELETE FROM $table WHERE id = ?";
+    my $tablename = $db_type eq 'mysql' ? "`$table`" : $table;
+    my $query = "DELETE FROM $tablename WHERE id = ?";
     $redo_check{ $_ } = 1 foreach @{ $redo_on{'Delete'}{ $table } || [] };
     return execute_query( $query, $id );
 }
@@ -1450,6 +1459,8 @@ sub update_records {
     my $where = shift;
     my $what = shift;
 
+    my $tablename = $db_type eq 'mysql' ? "`$table`" : $table;
+
     my (@where_cols, @where_binds);
     while ( my ($k, $v) = each %$where ) { push @where_cols, $k; push @where_binds, $v; }
 
@@ -1457,7 +1468,7 @@ sub update_records {
     while ( my ($k, $v) = each %$what ) { push @what_cols, $k; push @what_binds, $v; }
 
     print "Updating record(s) in $table\n" if $opt{'verbose'};
-    my $query = "UPDATE $table SET ". join(', ', map "$_ = ?", @what_cols)
+    my $query = "UPDATE $tablename SET ". join(', ', map "$_ = ?", @what_cols)
         ." WHERE ". join(' AND ', map "$_ = ?", @where_cols);
     $redo_check{ $_ } = 1 foreach @{ $redo_on{'Update'}{ $table } || [] };
     return execute_query( $query, @what_binds, @where_binds );
diff --git a/t/api/db_indexes.t b/t/api/db_indexes.t
index 3c305d84d9..fbc205d9ac 100644
--- a/t/api/db_indexes.t
+++ b/t/api/db_indexes.t
@@ -109,14 +109,29 @@ note "test ->CreateIndex and ->IndexesThatBeginWith methods";
         );
         ok $name, $msg;
     }
+    {
+        # this case is a later addition that exists because MySQL 8
+        # made "Groups" a reserved word, requiring it to be quoted
+        # in these contexts.
+        my ($name, $msg) = $handle->CreateIndex(
+            Table => 'Groups', Name => 'test_groups1',
+            Columns => ['Creator'],
+        );
+        ok $name, $msg;
+    }
 
     my @list = $handle->IndexesThatBeginWith( Table => 'Users', Columns => ['Organization'] );
     is_deeply([sort map $_->{Name}, @list], [qw(test_users1 test_users2)]);
 
+    @list = $handle->IndexesThatBeginWith( Table => 'Groups', Columns => ['Creator'] );
+    is_deeply([sort map $_->{Name}, @list], [qw(test_groups1)]);
+
     my ($status, $msg) = $handle->DropIndex( Table => 'Users', Name => 'test_users1' );
     ok $status, $msg;
     ($status, $msg) = $handle->DropIndex( Table => 'Users', Name => 'test_users2' );
     ok $status, $msg;
+    ($status, $msg) = $handle->DropIndex( Table => 'Groups', Name => 'test_groups1' );
+    ok $status, $msg;
 }
 
 note "Test some cases sensitivity aspects";
diff --git a/t/validator/role_groups.t b/t/validator/role_groups.t
index a32ddcf138..5fe56634d9 100644
--- a/t/validator/role_groups.t
+++ b/t/validator/role_groups.t
@@ -7,7 +7,9 @@ my $ticket = RT::Test->create_ticket( Queue => 'General', Subject => 'test ticke
 
 RT::Test->db_is_valid;
 
-$RT::Handle->dbh->do("DELETE FROM Groups where Domain IN ('RT::Queue-Role', 'RT::Ticket-Role')");
+my $groups_table = RT::Group->can('QuotedTableName') ? RT::Group->QuotedTableName('Groups') : 'Groups';
+
+$RT::Handle->dbh->do("DELETE FROM $groups_table where Domain IN ('RT::Queue-Role', 'RT::Ticket-Role')");
 DBIx::SearchBuilder::Record::Cachable->FlushCache;
 
 for my $object ( $ticket, $ticket->QueueObj ) {
diff --git a/t/web/query_log.t b/t/web/query_log.t
index cfb4d81d71..4d9ac87eb7 100644
--- a/t/web/query_log.t
+++ b/t/web/query_log.t
@@ -15,4 +15,6 @@ $m->get_ok("/Admin/Tools/Queries.html");
 $m->text_contains("/index.html", "we include info about a page we hit while logging in");
 $m->text_contains("Stack:", "stack traces");
 $m->text_like(qr{/autohandler:\d+}, "stack trace includes mason components");
-$m->text_contains("SELECT * FROM Principals WHERE id = '".$root->id."'", "we interpolate bind params");
+
+my $id = $root->id;
+$m->text_like(qr/SELECT \* FROM .?Principals.? WHERE id = '$id'/, "we interpolate bind params");

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list