Skip to content

Commit

Permalink
Add NullSortOrder and use in metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
khellang committed Feb 18, 2019
1 parent d3d0a9a commit 976b1fe
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public override MethodCallCodeFragment GenerateFluentApi(IIndex index, IAnnotati
return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasCollation), annotation.Value);
if (annotation.Name == NpgsqlAnnotationNames.IndexSortOrder)
return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasDescendingOrder), annotation.Value);
if (annotation.Name == NpgsqlAnnotationNames.IndexNullsFirst)
if (annotation.Name == NpgsqlAnnotationNames.IndexNullSortOrder)
return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasNullsFirst), annotation.Value);
if (annotation.Name == NpgsqlAnnotationNames.IndexInclude)
return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlInclude), annotation.Value);
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore.PG/Extensions/NpgsqlIndexBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ public static IndexBuilder ForNpgsqlHasDescendingOrder(
/// <returns> A builder to further configure the index. </returns>
public static IndexBuilder ForNpgsqlHasNullsFirst(
[NotNull] this IndexBuilder indexBuilder,
[CanBeNull, ItemNotNull] params bool?[] values)
[CanBeNull] params NullSortOrder[] values)
{
Check.NotNull(indexBuilder, nameof(indexBuilder));

indexBuilder.Metadata.Npgsql().NullsFirst = values;
indexBuilder.Metadata.Npgsql().NullSortOrder = values;

return indexBuilder;
}
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.PG/Metadata/INpgsqlIndexAnnotations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public interface INpgsqlIndexAnnotations : IRelationalIndexAnnotations
/// <remarks>
/// https://www.postgresql.org/docs/current/static/indexes-ordering.html
/// </remarks>
IReadOnlyList<bool?> NullsFirst { get; }
IReadOnlyList<NullSortOrder> NullSortOrder { get; }

/// <summary>
/// The included property names, or <c>null</c> if they have not been specified.
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class NpgsqlAnnotationNames
public const string IndexOperators = Prefix + "IndexOperators";
public const string IndexCollation = Prefix + "IndexCollation";
public const string IndexSortOrder = Prefix + "IndexSortOrder";
public const string IndexNullsFirst = Prefix + "IndexNullsFirst";
public const string IndexNullSortOrder = Prefix + "IndexNullSortOrder";
public const string IndexInclude = Prefix + "IndexInclude";
public const string PostgresExtensionPrefix = Prefix + "PostgresExtension:";
public const string EnumPrefix = Prefix + "Enum:";
Expand Down
12 changes: 6 additions & 6 deletions src/EFCore.PG/Metadata/NpgsqlIndexAnnotations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ public SortOrder[] SortOrder
/// <remarks>
/// https://www.postgresql.org/docs/current/static/indexes-ordering.html
/// </remarks>
public bool?[] NullsFirst
public NullSortOrder[] NullSortOrder
{
get => (bool?[])Annotations.Metadata[NpgsqlAnnotationNames.IndexNullsFirst];
set => SetNullsFirst(value);
get => (NullSortOrder[])Annotations.Metadata[NpgsqlAnnotationNames.IndexNullSortOrder];
set => SetNullSortOrder(value);
}

IReadOnlyList<bool?> INpgsqlIndexAnnotations.NullsFirst => NullsFirst;
IReadOnlyList<NullSortOrder> INpgsqlIndexAnnotations.NullSortOrder => NullSortOrder;

/// <summary>
/// The included property names, or <c>null</c> if they have not been specified.
Expand Down Expand Up @@ -111,8 +111,8 @@ protected virtual bool SetCollation(string[] value)
protected virtual bool SetSortOrder(SortOrder[] value)
=> Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexSortOrder, value);

protected virtual bool SetNullsFirst(bool?[] value)
=> Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexNullsFirst, value);
protected virtual bool SetNullSortOrder(NullSortOrder[] value)
=> Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexNullSortOrder, value);

protected virtual bool SetIncludeProperties(string[] value)
=> Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexInclude, value);
Expand Down
29 changes: 29 additions & 0 deletions src/EFCore.PG/Metadata/NullSortOrder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Npgsql.EntityFrameworkCore.PostgreSQL.Metadata
{
/// <summary>
/// Options for modifying sort ordering of <c>NULL</c>-values in indexes.
/// </summary>
public enum NullSortOrder
{
/// <summary>
/// Represents an unspecified sort order. The database default will be used.
/// </summary>
Unspecified = 0,

/// <summary>
/// Specifies that nulls sort before non-nulls.
/// </summary>
/// <remarks>
/// This is the default when <see cref="SortOrder.Descending"/> is specified.
/// </remarks>
NullsFirst = 1,

/// <summary>
/// Specifies that nulls sort after non-nulls.
/// </summary>
/// <remarks>
/// This is the default when <see cref="SortOrder.Descending"/> is not specified.
/// </remarks>
NullsLast = 2,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public override IEnumerable<IAnnotation> For(IIndex index)
yield return new Annotation(NpgsqlAnnotationNames.IndexCollation, index.Npgsql().Collation);
if (index.Npgsql().SortOrder != null)
yield return new Annotation(NpgsqlAnnotationNames.IndexSortOrder, index.Npgsql().SortOrder);
if (index.Npgsql().NullsFirst != null)
yield return new Annotation(NpgsqlAnnotationNames.IndexNullsFirst, index.Npgsql().NullsFirst);
if (index.Npgsql().NullSortOrder != null)
yield return new Annotation(NpgsqlAnnotationNames.IndexNullSortOrder, index.Npgsql().NullSortOrder);
if (index.Npgsql().IncludeProperties != null)
yield return new Annotation(NpgsqlAnnotationNames.IndexInclude, index.Npgsql().IncludeProperties);
}
Expand Down
28 changes: 20 additions & 8 deletions src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1246,9 +1246,21 @@ string IndexColumnList(IndexColumn[] columns)
}
}

if (column.NullsFirst.HasValue)
if (column.NullSortOrder != NullSortOrder.Unspecified)
{
builder.Append(" NULLS ").Append(column.NullsFirst.Value ? "FIRST" : "LAST");
builder.Append(" NULLS ");

switch (column.NullSortOrder)
{
case NullSortOrder.NullsFirst:
builder.Append("FIRST");
break;
case NullSortOrder.NullsLast:
builder.Append("LAST");
break;
default:
throw new ArgumentOutOfRangeException();
}
}

isFirst = false;
Expand Down Expand Up @@ -1278,7 +1290,7 @@ static IndexColumn[] GetIndexColumns(CreateIndexOperation operation)
var operators = operation[NpgsqlAnnotationNames.IndexOperators] as string[];
var collations = operation[NpgsqlAnnotationNames.IndexCollation] as string[];
var sortOrders = operation[NpgsqlAnnotationNames.IndexSortOrder] as SortOrder[];
var nullsFirsts = operation[NpgsqlAnnotationNames.IndexNullsFirst] as bool?[];
var nullSortOrders = operation[NpgsqlAnnotationNames.IndexNullSortOrder] as NullSortOrder[];

var columns = new IndexColumn[operation.Columns.Length];

Expand All @@ -1288,23 +1300,23 @@ static IndexColumn[] GetIndexColumns(CreateIndexOperation operation)
var @operator = i < operators?.Length ? operators[i] : null;
var collation = i < collations?.Length ? collations[i] : null;
var sortOrder = i < sortOrders?.Length ? sortOrders[i] : SortOrder.Unspecified;
var nullsFirst = i < nullsFirsts?.Length ? nullsFirsts[i] : null;
var nullSortOrder = i < nullSortOrders?.Length ? nullSortOrders[i] : NullSortOrder.Unspecified;

columns[i] = new IndexColumn(name, @operator, collation, sortOrder, nullsFirst);
columns[i] = new IndexColumn(name, @operator, collation, sortOrder, nullSortOrder);
}

return columns;
}

struct IndexColumn
{
public IndexColumn(string name, string @operator, string collation, SortOrder sortOrder, bool? nullsFirst)
public IndexColumn(string name, string @operator, string collation, SortOrder sortOrder, NullSortOrder nullSortOrder)
{
Name = name;
Operator = @operator;
Collation = collation;
SortOrder = sortOrder;
NullsFirst = nullsFirst;
NullSortOrder = nullSortOrder;
}

public string Name { get; }
Expand All @@ -1315,7 +1327,7 @@ public IndexColumn(string name, string @operator, string collation, SortOrder so

public SortOrder SortOrder { get; }

public bool? NullsFirst { get; }
public NullSortOrder NullSortOrder { get; }
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ public void CreateIndexOperation_nulls_first()
Table = "People",
Schema = "dbo",
Columns = new[] { "FirstName", "MiddleName", "LastName" },
[NpgsqlAnnotationNames.IndexNullsFirst] = new bool?[] { true, null, false }
[NpgsqlAnnotationNames.IndexNullSortOrder] = new bool?[] { true, null, false }
});

Assert.Equal(
Expand Down

0 comments on commit 976b1fe

Please sign in to comment.