forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPostgreSQL81Dialect.cs
135 lines (121 loc) · 4.36 KB
/
PostgreSQL81Dialect.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System.Data;
using NHibernate.Dialect.Function;
using NHibernate.SqlCommand;
namespace NHibernate.Dialect
{
/// <summary>
/// An SQL dialect for PostgreSQL 8.1 and above.
/// </summary>
/// <remarks>
/// <para>
/// PostgreSQL 8.1 supports <c>FOR UPDATE ... NOWAIT</c> syntax.
/// </para>
/// <para>
/// PostgreSQL supports Identity column using the "SERIAL" type.
/// Serial type is a "virtual" type that will automatically:
/// </para>
/// <list type="bullet">
/// <item><description>Create a sequence named tablename_colname_seq.</description></item>
/// <item><description>Set the default value of this column to the next value of the
/// sequence. (using function <c>nextval('tablename_colname_seq')</c>)</description></item>
/// <item><description>Add a "NOT NULL" constraint to this column.</description></item>
/// <item><description>Set the sequence as "owned by" the table.</description></item>
/// </list>
/// <para>
/// To insert the next value of the sequence into the serial column,
/// exclude the column from the list of columns
/// in the INSERT statement or use the DEFAULT key word.
/// </para>
/// <para>
/// If the table or the column is dropped, the sequence is dropped too.
/// </para>
/// </remarks>
/// <seealso cref="PostgreSQLDialect" />
public class PostgreSQL81Dialect : PostgreSQLDialect
{
protected override void RegisterDateTimeTypeMappings()
{
base.RegisterDateTimeTypeMappings();
RegisterColumnType(DbType.DateTime, 6, "timestamp($s)");
RegisterColumnType(DbType.Time, 6, "time($s)");
// Not overriding default scale: Posgres doc writes it means "no explicit limit", so max of what it can support,
// which suits our needs.
// timezone seems not available prior to version 8.0
RegisterFunction(
"current_utctimestamp",
new SQLFunctionTemplate(NHibernateUtil.UtcDateTime, "timezone('UTC', current_timestamp)"));
}
public override string ForUpdateNowaitString
{
get { return " for update nowait"; }
}
public override string GetForUpdateNowaitString(string aliases)
{
return " for update of " + aliases + " nowait";
}
/// <summary>
/// PostgreSQL supports Identity column using the "SERIAL" type.
/// </summary>
public override bool SupportsIdentityColumns
{
get { return true; }
}
/// <summary>
/// PostgreSQL doesn't have type in identity column.
/// </summary>
/// <remarks>
/// To create an identity column it uses the SQL syntax
/// <c>CREATE TABLE tablename (colname SERIAL);</c> or
/// <c>CREATE TABLE tablename (colname BIGSERIAL);</c>
/// </remarks>
public override bool HasDataTypeInIdentityColumn
{
get { return false; }
}
/// <summary>
/// PostgreSQL supports <c>serial</c> and <c>serial4</c> type for 4 bytes integer auto increment column.
/// <c>bigserial</c> or <c>serial8</c> can be used for 8 bytes integer auto increment column.
/// </summary>
/// <returns><c>bigserial</c> if <paramref name="type"/> equal Int64,
/// <c>serial</c> otherwise</returns>
public override string GetIdentityColumnString(DbType type)
{
return (type == DbType.Int64) ? "bigserial" : "serial";
}
/// <summary>
/// The sql syntax to insert a row without specifying any column in PostgreSQL is
/// <c>INSERT INTO table DEFAULT VALUES;</c>
/// </summary>
public override string NoColumnsInsertString
{
get { return "default values"; }
}
/// <summary>
/// PostgreSQL 8.1 and above defined the function <c>lastval()</c> that returns the
/// value of the last sequence that <c>nextval()</c> was used on in the current session.
/// Call <c>lastval()</c> if <c>nextval()</c> has not yet been called in the current
/// session throw an exception.
/// </summary>
public override string IdentitySelectString
{
get { return "select lastval()"; }
}
public override SqlString AppendIdentitySelectToInsert(SqlString insertSql)
{
return insertSql.Append("; " + IdentitySelectString);
}
public override SqlString AppendIdentitySelectToInsert(SqlString insertString, string identifierColumnName)
{
return insertString.Append(" returning ", identifierColumnName);
}
public override bool SupportsInsertSelectIdentity
{
get { return true; }
}
/// <inheritdoc />
public override bool SupportsDateTimeScale => true;
// Said to be 63 bytes at least since v8.
/// <inheritdoc />
public override int MaxAliasLength => 63;
}
}