/// <summary>
        /// Gets the default name of the type.
        /// </summary>
        /// <param name="typeMetadata">The type metadata.</param>
        /// <returns>A type name for the given type metadata.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when a type is unknown or failed to be parsed.</exception>
        protected static Identifier GetDefaultTypeName(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }

            switch (typeMetadata.DataType)
            {
            case DataType.BigInteger:
                return("bigint");

            case DataType.Binary:
                return(typeMetadata.IsFixedLength ? "binary" : "varbinary");

            case DataType.LargeBinary:
                return("longblob");

            case DataType.Boolean:
                return("bit");

            case DataType.Date:
                return("date");

            case DataType.DateTime:
                return("datetime");

            case DataType.Float:
                return("double");

            case DataType.Integer:
                return("int");

            case DataType.Interval:
                return("timestamp");

            case DataType.Numeric:
                return("numeric");

            case DataType.SmallInteger:
                return("smallint");

            case DataType.String:
            case DataType.Unicode:
                return(typeMetadata.IsFixedLength ? "char" : "varchar");

            case DataType.Text:
            case DataType.UnicodeText:
                return("longtext");

            case DataType.Time:
                return("time");

            case DataType.Unknown:
                throw new ArgumentOutOfRangeException(nameof(typeMetadata), "Unable to determine a type name for an unknown data type.");

            default:
                throw new ArgumentOutOfRangeException(nameof(typeMetadata), "Unable to determine a type name for data type: " + typeMetadata.DataType.ToString());
            }
        }
        /// <summary>
        /// Creates a column data type based on provided metadata.
        /// </summary>
        /// <param name="typeMetadata">Column type metadata.</param>
        /// <returns>A column data type.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        public IDbType CreateColumnType(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }

            if (typeMetadata.TypeName == null)
            {
                typeMetadata.TypeName = GetDefaultTypeName(typeMetadata);
            }
            if (typeMetadata.DataType == DataType.Unknown)
            {
                typeMetadata.DataType = GetDataType(typeMetadata.TypeName);
            }
            if (typeMetadata.ClrType == null)
            {
                typeMetadata.ClrType = GetClrType(typeMetadata.TypeName);
            }
            typeMetadata.IsFixedLength = GetIsFixedLength(typeMetadata.TypeName);

            var definition = GetFormattedTypeName(typeMetadata);

            return(new ColumnDataType(
                       typeMetadata.TypeName,
                       typeMetadata.DataType,
                       definition,
                       typeMetadata.ClrType,
                       typeMetadata.IsFixedLength,
                       typeMetadata.MaxLength,
                       typeMetadata.NumericPrecision,
                       typeMetadata.Collation
                       ));
        }
        /// <summary>
        /// Gets the name of the formatted type.
        /// </summary>
        /// <param name="typeMetadata">The type metadata.</param>
        /// <returns>A string representing a type name.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when a type name is missing.</exception>
        protected static string GetFormattedTypeName(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }
            if (typeMetadata.TypeName == null)
            {
                throw new ArgumentException("The type name is missing. A formatted type name cannot be generated.", nameof(typeMetadata));
            }

            var builder  = StringBuilderCache.Acquire(typeMetadata.TypeName.LocalName.Length * 2);
            var typeName = typeMetadata.TypeName;

            if (string.Equals(typeName.Schema, "pg_catalog", StringComparison.OrdinalIgnoreCase))
            {
                builder.Append(QuoteIdentifier(typeName.LocalName));
            }
            else
            {
                builder.Append(QuoteName(typeName));
            }

            if (TypeNamesWithNoLengthAnnotation.Contains(typeName))
            {
                return(builder.GetStringAndRelease());
            }

            builder.Append('(');

            var npWithPrecisionOrScale = typeMetadata.NumericPrecision.Filter(np => np.Precision > 0 || np.Scale > 0);

            if (npWithPrecisionOrScale.IsSome)
            {
                npWithPrecisionOrScale.IfSome(precision =>
                {
                    builder.Append(precision.Precision.ToString(CultureInfo.InvariantCulture));
                    if (precision.Scale > 0)
                    {
                        builder.Append(", ");
                        builder.Append(precision.Scale.ToString(CultureInfo.InvariantCulture));
                    }
                });
            }
            else if (typeMetadata.MaxLength > 0)
            {
                var maxLength = typeMetadata.DataType == DataType.Unicode || typeMetadata.DataType == DataType.UnicodeText
                    ? typeMetadata.MaxLength / 2
                    : typeMetadata.MaxLength;

                builder.Append(maxLength.ToString(CultureInfo.InvariantCulture));
            }

            builder.Append(')');

            return(builder.GetStringAndRelease());
        }
Example #4
0
 public IDbType CreateColumnType(ColumnTypeMetadata typeMetadata) => new ColumnDataType(
     "test_type",
     DataType.BigInteger,
     "test_type(10)",
     typeof(object),
     false,
     10,
     new NumericPrecision(10, 0),
     null
     );
Example #5
0
    private ColumnTypeMetadata GetColumnTypeMetadata(string columnTypeName, bool unsigned, int length)
    {
        ColumnTypeMetadata columnTypeMetadata;

        if (!m_columnTypeMetadataLookup.TryGetValue(ColumnTypeMetadata.CreateLookupKey(columnTypeName, unsigned, length), out columnTypeMetadata) && length != 0)
        {
            m_columnTypeMetadataLookup.TryGetValue(ColumnTypeMetadata.CreateLookupKey(columnTypeName, unsigned, 0), out columnTypeMetadata);
        }
        return(columnTypeMetadata);
    }
Example #6
0
    public DbTypeMapping GetDbTypeMapping(string columnTypeName, bool unsigned = false, int length = 0)
    {
        ColumnTypeMetadata columnTypeMetadata = GetColumnTypeMetadata(columnTypeName, unsigned, length);

        if (columnTypeMetadata == null)
        {
            return(null);
        }
        return(columnTypeMetadata.DbTypeMapping);
    }
Example #7
0
        public ReflectionColumnDataType(IDatabaseDialect dialect, Type columnType, Type clrType)
        {
            if (dialect == null)
            {
                throw new ArgumentNullException(nameof(dialect));
            }
            if (columnType == null)
            {
                throw new ArgumentNullException(nameof(columnType));
            }
            if (clrType == null)
            {
                throw new ArgumentNullException(nameof(clrType));
            }

            var attr = dialect.GetDialectAttribute <DeclaredTypeAttribute>(columnType);

            if (attr == null)
            {
                throw new ArgumentException($"The column type { columnType.FullName } does not contain a definition for the dialect { dialect.GetType().FullName }");
            }

            var typeProvider = dialect.TypeProvider;

            if (typeProvider == null)
            {
                throw new ArgumentException("The given dialect does not contain a valid type provider.", nameof(dialect));
            }

            var collationAttr = dialect.GetDialectAttribute <CollationAttribute>(columnType);
            var typeMetadata  = new ColumnTypeMetadata
            {
                ClrType   = clrType,
                Collation = collationAttr?.CollationName != null
                    ? Option <Identifier> .Some(collationAttr.CollationName)
                    : Option <Identifier> .None,
                DataType         = attr.DataType,
                IsFixedLength    = attr.IsFixedLength,
                MaxLength        = attr.Length,
                NumericPrecision = attr.Precision > 0 && attr.Scale > 0
                    ? Option <INumericPrecision> .Some(new NumericPrecision(attr.Precision, attr.Scale))
                    : Option <INumericPrecision> .None,
            };
            var dbType = typeProvider.CreateColumnType(typeMetadata);

            // map dbType to properties, avoids keeping a reference
            TypeName         = dbType.TypeName;
            DataType         = dbType.DataType;
            Definition       = dbType.Definition;
            IsFixedLength    = dbType.IsFixedLength;
            MaxLength        = dbType.MaxLength;
            ClrType          = dbType.ClrType;
            NumericPrecision = dbType.NumericPrecision;
            Collation        = dbType.Collation;
        }
Example #8
0
        private async Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsyncCore(Identifier tableName, CancellationToken cancellationToken)
        {
            var query = await DbConnection.QueryAsync <ColumnDataV10>(
                ColumnsQuery,
                new { SchemaName = tableName.Schema, TableName = tableName.LocalName },
                cancellationToken
                ).ConfigureAwait(false);

            var result = new List <IDatabaseColumn>();

            foreach (var row in query)
            {
                var typeMetadata = new ColumnTypeMetadata
                {
                    TypeName  = Identifier.CreateQualifiedIdentifier(Constants.PgCatalog, row.data_type),
                    Collation = !row.collation_name.IsNullOrWhiteSpace()
                        ? Option <Identifier> .Some(Identifier.CreateQualifiedIdentifier(row.collation_catalog, row.collation_schema, row.collation_name))
                        : Option <Identifier> .None,
                    MaxLength = row.character_maximum_length > 0
                        ? row.character_maximum_length
                        : CreatePrecisionFromBase(row.numeric_precision, row.numeric_precision_radix),
                    NumericPrecision = row.numeric_precision_radix > 0
                        ? Option <INumericPrecision> .Some(CreatePrecisionWithScaleFromBase(row.numeric_precision, row.numeric_scale, row.numeric_precision_radix))
                        : Option <INumericPrecision> .None
                };

                var columnType = TypeProvider.CreateColumnType(typeMetadata);
                var columnName = Identifier.CreateQualifiedIdentifier(row.column_name);

                var isAutoIncrement = row.is_identity == Constants.Yes;
                var autoIncrement   = isAutoIncrement &&
                                      decimal.TryParse(row.identity_start, out var seqStart) &&
                                      decimal.TryParse(row.identity_increment, out var seqIncr)
                    ? Option <IAutoIncrement> .Some(new AutoIncrement(seqStart, seqIncr))
                    : Option <IAutoIncrement> .None;

                var isSerialAutoIncrement = !isAutoIncrement && !row.serial_sequence_schema_name.IsNullOrWhiteSpace() && !row.serial_sequence_local_name.IsNullOrWhiteSpace();
                if (isSerialAutoIncrement)
                {
                    autoIncrement = Option <IAutoIncrement> .Some(new AutoIncrement(1, 1));
                }

                var defaultValue = !row.column_default.IsNullOrWhiteSpace()
                    ? Option <string> .Some(row.column_default)
                    : Option <string> .None;

                var isNullable = row.is_nullable == Constants.Yes;

                var column = new DatabaseColumn(columnName, columnType, isNullable, defaultValue, autoIncrement);
                result.Add(column);
            }

            return(result);
        }
        /// <summary>
        /// Creates a column data type based on provided metadata.
        /// </summary>
        /// <param name="typeMetadata">Column type metadata.</param>
        /// <returns>A column data type.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        public IDbType CreateColumnType(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }

            if (typeMetadata.TypeName == null)
            {
                typeMetadata.TypeName = GetDefaultTypeName(typeMetadata);
            }
            if (typeMetadata.DataType == DataType.Unknown)
            {
                typeMetadata.DataType = GetDataType(typeMetadata.TypeName);
                if (typeMetadata.DataType == DataType.Numeric)
                {
                    var numericPrecision = typeMetadata.NumericPrecision.Filter(np => np.Scale == 0);
                    numericPrecision.IfSome(np =>
                    {
                        typeMetadata.DataType = np.Precision < 8
                            ? DataType.Integer     // 2^32
                            : DataType.BigInteger; // note: could require storing in a decimal instead of long
                    });
                    if (typeMetadata.NumericPrecision.IsNone)
                    {
                        typeMetadata.DataType = typeMetadata.MaxLength < 8
                            ? DataType.Integer     // 2^32
                            : DataType.BigInteger; // note: could require storing in a decimal instead of long
                    }
                }
            }
            if (typeMetadata.ClrType == null)
            {
                typeMetadata.ClrType = GetClrType(typeMetadata.TypeName);
            }
            typeMetadata.IsFixedLength = GetIsFixedLength(typeMetadata.TypeName);

            var definition = GetFormattedTypeName(typeMetadata);

            return(new ColumnDataType(
                       typeMetadata.TypeName,
                       typeMetadata.DataType,
                       definition,
                       typeMetadata.ClrType,
                       typeMetadata.IsFixedLength,
                       typeMetadata.MaxLength,
                       typeMetadata.NumericPrecision,
                       typeMetadata.Collation
                       ));
        }
Example #10
0
    private void AddColumnTypeMetadata(ColumnTypeMetadata columnTypeMetadata)
    {
        m_columnTypeMetadata.Add(columnTypeMetadata);
        string lookupKey = columnTypeMetadata.CreateLookupKey();

        if (!m_columnTypeMetadataLookup.ContainsKey(lookupKey))
        {
            m_columnTypeMetadataLookup.Add(lookupKey, columnTypeMetadata);
        }
        if (!m_mySqlDbTypeToColumnTypeMetadata.ContainsKey(columnTypeMetadata.MySqlDbType))
        {
            m_mySqlDbTypeToColumnTypeMetadata.Add(columnTypeMetadata.MySqlDbType, columnTypeMetadata);
        }
    }
Example #11
0
        /// <summary>
        /// Gets the data type that most closely matches the provided data type.
        /// </summary>
        /// <param name="otherType">An data type to compare with.</param>
        /// <returns>The closest matching column data type.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="otherType"/> is <c>null</c>.</exception>
        public IDbType GetComparableColumnType(IDbType otherType)
        {
            if (otherType == null)
            {
                throw new ArgumentNullException(nameof(otherType));
            }

            // only interested in these two bits of information
            var typeMetadata = new ColumnTypeMetadata
            {
                Collation = otherType.Collation,
                DataType  = otherType.DataType
            };

            return(CreateColumnType(typeMetadata));
        }
        private async Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsyncCore(Identifier viewName, CancellationToken cancellationToken)
        {
            var query = await DbConnection.QueryAsync <ColumnData>(
                ColumnsQuery,
                new { SchemaName = viewName.Schema, ViewName = viewName.LocalName },
                cancellationToken
                ).ConfigureAwait(false);

            var result = new List <IDatabaseColumn>();

            foreach (var row in query)
            {
                var precision = row.DateTimePrecision > 0
                    ? new NumericPrecision(row.DateTimePrecision, 0)
                    : new NumericPrecision(row.Precision, row.Scale);

                var typeMetadata = new ColumnTypeMetadata
                {
                    TypeName  = Identifier.CreateQualifiedIdentifier(row.DataTypeName),
                    Collation = !row.Collation.IsNullOrWhiteSpace()
                        ? Option <Identifier> .Some(Identifier.CreateQualifiedIdentifier(row.Collation))
                        : Option <Identifier> .None,
                    MaxLength        = row.CharacterMaxLength,
                    NumericPrecision = precision
                };
                var columnType = Dialect.TypeProvider.CreateColumnType(typeMetadata);

                var columnName      = Identifier.CreateQualifiedIdentifier(row.ColumnName);
                var isAutoIncrement = row.ExtraInformation != null &&
                                      row.ExtraInformation.Contains(Constants.AutoIncrement, StringComparison.OrdinalIgnoreCase);
                var autoIncrement = isAutoIncrement
                    ? Option <IAutoIncrement> .Some(new AutoIncrement(1, 1))
                    : Option <IAutoIncrement> .None;

                var isNullable   = !string.Equals(row.IsNullable, Constants.No, StringComparison.OrdinalIgnoreCase);
                var defaultValue = !row.DefaultValue.IsNullOrWhiteSpace()
                    ? Option <string> .Some(row.DefaultValue)
                    : Option <string> .None;

                var column = new DatabaseColumn(columnName, columnType, isNullable, defaultValue, autoIncrement);
                result.Add(column);
            }

            return(result);
        }
Example #13
0
        /// <summary>
        /// Creates a column data type based on provided metadata.
        /// </summary>
        /// <param name="typeMetadata">Column type metadata.</param>
        /// <returns>A column data type.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        public IDbType CreateColumnType(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }

            var typeName  = GetDefaultTypeName(typeMetadata.DataType);
            var affinity  = GetAffinity(typeName);
            var collation = typeMetadata.Collation.Match(
                c => Enum.TryParse(c.LocalName, out SqliteCollation sc) ? sc : SqliteCollation.None,
                () => SqliteCollation.None
                );

            return(collation == SqliteCollation.None
                ? new SqliteColumnType(affinity)
                : new SqliteColumnType(affinity, collation));
        }
        private async Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsyncCore(Identifier viewName, CancellationToken cancellationToken)
        {
            var query = await DbConnection.QueryAsync <ColumnData>(
                ColumnsQuery,
                new { SchemaName = viewName.Schema, ViewName = viewName.LocalName },
                cancellationToken
                ).ConfigureAwait(false);

            var columnNames = query
                              .Where(row => row.ColumnName != null)
                              .Select(row => row.ColumnName !)
                              .ToList();
            var notNullableColumnNames = await GetNotNullConstrainedColumnsAsync(viewName, columnNames, cancellationToken).ConfigureAwait(false);

            var result = new List <IDatabaseColumn>();

            foreach (var row in query)
            {
                var typeMetadata = new ColumnTypeMetadata
                {
                    TypeName  = Identifier.CreateQualifiedIdentifier(row.ColumnTypeSchema, row.ColumnTypeName),
                    Collation = !row.Collation.IsNullOrWhiteSpace()
                        ? Option <Identifier> .Some(Identifier.CreateQualifiedIdentifier(row.Collation))
                        : Option <Identifier> .None,
                    MaxLength        = row.DataLength,
                    NumericPrecision = row.Precision > 0 || row.Scale > 0
                        ? Option <INumericPrecision> .Some(new NumericPrecision(row.Precision, row.Scale))
                        : Option <INumericPrecision> .None
                };
                var columnType = Dialect.TypeProvider.CreateColumnType(typeMetadata);

                var isNullable   = !notNullableColumnNames.Contains(row.ColumnName);
                var columnName   = Identifier.CreateQualifiedIdentifier(row.ColumnName);
                var defaultValue = !row.DefaultValue.IsNullOrWhiteSpace()
                     ? Option <string> .Some(row.DefaultValue)
                     : Option <string> .None;

                var column = new OracleDatabaseColumn(columnName, columnType, isNullable, defaultValue);

                result.Add(column);
            }

            return(result);
        }
        /// <summary>
        /// Gets the data type that most closely matches the provided data type.
        /// </summary>
        /// <param name="otherType">An data type to compare with.</param>
        /// <returns>The closest matching column data type.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="otherType"/> is <c>null</c>.</exception>
        public IDbType GetComparableColumnType(IDbType otherType)
        {
            if (otherType == null)
            {
                throw new ArgumentNullException(nameof(otherType));
            }

            var typeMetadata = new ColumnTypeMetadata
            {
                ClrType          = null, // ignoring so we get the default type provided
                Collation        = otherType.Collation,
                DataType         = otherType.DataType,
                IsFixedLength    = otherType.IsFixedLength,
                MaxLength        = otherType.MaxLength,
                NumericPrecision = otherType.NumericPrecision,
                TypeName         = null // ignoring so we get a default name generated
            };

            return(CreateColumnType(typeMetadata));
        }
Example #16
0
        private async Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsyncCore(Identifier viewName, CancellationToken cancellationToken)
        {
            var query = await DbConnection.QueryAsync <ColumnData>(
                ColumnsQuery,
                new { SchemaName = viewName.Schema, ViewName = viewName.LocalName },
                cancellationToken
                ).ConfigureAwait(false);

            var result = new List <IDatabaseColumn>();

            foreach (var row in query)
            {
                var typeMetadata = new ColumnTypeMetadata
                {
                    TypeName  = Identifier.CreateQualifiedIdentifier(row.ColumnTypeSchema, row.ColumnTypeName),
                    Collation = !row.Collation.IsNullOrWhiteSpace()
                        ? Option <Identifier> .Some(Identifier.CreateQualifiedIdentifier(row.Collation))
                        : Option <Identifier> .None,
                    MaxLength        = row.MaxLength,
                    NumericPrecision = new NumericPrecision(row.Precision, row.Scale)
                };
                var columnType = Dialect.TypeProvider.CreateColumnType(typeMetadata);

                var columnName    = Identifier.CreateQualifiedIdentifier(row.ColumnName);
                var autoIncrement = row.IdentityIncrement
                                    .Match(
                    incr => row.IdentitySeed.Match(seed => new AutoIncrement(seed, incr), () => Option <IAutoIncrement> .None),
                    () => Option <IAutoIncrement> .None
                    );
                var defaultValue = row.HasDefaultValue && row.DefaultValue != null
                    ? Option <string> .Some(row.DefaultValue)
                    : Option <string> .None;

                var column = new DatabaseColumn(columnName, columnType, row.IsNullable, defaultValue, autoIncrement);

                result.Add(column);
            }

            return(result);
        }
Example #17
0
        private async Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsyncCore(Identifier viewName, CancellationToken cancellationToken)
        {
            var query = await DbConnection.QueryAsync <ColumnData>(
                ColumnsQuery,
                new { SchemaName = viewName.Schema, ViewName = viewName.LocalName },
                cancellationToken
                ).ConfigureAwait(false);

            var result = new List <IDatabaseColumn>();

            foreach (var row in query)
            {
                var typeMetadata = new ColumnTypeMetadata
                {
                    TypeName  = Identifier.CreateQualifiedIdentifier(row.data_type),
                    Collation = !row.collation_name.IsNullOrWhiteSpace()
                        ? Option <Identifier> .Some(Identifier.CreateQualifiedIdentifier(row.collation_catalog, row.collation_schema, row.collation_name))
                        : Option <Identifier> .None,
                    //TODO -- need to fix max length as it's different for char-like objects and numeric
                    //MaxLength = row.,
                    // TODO: numeric_precision has a base, can be either binary or decimal, need to use the correct one
                    NumericPrecision = new NumericPrecision(row.numeric_precision, row.numeric_scale)
                };

                var columnType    = Dialect.TypeProvider.CreateColumnType(typeMetadata);
                var columnName    = Identifier.CreateQualifiedIdentifier(row.column_name);
                var autoIncrement = Option <IAutoIncrement> .None;
                var defaultValue  = !row.column_default.IsNullOrWhiteSpace()
                     ? Option <string> .Some(row.column_default)
                     : Option <string> .None;

                var column = new DatabaseColumn(columnName, columnType, row.is_nullable == Constants.Yes, defaultValue, autoIncrement);
                result.Add(column);
            }

            return(result);
        }
        /// <summary>
        /// Gets the default name of the type.
        /// </summary>
        /// <param name="typeMetadata">The type metadata.</param>
        /// <returns>A type name for the given type metadata.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when a type is unknown or failed to be parsed.</exception>
        protected static Identifier GetDefaultTypeName(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }

            switch (typeMetadata.DataType)
            {
            case DataType.Boolean:
                return(new Identifier("pg_catalog", "bool"));

            case DataType.BigInteger:
                return(new Identifier("pg_catalog", "int8"));

            case DataType.Binary:
                return(typeMetadata.IsFixedLength
                        ? new Identifier("pg_catalog", "bit")
                        : new Identifier("pg_catalog", "varbit"));

            case DataType.LargeBinary:
                return(new Identifier("pg_catalog", "bytea"));

            case DataType.Date:
                return(new Identifier("pg_catalog", "date"));

            case DataType.DateTime:
                return(new Identifier("pg_catalog", "timestamp"));

            case DataType.Float:
                return(new Identifier("pg_catalog", "float8"));

            case DataType.Integer:
                return(new Identifier("pg_catalog", "int4"));

            case DataType.Interval:
                return(new Identifier("pg_catalog", "interval"));

            case DataType.Numeric:
                return(new Identifier("pg_catalog", "numeric"));

            case DataType.SmallInteger:
                return(new Identifier("pg_catalog", "int2"));

            case DataType.Time:
                return(new Identifier("pg_catalog", "time"));

            case DataType.String:
            case DataType.Unicode:
                return(typeMetadata.IsFixedLength
                        ? new Identifier("pg_catalog", "char")
                        : new Identifier("pg_catalog", "varchar"));

            case DataType.Text:
            case DataType.UnicodeText:
                return(new Identifier("pg_catalog", "text"));

            case DataType.Unknown:
                throw new ArgumentOutOfRangeException(nameof(typeMetadata), "Unable to determine a type name for an unknown data type.");

            default:
                throw new ArgumentOutOfRangeException(nameof(typeMetadata), "Unable to determine a type name for data type: " + typeMetadata.DataType.ToString());
            }
        }
        /// <summary>
        /// Gets the default name of the type.
        /// </summary>
        /// <param name="typeMetadata">The type metadata.</param>
        /// <returns>A type name for the given type metadata.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="typeMetadata"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when a type is unknown or failed to be parsed.</exception>
        protected static Identifier GetDefaultTypeName(ColumnTypeMetadata typeMetadata)
        {
            if (typeMetadata == null)
            {
                throw new ArgumentNullException(nameof(typeMetadata));
            }

            switch (typeMetadata.DataType)
            {
            case DataType.BigInteger:
                return(new Identifier("SYS", "NUMBER"));

            case DataType.Binary:
            case DataType.LargeBinary:
                return(typeMetadata.IsFixedLength
                        ? new Identifier("SYS", "RAW")
                        : new Identifier("SYS", "BLOB"));

            case DataType.Boolean:
                return(new Identifier("SYS", "CHAR"));

            case DataType.Date:
                return(new Identifier("SYS", "DATE"));

            case DataType.DateTime:
                return(new Identifier("SYS", "TIMESTAMP WITH LOCAL TIME ZONE"));

            case DataType.Float:
                return(new Identifier("SYS", "FLOAT"));

            case DataType.Integer:
                return(new Identifier("SYS", "NUMBER"));

            case DataType.Interval:
                return(new Identifier("sys", "TIMESTAMP WITH LOCAL TIME ZONE"));

            case DataType.Numeric:
            case DataType.SmallInteger:
                return(new Identifier("SYS", "NUMBER"));

            case DataType.String:
            case DataType.Text:
                return(typeMetadata.IsFixedLength
                        ? new Identifier("SYS", "CHAR")
                        : new Identifier("SYS", "VARCHAR2"));

            case DataType.Time:
                return(new Identifier("SYS", "INTERVAL DAY TO SECOND"));

            case DataType.Unicode:
            case DataType.UnicodeText:
                return(typeMetadata.IsFixedLength
                        ? new Identifier("SYS", "NCHAR")
                        : new Identifier("SYS", "NVARCHAR2"));

            case DataType.Unknown:
                throw new ArgumentOutOfRangeException(nameof(typeMetadata), "Unable to determine a type name for an unknown data type.");

            default:
                throw new ArgumentOutOfRangeException(nameof(typeMetadata), "Unable to determine a type name for data type: " + typeMetadata.DataType.ToString(), nameof(typeMetadata));
            }
        }