use crate::parser::SqlDialect;
use once_cell::sync::Lazy;
use regex::Regex;
pub struct TypeMapper;
impl TypeMapper {
pub fn convert(stmt: &str, from: SqlDialect, to: SqlDialect) -> String {
match (from, to) {
(SqlDialect::MySql, SqlDialect::Postgres) => Self::mysql_to_postgres(stmt),
(SqlDialect::MySql, SqlDialect::Sqlite) => Self::mysql_to_sqlite(stmt),
(SqlDialect::MySql, SqlDialect::Mssql) => Self::mysql_to_mssql(stmt),
(SqlDialect::Postgres, SqlDialect::MySql) => Self::postgres_to_mysql(stmt),
(SqlDialect::Postgres, SqlDialect::Sqlite) => Self::postgres_to_sqlite(stmt),
(SqlDialect::Postgres, SqlDialect::Mssql) => Self::postgres_to_mssql(stmt),
(SqlDialect::Sqlite, SqlDialect::MySql) => Self::sqlite_to_mysql(stmt),
(SqlDialect::Sqlite, SqlDialect::Postgres) => Self::sqlite_to_postgres(stmt),
(SqlDialect::Sqlite, SqlDialect::Mssql) => Self::sqlite_to_mssql(stmt),
(SqlDialect::Mssql, SqlDialect::MySql) => Self::mssql_to_mysql(stmt),
(SqlDialect::Mssql, SqlDialect::Postgres) => Self::mssql_to_postgres(stmt),
(SqlDialect::Mssql, SqlDialect::Sqlite) => Self::mssql_to_sqlite(stmt),
_ => stmt.to_string(),
}
}
fn mysql_to_postgres(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_TINYINT_BOOL.replace_all(&result, "BOOLEAN").to_string();
result = RE_TINYINT.replace_all(&result, "SMALLINT").to_string();
result = RE_SMALLINT.replace_all(&result, "SMALLINT").to_string();
result = RE_MEDIUMINT.replace_all(&result, "INTEGER").to_string();
result = RE_INT_SIZE.replace_all(&result, "INTEGER").to_string();
result = RE_BIGINT_SIZE.replace_all(&result, "BIGINT").to_string();
result = RE_DOUBLE
.replace_all(&result, "DOUBLE PRECISION")
.to_string();
result = RE_FLOAT.replace_all(&result, "REAL").to_string();
result = RE_LONGTEXT.replace_all(&result, "TEXT").to_string();
result = RE_MEDIUMTEXT.replace_all(&result, "TEXT").to_string();
result = RE_TINYTEXT.replace_all(&result, "TEXT").to_string();
result = RE_LONGBLOB.replace_all(&result, "BYTEA").to_string();
result = RE_MEDIUMBLOB.replace_all(&result, "BYTEA").to_string();
result = RE_TINYBLOB.replace_all(&result, "BYTEA").to_string();
result = RE_BLOB.replace_all(&result, "BYTEA").to_string();
result = RE_VARBINARY.replace_all(&result, "BYTEA").to_string();
result = RE_BINARY.replace_all(&result, "BYTEA").to_string();
result = RE_DATETIME.replace_all(&result, "TIMESTAMP").to_string();
result = RE_JSON.replace_all(&result, "JSONB").to_string();
result = RE_ENUM.replace_all(&result, "VARCHAR(255)").to_string();
result = RE_SET.replace_all(&result, "VARCHAR(255)").to_string();
result = RE_UNSIGNED.replace_all(&result, "").to_string();
result = RE_ZEROFILL.replace_all(&result, "").to_string();
result
}
fn mysql_to_sqlite(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_TINYINT.replace_all(&result, "INTEGER").to_string();
result = RE_SMALLINT.replace_all(&result, "INTEGER").to_string();
result = RE_MEDIUMINT.replace_all(&result, "INTEGER").to_string();
result = RE_INT_SIZE.replace_all(&result, "INTEGER").to_string();
result = RE_BIGINT_SIZE.replace_all(&result, "INTEGER").to_string();
result = RE_DOUBLE.replace_all(&result, "REAL").to_string();
result = RE_FLOAT.replace_all(&result, "REAL").to_string();
result = RE_DECIMAL.replace_all(&result, "REAL").to_string();
result = RE_LONGTEXT.replace_all(&result, "TEXT").to_string();
result = RE_MEDIUMTEXT.replace_all(&result, "TEXT").to_string();
result = RE_TINYTEXT.replace_all(&result, "TEXT").to_string();
result = RE_VARCHAR.replace_all(&result, "TEXT").to_string();
result = RE_CHAR.replace_all(&result, "TEXT").to_string();
result = RE_LONGBLOB.replace_all(&result, "BLOB").to_string();
result = RE_MEDIUMBLOB.replace_all(&result, "BLOB").to_string();
result = RE_TINYBLOB.replace_all(&result, "BLOB").to_string();
result = RE_VARBINARY.replace_all(&result, "BLOB").to_string();
result = RE_BINARY.replace_all(&result, "BLOB").to_string();
result = RE_DATETIME.replace_all(&result, "TEXT").to_string();
result = RE_TIMESTAMP.replace_all(&result, "TEXT").to_string();
result = RE_DATE.replace_all(&result, "TEXT").to_string();
result = RE_TIME.replace_all(&result, "TEXT").to_string();
result = RE_JSON.replace_all(&result, "TEXT").to_string();
result = RE_ENUM.replace_all(&result, "TEXT").to_string();
result = RE_SET.replace_all(&result, "TEXT").to_string();
result = RE_UNSIGNED.replace_all(&result, "").to_string();
result = RE_ZEROFILL.replace_all(&result, "").to_string();
result
}
fn postgres_to_mysql(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_BIGSERIAL
.replace_all(&result, "BIGINT AUTO_INCREMENT")
.to_string();
result = RE_SERIAL
.replace_all(&result, "INT AUTO_INCREMENT")
.to_string();
result = RE_SMALLSERIAL
.replace_all(&result, "SMALLINT AUTO_INCREMENT")
.to_string();
result = RE_BYTEA.replace_all(&result, "LONGBLOB").to_string();
result = RE_DOUBLE_PRECISION
.replace_all(&result, "DOUBLE")
.to_string();
result = RE_REAL.replace_all(&result, "FLOAT").to_string();
result = RE_BOOLEAN.replace_all(&result, "TINYINT(1)").to_string();
result = RE_TIMESTAMPTZ.replace_all(&result, "DATETIME").to_string();
result = RE_TIMESTAMP_WITH_TZ
.replace_all(&result, "DATETIME")
.to_string();
result = RE_TIMESTAMP_NO_TZ
.replace_all(&result, "DATETIME")
.to_string();
result = RE_JSONB.replace_all(&result, "JSON").to_string();
result = RE_UUID.replace_all(&result, "VARCHAR(36)").to_string();
result
}
fn postgres_to_sqlite(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_BIGSERIAL.replace_all(&result, "INTEGER").to_string();
result = RE_SERIAL.replace_all(&result, "INTEGER").to_string();
result = RE_SMALLSERIAL.replace_all(&result, "INTEGER").to_string();
result = RE_BYTEA.replace_all(&result, "BLOB").to_string();
result = RE_DOUBLE_PRECISION.replace_all(&result, "REAL").to_string();
result = RE_BOOLEAN.replace_all(&result, "INTEGER").to_string();
result = RE_TIMESTAMPTZ.replace_all(&result, "TEXT").to_string();
result = RE_TIMESTAMP_WITH_TZ
.replace_all(&result, "TEXT")
.to_string();
result = RE_TIMESTAMP_NO_TZ.replace_all(&result, "TEXT").to_string();
result = RE_JSONB.replace_all(&result, "TEXT").to_string();
result = RE_JSON.replace_all(&result, "TEXT").to_string();
result = RE_UUID.replace_all(&result, "TEXT").to_string();
result = RE_VARCHAR.replace_all(&result, "TEXT").to_string();
result
}
fn sqlite_to_mysql(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_REAL.replace_all(&result, "DOUBLE").to_string();
result
}
fn sqlite_to_postgres(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_REAL.replace_all(&result, "DOUBLE PRECISION").to_string();
result = RE_BLOB.replace_all(&result, "BYTEA").to_string();
result
}
fn mysql_to_mssql(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_TINYINT_BOOL.replace_all(&result, "BIT").to_string();
result = RE_TINYINT.replace_all(&result, "TINYINT").to_string();
result = RE_SMALLINT.replace_all(&result, "SMALLINT").to_string();
result = RE_MEDIUMINT.replace_all(&result, "INT").to_string();
result = RE_INT_SIZE.replace_all(&result, "INT").to_string();
result = RE_BIGINT_SIZE.replace_all(&result, "BIGINT").to_string();
result = RE_DOUBLE.replace_all(&result, "FLOAT").to_string();
result = RE_FLOAT.replace_all(&result, "REAL").to_string();
result = RE_LONGTEXT
.replace_all(&result, "NVARCHAR(MAX)")
.to_string();
result = RE_MEDIUMTEXT
.replace_all(&result, "NVARCHAR(MAX)")
.to_string();
result = RE_TINYTEXT
.replace_all(&result, "NVARCHAR(255)")
.to_string();
result = RE_LONGBLOB
.replace_all(&result, "VARBINARY(MAX)")
.to_string();
result = RE_MEDIUMBLOB
.replace_all(&result, "VARBINARY(MAX)")
.to_string();
result = RE_TINYBLOB
.replace_all(&result, "VARBINARY(255)")
.to_string();
result = RE_BLOB.replace_all(&result, "VARBINARY(MAX)").to_string();
result = RE_DATETIME.replace_all(&result, "DATETIME2").to_string();
result = RE_JSON.replace_all(&result, "NVARCHAR(MAX)").to_string();
result = RE_ENUM.replace_all(&result, "NVARCHAR(255)").to_string();
result = RE_SET.replace_all(&result, "NVARCHAR(255)").to_string();
result = RE_UNSIGNED.replace_all(&result, "").to_string();
result = RE_ZEROFILL.replace_all(&result, "").to_string();
result
}
fn postgres_to_mssql(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_BIGSERIAL
.replace_all(&result, "BIGINT IDENTITY(1,1)")
.to_string();
result = RE_SERIAL
.replace_all(&result, "INT IDENTITY(1,1)")
.to_string();
result = RE_SMALLSERIAL
.replace_all(&result, "SMALLINT IDENTITY(1,1)")
.to_string();
result = RE_BYTEA.replace_all(&result, "VARBINARY(MAX)").to_string();
result = RE_DOUBLE_PRECISION
.replace_all(&result, "FLOAT")
.to_string();
result = RE_BOOLEAN.replace_all(&result, "BIT").to_string();
result = RE_TIMESTAMPTZ
.replace_all(&result, "DATETIMEOFFSET")
.to_string();
result = RE_TIMESTAMP_WITH_TZ
.replace_all(&result, "DATETIMEOFFSET")
.to_string();
result = RE_TIMESTAMP_NO_TZ
.replace_all(&result, "DATETIME2")
.to_string();
result = RE_JSONB.replace_all(&result, "NVARCHAR(MAX)").to_string();
result = RE_JSON.replace_all(&result, "NVARCHAR(MAX)").to_string();
result = RE_UUID.replace_all(&result, "UNIQUEIDENTIFIER").to_string();
result = RE_TEXT.replace_all(&result, "NVARCHAR(MAX)").to_string();
result
}
fn sqlite_to_mssql(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_REAL.replace_all(&result, "FLOAT").to_string();
result = RE_BLOB.replace_all(&result, "VARBINARY(MAX)").to_string();
result = RE_TEXT.replace_all(&result, "NVARCHAR(MAX)").to_string();
result
}
fn mssql_to_mysql(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_BIT.replace_all(&result, "TINYINT(1)").to_string();
result = RE_NVARCHAR_MAX.replace_all(&result, "LONGTEXT").to_string();
result = RE_NVARCHAR.replace_all(&result, "VARCHAR$1").to_string();
result = RE_NCHAR.replace_all(&result, "CHAR$1").to_string();
result = RE_NTEXT.replace_all(&result, "LONGTEXT").to_string();
result = RE_VARCHAR_MAX.replace_all(&result, "LONGTEXT").to_string();
result = RE_VARBINARY_MAX
.replace_all(&result, "LONGBLOB")
.to_string();
result = RE_IMAGE.replace_all(&result, "LONGBLOB").to_string();
result = RE_DATETIME2.replace_all(&result, "DATETIME(6)").to_string();
result = RE_DATETIMEOFFSET
.replace_all(&result, "DATETIME")
.to_string();
result = RE_SMALLDATETIME
.replace_all(&result, "DATETIME")
.to_string();
result = RE_MONEY.replace_all(&result, "DECIMAL(19,4)").to_string();
result = RE_SMALLMONEY
.replace_all(&result, "DECIMAL(10,4)")
.to_string();
result = RE_UNIQUEIDENTIFIER
.replace_all(&result, "VARCHAR(36)")
.to_string();
result = RE_XML.replace_all(&result, "LONGTEXT").to_string();
result = RE_MSSQL_TIMESTAMP_BRACKETED
.replace_all(&result, "BINARY(8)")
.to_string();
result = RE_ROWVERSION_ONLY
.replace_all(&result, "BINARY(8)")
.to_string();
result = RE_ON_PRIMARY.replace_all(&result, "").to_string();
result = RE_CLUSTERED.replace_all(&result, "").to_string();
result = RE_NONCLUSTERED.replace_all(&result, "").to_string();
result
}
fn mssql_to_postgres(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_MSSQL_TIMESTAMP_BRACKETED
.replace_all(&result, "BYTEA")
.to_string();
result = RE_ROWVERSION_ONLY.replace_all(&result, "BYTEA").to_string();
result = RE_BIT.replace_all(&result, "BOOLEAN").to_string();
result = RE_NVARCHAR_MAX.replace_all(&result, "TEXT").to_string();
result = RE_NVARCHAR.replace_all(&result, "VARCHAR$1").to_string();
result = RE_NCHAR.replace_all(&result, "CHAR$1").to_string();
result = RE_NTEXT.replace_all(&result, "TEXT").to_string();
result = RE_VARCHAR_MAX.replace_all(&result, "TEXT").to_string();
result = RE_VARBINARY_MAX.replace_all(&result, "BYTEA").to_string();
result = RE_VARBINARY.replace_all(&result, "BYTEA").to_string();
result = RE_IMAGE.replace_all(&result, "BYTEA").to_string();
result = RE_DATETIME2.replace_all(&result, "TIMESTAMP").to_string();
result = RE_DATETIME.replace_all(&result, "TIMESTAMP").to_string();
result = RE_DATETIMEOFFSET
.replace_all(&result, "TIMESTAMPTZ")
.to_string();
result = RE_SMALLDATETIME
.replace_all(&result, "TIMESTAMP")
.to_string();
result = RE_MONEY.replace_all(&result, "DECIMAL(19,4)").to_string();
result = RE_SMALLMONEY
.replace_all(&result, "DECIMAL(10,4)")
.to_string();
result = RE_UNIQUEIDENTIFIER.replace_all(&result, "UUID").to_string();
result = RE_FLOAT
.replace_all(&result, "DOUBLE PRECISION")
.to_string();
result = RE_ON_PRIMARY.replace_all(&result, "").to_string();
result = RE_CLUSTERED.replace_all(&result, "").to_string();
result = RE_NONCLUSTERED.replace_all(&result, "").to_string();
result
}
fn mssql_to_sqlite(stmt: &str) -> String {
let mut result = stmt.to_string();
result = RE_BIT.replace_all(&result, "INTEGER").to_string();
result = RE_NVARCHAR_MAX.replace_all(&result, "TEXT").to_string();
result = RE_NVARCHAR.replace_all(&result, "TEXT").to_string();
result = RE_NCHAR.replace_all(&result, "TEXT").to_string();
result = RE_NTEXT.replace_all(&result, "TEXT").to_string();
result = RE_VARCHAR_MAX.replace_all(&result, "TEXT").to_string();
result = RE_VARBINARY_MAX.replace_all(&result, "BLOB").to_string();
result = RE_VARBINARY.replace_all(&result, "BLOB").to_string();
result = RE_IMAGE.replace_all(&result, "BLOB").to_string();
result = RE_DATETIME2.replace_all(&result, "TEXT").to_string();
result = RE_DATETIME.replace_all(&result, "TEXT").to_string();
result = RE_DATETIMEOFFSET.replace_all(&result, "TEXT").to_string();
result = RE_SMALLDATETIME.replace_all(&result, "TEXT").to_string();
result = RE_MONEY.replace_all(&result, "REAL").to_string();
result = RE_SMALLMONEY.replace_all(&result, "REAL").to_string();
result = RE_UNIQUEIDENTIFIER.replace_all(&result, "TEXT").to_string();
result = RE_XML.replace_all(&result, "TEXT").to_string();
result = RE_MSSQL_TIMESTAMP_BRACKETED
.replace_all(&result, "BLOB")
.to_string();
result = RE_ROWVERSION_ONLY.replace_all(&result, "BLOB").to_string();
result = RE_FLOAT.replace_all(&result, "REAL").to_string();
result = RE_ON_PRIMARY.replace_all(&result, "").to_string();
result = RE_CLUSTERED.replace_all(&result, "").to_string();
result = RE_NONCLUSTERED.replace_all(&result, "").to_string();
result
}
}
static RE_TINYINT_BOOL: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bTINYINT\s*\(\s*1\s*\)").unwrap());
static RE_TINYINT: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bTINYINT\s*(\(\s*\d+\s*\))?").unwrap());
static RE_SMALLINT: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bSMALLINT\s*(\(\s*\d+\s*\))?").unwrap());
static RE_MEDIUMINT: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bMEDIUMINT\s*(\(\s*\d+\s*\))?").unwrap());
static RE_INT_SIZE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bINT\s*\(\s*\d+\s*\)").unwrap());
static RE_BIGINT_SIZE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bBIGINT\s*\(\s*\d+\s*\)").unwrap());
static RE_DOUBLE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bDOUBLE\b").unwrap());
static RE_FLOAT: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bFLOAT\s*(\(\s*\d+\s*(,\s*\d+\s*)?\))?").unwrap());
static RE_DECIMAL: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bDECIMAL\s*\(\s*\d+\s*(,\s*\d+\s*)?\)").unwrap());
static RE_LONGTEXT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bLONGTEXT\b").unwrap());
static RE_MEDIUMTEXT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bMEDIUMTEXT\b").unwrap());
static RE_TINYTEXT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bTINYTEXT\b").unwrap());
static RE_VARCHAR: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bVARCHAR\s*\(\s*\d+\s*\)").unwrap());
static RE_CHAR: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bCHAR\s*\(\s*\d+\s*\)").unwrap());
static RE_LONGBLOB: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bLONGBLOB\b").unwrap());
static RE_MEDIUMBLOB: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bMEDIUMBLOB\b").unwrap());
static RE_TINYBLOB: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bTINYBLOB\b").unwrap());
static RE_BLOB: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bBLOB\b").unwrap());
static RE_VARBINARY: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bVARBINARY\s*\(\s*\d+\s*\)").unwrap());
static RE_BINARY: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bBINARY\s*\(\s*\d+\s*\)").unwrap());
static RE_DATETIME: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bDATETIME(\(\s*\d+\s*\))?").unwrap());
static RE_TIMESTAMP: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bTIMESTAMP\s*(\(\s*\d+\s*\))?").unwrap());
static RE_DATE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bDATE\b").unwrap());
static RE_TIME: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bTIME\s*(\(\s*\d+\s*\))?").unwrap());
static RE_JSON: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bJSON\b").unwrap());
static RE_ENUM: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bENUM\s*\([^)]+\)").unwrap());
static RE_SET: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bSET\s*\([^)]+\)").unwrap());
static RE_UNSIGNED: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\s+UNSIGNED\b").unwrap());
static RE_ZEROFILL: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\s+ZEROFILL\b").unwrap());
static RE_SERIAL: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bSERIAL\b").unwrap());
static RE_BIGSERIAL: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bBIGSERIAL\b").unwrap());
static RE_SMALLSERIAL: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bSMALLSERIAL\b").unwrap());
static RE_BYTEA: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bBYTEA\b").unwrap());
static RE_DOUBLE_PRECISION: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bDOUBLE\s+PRECISION\b").unwrap());
static RE_REAL: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bREAL\b").unwrap());
static RE_BOOLEAN: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bBOOLEAN\b").unwrap());
static RE_TIMESTAMPTZ: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bTIMESTAMPTZ\b").unwrap());
static RE_TIMESTAMP_WITH_TZ: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bTIMESTAMP\s+WITH\s+TIME\s+ZONE\b").unwrap());
static RE_TIMESTAMP_NO_TZ: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bTIMESTAMP\s+WITHOUT\s+TIME\s+ZONE\b").unwrap());
static RE_JSONB: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bJSONB\b").unwrap());
static RE_UUID: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bUUID\b").unwrap());
static RE_TEXT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bTEXT\b").unwrap());
static RE_BIT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bBIT\b").unwrap());
static RE_NVARCHAR_MAX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bNVARCHAR\s*\(\s*MAX\s*\)").unwrap());
static RE_NVARCHAR: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bNVARCHAR\s*(\(\s*\d+\s*\))").unwrap());
static RE_NCHAR: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bNCHAR\s*(\(\s*\d+\s*\))").unwrap());
static RE_NTEXT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bNTEXT\b").unwrap());
static RE_VARCHAR_MAX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bVARCHAR\s*\(\s*MAX\s*\)").unwrap());
static RE_VARBINARY_MAX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bVARBINARY\s*\(\s*MAX\s*\)").unwrap());
static RE_IMAGE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bIMAGE\b").unwrap());
static RE_DATETIME2: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bDATETIME2\s*(\(\s*\d+\s*\))?").unwrap());
static RE_DATETIMEOFFSET: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bDATETIMEOFFSET\s*(\(\s*\d+\s*\))?").unwrap());
static RE_SMALLDATETIME: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bSMALLDATETIME\b").unwrap());
static RE_MONEY: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bMONEY\b").unwrap());
static RE_SMALLMONEY: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bSMALLMONEY\b").unwrap());
static RE_UNIQUEIDENTIFIER: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\bUNIQUEIDENTIFIER\b").unwrap());
static RE_XML: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bXML\b").unwrap());
static RE_MSSQL_TIMESTAMP_BRACKETED: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\[\s*TIMESTAMP\s*\]").unwrap());
static RE_ROWVERSION_ONLY: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bROWVERSION\b").unwrap());
static RE_ON_PRIMARY: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)\s*ON\s*\[\s*PRIMARY\s*\]").unwrap());
static RE_CLUSTERED: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bCLUSTERED\s+").unwrap());
static RE_NONCLUSTERED: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?i)\bNONCLUSTERED\s+").unwrap());