[Rt-commit] rt branch 5.0/db-type-mariadb created. rt-5.0.5-114-gfddd189d37

BPS Git Server git at git.bestpractical.com
Fri Jan 19 15:30:25 UTC 2024


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, 5.0/db-type-mariadb has been created
        at  fddd189d379faa84c97e7d2931b44765b66e7376 (commit)

- Log -----------------------------------------------------------------
commit fddd189d379faa84c97e7d2931b44765b66e7376
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Tue Jan 16 11:20:46 2024 -0500

    Add explicit support for MariaDB in addition to MySQL

diff --git a/configure.ac b/configure.ac
index dd34674364..e352b84ee3 100755
--- a/configure.ac
+++ b/configure.ac
@@ -116,11 +116,11 @@ AC_SUBST(LIBS_GROUP)
 dnl DB_TYPE
 AC_ARG_WITH(db-type,
 	    AS_HELP_STRING([--with-db-type=TYPE],
-	    		   [sort of database RT will use (default: mysql) (mysql, Pg, Oracle and SQLite are valid)]), 
+	    		   [sort of database RT will use (default: mysql) (mysql, MariaDB Pg, Oracle and SQLite are valid)]), 
             DB_TYPE=$withval,
             DB_TYPE=mysql)
-if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite' -a "$DB_TYPE" != 'Oracle' ; then
-	AC_MSG_ERROR([Only Oracle, Pg, mysql and SQLite are valid db types])
+if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'MariaDB' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite' -a "$DB_TYPE" != 'Oracle' ; then
+	AC_MSG_ERROR([Only Oracle, Pg, mysql, MariaDB and SQLite are valid db types])
 fi
 AC_SUBST(DB_TYPE)
 
diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 3ac04ff28a..2308fcfe5b 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -193,7 +193,9 @@ Set( @StaticRoots, () );
 =item C<$DatabaseType>
 
 Database driver being used; case matters.  Valid types are "mysql",
-"Oracle", and "Pg".  "SQLite" is also available for non-production use.
+"MariaDB", "Oracle", and "Pg".
+
+"SQLite" is also available for non-production use.
 
 =cut
 
diff --git a/etc/acl.MariaDB b/etc/acl.MariaDB
new file mode 100644
index 0000000000..da148bde66
--- /dev/null
+++ b/etc/acl.MariaDB
@@ -0,0 +1,38 @@
+
+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');
+    my $db_pass = RT->Config->Get('DatabasePassword');
+    unless ( $db_user ) {
+        RT->Logger->warn("DatabaseUser option is not defined or empty. Skipping...");
+        return;
+    }
+    if ( $db_user eq 'root' ) {
+        RT->Logger->warn("DatabaseUser is root. Skipping...");
+        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`.*
+               TO '$db_user'\@'$db_rthost'
+               IDENTIFIED BY '$db_pass';",
+    );
+}
+
+1;
diff --git a/etc/cpanfile b/etc/cpanfile
index 07ee82d182..3deb7a6e93 100644
--- a/etc/cpanfile
+++ b/etc/cpanfile
@@ -22,7 +22,7 @@ requires 'DateTime', '>= 0.44';
 requires 'DateTime::Format::Natural', '>= 0.67';
 requires 'DateTime::Locale', '>= 0.40, != 1.00, != 1.01';
 requires 'DBI', '>= 1.37';
-requires 'DBIx::SearchBuilder', '>= 1.80';
+requires 'DBIx::SearchBuilder', '>= 1.81';
 requires 'Devel::GlobalDestruction';
 requires 'Devel::StackTrace', '>= 1.19, != 1.28, != 1.29';
 requires 'Digest::base';
@@ -163,6 +163,11 @@ feature 'mysql' => sub {
     requires 'DBD::mysql', '>= 2.1018, != 4.042';
 };
 
+feature 'MariaDB' => sub {
+    requires 'DBD::MariaDB', '>= 1.23';
+    requires 'Apache::Session::MariaDB';
+};
+
 feature 'oracle' => sub {
     requires 'DBD::Oracle', '!= 1.23';
 };
diff --git a/etc/schema.MariaDB b/etc/schema.MariaDB
new file mode 100644
index 0000000000..382a10fc43
--- /dev/null
+++ b/etc/schema.MariaDB
@@ -0,0 +1,616 @@
+
+CREATE TABLE Attachments (
+  id BIGINT NOT NULL  AUTO_INCREMENT,
+  TransactionId BIGINT NOT NULL  ,
+  Parent BIGINT NOT NULL DEFAULT 0  ,
+  MessageId varchar(160) CHARACTER SET ascii NULL  ,
+  Subject varchar(255) NULL  ,
+  Filename varchar(255) NULL  ,
+  ContentType varchar(80) CHARACTER SET ascii NULL  ,
+  ContentEncoding varchar(80) CHARACTER SET ascii NULL  ,
+  Content LONGBLOB NULL  ,
+  Headers LONGTEXT NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Attachments2 ON Attachments (TransactionId) ;
+CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ;
+CREATE INDEX Attachments4 ON Attachments (Filename) ;
+
+CREATE TABLE Queues (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
+  CorrespondAddress varchar(120) NULL,
+  CommentAddress varchar(120) NULL,
+  Lifecycle varchar(32) NULL,
+  SubjectTag varchar(120) NULL,
+  SortOrder integer NOT NULL DEFAULT 0 ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  SLADisabled int2 NOT NULL DEFAULT 1 ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE UNIQUE INDEX Queues1 ON Queues (Name) ;
+CREATE INDEX Queues2 ON Queues (Disabled) ;
+
+
+
+CREATE TABLE Links (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Base varchar(240) NULL,
+  Target varchar(240) NULL,
+  Type varchar(20) CHARACTER SET ascii NOT NULL ,
+  LocalTarget integer NOT NULL DEFAULT 0  ,
+  LocalBase integer NOT NULL DEFAULT 0  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Links1 ON Links (Base);
+CREATE INDEX Links2 ON Links (Target);
+CREATE INDEX Links3 ON Links (LocalBase);
+CREATE INDEX Links4 ON Links (LocalTarget);
+CREATE INDEX Links5 ON Links (Type);
+
+
+
+CREATE TABLE Principals (
+        id INTEGER  AUTO_INCREMENT not null,
+        PrincipalType VARCHAR(16) not null,
+        Disabled int2 NOT NULL DEFAULT 0 ,
+        PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+
+CREATE TABLE `Groups` (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  Domain varchar(64) CHARACTER SET ascii NULL,
+  Instance integer,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Groups1 ON `Groups` (Domain, Name, Instance);
+CREATE INDEX Groups2 On `Groups` (Instance);
+
+CREATE TABLE ScripConditions (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  ExecModule varchar(60) CHARACTER SET ascii NULL,
+  Argument VARBINARY(255) NULL  ,
+  ApplicableTransTypes varchar(60) CHARACTER SET ascii NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+
+CREATE TABLE Transactions (
+  id BIGINT NOT NULL  AUTO_INCREMENT,
+  ObjectType varchar(64) CHARACTER SET ascii NOT NULL,
+  ObjectId integer NOT NULL DEFAULT 0  ,
+  TimeTaken integer NOT NULL DEFAULT 0  ,
+  Type varchar(20) CHARACTER SET ascii NULL,
+  Field varchar(255) CHARACTER SET ascii NULL,
+  OldValue varchar(255) NULL  ,
+  NewValue varchar(255) NULL  ,
+  ReferenceType varchar(255) CHARACTER SET ascii NULL,
+  OldReference integer NULL  ,
+  NewReference integer NULL  ,
+  Data varchar(255) NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Transactions1 ON Transactions (ObjectType, ObjectId);
+
+
+
+CREATE TABLE Scrips (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Description varchar(255),
+  ScripCondition integer NOT NULL DEFAULT 0  ,
+  ScripAction integer NOT NULL DEFAULT 0  ,
+  CustomIsApplicableCode text NULL  ,
+  CustomPrepareCode text NULL  ,
+  CustomCommitCode text NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
+  Template varchar(200) NOT NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE ObjectScrips (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Scrip integer NOT NULL  ,
+  Stage varchar(32) CHARACTER SET ascii NOT NULL DEFAULT 'TransactionCreate',
+  ObjectId integer NOT NULL,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
+
+CREATE TABLE ACL (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  PrincipalType varchar(25) CHARACTER SET ascii NOT NULL, #"User" "Group", "Owner", "Cc" "AdminCc", "Requestor"
+
+  PrincipalId integer NOT NULL DEFAULT 0 , #Foreign key to principals
+  RightName varchar(25) CHARACTER SET ascii NOT NULL,
+  ObjectType varchar(25) CHARACTER SET ascii NOT NULL,
+  ObjectId integer NOT NULL default 0,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX  ACL1 on ACL(RightName, ObjectType, ObjectId,PrincipalType,PrincipalId);
+
+
+
+CREATE TABLE GroupMembers (
+  id INTEGER NOT NULL AUTO_INCREMENT,
+  GroupId integer NOT NULL DEFAULT 0,
+  MemberId integer NOT NULL DEFAULT 0,  #Foreign key to Principals
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+CREATE UNIQUE INDEX GroupMembers1 on GroupMembers (GroupId, MemberId);
+
+
+
+
+create table CachedGroupMembers (
+        id int auto_increment,
+        GroupId int, # foreign key to Principals
+        MemberId int, # foreign key to Principals
+        Via int, #foreign key to CachedGroupMembers. (may point to $self->id)
+        ImmediateParentId int, #foreign key to prinicpals.
+                               # this points to the group that the member is
+                               # a member of, for ease of deletes.
+        Disabled int2 NOT NULL DEFAULT 0 , # if this cached group member is a member of this group by way of a disabled
+                                           # group or this group is disabled, this will be set to 1
+                                           # this allows us to not find members of disabled subgroups when listing off
+                                           # group members recursively.
+                                           # Also, this allows us to have the ACL system elide members of disabled groups
+        PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX DisGrouMem  on CachedGroupMembers (GroupId,MemberId,Disabled);
+CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId, GroupId, Disabled);
+CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId);
+
+
+
+CREATE TABLE Users (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NOT NULL  ,
+  Password VARCHAR(256) NULL  ,
+  AuthToken VARCHAR(16) CHARACTER SET ascii NULL  ,
+  Comments TEXT NULL  ,
+  Signature TEXT NULL  ,
+  EmailAddress varchar(120) NULL  ,
+  FreeformContactInfo TEXT NULL  ,
+  Organization varchar(200) NULL  ,
+  RealName varchar(120) NULL  ,
+  NickName varchar(16) NULL  ,
+  Lang varchar(16) NULL  ,
+  Gecos varchar(16) NULL  ,
+  HomePhone varchar(30) NULL  ,
+  WorkPhone varchar(30) NULL  ,
+  MobilePhone varchar(30) NULL  ,
+  PagerPhone varchar(30) NULL  ,
+  Address1 varchar(200) NULL  ,
+  Address2 varchar(200) NULL  ,
+  City varchar(100) NULL  ,
+  State varchar(100) NULL  ,
+  Zip varchar(16) NULL  ,
+  Country varchar(50) NULL  ,
+  Timezone varchar(50) NULL  ,
+  SMIMECertificate text NULL,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+
+CREATE UNIQUE INDEX Users1 ON Users (Name) ;
+CREATE INDEX Users4 ON Users (EmailAddress);
+
+
+
+
+CREATE TABLE Tickets (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  EffectiveId integer NOT NULL DEFAULT 0  ,
+  IsMerged int2 NULL DEFAULT NULL,
+  Queue integer NOT NULL DEFAULT 0  ,
+  Type varchar(16) CHARACTER SET ascii NULL  ,
+  Owner integer NOT NULL DEFAULT 0  ,
+  Subject varchar(200) NULL DEFAULT '[no subject]' ,
+  InitialPriority integer NOT NULL DEFAULT 0  ,
+  FinalPriority integer NOT NULL DEFAULT 0  ,
+  Priority integer NOT NULL DEFAULT 0  ,
+  TimeEstimated integer NOT NULL DEFAULT 0  ,
+  TimeWorked integer NOT NULL DEFAULT 0  ,
+  Status varchar(64) NULL  ,
+  SLA varchar(64) NULL  ,
+  TimeLeft integer NOT NULL DEFAULT 0  ,
+  Told DATETIME NULL  ,
+  Starts DATETIME NULL  ,
+  Started DATETIME NULL  ,
+  Due DATETIME NULL  ,
+  Resolved DATETIME NULL  ,
+
+
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
+CREATE INDEX Tickets2 ON Tickets (Owner) ;
+CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type) ;
+
+
+
+CREATE TABLE ScripActions (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  ExecModule varchar(60) CHARACTER SET ascii NULL,
+  Argument VARBINARY(255) NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+
+
+CREATE TABLE Templates (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Queue integer NOT NULL DEFAULT 0 ,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
+  Type varchar(16) CHARACTER SET ascii NULL  ,
+  Content TEXT NULL  ,
+  LastUpdated DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+
+
+CREATE TABLE ObjectCustomFieldValues (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomField int NOT NULL  ,
+  ObjectType varchar(255) CHARACTER SET ascii NOT NULL,     # Final target of the Object
+  ObjectId BIGINT NOT NULL  ,                  # New -- Replaces Ticket
+  SortOrder integer NOT NULL DEFAULT 0  ,   # New -- ordering for multiple values
+
+  Content varchar(255) NULL  ,
+  LargeContent LONGBLOB NULL,               # New -- to hold 255+ strings
+  ContentType varchar(80) CHARACTER SET ascii NULL,                 # New -- only text/* gets searched
+  ContentEncoding varchar(80) CHARACTER SET ascii NULL  ,           # New -- for binary Content
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,        # New -- whether the value was current
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (Content);
+CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId);
+CREATE INDEX ObjectCustomFieldValues3 ON ObjectCustomFieldValues (SortOrder);
+
+
+
+CREATE TABLE CustomFields (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Type varchar(200) CHARACTER SET ascii NULL  , # Changed -- 'Single' and 'Multiple' is moved out
+  RenderType varchar(64) CHARACTER SET ascii NULL  ,
+  MaxValues integer,            # New -- was 'Single'(1) and 'Multiple'(0)
+  Pattern TEXT NULL  ,  # New -- Must validate against this
+  BasedOn INTEGER NULL,
+  ValuesClass varchar(64) CHARACTER SET ascii NULL  ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+  LookupType varchar(255) CHARACTER SET ascii NOT NULL,
+  EntryHint varchar(255) NULL,
+  ValidationHint varchar(255) NULL,
+  UniqueValues int2 NOT NULL DEFAULT 0 ,
+  CanonicalizeClass varchar(64) CHARACTER SET ascii NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+
+
+CREATE TABLE ObjectCustomFields (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomField integer NOT NULL  ,
+  ObjectId integer NOT NULL,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX ObjectCustomFields1 ON ObjectCustomFields (ObjectId);
+
+
+
+CREATE TABLE CustomFieldValues (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomField int NOT NULL  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+  Category VARCHAR(255) NULL,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField);
+
+
+
+
+CREATE TABLE Attributes (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(255) NULL  ,
+  Description varchar(255) NULL  ,
+  Content LONGBLOB,
+  ContentType varchar(16) CHARACTER SET ascii,
+  ObjectType varchar(64) CHARACTER SET ascii,
+  ObjectId integer, # foreign key to anything
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Attributes1 on Attributes(Name);
+CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId);
+
+
+
+# sessions is used by Apache::Session to keep sessions in the database.
+# We should have a reaper script somewhere.
+
+CREATE TABLE sessions (
+    id char(32) NOT NULL,
+    a_session LONGBLOB,
+    LastUpdated TIMESTAMP,
+    PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE Classes (
+  id int(11) NOT NULL auto_increment,
+  Name varchar(255) NOT NULL default '',
+  Description varchar(255) NOT NULL default '',
+  SortOrder int(11) NOT NULL default '0',
+  Disabled int(2) NOT NULL default '0',
+  Creator int(11) NOT NULL default '0',
+  Created datetime default NULL,
+  LastUpdatedBy int(11) NOT NULL default '0',
+  LastUpdated datetime default NULL,
+  PRIMARY KEY  (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE Articles (
+  id int(11) NOT NULL auto_increment,
+  Name varchar(255) NOT NULL default '',
+  Summary varchar(255) NOT NULL default '',
+  SortOrder int(11) NOT NULL default '0',
+  Class int(11) NOT NULL default '0',
+  Parent int(11) NOT NULL default '0',
+  URI varchar(255) character set ascii default NULL,
+  Disabled int(2) NOT NULL default '0',
+  Creator int(11) NOT NULL default '0',
+  Created datetime default NULL,
+  LastUpdatedBy int(11) NOT NULL default '0',
+  LastUpdated datetime default NULL,
+  PRIMARY KEY  (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE Topics (
+  id int(11) NOT NULL auto_increment,
+  Parent int(11) NOT NULL default '0',
+  Name varchar(255) NOT NULL default '',
+  Description varchar(255) NOT NULL default '',
+  ObjectType varchar(64) character set ascii NOT NULL default '',
+  ObjectId int(11) NOT NULL default '0',
+  PRIMARY KEY  (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE ObjectTopics (
+  id int(11) NOT NULL auto_increment,
+  Topic int(11) NOT NULL default '0',
+  ObjectType varchar(64) character set ascii NOT NULL default '',
+  ObjectId int(11) NOT NULL default '0',
+  PRIMARY KEY  (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE ObjectClasses (
+  id int(11) NOT NULL auto_increment,
+  Class int(11) NOT NULL default '0',
+  ObjectType varchar(255) character set ascii NOT NULL default '',
+  ObjectId int(11) NOT NULL default '0',
+  Creator int(11) NOT NULL default '0',
+  Created datetime default NULL,
+  LastUpdatedBy int(11) NOT NULL default '0',
+  LastUpdated datetime default NULL,
+  PRIMARY KEY  (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE Assets (
+    id                int(11)         NOT NULL AUTO_INCREMENT,
+    Name              varchar(255)    NOT NULL DEFAULT '',
+    Catalog           int(11)         NOT NULL DEFAULT 0,
+    Status            varchar(64)     NOT NULL DEFAULT '',
+    Description       varchar(255)    NOT NULL DEFAULT '',
+    Creator           int(11)         NOT NULL DEFAULT 0,
+    Created           datetime                 DEFAULT NULL,
+    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
+    LastUpdated       datetime                 DEFAULT NULL,
+    PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX AssetsName ON Assets (Name);
+CREATE INDEX AssetsStatus ON Assets (Status);
+CREATE INDEX AssetsCatalog ON Assets (Catalog);
+
+CREATE TABLE Catalogs (
+    id                int(11)         NOT NULL AUTO_INCREMENT,
+    Name              varchar(255)    NOT NULL DEFAULT '',
+    Lifecycle         varchar(32)     NOT NULL DEFAULT 'assets',
+    Description       varchar(255)    NOT NULL DEFAULT '',
+    Disabled          int2            NOT NULL DEFAULT 0,
+    Creator           int(11)         NOT NULL DEFAULT 0,
+    Created           datetime                 DEFAULT NULL,
+    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
+    LastUpdated       datetime                 DEFAULT NULL,
+    PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX CatalogsName ON Catalogs (Name);
+CREATE INDEX CatalogsDisabled ON Catalogs (Disabled);
+
+CREATE TABLE CustomRoles (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  MaxValues integer,
+  EntryHint varchar(255) NULL  ,
+  LookupType varchar(255) CHARACTER SET ascii NOT NULL,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE TABLE ObjectCustomRoles (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomRole integer NOT NULL  ,
+  ObjectId integer NOT NULL,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE UNIQUE INDEX ObjectCustomRoles1 ON ObjectCustomRoles (ObjectId, CustomRole);
+
+CREATE TABLE Configurations (
+    id                int(11)         NOT NULL AUTO_INCREMENT,
+    Name              varchar(255)    NOT NULL,
+    Content           longblob        NULL,
+    ContentType       varchar(80)     CHARACTER SET ascii NULL,
+    Disabled          int2            NOT NULL DEFAULT 0,
+    Creator           int(11)         NOT NULL DEFAULT 0,
+    Created           datetime                 DEFAULT NULL,
+    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
+    LastUpdated       datetime                 DEFAULT NULL,
+    PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX Configurations1 ON Configurations (Name, Disabled);
+CREATE INDEX Configurations2 ON Configurations (Disabled);
+
+CREATE TABLE AuthTokens (
+    id                int(11)         NOT NULL AUTO_INCREMENT,
+    Owner             int(11)         NOT NULL DEFAULT 0,
+    Token             varchar(256)    NULL,
+    Description       varchar(255)    NOT NULL DEFAULT '',
+    LastUsed          datetime                 DEFAULT NULL,
+    Creator           int(11)         NOT NULL DEFAULT 0,
+    Created           datetime                 DEFAULT NULL,
+    LastUpdatedBy     int(11)         NOT NULL DEFAULT 0,
+    LastUpdated       datetime                 DEFAULT NULL,
+    Expires           datetime                 DEFAULT NULL,
+    PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE INDEX AuthTokensOwner ON AuthTokens (Owner);
+
+CREATE TABLE Shorteners (
+  id             INTEGER     NOT NULL AUTO_INCREMENT,
+  Code           VARCHAR(40) NOT NULL,
+  Content        LONGTEXT    NOT NULL,
+  Permanent      INT2        NOT NULL DEFAULT 0,
+  Creator        INTEGER     NOT NULL DEFAULT 0,
+  Created        DATETIME    NULL,
+  LastUpdatedBy  INTEGER     NULL DEFAULT 0,
+  LastUpdated    DATETIME    NULL,
+  LastAccessedBy INTEGER     NULL DEFAULT 0,
+  LastAccessed   DATETIME    NULL,
+  PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8mb4;
+
+CREATE UNIQUE INDEX Shorteners1 ON Shorteners(Code);
diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 96a7994338..8acd18bb07 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -806,7 +806,7 @@ our %META;
                     $RT::Logger->error("Column for full-text index is set to Content, not tsvector column; disabling");
                     $v->{Enable} = $v->{Indexed} = 0;
                 }
-            } elsif ($dbtype eq 'mysql') {
+            } elsif ($dbtype eq 'mysql' || $dbtype eq 'MariaDB') {
                 if (not $v->{'Table'}) {
                     $RT::Logger->error("No Table set for full-text index; disabling");
                     $v->{Enable} = $v->{Indexed} = 0;
diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index 02e4667d7f..7189bf0e39 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -131,7 +131,7 @@ sub Connect {
         = defined $ENV{RT_DATABASE_QUERY_TIMEOUT} && length $ENV{RT_DATABASE_QUERY_TIMEOUT}
         ? $ENV{RT_DATABASE_QUERY_TIMEOUT}
         : RT->Config->Get('DatabaseQueryTimeout');
-    if ( $db_type eq 'mysql' ) {
+    if ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         # set the character set
         $self->dbh->do("SET NAMES 'utf8mb4'");
         if ( defined $timeout && length $timeout ) {
@@ -234,7 +234,7 @@ sub SystemDSN {
     my $db_type = RT->Config->Get('DatabaseType');
 
     my $dsn = $self->DSN;
-    if ( $db_type eq 'mysql' ) {
+    if ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         # with mysql, you want to connect sans database to funge things
         $dsn =~ s/dbname=\Q$db_name//;
     }
@@ -283,13 +283,13 @@ sub CheckCompatibility {
     my $state = shift || 'post';
 
     my $db_type = RT->Config->Get('DatabaseType');
-    if ( $db_type eq "mysql" ) {
+    if ( $db_type eq "mysql" || $db_type eq 'MariaDB' ) {
         # Check which version we're running
         my $version = ($dbh->selectrow_array("show variables like 'version'"))[1];
         return (0, "couldn't get version of the mysql server")
             unless $version;
 
-        # MySQL and MariaDB are both 'mysql' type.
+        # MySQL and MariaDB are different types, but share many of the same checks
         # the minimum version supported is MySQL 5.7.7 / MariaDB 10.2.5
         # the version string for MariaDB includes "MariaDB" in Debian/RedHat
         my $is_mariadb        = $version =~ m{mariadb}i ? 1 : 0;
@@ -301,15 +301,15 @@ sub CheckCompatibility {
         return ( 0, "RT 5.0.0 is unsupported on MariaDB versions before $mariadb_min_version.  Your version is $version.")
             if $is_mariadb && cmp_version( $version, $mariadb_min_version ) < 0;
 
-        # MySQL must have InnoDB support
+        # MySQL and MariaDB must have InnoDB support
         local $dbh->{FetchHashKeyName} = 'NAME_lc';
         my $innodb = lc($dbh->selectall_hashref("SHOW ENGINES", "engine")->{InnoDB}{support} || "no");
         if ( $innodb eq "no" ) {
-            return (0, "RT requires that MySQL be compiled with InnoDB table support.\n".
+            return (0, "RT requires that MySQL/MariaDB be compiled with InnoDB table support.\n".
                 "See <http://dev.mysql.com/doc/mysql/en/innodb-storage-engine.html>\n".
                 "and check that there are no 'skip-innodb' lines in your my.cnf.");
         } elsif ( $innodb eq "disabled" ) {
-            return (0, "RT requires that MySQL InnoDB table support be enabled.\n".
+            return (0, "RT requires that MySQL/MariaDB InnoDB table support be enabled.\n".
                 "Remove the 'skip-innodb' or 'innodb = OFF' line from your my.cnf file, restart MySQL, and try again.\n");
         }
 
@@ -400,7 +400,7 @@ sub CreateDatabase {
     elsif ( $db_type eq 'Pg' ) {
         $status = $dbh->do("CREATE DATABASE $db_name WITH ENCODING='UNICODE' TEMPLATE template0");
     }
-    elsif ( $db_type eq 'mysql' ) {
+    elsif ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         $status = $dbh->do("CREATE DATABASE `$db_name` DEFAULT CHARACTER SET utf8");
     }
     else {
@@ -442,7 +442,7 @@ sub DropDatabase {
         $path = "$RT::VarPath/$path" unless substr($path, 0, 1) eq '/';
         unlink $path or return (0, "Couldn't remove '$path': $!");
         return (1);
-    } elsif ( $db_type eq 'mysql' ) {
+    } elsif ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         $dbh->do("DROP DATABASE `$db_name`")
             or return (0, $DBI::errstr);
     } else {
@@ -2020,7 +2020,7 @@ sub Indexes {
     my $dbh = $self->dbh;
 
     my $list;
-    if ( $db_type eq 'mysql' ) {
+    if ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         $list = $dbh->selectall_arrayref(
             'select distinct table_name, index_name from information_schema.statistics where table_schema = ?',
             undef, scalar RT->Config->Get('DatabaseName')
@@ -2082,7 +2082,7 @@ sub IndexInfo {
         Table => lc $args{'Table'},
         Name => lc $args{'Name'},
     );
-    if ( $db_type eq 'mysql' ) {
+    if ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         my $list = $dbh->selectall_arrayref(
             'select NON_UNIQUE, COLUMN_NAME, SUB_PART
             from information_schema.statistics
@@ -2190,7 +2190,7 @@ sub DropIndex {
     local $dbh->{'RaiseError'} = 0;
 
     my $res;
-    if ( $db_type eq 'mysql' ) {
+    if ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
         $args{'Table'} = $self->_CanonicTableNameMysql( $args{'Table'} );
         $res = $dbh->do(
             'drop index '. $dbh->quote_identifier($args{'Name'}) ." on ". $dbh->quote_identifier($args{'Table'}),
diff --git a/lib/RT/Installer.pm b/lib/RT/Installer.pm
index 3ee011a01d..9dcaebe4d7 100644
--- a/lib/RT/Installer.pm
+++ b/lib/RT/Installer.pm
@@ -62,13 +62,14 @@ my %Meta = (
                 grep {
                     my $m = 'DBD::' . $_;
                     RT::StaticUtil::RequireModule($m) ? 1 : 0
-                  } qw/mysql Pg SQLite Oracle/
+                  } qw/mysql MariaDB Pg SQLite Oracle/
             ],
             ValuesLabel => {
-                mysql  => 'MySQL',             #loc
-                Pg     => 'PostgreSQL',        #loc
-                SQLite => 'SQLite',            #loc
-                Oracle => 'Oracle',            #loc
+                mysql   => 'MySQL',             #loc
+                MariaDB => 'MariaDB',           #loc
+                Pg      => 'PostgreSQL',        #loc
+                SQLite  => 'SQLite',            #loc
+                Oracle  => 'Oracle',            #loc
             },
         },
     },
diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm
index e7c4caafca..bb5cda4a50 100644
--- a/lib/RT/Interface/Web/Handler.pm
+++ b/lib/RT/Interface/Web/Handler.pm
@@ -87,7 +87,7 @@ sub InitSessionDir {
     # Activate the following if running httpd as root (the normal case).
     # Resets ownership of all files created by Mason at startup.
     # Note that mysql uses DB for sessions, so there's no need to do this.
-    unless ( RT->Config->Get('DatabaseType') =~ /(?:mysql|Pg)/ ) {
+    unless ( RT->Config->Get('DatabaseType') =~ /(?:mysql|MariaDB|Pg)/ ) {
 
         # Clean up our umask to protect session files
         umask(0077);
diff --git a/lib/RT/Interface/Web/Session.pm b/lib/RT/Interface/Web/Session.pm
index 585ffd1b55..9300d4564d 100644
--- a/lib/RT/Interface/Web/Session.pm
+++ b/lib/RT/Interface/Web/Session.pm
@@ -97,9 +97,10 @@ sessions class names as values.
 
 sub Backends {
     return {
-        mysql  => 'Apache::Session::MySQL',
-        Pg     => 'Apache::Session::Postgres',
-        Oracle => 'Apache::Session::Oracle',
+        mysql   => 'Apache::Session::MySQL',
+        MariaDB => 'Apache::Session::MariaDB',
+        Pg      => 'Apache::Session::Postgres',
+        Oracle  => 'Apache::Session::Oracle',
     };
 }
 
diff --git a/lib/RT/Migrate/Serializer/JSON.pm b/lib/RT/Migrate/Serializer/JSON.pm
index 279671183f..411a1496b8 100644
--- a/lib/RT/Migrate/Serializer/JSON.pm
+++ b/lib/RT/Migrate/Serializer/JSON.pm
@@ -157,7 +157,7 @@ sub PushBasics {
 sub JSON {
     my $self = shift;
     $self->{JSON} ||= JSON->new->pretty->canonical;
-    $self->{JSON} = $self->{JSON}->utf8 if RT->Config->Get('DatabaseType') =~ /Pg|Oracle/;
+    $self->{JSON} = $self->{JSON}->utf8 if RT->Config->Get('DatabaseType') =~ /Pg|Oracle|MariaDB/;
     return $self->{JSON};
 }
 
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 275fe6653a..499e892b0f 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1023,7 +1023,7 @@ sub _TransContentLimit {
                 QUOTEVALUE  => 0,
             );
         }
-        elsif ( $db_type eq 'mysql' and not $config->{Sphinx}) {
+        elsif ( ($db_type eq 'mysql' || $db_type eq 'MariaDB') and not $config->{Sphinx}) {
             my $dbh = $RT::Handle->dbh;
             $self->Limit(
                 %rest,
@@ -1045,7 +1045,7 @@ sub _TransContentLimit {
                 QUOTEVALUE      => 0,
             );
         }
-        elsif ( $db_type eq 'mysql' ) {
+        elsif ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
             # XXX: We could theoretically skip the join to Attachments,
             # and have Sphinx simply index and group by the TicketId,
             # and join Ticket.id to that attribute, which would be much
diff --git a/lib/RT/Transactions.pm b/lib/RT/Transactions.pm
index e03d2995a8..7544cf4144 100644
--- a/lib/RT/Transactions.pm
+++ b/lib/RT/Transactions.pm
@@ -767,7 +767,7 @@ sub _AttachContentLimit {
                 QUOTEVALUE  => 0,
             );
         }
-        elsif ( $db_type eq 'mysql' and not $config->{Sphinx}) {
+        elsif ( ($db_type eq 'mysql' || $db_type eq 'MariaDB') and not $config->{Sphinx}) {
             my $dbh = $RT::Handle->dbh;
             $self->Limit(
                 %rest,
@@ -789,7 +789,7 @@ sub _AttachContentLimit {
                 QUOTEVALUE      => 0,
             );
         }
-        elsif ( $db_type eq 'mysql' ) {
+        elsif ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
             # This is a special character.  Note that \ does not escape
             # itself (in Sphinx 2.1.0, at least), so 'foo\;bar' becoming
             # 'foo\\;bar' is not a vulnerability, and is still parsed as
diff --git a/sbin/rt-fulltext-indexer.in b/sbin/rt-fulltext-indexer.in
index 2df8be4dc2..f23fd6d843 100644
--- a/sbin/rt-fulltext-indexer.in
+++ b/sbin/rt-fulltext-indexer.in
@@ -147,7 +147,7 @@ EOT
 }
 
 my $LAST;
-if ($db_type eq 'mysql') {
+if ( $db_type eq 'mysql' || $db_type eq 'MariaDB' ) {
     process_mysql();
 } elsif ($db_type eq 'Pg') {
     process_pg();
diff --git a/sbin/rt-setup-fulltext-index.in b/sbin/rt-setup-fulltext-index.in
index 4e75e7eda7..3da92fa39c 100644
--- a/sbin/rt-setup-fulltext-index.in
+++ b/sbin/rt-setup-fulltext-index.in
@@ -96,7 +96,7 @@ if ( $DB{'type'} eq 'Pg' ) {
         column => 'ContentIndex',
     );
 }
-elsif ( $DB{'type'} eq 'mysql' ) {
+elsif ( $DB{'type'} eq 'mysql' || $DB{'type'} eq 'MariaDB' ) {
     %DEFAULT = (
         table => 'AttachmentsIndex',
     );
@@ -186,6 +186,28 @@ if ( $DB{'type'} eq 'mysql' ) {
 
     insert_schema( "CREATE FULLTEXT INDEX $table ON $table(Content)" );
 
+    print_rt_config( Table => $table );
+}
+elsif ( $DB{'type'} eq 'MariaDB' ) {
+    my $table = $OPT{'table'} || prompt(
+        message => "Enter the name of a new table that will be used to store the\n"
+                 . "full-text content and indexes:",
+        default => $DEFAULT{'table'},
+        silent  => !$OPT{'ask'},
+    );
+    do_error_is_ok( dba_handle() => "DROP TABLE $table" )
+        unless $OPT{'dryrun'};
+
+    my $engine = "InnoDB";
+    my $schema = "CREATE TABLE $table ( "
+        ."id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
+        ."Content LONGTEXT ) ENGINE=$engine CHARACTER SET utf8mb4";
+    insert_schema( $schema );
+
+    insert_data( Table => $table, Engine => $engine );
+
+    insert_schema( "CREATE FULLTEXT INDEX $table ON $table(Content)" );
+
     print_rt_config( Table => $table );
 } elsif ($DB{'type'} eq 'sphinx') {
     check_sphinx();
diff --git a/t/api/db_indexes.t b/t/api/db_indexes.t
index fbc205d9ac..b2579a83fd 100644
--- a/t/api/db_indexes.t
+++ b/t/api/db_indexes.t
@@ -47,7 +47,7 @@ note "test handle->DropIndexIfExists method";
 
 note "test handle->IndexInfo method";
 {
-    if ($db_type ne 'Oracle' && $db_type ne 'mysql') {
+    if ($db_type ne 'Oracle' && $db_type ne 'mysql' && $db_type ne 'MariaDB') {
         my %res = $handle->IndexInfo( Table => 'Attachments', Name => 'Attachments1' );
         is_deeply(
             \%res,
@@ -134,8 +134,11 @@ note "test ->CreateIndex and ->IndexesThatBeginWith methods";
     ok $status, $msg;
 }
 
-note "Test some cases sensitivity aspects";
+if ( $db_type ne 'MariaDB'
+    || ( $handle->dbh->selectrow_array("show variables like 'lower_case_table_names'") )[1] )
 {
+    note "Test some cases sensitivity aspects";
+    if ( $db_type eq 'MariaDB' )
     {
         my %res = $handle->IndexInfo( Table => 'groupmembers', Name => 'groupmembers1' );
         is_deeply(
diff --git a/t/api/template.t b/t/api/template.t
index 1baac44b60..b02f114717 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -1,4 +1,4 @@
-
+use utf8;
 use warnings;
 use strict;
 
@@ -22,12 +22,12 @@ ok $alt_queue && $alt_queue->id, 'loaded or created queue';
     my ($val,$msg) = $template->Create(
         Queue => $queue->id,
         Name => 'Test',
-        Content => 'This is template content'
+        Content => 'This is template content with 😈'
     );
     ok $val, "created a template" or diag "error: $msg";
     ok my $id = $template->id, "id is defined";
     is $template->Name, 'Test';
-    is $template->Content, 'This is template content', "We created the object right";
+    is $template->Content, 'This is template content with 😈', "We created the object right";
 
     ($val, $msg) = $template->SetContent( 'This is new template content');
     ok $val, "changed content" or diag "error: $msg";
diff --git a/t/articles/search-interface.t b/t/articles/search-interface.t
index 1d9d46ea47..709302a69a 100644
--- a/t/articles/search-interface.t
+++ b/t/articles/search-interface.t
@@ -138,7 +138,7 @@ $m->text_contains('hoi polloi 4');
 DoArticleSearch($m, $class->Name, 'lorem');
 TODO:{
     local $TODO = 'Case insensitive search on LONGBLOB not available in MySQL'
-      if RT->Config->Get('DatabaseType') eq 'mysql';
+      if RT->Config->Get('DatabaseType') =~ /^(?:mysql|MariaDB)$/;
     $m->text_contains('Last Updated'); # Did we do a search?
     $m->text_contains('hoi polloi 4');
 }
diff --git a/t/fts/indexed_mysql.t b/t/fts/indexed_mysql.t
index 672b220723..f34ec4e9e4 100644
--- a/t/fts/indexed_mysql.t
+++ b/t/fts/indexed_mysql.t
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 
 use RT::Test tests => undef;
-plan skip_all => 'Not mysql' unless RT->Config->Get('DatabaseType') eq 'mysql';
+plan skip_all => 'Not mysql' unless RT->Config->Get('DatabaseType') =~ /^(?:mysql|MariaDB)$/;
 
 RT->Config->Set( FullTextSearch => Enable => 1, Indexed => 1, Table => 'AttachmentsIndex' );
 
diff --git a/t/ticket/search_utf8.t b/t/ticket/search_utf8.t
index ca2b720b9a..f93f31174a 100644
--- a/t/ticket/search_utf8.t
+++ b/t/ticket/search_utf8.t
@@ -31,7 +31,7 @@ for my $str (@tickets) {
 
 SKIP: for my $str (@tickets) {
     skip "MySQL's 4-byte char search is inaccurate", 20
-        if length $str == 1 && RT->Config->Get('DatabaseType') eq 'mysql';
+        if length $str == 1 && RT->Config->Get('DatabaseType') =~ /^(?:mysql|MariaDB)$/;
     my $tickets = RT::Tickets->new( RT->SystemUser );
     $tickets->FromSQL("Subject LIKE '$str'");
     diag "Search $str in subject";
diff --git a/t/validator/group_members.t b/t/validator/group_members.t
index ada0815a16..5f2c3575b9 100644
--- a/t/validator/group_members.t
+++ b/t/validator/group_members.t
@@ -115,8 +115,13 @@ RT::Test->db_is_valid;
     ok $group && $group->id, 'loaded or created group';
 
     my $dbh = $group->_Handle->dbh;
-    $dbh->do('DELETE FROM Principals WHERE id = ?', {RaiseError => 1}, $group->id);
-    $dbh->do('DELETE FROM CachedGroupMembers WHERE GroupId = ?', {RaiseError => 1}, $group->id);
+
+    # DBD::MariaDB doesn't support to pass RaiseError attribute in do parameters.
+    {
+        local $dbh->{RaiseError} = 1;
+        $dbh->do( 'DELETE FROM Principals WHERE id = ?',              {}, $group->id );
+        $dbh->do( 'DELETE FROM CachedGroupMembers WHERE GroupId = ?', {}, $group->id );
+    }
     DBIx::SearchBuilder::Record::Cachable->FlushCache;
 
     my ($ecode, $res) = RT::Test->run_validator(resolve => 1, timeout => 30);

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


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list