@@ -9,6 +9,61 @@ module PostgreSQL
9
9
# @private
10
10
OID = ::ActiveRecord ::ConnectionAdapters ::PostgreSQL ::OID
11
11
12
+ # this version makes sure to register the types by name as well
13
+ # we still need to version with OID since it's used from SchemaStatements as well
14
+ class ArjdbcTypeMapInitializer < OID ::TypeMapInitializer
15
+ private
16
+
17
+ def name_with_ns ( row )
18
+ if row [ 'in_ns' ]
19
+ row [ 'typname' ]
20
+ else
21
+ %Q("#{ row [ 'nspname' ] } "."#{ row [ 'typname' ] } ")
22
+ end
23
+ end
24
+
25
+ def register_enum_type ( row )
26
+ super
27
+ register name_with_ns ( row ) , OID ::Enum . new
28
+ end
29
+
30
+ def register_array_type ( row )
31
+ super
32
+ register_with_subtype ( name_with_ns ( row ) , row [ 'typelem' ] . to_i ) do |subtype |
33
+ OID ::Array . new ( subtype , row [ 'typdelim' ] )
34
+ end
35
+ end
36
+
37
+ def register_range_type ( row )
38
+ super
39
+ name = name_with_ns ( row )
40
+ register_with_subtype ( name , row [ 'rngsubtype' ] . to_i ) do |subtype |
41
+ OID ::Range . new ( subtype , name . to_sym )
42
+ end
43
+ end
44
+
45
+ def register_domain_type ( row )
46
+ if base_type = @store . lookup ( row [ 'typbasetype' ] . to_i )
47
+ register row [ 'oid' ] , base_type
48
+ register name_with_ns ( row ) , base_type
49
+ else
50
+ warn "unknown base type (OID: #{ row [ 'typbasetype' ] } ) for domain #{ row [ 'typname' ] } ."
51
+ end
52
+ end
53
+
54
+ def register_composite_type ( row )
55
+ if subtype = @store . lookup ( row [ 'typelem' ] . to_i )
56
+ register row [ 'oid' ] , OID ::Vector . new ( row [ 'typdelim' ] , subtype )
57
+ register name_with_ns ( row ) , OID ::Vector . new ( row [ 'typdelim' ] , subtype )
58
+ end
59
+ end
60
+
61
+ def assert_valid_registration ( oid , oid_type )
62
+ ret = super
63
+ ret == 0 ? oid : ret
64
+ end
65
+ end
66
+
12
67
# @private
13
68
module OIDTypes
14
69
@@ -41,7 +96,7 @@ def lookup_cast_type(sql_type)
41
96
42
97
def get_oid_type ( oid , fmod , column_name , sql_type = '' ) # :nodoc:
43
98
if !type_map . key? ( oid )
44
- load_additional_types ( type_map , [ oid ] )
99
+ load_additional_types ( type_map , oid )
45
100
end
46
101
47
102
type_map . fetch ( oid , fmod , sql_type ) {
@@ -133,26 +188,45 @@ def initialize_type_map(m)
133
188
end
134
189
135
190
load_additional_types ( m )
191
+
192
+ # pgjdbc returns these if the column is auto-incrmenting
193
+ m . alias_type 'serial' , 'int4'
194
+ m . alias_type 'bigserial' , 'int8'
136
195
end
137
196
138
- def load_additional_types ( type_map , oids = nil ) # :nodoc:
139
- initializer = OID :: TypeMapInitializer . new ( type_map )
197
+ def load_additional_types ( type_map , oid = nil ) # :nodoc:
198
+ initializer = ArjdbcTypeMapInitializer . new ( type_map )
140
199
141
200
if supports_ranges?
142
201
query = <<-SQL
143
- SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
202
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype,
203
+ ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
144
204
FROM pg_type as t
145
205
LEFT JOIN pg_range as r ON oid = rngtypid
206
+ JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
146
207
SQL
147
208
else
148
209
query = <<-SQL
149
- SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
210
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype,
211
+ ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
150
212
FROM pg_type as t
213
+ JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
151
214
SQL
152
215
end
153
216
154
- if oids
155
- query += "WHERE t.oid::integer IN (%s)" % oids . join ( ", " )
217
+ if oid
218
+ if oid . is_a? Numeric || oid . match ( /^\d +$/ )
219
+ # numeric OID
220
+ query += "WHERE t.oid::integer = %s" % oid
221
+
222
+ elsif m = oid . match ( /"?(\w +)"?\. "?(\w +)"?/ )
223
+ # namespace and type name
224
+ query += "WHERE ns.nspname = '%s' AND t.typname = '%s'" % [ m [ 1 ] , m [ 2 ] ]
225
+
226
+ else
227
+ # only type name
228
+ query += "WHERE t.typname = '%s' AND ns.nspname = ANY(current_schemas(true))" % oid
229
+ end
156
230
else
157
231
query += initializer . query_conditions_for_initial_load ( type_map )
158
232
end
0 commit comments