Skip to content

Commit

Permalink
feat(spanner): add PG.OID support
Browse files Browse the repository at this point in the history
Adding the implementation and unit tests.
  • Loading branch information
skuruppu authored and amanda-tarafa committed Feb 22, 2024
1 parent 01d881e commit 43818f3
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void CreateKeyFromParameterCollection()
{ "", SpannerDbType.PgJsonb, "{\"key1\": \"value1\"}" },
{ "", SpannerDbType.Numeric, SpannerNumeric.Parse("10.1") },
{ "", SpannerDbType.PgNumeric, PgNumeric.Parse("20.1") },
{ "", SpannerDbType.PgOid, 2 },
{ "", SpannerDbType.String, "test" },
{ "", SpannerDbType.Timestamp, new DateTime(2021, 9, 10, 9, 37, 10, DateTimeKind.Utc) }
});
Expand All @@ -54,6 +55,7 @@ public void CreateKeyFromParameterCollection()
Value.ForString("{\"key1\": \"value1\"}"),
Value.ForString("10.1"),
Value.ForString("20.1"),
Value.ForString("2"),
Value.ForString("test"),
Value.ForString("2021-09-10T09:37:10Z")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ public enum TestType
{ "NumericField", SpannerDbType.Numeric, SpannerNumeric.MaxValue },
{ "PgNumericField", SpannerDbType.PgNumeric, PgNumeric.NaN },
{ "JsonField", SpannerDbType.Json, "{\"field\": \"value\"}" },
{ "PgJsonbField", SpannerDbType.PgJsonb, "{\"field1\": \"value1\"}" }
{ "PgJsonbField", SpannerDbType.PgJsonb, "{\"field1\": \"value1\"}" },
{ "PgOidField", SpannerDbType.PgOid, 3L }
};

// Structs are serialized as lists of their values. The field names aren't present, as they're
// specified in the type.
private static readonly string s_sampleStructSerialized =
"[ \"stringValue\", \"2\", \"NaN\", true, \"2017-01-31\", \"2017-01-31T03:15:30Z\", \"99999999999999999999999999999.999999999\", \"NaN\", \"{\\\"field\\\": \\\"value\\\"}\", \"{\\\"field1\\\": \\\"value1\\\"}\" ]";
"[ \"stringValue\", \"2\", \"NaN\", true, \"2017-01-31\", \"2017-01-31T03:15:30Z\", \"99999999999999999999999999999.999999999\", \"NaN\", \"{\\\"field\\\": \\\"value\\\"}\", \"{\\\"field1\\\": \\\"value1\\\"}\", \"3\" ]";

private static string Quote(string s) => $"\"{s}\"";

Expand Down Expand Up @@ -337,6 +338,11 @@ public static IEnumerable<object[]> GetValidValueConversions()
"[ \"4\", \"5\", \"6\" ]"
};
yield return new object[]
{
new List<int>(GetIntsForArray()), SpannerDbType.ArrayOf(SpannerDbType.PgOid),
"[ \"4\", \"5\", \"6\" ]"
};
yield return new object[]
{
new List<bool>(GetBoolsForArray()), SpannerDbType.ArrayOf(SpannerDbType.Bool),
"[ true, false, true ]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public static IEnumerable<object[]> GetSpannerStringConversions()
yield return new object[] { "DATE", SpannerDbType.Date };
yield return new object[] { "FLOAT64", SpannerDbType.Float64 };
yield return new object[] { "INT64", SpannerDbType.Int64 };
yield return new object[] { "OID{PG}", SpannerDbType.PgOid };
yield return new object[] { "TIMESTAMP", SpannerDbType.Timestamp };
yield return new object[] { "NUMERIC", SpannerDbType.Numeric };
yield return new object[] { "NUMERIC{PG}", SpannerDbType.PgNumeric };
Expand All @@ -83,6 +84,7 @@ public static IEnumerable<object[]> GetSpannerStringConversions()
yield return new object[] { " DATE ", SpannerDbType.Date };
yield return new object[] { " FLOAT64 ", SpannerDbType.Float64 };
yield return new object[] { " INT64 ", SpannerDbType.Int64 };
yield return new object[] { " OID{PG}", SpannerDbType.PgOid };
yield return new object[] { " TIMESTAMP ", SpannerDbType.Timestamp };
yield return new object[] { " NUMERIC ", SpannerDbType.Numeric };
yield return new object[] { " NUMERIC{PG} ", SpannerDbType.PgNumeric };
Expand All @@ -109,6 +111,7 @@ public static IEnumerable<object[]> GetSpannerStringConversions()
yield return new object[] { "ARRAY<DATE>", SpannerDbType.ArrayOf(SpannerDbType.Date) };
yield return new object[] { "ARRAY<FLOAT64>", SpannerDbType.ArrayOf(SpannerDbType.Float64) };
yield return new object[] { "ARRAY<INT64>", SpannerDbType.ArrayOf(SpannerDbType.Int64) };
yield return new object[] { "ARRAY<OID{PG}>", SpannerDbType.ArrayOf(SpannerDbType.PgOid) };
yield return new object[] { "ARRAY<TIMESTAMP>", SpannerDbType.ArrayOf(SpannerDbType.Timestamp) };

yield return new object[] { "ARRAY<STRING(5)>", SpannerDbType.ArrayOf(SpannerDbType.String), false };
Expand Down Expand Up @@ -161,9 +164,10 @@ public static IEnumerable<object[]> GetSpannerStringConversions()
{ "F8", SpannerDbType.Numeric, null },
{ "F9", SpannerDbType.Json, null },
{ "F10", SpannerDbType.PgNumeric, null },
{ "F11", SpannerDbType.PgJsonb, null }
{ "F11", SpannerDbType.PgJsonb, null },
{ "F12", SpannerDbType.PgOid, null }
};
yield return new object[] { "STRUCT<F1:STRING,F2:INT64,F3:BOOL,F4:BYTES,F5:DATE,F6:FLOAT64,F7:TIMESTAMP,F8:NUMERIC,F9:JSON,F10:NUMERIC{PG},F11:JSONB{PG}>", sampleStruct.GetSpannerDbType() };
yield return new object[] { "STRUCT<F1:STRING,F2:INT64,F3:BOOL,F4:BYTES,F5:DATE,F6:FLOAT64,F7:TIMESTAMP,F8:NUMERIC,F9:JSON,F10:NUMERIC{PG},F11:JSONB{PG},F12:OID{PG}>", sampleStruct.GetSpannerDbType() };

sampleStruct = new SpannerStruct
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ public static IEnumerable<object[]> GetDbTypeConversions()
yield return new object[] { SpannerDbType.Numeric, DbType.VarNumeric, true };
yield return new object[] { SpannerDbType.Unspecified, DbType.Object, true };
yield return new object[] { SpannerDbType.String, DbType.String, true };
// There is no DbType that will map automatically to SpannerDbType.Json or SpannerDbType.PgJsonb.
// There is no DbType that will map automatically to SpannerDbType.Json, SpannerDbType.PgJsonb
// or SpannerDbType.PgOid.
yield return new object[] { SpannerDbType.Json, DbType.String, false };
yield return new object[] { SpannerDbType.PgJsonb, DbType.String, false };
yield return new object[] { SpannerDbType.PgOid, DbType.Int64, false };
}

[Theory]
Expand Down Expand Up @@ -126,6 +128,7 @@ public static IEnumerable<object[]> GetDbTypeSizesFailures()
yield return new object[] { SpannerDbType.Date, 0 };
yield return new object[] { SpannerDbType.Float64, 0 };
yield return new object[] { SpannerDbType.Int64, 0 };
yield return new object[] { SpannerDbType.PgOid, 0 };
yield return new object[] { SpannerDbType.Timestamp, 0 };
yield return new object[] { SpannerDbType.Json, 0 };
yield return new object[] { SpannerDbType.PgJsonb, 0 };
Expand Down Expand Up @@ -155,6 +158,7 @@ public static IEnumerable<object[]> AllSpannerTypes()
yield return new object[] { SpannerDbType.Date };
yield return new object[] { SpannerDbType.Float64 };
yield return new object[] { SpannerDbType.Int64 };
yield return new object[] { SpannerDbType.PgOid };
yield return new object[] { SpannerDbType.Numeric };
yield return new object[] { SpannerDbType.PgNumeric };
yield return new object[] { SpannerDbType.Timestamp };
Expand All @@ -166,6 +170,7 @@ public static IEnumerable<object[]> AllSpannerTypes()
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.Date) };
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.Float64) };
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.Int64) };
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.PgOid) };
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.Numeric) };
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.PgNumeric) };
yield return new object[] { SpannerDbType.ArrayOf(SpannerDbType.Timestamp) };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ private static bool TryParsePartial(string complexName, out V1.Type type, out in
}

var trimmedComplexName = complexName.Trim();
// Special handling for NUMERIC{PG} and JSONB{PG}, as other types are just based on TypeCode and we need to keep the code backward compatible.
// Special handling for NUMERIC{PG}, JSONB{PG} and OID{PG}, as other types are just based on
// TypeCode and we need to keep the code backward compatible.
if (string.Equals(trimmedComplexName, "NUMERIC{PG}", StringComparison.OrdinalIgnoreCase))
{
type.Code = TypeCode.Numeric;
Expand All @@ -156,6 +157,12 @@ private static bool TryParsePartial(string complexName, out V1.Type type, out in
type.TypeAnnotation = TypeAnnotationCode.PgJsonb;
return true;
}
else if (string.Equals(trimmedComplexName, "OID{PG}", StringComparison.OrdinalIgnoreCase))
{
type.Code = TypeCode.Int64;
type.TypeAnnotation = TypeAnnotationCode.PgOid;
return true;
}

int remainderStart = complexName.IndexOfAny(new[] { '<', '(' });
remainderStart = remainderStart != -1 ? remainderStart : complexName.Length;
Expand Down Expand Up @@ -222,6 +229,10 @@ public override string ToString()
{
return "JSONB{PG}";
}
else if (TypeAnnotationCode == TypeAnnotationCode.PgOid)
{
return "OID{PG}";
}

return Size.HasValue ? $"{TypeCode.GetOriginalName()}({Size})" : TypeCode.GetOriginalName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ public sealed partial class SpannerDbType
/// </summary>
public static SpannerDbType PgNumeric { get; } = new SpannerDbType(TypeCode.Numeric, TypeAnnotationCode.PgNumeric);

/// <summary>
/// Representation of PostgreSQL OID type.
/// </summary>
public static SpannerDbType PgOid { get; } = new SpannerDbType(TypeCode.Int64, TypeAnnotationCode.PgOid);

private static readonly Dictionary<V1.Type, SpannerDbType> s_simpleTypes
= new Dictionary<V1.Type, SpannerDbType>
{
Expand All @@ -105,7 +110,8 @@ public sealed partial class SpannerDbType
{ new V1.Type { Code = TypeCode.Json }, Json },
{ new V1.Type { Code = TypeCode.Json, TypeAnnotation = TypeAnnotationCode.PgJsonb }, PgJsonb },
{ new V1.Type { Code = TypeCode.Numeric }, Numeric },
{ new V1.Type { Code = TypeCode.Numeric, TypeAnnotation = TypeAnnotationCode.PgNumeric }, PgNumeric }
{ new V1.Type { Code = TypeCode.Numeric, TypeAnnotation = TypeAnnotationCode.PgNumeric }, PgNumeric },
{ new V1.Type { Code = TypeCode.Int64, TypeAnnotation = TypeAnnotationCode.PgOid }, PgOid }
};

internal static SpannerDbType FromType(V1.Type type) =>
Expand Down Expand Up @@ -161,6 +167,7 @@ public DbType DbType
case TypeCode.Bool:
return DbType.Boolean;
case TypeCode.Int64:
// This handles PG.OID as well.
return DbType.Int64;
case TypeCode.Float64:
return DbType.Double;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ internal object GetValidatedValue()
+ $"({nameof(SpannerDbType.Bool)}, {nameof(SpannerDbType.Int64)}, {nameof(SpannerDbType.Float64)},"
+ $" {nameof(SpannerDbType.Timestamp)}, {nameof(SpannerDbType.Date)}, {nameof(SpannerDbType.String)},"
+ $" {nameof(SpannerDbType.Bytes)}, {nameof(SpannerDbType.Json)}, {nameof(SpannerDbType.PgJsonb)}, {nameof(SpannerDbType.Numeric)},"
+ $" {nameof(SpannerDbType.PgNumeric)})");
+ $" {nameof(SpannerDbType.PgNumeric)}, {nameof(SpannerDbType.PgOid)})");
}
return Value;
}
Expand Down

0 comments on commit 43818f3

Please sign in to comment.