Skip to content

Commit

Permalink
Handle PG 10 IDENTITY in resultset metadata
Browse files Browse the repository at this point in the history
Fixes #1789

(cherry picked from commit 44f34bf)
  • Loading branch information
roji committed Feb 3, 2018
1 parent 4161e64 commit 8e980ef
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
13 changes: 8 additions & 5 deletions src/Npgsql/Schema/DbColumnSchemaGenerator.cs
Expand Up @@ -30,9 +30,13 @@ internal DbColumnSchemaGenerator(NpgsqlConnection connection, RowDescriptionMess

#region Columns queries

static string GenerateColumnsQuery(string columnFieldFilter) =>
static string GenerateColumnsQuery(Version pgVersion, string columnFieldFilter) =>
pgVersion < new Version(8, 2)
? GenerateOldColumnsQuery(columnFieldFilter)
:
$@"SELECT
typ.oid AS typoid, nspname, relname, attname, typ.typname, attrelid, attnum, attnotnull,
{(pgVersion >= new Version(10, 0) ? "attidentity != ''" : "FALSE")} AS isidentity,
CASE WHEN typ.typtype = 'd' THEN typ.typtypmod ELSE atttypmod END AS typmod,
CASE WHEN atthasdef THEN (SELECT pg_get_expr(adbin, cls.oid) FROM pg_attrdef WHERE adrelid = cls.oid AND adnum = attr.attnum) ELSE NULL END AS default,
CASE WHEN col.is_updatable = 'YES' THEN true ELSE false END AS is_updatable,
Expand Down Expand Up @@ -115,9 +119,7 @@ internal ReadOnlyCollection<NpgsqlDbColumn> GetColumnSchema()

if (_fetchAdditionalInfo && columnFieldFilter != "")
{
var query = _connection.PostgreSqlVersion >= new Version(8, 2)
? GenerateColumnsQuery(columnFieldFilter)
: GenerateOldColumnsQuery(columnFieldFilter);
var query = GenerateColumnsQuery(_connection.PostgreSqlVersion, columnFieldFilter);

#if NETSTANDARD1_3
using (var connection = _connection.Clone())
Expand Down Expand Up @@ -196,7 +198,8 @@ NpgsqlDbColumn LoadColumnDefinition(NpgsqlDataReader reader, TypeHandlerRegistry
var defaultValueOrdinal = reader.GetOrdinal("default");
column.DefaultValue = reader.IsDBNull(defaultValueOrdinal) ? null : reader.GetString(defaultValueOrdinal);

column.IsAutoIncrement = column.DefaultValue != null && column.DefaultValue.StartsWith("nextval(");
column.IsAutoIncrement = reader.GetBoolean(reader.GetOrdinal("isidentity")) ||
column.DefaultValue != null && column.DefaultValue.StartsWith("nextval(");

ColumnPostConfig(column, reader.GetInt32(reader.GetOrdinal("typmod")));

Expand Down
29 changes: 26 additions & 3 deletions test/Npgsql.Tests/ReaderNewSchemaTests.cs
Expand Up @@ -21,6 +21,7 @@
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#endregion

using System;
using System.Data;
using System.Linq;
using Npgsql.PostgresTypes;
Expand Down Expand Up @@ -245,9 +246,31 @@ public void IsAutoIncrement()
using (var reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo))
{
var columns = reader.GetColumnSchema();
Assert.That(columns[0].IsAutoIncrement, Is.True);
Assert.That(columns[1].IsAutoIncrement, Is.False);
Assert.That(columns[2].IsAutoIncrement, Is.Null);
Assert.That(columns[0].IsAutoIncrement, Is.True, "Serial not identified as autoincrement");
Assert.That(columns[1].IsAutoIncrement, Is.False, "Regular int column identified as autoincrement");
Assert.That(columns[2].IsAutoIncrement, Is.Null, "Literal int identified as autoincrement");
}
}
}

[Test]
public void IsAutoIncrementIdentity()
{
using (var conn = OpenConnection())
{
if (conn.PostgreSqlVersion < new Version(10, 0))
Assert.Ignore("IDENTITY introduced in PostgreSQL 10");

conn.ExecuteNonQuery("CREATE TEMP TABLE data (inc SERIAL, identity INT GENERATED BY DEFAULT AS IDENTITY, non_inc INT)");

using (var cmd = new NpgsqlCommand("SELECT inc,identity,non_inc,8 FROM data", conn))
using (var reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo))
{
var columns = reader.GetColumnSchema();
Assert.That(columns[0].IsAutoIncrement, Is.True, "Serial not identified as autoincrement");
Assert.That(columns[1].IsAutoIncrement, Is.True, "PG 10 IDENTITY not identified as autoincrement");
Assert.That(columns[2].IsAutoIncrement, Is.False, "Regular int column identified as autoincrement");
Assert.That(columns[3].IsAutoIncrement, Is.Null, "Literal int identified as autoincrement");
}
}
}
Expand Down

0 comments on commit 8e980ef

Please sign in to comment.