activerecord-materialize-adapter 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/active_record/connection_adapters/materialize/column.rb +0 -9
- data/lib/active_record/connection_adapters/materialize/database_statements.rb +22 -41
- data/lib/active_record/connection_adapters/materialize/oid.rb +0 -12
- data/lib/active_record/connection_adapters/materialize/oid/type_map_initializer.rb +5 -48
- data/lib/active_record/connection_adapters/materialize/quoting.rb +1 -7
- data/lib/active_record/connection_adapters/materialize/schema/source_statements.rb +66 -0
- data/lib/active_record/connection_adapters/materialize/schema/view_statements.rb +22 -0
- data/lib/active_record/connection_adapters/materialize/schema_creation.rb +18 -53
- data/lib/active_record/connection_adapters/materialize/schema_definitions.rb +3 -6
- data/lib/active_record/connection_adapters/materialize/schema_dumper.rb +82 -22
- data/lib/active_record/connection_adapters/materialize/schema_statements.rb +102 -354
- data/lib/active_record/connection_adapters/materialize/version.rb +1 -1
- data/lib/active_record/connection_adapters/materialize_adapter.rb +100 -253
- metadata +9 -15
- data/lib/active_record/connection_adapters/materialize/oid/cidr.rb +0 -50
- data/lib/active_record/connection_adapters/materialize/oid/legacy_point.rb +0 -44
- data/lib/active_record/connection_adapters/materialize/oid/money.rb +0 -41
- data/lib/active_record/connection_adapters/materialize/oid/point.rb +0 -64
- data/lib/active_record/connection_adapters/materialize/oid/range.rb +0 -96
- data/lib/active_record/connection_adapters/materialize/oid/uuid.rb +0 -25
- data/lib/active_record/connection_adapters/materialize/oid/vector.rb +0 -28
- data/lib/active_record/connection_adapters/materialize/oid/xml.rb +0 -30
@@ -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: "
|
111
|
+
primary_key: "bigint",
|
109
112
|
string: { name: "character varying" },
|
110
113
|
text: { name: "text" },
|
111
|
-
integer: { name: "integer"
|
112
|
-
|
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
|
-
|
126
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
532
|
-
|
533
|
-
m.
|
534
|
-
m
|
535
|
-
|
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.
|
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
|
-
|
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 =
|
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
|
-
|
673
|
-
log(sql, name, binds,
|
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,
|
541
|
+
@connection.exec_params(prepare_statement(sql, typed_binds), [])
|
676
542
|
end
|
677
543
|
end
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
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
|
-
|
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
|
-
"#{
|
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
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
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
|
-
|
749
|
-
|
750
|
-
|
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
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
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
|