From 6fad1bd148b9231c075ba7249b3ce77a05b2715c Mon Sep 17 00:00:00 2001
From: Sergey Kurt <sergeykurt@outlook.com>
Date: Wed, 15 Mar 2017 15:31:09 +0300
Subject: [PATCH] Added column flag for autogenerated values like IDENTITY |
 TIMESTAMP | ROWVERSION

---
 bdb/column.go        |  7 ++++++-
 bdb/drivers/mssql.go | 30 +++++++++++++++---------------
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/bdb/column.go b/bdb/column.go
index 5ed7a8b..9ce4bc4 100644
--- a/bdb/column.go
+++ b/bdb/column.go
@@ -29,6 +29,11 @@ type Column struct {
 	// tinyint(1) instead of tinyint
 	// Used for "tinyint-as-bool" flag
 	FullDBType string
+
+	// MS SQL only bits
+	// Used to indicate that the value
+	// for this column is auto generated by database on insert (i.e. - timestamp (old) or rowversion (new))
+	AutoGenerated bool
 }
 
 // ColumnNames of the columns.
@@ -57,7 +62,7 @@ func FilterColumnsByDefault(defaults bool, columns []Column) []Column {
 	var cols []Column
 
 	for _, c := range columns {
-		if (defaults && len(c.Default) != 0) || (!defaults && len(c.Default) == 0) {
+		if (defaults && (len(c.Default) != 0 || c.AutoGenerated)) || (!defaults && len(c.Default) == 0 && !c.AutoGenerated) {
 			cols = append(cols, c)
 		}
 	}
diff --git a/bdb/drivers/mssql.go b/bdb/drivers/mssql.go
index 920ce09..254f68d 100644
--- a/bdb/drivers/mssql.go
+++ b/bdb/drivers/mssql.go
@@ -151,10 +151,11 @@ func (m *MSSQLDriver) Columns(schema, tableName string) ([]bdb.Column, error) {
                              AND   table_name = tc.table_name
                              AND   constraint_name = tc.constraint_name) = 1) THEN 1
          ELSE 0
-       END AS is_unique
+       END AS is_unique,
+	   COLUMNPROPERTY(object_id($1 + '.' + $2), c.column_name, 'IsIdentity') as is_identity
 	FROM information_schema.columns c
-	WHERE table_name = ? AND table_schema = ?;
-	`, tableName, schema)
+	WHERE table_schema = $1 AND table_name = $2;
+	`, schema, tableName)
 
 	if err != nil {
 		return nil, err
@@ -163,25 +164,24 @@ func (m *MSSQLDriver) Columns(schema, tableName string) ([]bdb.Column, error) {
 
 	for rows.Next() {
 		var colName, colType, colFullType string
-		var nullable, unique bool
+		var nullable, unique, identity, auto bool
 		var defaultValue *string
-		if err := rows.Scan(&colName, &colFullType, &colType, &defaultValue, &nullable, &unique); err != nil {
+		if err := rows.Scan(&colName, &colFullType, &colType, &defaultValue, &nullable, &unique, &identity); err != nil {
 			return nil, errors.Wrapf(err, "unable to scan for table %s", tableName)
 		}
 
+		auto = identity || strings.EqualFold(colType, "timestamp") || strings.EqualFold(colType, "rowversion")
+
 		column := bdb.Column{
-			Name:       colName,
-			FullDBType: colFullType, // example: tinyint(1) instead of tinyint
-			DBType:     colType,
-			Nullable:   nullable,
-			Unique:     unique,
+			Name:          colName,
+			FullDBType:    colFullType,
+			DBType:        colType,
+			Nullable:      nullable,
+			Unique:        unique,
+			AutoGenerated: auto,
 		}
 
-		// Hack to exclude columns with types timestamp and rowversion from inserts
-		// Values for this columns provides by SQL Server on Insert clause
-		if (strings.EqualFold(colType, "timestamp") || strings.EqualFold(colType, "rowversion")) && defaultValue == nil {
-			column.Default = colType
-		} else if defaultValue != nil && *defaultValue != "NULL" {
+		if defaultValue != nil && *defaultValue != "NULL" {
 			column.Default = *defaultValue
 		}
 		columns = append(columns, column)