/// <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()); }
public IDbType CreateColumnType(ColumnTypeMetadata typeMetadata) => new ColumnDataType( "test_type", DataType.BigInteger, "test_type(10)", typeof(object), false, 10, new NumericPrecision(10, 0), null );
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); }
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); }
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; }
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 )); }
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); } }
/// <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); }
/// <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)); }
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); }
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)); } }