@@ -5,7 +5,7 @@ module PostgreSQL
55 module Adapter
66 module DatabaseStatements
77
8- EXTENDED_DATABASE_TYPES = %i( enum enum_set interval )
8+ EXTENDED_DATABASE_TYPES = %i[ enum enum_set interval ]
99
1010 # Switch between dump mode or not
1111 def dump_mode!
@@ -48,8 +48,8 @@ def extended_types
4848 def schema_exists? ( name , filtered : true )
4949 return user_defined_schemas . include? ( name . to_s ) if filtered
5050
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 ) }
5353 SQL
5454 end
5555
@@ -59,96 +59,75 @@ def type_exists?(name)
5959 end
6060 alias data_type_exists? type_exists?
6161
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-
7762 # Change some of the types being mapped
7863 def initialize_type_map ( m = type_map )
7964 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
8565
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
8776 end
8877
8978 # :nodoc:
9079 def load_additional_types ( oids = nil )
80+ type_map . alias_type 'regclass' , 'varchar'
81+ type_map . alias_type 'regconfig' , 'varchar'
9182 super
9283 torque_load_additional_types ( oids )
9384 end
9485
9586 # Add the composite types to be loaded too.
9687 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')
117100 SQL
118101
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')"
121106 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
122118 end
123119
124120 # Gets a list of user defined types.
125121 # You can even choose the +category+ filter
126122 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
138129 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 ( "', '" ) } ')
152131 SQL
153132 end
154133
@@ -195,20 +174,20 @@ def user_defined_schemas_sql
195174 # Get the list of columns, and their definition, but only from the
196175 # actual table, does not include columns that comes from inherited table
197176 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
212191 SQL
213192 end
214193
0 commit comments