activerecord-materialize-adapter 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_record/connection_adapters/materialize/column.rb +0 -9
  3. data/lib/active_record/connection_adapters/materialize/database_statements.rb +22 -41
  4. data/lib/active_record/connection_adapters/materialize/oid.rb +0 -12
  5. data/lib/active_record/connection_adapters/materialize/oid/type_map_initializer.rb +5 -48
  6. data/lib/active_record/connection_adapters/materialize/quoting.rb +1 -7
  7. data/lib/active_record/connection_adapters/materialize/schema/source_statements.rb +66 -0
  8. data/lib/active_record/connection_adapters/materialize/schema/view_statements.rb +22 -0
  9. data/lib/active_record/connection_adapters/materialize/schema_creation.rb +18 -53
  10. data/lib/active_record/connection_adapters/materialize/schema_definitions.rb +3 -6
  11. data/lib/active_record/connection_adapters/materialize/schema_dumper.rb +82 -22
  12. data/lib/active_record/connection_adapters/materialize/schema_statements.rb +102 -354
  13. data/lib/active_record/connection_adapters/materialize/version.rb +1 -1
  14. data/lib/active_record/connection_adapters/materialize_adapter.rb +100 -253
  15. metadata +9 -15
  16. data/lib/active_record/connection_adapters/materialize/oid/cidr.rb +0 -50
  17. data/lib/active_record/connection_adapters/materialize/oid/legacy_point.rb +0 -44
  18. data/lib/active_record/connection_adapters/materialize/oid/money.rb +0 -41
  19. data/lib/active_record/connection_adapters/materialize/oid/point.rb +0 -64
  20. data/lib/active_record/connection_adapters/materialize/oid/range.rb +0 -96
  21. data/lib/active_record/connection_adapters/materialize/oid/uuid.rb +0 -25
  22. data/lib/active_record/connection_adapters/materialize/oid/vector.rb +0 -28
  23. data/lib/active_record/connection_adapters/materialize/oid/xml.rb +0 -30
@@ -3,7 +3,7 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module Materialize
6
- VERSION = "0.2.0"
6
+ VERSION = "0.3.0"
7
7
  end
8
8
  end
9
9
  end
@@ -29,9 +29,12 @@ require "active_record/connection_adapters/materialize/schema_creation"
29
29
  require "active_record/connection_adapters/materialize/schema_definitions"
30
30
  require "active_record/connection_adapters/materialize/schema_dumper"
31
31
  require "active_record/connection_adapters/materialize/schema_statements"
32
+ require "active_record/connection_adapters/materialize/schema/source_statements"
33
+ require "active_record/connection_adapters/materialize/schema/view_statements"
32
34
  require "active_record/connection_adapters/materialize/type_metadata"
33
35
  require "active_record/connection_adapters/materialize/utils"
34
36
  require "active_record/tasks/materialize_database_tasks"
37
+ require 'materialize/errors/incomplete_input'
35
38
 
36
39
  module ActiveRecord
37
40
  module ConnectionHandling # :nodoc:
@@ -105,45 +108,24 @@ module ActiveRecord
105
108
  class_attribute :create_unlogged_tables, default: false
106
109
 
107
110
  NATIVE_DATABASE_TYPES = {
108
- primary_key: "bigserial primary key",
111
+ primary_key: "bigint",
109
112
  string: { name: "character varying" },
110
113
  text: { name: "text" },
111
- integer: { name: "integer", limit: 4 },
112
- float: { name: "float" },
114
+ integer: { name: "integer" },
115
+ bigint: { name: "int8" },
116
+ float: { name: "float4" },
117
+ double: { name: "float8" },
113
118
  decimal: { name: "decimal" },
114
119
  datetime: { name: "timestamp" },
120
+ timestampz: { name: "timestamp with time zone" },
115
121
  time: { name: "time" },
116
122
  date: { name: "date" },
117
- daterange: { name: "daterange" },
118
- numrange: { name: "numrange" },
119
- tsrange: { name: "tsrange" },
120
- tstzrange: { name: "tstzrange" },
121
- int4range: { name: "int4range" },
122
- int8range: { name: "int8range" },
123
123
  binary: { name: "bytea" },
124
124
  boolean: { name: "boolean" },
125
- xml: { name: "xml" },
126
- tsvector: { name: "tsvector" },
127
- hstore: { name: "hstore" },
128
- inet: { name: "inet" },
129
- cidr: { name: "cidr" },
130
- macaddr: { name: "macaddr" },
131
- uuid: { name: "uuid" },
132
- json: { name: "json" },
133
- jsonb: { name: "jsonb" },
134
- ltree: { name: "ltree" },
135
- citext: { name: "citext" },
136
- point: { name: "point" },
137
- line: { name: "line" },
138
- lseg: { name: "lseg" },
139
- box: { name: "box" },
140
- path: { name: "path" },
141
- polygon: { name: "polygon" },
142
- circle: { name: "circle" },
143
- bit: { name: "bit" },
144
- bit_varying: { name: "bit varying" },
145
- money: { name: "money" },
125
+ map: { name: "map" },
126
+ json: { name: "jsonb" },
146
127
  interval: { name: "interval" },
128
+ record: { name: "record" },
147
129
  oid: { name: "oid" },
148
130
  }
149
131
 
@@ -153,74 +135,31 @@ module ActiveRecord
153
135
  include Materialize::ReferentialIntegrity
154
136
  include Materialize::SchemaStatements
155
137
  include Materialize::DatabaseStatements
138
+ include Materialize::Schema::SourceStatements
139
+ include Materialize::Schema::ViewStatements
156
140
 
157
141
  def supports_bulk_alter?
158
142
  true
159
143
  end
160
144
 
161
- def supports_index_sort_order?
162
- true
163
- end
164
-
165
- def supports_partitioned_indexes?
166
- database_version >= 110_000
167
- end
168
-
169
- def supports_partial_index?
170
- true
171
- end
172
-
173
- def supports_expression_index?
174
- true
175
- end
176
-
145
+ # TODO: test transaction isolation
177
146
  def supports_transaction_isolation?
178
147
  true
179
148
  end
180
149
 
181
- def supports_foreign_keys?
182
- true
183
- end
184
-
185
- def supports_validate_constraints?
186
- true
187
- end
188
-
189
150
  def supports_views?
190
151
  true
191
152
  end
192
153
 
193
- def supports_datetime_with_precision?
194
- true
195
- end
196
-
197
154
  def supports_json?
198
155
  true
199
156
  end
200
157
 
201
- def supports_comments?
202
- true
203
- end
204
-
205
- def supports_savepoints?
206
- true
207
- end
208
-
158
+ # TODO: test insert returning
209
159
  def supports_insert_returning?
210
160
  true
211
161
  end
212
162
 
213
- def supports_insert_on_conflict?
214
- database_version >= 90500
215
- end
216
- alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
217
- alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
218
- alias supports_insert_conflict_target? supports_insert_on_conflict?
219
-
220
- def index_algorithms
221
- { concurrently: "CONCURRENTLY" }
222
- end
223
-
224
163
  class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
225
164
  def initialize(connection, max)
226
165
  super(max)
@@ -266,7 +205,6 @@ module ActiveRecord
266
205
  @type_map = Type::HashLookupTypeMap.new
267
206
  initialize_type_map
268
207
  @local_tz = execute("SHOW TIMEZONE", "SCHEMA").first["TimeZone"]
269
- @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
270
208
  end
271
209
 
272
210
  def self.database_exists?(config)
@@ -339,10 +277,6 @@ module ActiveRecord
339
277
  true
340
278
  end
341
279
 
342
- def supports_extensions?
343
- true
344
- end
345
-
346
280
  def supports_ranges?
347
281
  true
348
282
  end
@@ -352,14 +286,6 @@ module ActiveRecord
352
286
  true
353
287
  end
354
288
 
355
- def supports_foreign_tables?
356
- true
357
- end
358
-
359
- def supports_pgcrypto_uuid?
360
- database_version >= 90400
361
- end
362
-
363
289
  def supports_optimizer_hints?
364
290
  unless defined?(@has_pg_hint_plan)
365
291
  @has_pg_hint_plan = extension_available?("pg_hint_plan")
@@ -389,33 +315,9 @@ module ActiveRecord
389
315
  query_value("SELECT pg_advisory_unlock(#{lock_id})")
390
316
  end
391
317
 
392
- def enable_extension(name)
393
- exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
394
- reload_type_map
395
- }
396
- end
397
-
398
- def disable_extension(name)
399
- exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap {
400
- reload_type_map
401
- }
402
- end
403
-
404
- def extension_available?(name)
405
- query_value("SELECT true FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA")
406
- end
407
-
408
- def extension_enabled?(name)
409
- query_value("SELECT installed_version IS NOT NULL FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA")
410
- end
411
-
412
- def extensions
413
- exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
414
- end
415
-
416
318
  # Returns the configured supported identifier length supported by Materialize
417
319
  def max_identifier_length
418
- @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
320
+ @max_identifier_length || 64
419
321
  end
420
322
 
421
323
  # Set the authorized user for this session
@@ -424,10 +326,6 @@ module ActiveRecord
424
326
  execute("SET SESSION AUTHORIZATION #{user}")
425
327
  end
426
328
 
427
- def use_insert_returning?
428
- @use_insert_returning
429
- end
430
-
431
329
  def column_name_for_operation(operation, node) # :nodoc:
432
330
  OPERATION_ALIASES.fetch(operation) { operation.downcase }
433
331
  end
@@ -520,44 +418,52 @@ module ActiveRecord
520
418
  }
521
419
  end
522
420
 
421
+ def load_additional_types(oids = nil)
422
+ initializer = OID::TypeMapInitializer.new(type_map)
423
+
424
+ query = <<~SQL
425
+ SELECT t.id, t.oid, t.schema_id, t.name
426
+ FROM mz_types as t
427
+ LEFT JOIN mz_schemas s ON t.schema_id = s.id
428
+ LEFT JOIN mz_databases d ON s.database_id = d.id
429
+ WHERE
430
+ (d.name = #{quote(current_database)} OR s.name = 'pg_catalog')
431
+ SQL
432
+
433
+ if oids
434
+ query += "AND t.oid IN (%s)" % oids.join(", ")
435
+ else
436
+ query += initializer.query_conditions_for_initial_load
437
+ end
438
+
439
+ execute_and_clear(query, "SCHEMA", []) do |records|
440
+ initializer.run(records)
441
+ end
442
+ end
443
+
523
444
  def initialize_type_map(m = type_map)
524
445
  m.register_type "int2", Type::Integer.new(limit: 2)
525
446
  m.register_type "int4", Type::Integer.new(limit: 4)
526
447
  m.register_type "int8", Type::Integer.new(limit: 8)
448
+ m.alias_type "int", "int4"
449
+ m.alias_type "integer", "int4"
450
+ m.alias_type "bigint", "int8"
527
451
  m.register_type "oid", OID::Oid.new
528
452
  m.register_type "float4", Type::Float.new
529
453
  m.alias_type "float8", "float4"
454
+ m.alias_type "double", "float4"
530
455
  m.register_type "text", Type::Text.new
531
- register_class_with_limit m, "varchar", Type::String
532
- m.alias_type "char", "varchar"
533
- m.alias_type "name", "varchar"
534
- m.alias_type "bpchar", "varchar"
535
- m.register_type "bool", Type::Boolean.new
536
- register_class_with_limit m, "bit", OID::Bit
537
- register_class_with_limit m, "varbit", OID::BitVarying
456
+ m.alias_type "varchar", "text"
457
+
458
+ m.register_type "boolean", Type::Boolean.new
459
+ register_class_with_limit m, "bytea", OID::BitVarying
460
+
538
461
  m.alias_type "timestamptz", "timestamp"
539
462
  m.register_type "date", OID::Date.new
540
463
 
541
- m.register_type "money", OID::Money.new
542
464
  m.register_type "bytea", OID::Bytea.new
543
- m.register_type "point", OID::Point.new
544
- m.register_type "hstore", OID::Hstore.new
545
- m.register_type "json", Type::Json.new
546
465
  m.register_type "jsonb", OID::Jsonb.new
547
- m.register_type "cidr", OID::Cidr.new
548
- m.register_type "inet", OID::Inet.new
549
- m.register_type "uuid", OID::Uuid.new
550
- m.register_type "xml", OID::Xml.new
551
- m.register_type "tsvector", OID::SpecializedString.new(:tsvector)
552
- m.register_type "macaddr", OID::SpecializedString.new(:macaddr)
553
- m.register_type "citext", OID::SpecializedString.new(:citext)
554
- m.register_type "ltree", OID::SpecializedString.new(:ltree)
555
- m.register_type "line", OID::SpecializedString.new(:line)
556
- m.register_type "lseg", OID::SpecializedString.new(:lseg)
557
- m.register_type "box", OID::SpecializedString.new(:box)
558
- m.register_type "path", OID::SpecializedString.new(:path)
559
- m.register_type "polygon", OID::SpecializedString.new(:polygon)
560
- m.register_type "circle", OID::SpecializedString.new(:circle)
466
+ m.alias_type "json", "jsonb"
561
467
 
562
468
  m.register_type "interval" do |_, _, sql_type|
563
469
  precision = extract_precision(sql_type)
@@ -567,25 +473,7 @@ module ActiveRecord
567
473
  register_class_with_precision m, "time", Type::Time
568
474
  register_class_with_precision m, "timestamp", OID::DateTime
569
475
 
570
- m.register_type "numeric" do |_, fmod, sql_type|
571
- precision = extract_precision(sql_type)
572
- scale = extract_scale(sql_type)
573
-
574
- # The type for the numeric depends on the width of the field,
575
- # so we'll do something special here.
576
- #
577
- # When dealing with decimal columns:
578
- #
579
- # places after decimal = fmod - 4 & 0xffff
580
- # places before decimal = (fmod - 4) >> 16 & 0xffff
581
- if fmod && (fmod - 4 & 0xffff).zero?
582
- # FIXME: Remove this class, and the second argument to
583
- # lookups on PG
584
- Type::DecimalWithoutScale.new(precision: precision)
585
- else
586
- OID::Decimal.new(precision: precision, scale: scale)
587
- end
588
- end
476
+ load_additional_types
589
477
  end
590
478
 
591
479
  # Extracts the value from a Materialize column default definition.
@@ -623,26 +511,6 @@ module ActiveRecord
623
511
  !default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
624
512
  end
625
513
 
626
- def load_additional_types(oids = nil)
627
- initializer = OID::TypeMapInitializer.new(type_map)
628
-
629
- query = <<~SQL
630
- SELECT t.oid, t.typname, t.typelem, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
631
- FROM pg_type as t
632
- LEFT JOIN pg_range as r ON oid = rngtypid
633
- SQL
634
-
635
- if oids
636
- query += "WHERE t.oid IN (%s)" % oids.join(", ")
637
- else
638
- query += initializer.query_conditions_for_initial_load
639
- end
640
-
641
- execute_and_clear(query, "SCHEMA", []) do |records|
642
- initializer.run(records)
643
- end
644
- end
645
-
646
514
  FEATURE_NOT_SUPPORTED = "0A000" #:nodoc:
647
515
 
648
516
  def execute_and_clear(sql, name, binds, prepare: false)
@@ -652,10 +520,8 @@ module ActiveRecord
652
520
 
653
521
  if without_prepared_statement?(binds)
654
522
  result = exec_no_cache(sql, name, [])
655
- elsif !prepare
656
- result = exec_no_cache(sql, name, binds)
657
523
  else
658
- result = exec_cache(sql, name, binds)
524
+ result = exec_no_cache(sql, name, binds)
659
525
  end
660
526
  ret = yield result
661
527
  result.clear
@@ -669,39 +535,18 @@ module ActiveRecord
669
535
  # made since we established the connection
670
536
  update_typemap_for_default_timezone
671
537
 
672
- type_casted_binds = type_casted_binds(binds)
673
- log(sql, name, binds, type_casted_binds) do
538
+ typed_binds = type_casted_binds(binds)
539
+ log(sql, name, binds, typed_binds) do
674
540
  ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
675
- @connection.exec_params(sql, type_casted_binds)
541
+ @connection.exec_params(prepare_statement(sql, typed_binds), [])
676
542
  end
677
543
  end
678
- end
679
-
680
- def exec_cache(sql, name, binds)
681
- materialize_transactions
682
- update_typemap_for_default_timezone
683
-
684
- stmt_key = prepare_statement(sql, binds)
685
- type_casted_binds = type_casted_binds(binds)
686
-
687
- log(sql, name, binds, type_casted_binds, stmt_key) do
688
- ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
689
- @connection.exec_prepared(stmt_key, type_casted_binds)
690
- end
691
- end
692
- rescue ActiveRecord::StatementInvalid => e
693
- raise unless is_cached_plan_failure?(e)
694
-
695
- # Nothing we can do if we are in a transaction because all commands
696
- # will raise InFailedSQLTransaction
697
- if in_transaction?
698
- raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
544
+ rescue ActiveRecord::StatementInvalid,
545
+ PG::InternalError => error
546
+ if error.message.include? "At least one input has no complete timestamps yet"
547
+ raise ::Materialize::Errors::IncompleteInput, error.message
699
548
  else
700
- @lock.synchronize do
701
- # outside of transactions we can simply flush this query and retry
702
- @statements.delete sql_key(sql)
703
- end
704
- retry
549
+ raise
705
550
  end
706
551
  end
707
552
 
@@ -730,27 +575,33 @@ module ActiveRecord
730
575
  # Returns the statement identifier for the client side cache
731
576
  # of statements
732
577
  def sql_key(sql)
733
- "#{schema_search_path}-#{sql}"
578
+ "#{sql}"
734
579
  end
735
580
 
736
- # Prepare the statement if it hasn't been prepared, return
737
- # the statement key.
738
581
  def prepare_statement(sql, binds)
739
- @lock.synchronize do
740
- sql_key = sql_key(sql)
741
- unless @statements.key? sql_key
742
- nextkey = @statements.next_key
743
- begin
744
- @connection.prepare nextkey, sql
745
- rescue => e
746
- raise translate_exception_class(e, sql, binds)
582
+ parametrized_statement = sql.split(/\s+/)
583
+ binds.each_with_index do |n, i|
584
+ index = i + 1
585
+ part = \
586
+ case n
587
+ when String
588
+ "'#{quote_string(n)}'"
589
+ when Numeric
590
+ n.to_s
747
591
  end
748
- # Clear the queue
749
- @connection.get_last_result
750
- @statements[sql_key] = nextkey
592
+
593
+ parametrized_statement = parametrized_statement.map do |token|
594
+ token
595
+ .gsub("$#{index}", part)
596
+ .gsub("($#{index}", "(#{part}")
597
+ .gsub("$#{index})", "#{part})")
598
+ .gsub("($#{index})", "(#{part})")
599
+ .gsub(",$#{index}", ",#{part}")
600
+ .gsub("$#{index},", "#{part},")
601
+ .gsub(",$#{index},", ",#{part},")
751
602
  end
752
- @statements[sql_key]
753
603
  end
604
+ parametrized_statement.join ' '
754
605
  end
755
606
 
756
607
  # Connects to a Materialize server and sets up the adapter depending on the
@@ -768,7 +619,6 @@ module ActiveRecord
768
619
  if @config[:encoding]
769
620
  @connection.set_client_encoding(@config[:encoding])
770
621
  end
771
- self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
772
622
 
773
623
  variables = @config.fetch(:variables, {}).stringify_keys
774
624
 
@@ -814,16 +664,20 @@ module ActiveRecord
814
664
  # - ::regclass is a function that gives the id for a table name
815
665
  def column_definitions(table_name)
816
666
  query(<<~SQL, "SCHEMA")
817
- SELECT a.attname, format_type(a.atttypid, a.atttypmod),
818
- pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
819
- c.collname, col_description(a.attrelid, a.attnum) AS comment
820
- FROM pg_attribute a
821
- LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
822
- LEFT JOIN pg_type t ON a.atttypid = t.oid
823
- LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
824
- WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
825
- AND a.attnum > 0 AND NOT a.attisdropped
826
- ORDER BY a.attnum
667
+ SELECT
668
+ c.name,
669
+ c.type AS format_type,
670
+ c.nullable,
671
+ NULL AS default,
672
+ NULL AS comment
673
+ FROM mz_columns c
674
+ LEFT JOIN mz_tables t ON c.id = t.id
675
+ LEFT JOIN mz_schemas s ON t.schema_id = s.id
676
+ LEFT JOIN mz_databases d ON s.database_id = d.id
677
+ WHERE
678
+ t.name = #{quote(table_name)}
679
+ AND d.name = #{quote(current_database)}
680
+ ORDER BY c.position
827
681
  SQL
828
682
  end
829
683
 
@@ -890,10 +744,15 @@ module ActiveRecord
890
744
  "int2" => PG::TextDecoder::Integer,
891
745
  "int4" => PG::TextDecoder::Integer,
892
746
  "int8" => PG::TextDecoder::Integer,
747
+ "integer" => PG::TextDecoder::Integer,
748
+ "bigint" => PG::TextDecoder::Integer,
893
749
  "oid" => PG::TextDecoder::Integer,
750
+ "float" => PG::TextDecoder::Float,
894
751
  "float4" => PG::TextDecoder::Float,
895
752
  "float8" => PG::TextDecoder::Float,
753
+ "double" => PG::TextDecoder::Float,
896
754
  "bool" => PG::TextDecoder::Boolean,
755
+ "boolean" => PG::TextDecoder::Boolean,
897
756
  }
898
757
 
899
758
  if defined?(PG::TextDecoder::TimestampUtc)
@@ -929,24 +788,12 @@ module ActiveRecord
929
788
  end
930
789
 
931
790
  ActiveRecord::Type.add_modifier({ array: true }, OID::Array, adapter: :materialize)
932
- ActiveRecord::Type.add_modifier({ range: true }, OID::Range, adapter: :materialize)
933
- ActiveRecord::Type.register(:bit, OID::Bit, adapter: :materialize)
934
- ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :materialize)
935
791
  ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :materialize)
936
- ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :materialize)
937
792
  ActiveRecord::Type.register(:date, OID::Date, adapter: :materialize)
938
793
  ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :materialize)
939
794
  ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :materialize)
940
795
  ActiveRecord::Type.register(:enum, OID::Enum, adapter: :materialize)
941
- ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :materialize)
942
- ActiveRecord::Type.register(:inet, OID::Inet, adapter: :materialize)
943
796
  ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :materialize)
944
- ActiveRecord::Type.register(:money, OID::Money, adapter: :materialize)
945
- ActiveRecord::Type.register(:point, OID::Point, adapter: :materialize)
946
- ActiveRecord::Type.register(:legacy_point, OID::LegacyPoint, adapter: :materialize)
947
- ActiveRecord::Type.register(:uuid, OID::Uuid, adapter: :materialize)
948
- ActiveRecord::Type.register(:vector, OID::Vector, adapter: :materialize)
949
- ActiveRecord::Type.register(:xml, OID::Xml, adapter: :materialize)
950
797
  end
951
798
  end
952
799
  end