diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 1ab5bf1c..6b638cad 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -795,14 +795,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index a790dee9..2986858d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -221,7 +221,7 @@ namespace FreeSql.Tests.PostgreSQL var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); } - [Table(Name = "ccc.TopicAddField", OldName = "TopicAddField")] + [Table(Name = "ccc2.TopicAddField", OldName = "ccc.TopicAddField")] public class TopicAddField { [Column(IsIdentity = true)] @@ -235,8 +235,8 @@ namespace FreeSql.Tests.PostgreSQL //[Column(DbType = "varchar(200) not null", OldName = "title")] //public string title222 { get; set; } = "333"; - //[Column(DbType = "varchar(200) not null")] - //public string title222333 { get; set; } = "xxx"; + [Column(DbType = "varchar(200) not null")] + public string title222333 { get; set; } = "xxx"; //[Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] //public string titleaaa { get; set; } = "fsdf"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 8441fcd6..2555a628 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -85,10 +85,11 @@ namespace FreeSql.Odbc.PostgreSQL var sb = new StringBuilder(); var seqcols = new List>(); //序列 - var is96 = true; + var isPg96 = true; + var isPg10 = (_orm.DbFirst as OdbcPostgreSQLDbFirst).IsPg10; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { - is96 = OdbcPostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); + isPg96 = OdbcPostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); } foreach (var obj in objects) @@ -134,8 +135,13 @@ namespace FreeSql.Odbc.PostgreSQL sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + else seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + sb.Append(","); } if (tb.Primarys.Any()) { @@ -183,7 +189,7 @@ namespace FreeSql.Odbc.PostgreSQL tboldname = null; //如果新表已经存在,不走改表名逻辑 //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql(@" + var sql = _commonUtils.FormatSql($@" select a.attname, t.typname, @@ -193,7 +199,7 @@ case when a.attnotnull then '0' else '1' end as is_nullable, --e.adsrc, (select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, a.attndims, -d.description as comment +d.description as comment{(isPg10 ? ", a.attidentity" : "")} from pg_class c inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid inner join pg_type t on t.oid = a.atttypid @@ -202,7 +208,7 @@ left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); +where ns.nspname = {{0}} and c.relname = {{1}}", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { @@ -221,13 +227,16 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (attndims == 0) attndims++; } if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + var is_identity_pg9 = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")); return new { column = string.Concat(a[0]), sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")), + is_identity_pg9 = is_identity_pg9, + is_identity = is_identity_pg9 + || isPg10 && new[] { "a", "d" }.Contains(string.Concat(a[8])), //pg10 GENERATED { BY DEFAULT | AWAYS } AS IDENTITY attndims, comment = string.Concat(a[7]) }; @@ -266,7 +275,27 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + { + if (isPg10) + { + if (tbstructcol.is_identity) + { + if (tbstructcol.is_identity_pg9) + seqcols.Add(NativeTuple.Create(tbcol, tbname, false)); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" DROP IDENTITY IF EXISTS;\r\n"); + } + else + { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ADD GENERATED BY DEFAULT AS IDENTITY"); + var maxval = _orm.Ado.QuerySingle($"select max({_commonUtils.QuoteSqlName(tbcol.Attribute.Name)}) from {_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")}"); + if (maxval > 0) + sbalter.Append(" (START ").Append(maxval + 1).Append(")"); + sbalter.Append(";\r\n"); + } + } + else + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -278,14 +307,20 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ADD GENERATED BY DEFAULT AS IDENTITY;\r\n"); + else + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql($@" select c.attname, b.relname, -{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, +{(isPg96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, case when indisunique = 't' then 1 else 0 end IsUnique from pg_index a inner join pg_class b on b.oid = a.indexrelid @@ -299,7 +334,7 @@ where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; var ukname = ReplaceIndexName(uk.Name, tbname[1]); var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length) + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || isPg96 == false)).Any()).Count() != uk.Columns.Length) { if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); sbalter.Append("CREATE "); @@ -345,8 +380,13 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + else seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + sb.Append(","); } if (tb.Primarys.Any()) { @@ -403,11 +443,27 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp } sb.Remove(sb.Length - 2, 2).Append(");\r\n"); } + if (isPg10) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbcol.Attribute.IsIdentity) + { + var maxval = _orm.Ado.QuerySingle($"select max({_commonUtils.QuoteSqlName(tbcol.Attribute.Name)}) from {tablename}"); + if (maxval > 0) + { + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET GENERATED BY DEFAULT"); + sb.Append(" RESTART ").Append(maxval + 1).Append(""); + sb.Append(";\r\n"); + } + } + } + } } foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); ; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 0776863d..a28b037b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -132,12 +132,13 @@ namespace FreeSql.PostgreSQL protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + var seqcols = new List>(); //序列 - var is96 = true; + var isPg96 = true; + var isPg10 = (_orm.DbFirst as PostgreSQLDbFirst).IsPg10; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { - is96 = PostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); + isPg96 = PostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); } foreach (var obj in objects) @@ -183,8 +184,13 @@ namespace FreeSql.PostgreSQL sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + else seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + sb.Append(","); } if (tb.Primarys.Any()) { @@ -232,7 +238,7 @@ namespace FreeSql.PostgreSQL tboldname = null; //如果新表已经存在,不走改表名逻辑 //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql(@" + var sql = _commonUtils.FormatSql($@" select a.attname, t.typname, @@ -242,7 +248,7 @@ case when a.attnotnull then '0' else '1' end as is_nullable, --e.adsrc, (select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, a.attndims, -d.description as comment +d.description as comment{(isPg10 ? ", a.attidentity" : "")} from pg_class c inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid inner join pg_type t on t.oid = a.atttypid @@ -251,7 +257,7 @@ left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); +where ns.nspname = {{0}} and c.relname = {{1}}", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { @@ -270,13 +276,16 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (attndims == 0) attndims++; } if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + var is_identity_pg9 = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")); return new { column = string.Concat(a[0]), sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")), //pgsql10 + is_identity_pg9 = is_identity_pg9, + is_identity = is_identity_pg9 + || isPg10 && new[] { "a", "d" }.Contains(string.Concat(a[8])), //pg10 GENERATED { BY DEFAULT | AWAYS } AS IDENTITY attndims, comment = string.Concat(a[7]) }; @@ -312,7 +321,27 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + { + if (isPg10) + { + if (tbstructcol.is_identity) + { + if (tbstructcol.is_identity_pg9) + seqcols.Add(NativeTuple.Create(tbcol, tbname, false)); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" DROP IDENTITY IF EXISTS;\r\n"); + } + else + { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ADD GENERATED BY DEFAULT AS IDENTITY"); + var maxval = _orm.Ado.QuerySingle($"select max({_commonUtils.QuoteSqlName(tbcol.Attribute.Name)}) from {_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")}"); + if (maxval > 0) + sbalter.Append(" (START ").Append(maxval + 1).Append(")"); + sbalter.Append(";\r\n"); + } + } + else + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -324,14 +353,20 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ADD GENERATED BY DEFAULT AS IDENTITY;\r\n"); + else + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql($@" select c.attname, b.relname, -{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, +{(isPg96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, case when indisunique = 't' then 1 else 0 end IsUnique from pg_index a inner join pg_class b on b.oid = a.indexrelid @@ -345,7 +380,7 @@ where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; var ukname = ReplaceIndexName(uk.Name, tbname[1]); var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length) + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || isPg96 == false)).Any()).Count() != uk.Columns.Length) { if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); sbalter.Append("CREATE "); @@ -391,8 +426,13 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + else seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + sb.Append(","); } if (tb.Primarys.Any()) { @@ -449,6 +489,22 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp } sb.Remove(sb.Length - 2, 2).Append(");\r\n"); } + if (isPg10) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbcol.Attribute.IsIdentity) + { + var maxval = _orm.Ado.QuerySingle($"select max({_commonUtils.QuoteSqlName(tbcol.Attribute.Name)}) from {tablename}"); + if (maxval > 0) + { + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET GENERATED BY DEFAULT"); + sb.Append(" RESTART ").Append(maxval + 1).Append(""); + sb.Append(";\r\n"); + } + } + } + } } foreach (var seqcol in seqcols) {