@@ -5,7 +5,7 @@ module PostgreSQL
5
5
module Adapter
6
6
module DatabaseStatements
7
7
8
- EXTENDED_DATABASE_TYPES = %i( enum enum_set interval )
8
+ EXTENDED_DATABASE_TYPES = %i[ enum enum_set interval ]
9
9
10
10
# Switch between dump mode or not
11
11
def dump_mode!
@@ -48,8 +48,8 @@ def extended_types
48
48
def schema_exists? ( name , filtered : true )
49
49
return user_defined_schemas . include? ( name . to_s ) if filtered
50
50
51
- query_value ( <<-SQL ) == 1
52
- SELECT 1 FROM pg_catalog.pg_namespace WHERE nspname = ' #{ name } '
51
+ query_value ( <<-SQL , "SCHEMA" ) == 1
52
+ SELECT 1 FROM pg_catalog.pg_namespace WHERE nspname = #{ quote ( name ) }
53
53
SQL
54
54
end
55
55
@@ -59,96 +59,75 @@ def type_exists?(name)
59
59
end
60
60
alias data_type_exists? type_exists?
61
61
62
- # Configure the interval format
63
- def configure_connection
64
- super
65
- execute ( "SET SESSION IntervalStyle TO 'iso_8601'" , 'SCHEMA' )
66
- end
67
-
68
- # Since enums create new types, type map needs to be rebooted to include
69
- # the new ones, both normal and array one
70
- def create_enum ( name , *)
71
- super
72
-
73
- oid = query_value ( "SELECT #{ quote ( name ) } ::regtype::oid" , "SCHEMA" ) . to_i
74
- load_additional_types ( [ oid ] )
75
- end
76
-
77
62
# Change some of the types being mapped
78
63
def initialize_type_map ( m = type_map )
79
64
super
80
- m . register_type 'box' , OID ::Box . new
81
- m . register_type 'circle' , OID ::Circle . new
82
- m . register_type 'interval' , OID ::Interval . new
83
- m . register_type 'line' , OID ::Line . new
84
- m . register_type 'segment' , OID ::Segment . new
85
65
86
- m . alias_type 'regclass' , 'varchar'
66
+ if PostgreSQL . config . geometry . enabled
67
+ m . register_type 'box' , OID ::Box . new
68
+ m . register_type 'circle' , OID ::Circle . new
69
+ m . register_type 'line' , OID ::Line . new
70
+ m . register_type 'segment' , OID ::Segment . new
71
+ end
72
+
73
+ if PostgreSQL . config . interval . enabled
74
+ m . register_type 'interval' , OID ::Interval . new
75
+ end
87
76
end
88
77
89
78
# :nodoc:
90
79
def load_additional_types ( oids = nil )
80
+ type_map . alias_type 'regclass' , 'varchar'
81
+ type_map . alias_type 'regconfig' , 'varchar'
91
82
super
92
83
torque_load_additional_types ( oids )
93
84
end
94
85
95
86
# Add the composite types to be loaded too.
96
87
def torque_load_additional_types ( oids = nil )
97
- filter = ( "AND a.typelem::integer IN (%s)" % oids . join ( ', ' ) ) if oids
98
-
99
- query = <<-SQL
100
- SELECT a.typelem AS oid, t.typname, t.typelem,
101
- t.typdelim, t.typbasetype, t.typtype,
102
- t.typarray
103
- FROM pg_type t
104
- INNER JOIN pg_type a ON (a.oid = t.typarray)
105
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
106
- WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
107
- AND t.typtype IN ( 'e' )
108
- #{ filter }
109
- AND NOT EXISTS(
110
- SELECT 1 FROM pg_catalog.pg_type el
111
- WHERE el.oid = t.typelem AND el.typarray = t.oid
112
- )
113
- AND (t.typrelid = 0 OR (
114
- SELECT c.relkind = 'c' FROM pg_catalog.pg_class c
115
- WHERE c.oid = t.typrelid
116
- ))
88
+ return unless torque_load_additional_types?
89
+
90
+ # Types: (b)ase, (c)omposite, (d)omain, (e)num, (p)seudotype, (r)ange
91
+ # (m)ultirange
92
+
93
+ query = <<~SQL
94
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput,
95
+ r.rngsubtype, t.typtype, t.typbasetype, t.typarray
96
+ FROM pg_type as t
97
+ LEFT JOIN pg_range as r ON oid = rngtypid
98
+ LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
99
+ WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
117
100
SQL
118
101
119
- execute_and_clear ( query , 'SCHEMA' , [ ] ) do |records |
120
- records . each { |row | OID ::Enum . create ( row , type_map ) }
102
+ if oids
103
+ query += " AND t.oid IN (%s)" % oids . join ( ", " )
104
+ else
105
+ query += " AND t.typtype IN ('e')"
121
106
end
107
+
108
+ options = { allow_retry : true , materialize_transactions : false }
109
+ internal_execute ( query , 'SCHEMA' , **options ) . each do |row |
110
+ if row [ 'typtype' ] == 'e' && PostgreSQL . config . enum . enabled
111
+ OID ::Enum . create ( row , type_map )
112
+ end
113
+ end
114
+ end
115
+
116
+ def torque_load_additional_types?
117
+ PostgreSQL . config . enum . enabled
122
118
end
123
119
124
120
# Gets a list of user defined types.
125
121
# You can even choose the +category+ filter
126
122
def user_defined_types ( *categories )
127
- category_condition = categories . present? \
128
- ? "AND t.typtype IN ('#{ categories . join ( "', '" ) } ')" \
129
- : "AND t.typtype NOT IN ('b', 'd')"
130
-
131
- select_all ( <<-SQL , 'SCHEMA' ) . rows . to_h
132
- SELECT t.typname AS name,
133
- CASE t.typtype
134
- WHEN 'e' THEN 'enum'
135
- END AS type
136
- FROM pg_type t
137
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
123
+ categories = categories . compact . presence || %w[ c e p r m ]
124
+
125
+ query ( <<-SQL , 'SCHEMA' ) . to_h
126
+ SELECT t.typname, t.typtype
127
+ FROM pg_type as t
128
+ LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
138
129
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
139
- #{ category_condition }
140
- AND NOT EXISTS(
141
- SELECT 1
142
- FROM pg_catalog.pg_type el
143
- WHERE el.oid = t.typelem
144
- AND el.typarray = t.oid
145
- )
146
- AND (t.typrelid = 0 OR (
147
- SELECT c.relkind = 'c'
148
- FROM pg_catalog.pg_class c
149
- WHERE c.oid = t.typrelid
150
- ))
151
- ORDER BY t.typtype DESC
130
+ AND t.typtype IN ('#{ categories . join ( "', '" ) } ')
152
131
SQL
153
132
end
154
133
@@ -195,20 +174,20 @@ def user_defined_schemas_sql
195
174
# Get the list of columns, and their definition, but only from the
196
175
# actual table, does not include columns that comes from inherited table
197
176
def column_definitions ( table_name )
198
- local = 'AND a.attislocal' if @_dump_mode
199
-
200
- query ( <<-SQL , 'SCHEMA' )
201
- SELECT a.attname, format_type (a.atttypid , a.atttypmod) ,
202
- pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod ,
203
- c.collname, col_description(a.attrelid, a.attnum) AS comment,
204
- #{ supports_virtual_columns? ? 'attgenerated' : quote ( '' ) } as attgenerated
205
- FROM pg_attribute a
206
- LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
207
- LEFT JOIN pg_type t ON a.atttypid = t .oid
208
- LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
209
- WHERE a.attrelid = #{ quote ( quote_table_name ( table_name ) ) } ::regclass
210
- AND a.attnum > 0 AND NOT a.attisdropped #{ local }
211
- ORDER BY a.attnum
177
+ query ( <<~SQL , "SCHEMA" )
178
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod),
179
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
180
+ c.collname, col_description (a.attrelid , a.attnum) AS comment ,
181
+ #{ supports_identity_columns? ? 'attidentity' : quote ( '' ) } AS identity ,
182
+ #{ supports_virtual_columns? ? 'attgenerated' : quote ( '' ) } as attgenerated
183
+ FROM pg_attribute a
184
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
185
+ LEFT JOIN pg_type t ON a.atttypid = t.oid
186
+ LEFT JOIN pg_collation c ON a.attcollation = c .oid AND a.attcollation <> t.typcollation
187
+ WHERE a.attrelid = #{ quote ( quote_table_name ( table_name ) ) } ::regclass
188
+ AND a.attnum > 0 AND NOT a.attisdropped
189
+ #{ ' AND a.attislocal' if @_dump_mode }
190
+ ORDER BY a.attnum
212
191
SQL
213
192
end
214
193
0 commit comments