Class: ActiveRecord::ConnectionAdapters::DuckdbAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::DuckdbAdapter
- Includes:
- ActiveRecord::ConnectionAdapters::Duckdb::DatabaseLimits, ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatements, ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatementsRails72, ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatementsRails8, ActiveRecord::ConnectionAdapters::Duckdb::Quoting, ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatements, ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatementsRails80, ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatementsRails81
- Defined in:
- lib/active_record/connection_adapters/duckdb_adapter.rb
Overview
This adapter provides a connection to a DuckDB database.
Constant Summary collapse
- ADAPTER_NAME =
'DuckDB'- MEMORY_MODE_KEYS =
DB configuration if used in memory mode
[:memory, 'memory', ':memory:', ':memory'].freeze
- TYPE_MAP =
Type map for DuckDB SQL types to ActiveRecord types
Type::TypeMap.new.tap { |m| initialize_type_map(m) }
- NATIVE_DATABASE_TYPES =
https://duckdb.org/docs/stable/sql/data_types/overview.html Integer limits (in bytes): tinyint=1, smallint=2, integer=4, bigint=8
{ primary_key: 'INTEGER PRIMARY KEY', string: { name: 'VARCHAR' }, integer: { name: 'INTEGER', limit: 4 }, float: { name: 'REAL' }, decimal: { name: 'DECIMAL' }, datetime: { name: 'TIMESTAMP' }, time: { name: 'TIME' }, date: { name: 'DATE' }, bigint: { name: 'BIGINT', limit: 8 }, binary: { name: 'BLOB' }, boolean: { name: 'BOOLEAN' }, uuid: { name: 'UUID' }, # DuckDB-specific signed integer types tinyint: { name: 'TINYINT', limit: 1 }, smallint: { name: 'SMALLINT', limit: 2 }, hugeint: { name: 'HUGEINT' }, # DuckDB-specific unsigned integer types utinyint: { name: 'UTINYINT', limit: 1 }, usmallint: { name: 'USMALLINT', limit: 2 }, uinteger: { name: 'UINTEGER', limit: 4 }, ubigint: { name: 'UBIGINT', limit: 8 }, uhugeint: { name: 'UHUGEINT' }, # Other DuckDB types interval: { name: 'INTERVAL' } }.freeze
- EARLY_SETTINGS =
Settings that MUST be applied before loading extensions
%i[allow_persistent_secrets allow_community_extensions].freeze
- DEFAULT_SETTINGS =
Default DuckDB settings for secure and predictable behavior Note: lock_configuration is handled separately at the end of configure_connection
{ allow_persistent_secrets: false, allow_community_extensions: false, autoinstall_known_extensions: false, autoload_known_extensions: false, threads: 1, memory_limit: '1GiB', max_temp_directory_size: '4GiB' }.freeze
Constants included from ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatements
ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatements::DUMPABLE_DUCKLAKE_OPTIONS
Constants included from ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatements
ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatements::READ_QUERY_PATTERN
Class Method Summary collapse
-
.configure_primary_key_type(type) ⇒ Symbol
Configures the primary key type at the class level.
-
.database_exists?(config) ⇒ Boolean
Checks if the DuckDB database file exists.
-
.dbconsole(config, options = {}) ⇒ void
Opens the DuckDB command line console.
-
.new_client(config) ⇒ DuckDB::Connection
Creates a new DuckDB database connection.
Instance Method Summary collapse
-
#active? ⇒ Boolean
Checks if the database connection is active.
-
#column_definitions(table_name) ⇒ Array<Array>
Returns column definitions for a table using PRAGMA table_info.
-
#configuration_locked? ⇒ Boolean
Checks if DuckDB configuration is locked.
-
#configure_connection ⇒ void
Configures the DuckDB connection with extensions, settings, secrets, and attachments.
-
#create_savepoint(_name = nil) ⇒ Object
DuckDB does not support savepoints.
-
#create_schema_dumper(options) ⇒ Duckdb::SchemaDumper
Creates a schema dumper instance for DuckDB Uses the DuckDB-specific SchemaDumper class to handle DuckDB types and DuckLake features.
-
#default_sequence_name(table_name, column_name = 'id') ⇒ String
Generates default sequence name following PostgreSQL/Oracle conventions.
-
#default_value_for_table(table_name) ⇒ nil
Returns default value for table in schema dumping.
-
#disconnect ⇒ void
Disconnects from the DuckDB database and cleans up the connection.
-
#ducklake? ⇒ Boolean
Detects if the current database is a DuckLake database Uses a metadata query to check the database type.
-
#ducklake_extension_available? ⇒ Boolean
Checks if the DuckLake extension is available and can be loaded.
-
#exec_rollback_to_savepoint(_name = nil) ⇒ Object
DuckDB does not support savepoints.
-
#indexes(table_name = nil) ⇒ Array
Returns indexes for a table or all tables.
-
#lookup_cast_type(sql_type) ⇒ ActiveRecord::Type::Value
Looks up the cast type for a given SQL type string Uses the DuckDB TYPE_MAP to return appropriate ActiveRecord types This ensures BIGINT columns use BigInteger type for full 8-byte range support.
-
#native_database_types ⇒ Hash
Returns the native database types supported by DuckDB DuckLake doesn't support PRIMARY KEY constraints, so we return a modified version.
-
#next_sequence_value(sequence_name) ⇒ String
Generates SQL for getting the next sequence value.
-
#prefetch_primary_key?(_table_name) ⇒ Boolean
Determines if primary key should be prefetched before insert.
-
#primary_key(table_name) ⇒ String?
Returns the primary key column name for a table.
-
#primary_key_definition(table_name) ⇒ nil
Override to prevent Rails schema dumper from detecting sequence defaults as table defaults.
-
#primary_key_type_for_schema_dump(table_name) ⇒ Symbol?
Determines the primary key type for schema dumping.
-
#primary_keys(table_name) ⇒ Array<String>
Returns the primary key columns for a table.
-
#raw_connection ⇒ DuckDB::Connection?
Returns the raw DuckDB connection object.
-
#release_savepoint(_name = nil) ⇒ Object
DuckDB does not support savepoints.
-
#return_value_after_insert?(column) ⇒ Boolean
Determines if a column value should be returned after insert.
-
#schema_type(column) ⇒ Symbol
Maps DuckDB column types to ActiveRecord schema types Override schema dumping to fix type detection.
-
#serial_sequence(table, column) ⇒ nil
Returns the sequence name for a serial column.
-
#supports_insert_on_duplicate_skip? ⇒ Boolean
Indicates whether the adapter supports INSERT ON DUPLICATE SKIP syntax.
-
#supports_insert_on_duplicate_update? ⇒ Boolean
Indicates whether the adapter supports INSERT ON DUPLICATE UPDATE syntax.
-
#supports_insert_returning? ⇒ Boolean
Indicates whether the adapter supports INSERT RETURNING for Rails 8 DuckLake does NOT support INSERT...RETURNING, so we check for DuckLake mode.
-
#supports_primary_key_type?(type) ⇒ Boolean
Indicates whether the adapter supports a specific primary key type Support Rails id: :uuid convention.
-
#supports_savepoints? ⇒ Boolean
DuckDB does not support savepoints at the SQL level.
-
#table_default_value(table_name) ⇒ nil
Override to ensure sequence defaults never appear at table level.
-
#table_options(table_name) ⇒ Hash
Returns table options for schema dumping.
-
#use_insert_returning? ⇒ Boolean
Indicates whether the adapter supports INSERT...RETURNING syntax DuckLake does NOT support INSERT...RETURNING, so we check for DuckLake mode.
-
#valid_type?(type) ⇒ Boolean
Check if a type is valid for schema dumping.
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatementsRails80
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatementsRails81
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatementsRails72
#exec_delete, #internal_exec_query
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatementsRails8
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::SchemaStatements
#create_sequence, #create_table, #create_table_definition, #data_source_sql, #drop_sequence, #ducklake_metadata_schema, #ducklake_options, #ducklake_table_options, #execute, #internal_string_options_for_primary_key, #lookup_cast_type_from_column, #partition_expressions, #quoted_scope, #reset_sequence!, #schema_creation, #sequence_exists?, #sequences, #set_ducklake_option, #set_partitioned_by, #tables, #type_to_sql, #views
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::Quoting
#quote, #quote_column_name, #quote_table_name
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatements
#affected_rows, #begin_db_transaction, #cast_result, #columns_for_insert, #commit_db_transaction, #exec_rollback_db_transaction, #execute, #last_inserted_id, #write_query?
Methods included from ActiveRecord::ConnectionAdapters::Duckdb::DatabaseLimits
#index_name_length, #max_identifier_length, #table_alias_length, #table_name_length
Class Method Details
.configure_primary_key_type(type) ⇒ Symbol
Configures the primary key type at the class level
508 509 510 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 508 def self.configure_primary_key_type(type) self.primary_key_type = type end |
.database_exists?(config) ⇒ Boolean
Checks if the DuckDB database file exists
248 249 250 251 252 253 254 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 248 def database_exists?(config) # Logic to check if database exists database_path = config[:database] return true if MEMORY_MODE_KEYS.include?(database_path) File.exist?(database_path.to_s) end |
.dbconsole(config, options = {}) ⇒ void
This method returns an undefined value.
Opens the DuckDB command line console
237 238 239 240 241 242 243 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 237 def dbconsole(config, = {}) db_config = config.configuration_hash args = [] args << db_config[:database] if db_config[:database] && !MEMORY_MODE_KEYS.include?(db_config[:database]) find_cmd_and_exec('duckdb', *args) end |
.new_client(config) ⇒ DuckDB::Connection
Creates a new DuckDB database connection
100 101 102 103 104 105 106 107 108 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 100 def new_client(config) database = config[:database] || :memory db = if MEMORY_MODE_KEYS.include?(database) DuckDB::Database.open else DuckDB::Database.open(database.to_s) end db.connect end |
Instance Method Details
#active? ⇒ Boolean
Checks if the database connection is active
213 214 215 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 213 def active? !!(@raw_connection || @connection) end |
#column_definitions(table_name) ⇒ Array<Array>
Returns column definitions for a table using PRAGMA table_info
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 423 def column_definitions(table_name) # Use PRAGMA table_info which gives us more accurate type information # including primary key detection that information_schema might miss pragma_results = execute("PRAGMA table_info(#{quote(table_name.to_s)})", 'SCHEMA') pragma_results.map do |row| _cid, column_name, data_type, not_null, column_default, pk = row # Format the type properly - DuckDB PRAGMA gives us the actual type # Preserve VARCHAR limits and other type information formatted_type = case data_type.to_s.upcase when /^BIGINT$/i 'BIGINT' when /^INTEGER$/i 'INTEGER' when /^VARCHAR$/i, /^VARCHAR\(\d+\)$/i data_type.to_s # Preserve the full VARCHAR(n) format when /^DECIMAL\(\d+,\d+\)$/i data_type.to_s # Preserve DECIMAL(p,s) format when /^TIMESTAMP$/i 'TIMESTAMP' when /^BOOLEAN$/i 'BOOLEAN' when /^UUID$/i 'UUID' when /^BLOB$/i 'BLOB' when /^DATE$/i 'DATE' when /^TIME$/i 'TIME' when /^REAL$/i, /^DOUBLE$/i data_type.to_s else data_type.to_s end # Convert PRAGMA results to match information_schema format # Note: DuckLake returns booleans (true/false) while regular DuckDB may return integers (1/0) [ column_name, # column_name formatted_type, # formatted_type column_default, # column_default not_null.in?([1, true]), # not_null (true if NOT NULL constraint) nil, # type_id nil, # type_modifier nil, # collation_name nil, # comment nil, # identity nil, # generated pk.in?([1, true]) # primary_key flag (true if primary key) ] end end |
#configuration_locked? ⇒ Boolean
Checks if DuckDB configuration is locked. Once lock_configuration is set to true, no configuration changes can be made.
411 412 413 414 415 416 417 418 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 411 def configuration_locked? return false unless raw_connection result = raw_connection.query("SELECT current_setting('lock_configuration')") result.first&.first == true rescue DuckDB::Error false end |
#configure_connection ⇒ void
This method returns an undefined value.
Configures the DuckDB connection with extensions, settings, secrets, and attachments. DuckDB locks configuration permanently after initial setup, so we skip reconfiguration if the connection is already configured. This is necessary because Rails/test-prof may call reset! which triggers configure_connection again.
393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 393 def configure_connection # Skip reconfiguration if already configured - DuckDB locks configuration permanently return if configuration_locked? super DuckDB.default_timezone = ActiveRecord.default_timezone apply_early_settings install_extensions apply_settings create_secrets attach_databases use_database lock_configuration end |
#create_savepoint(_name = nil) ⇒ Object
DuckDB does not support savepoints.
330 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 330 def create_savepoint(_name = nil) = raise SavepointsNotSupported |
#create_schema_dumper(options) ⇒ Duckdb::SchemaDumper
Creates a schema dumper instance for DuckDB Uses the DuckDB-specific SchemaDumper class to handle DuckDB types and DuckLake features
606 607 608 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 606 def create_schema_dumper() # :nodoc: Duckdb::SchemaDumper.create(self, ) end |
#default_sequence_name(table_name, column_name = 'id') ⇒ String
Generates default sequence name following PostgreSQL/Oracle conventions
501 502 503 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 501 def default_sequence_name(table_name, column_name = 'id') "#{table_name}_#{column_name}_seq" end |
#default_value_for_table(table_name) ⇒ nil
Returns default value for table in schema dumping
539 540 541 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 539 def default_value_for_table(table_name) nil end |
#disconnect ⇒ void
This method returns an undefined value.
Disconnects from the DuckDB database and cleans up the connection
206 207 208 209 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 206 def disconnect @connection&.close @connection = nil end |
#ducklake? ⇒ Boolean
Detects if the current database is a DuckLake database Uses a metadata query to check the database type
274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 274 def ducklake? return @ducklake if defined?(@ducklake) @ducklake = begin with_raw_connection do |conn| result = conn.query('SELECT type FROM duckdb_databases() WHERE database_name = current_database()') db_type = result.first&.first db_type.to_s.downcase == 'ducklake' end rescue DuckDB::Error false end end |
#ducklake_extension_available? ⇒ Boolean
Checks if the DuckLake extension is available and can be loaded
290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 290 def ducklake_extension_available? return @ducklake_extension_available if defined?(@ducklake_extension_available) @ducklake_extension_available = begin with_raw_connection do |conn| conn.execute('INSTALL ducklake') conn.execute('LOAD ducklake') end true rescue DuckDB::Error false end end |
#exec_rollback_to_savepoint(_name = nil) ⇒ Object
DuckDB does not support savepoints.
335 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 335 def exec_rollback_to_savepoint(_name = nil) = raise SavepointsNotSupported |
#indexes(table_name = nil) ⇒ Array
Returns indexes for a table or all tables
569 570 571 572 573 574 575 576 577 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 569 def indexes(table_name = nil) if table_name # Delegate to the schema statements implementation super else # This shouldn't happen in normal schema dumping, but handle gracefully [] end end |
#lookup_cast_type(sql_type) ⇒ ActiveRecord::Type::Value
Looks up the cast type for a given SQL type string Uses the DuckDB TYPE_MAP to return appropriate ActiveRecord types This ensures BIGINT columns use BigInteger type for full 8-byte range support
228 229 230 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 228 def lookup_cast_type(sql_type) TYPE_MAP.lookup(sql_type) end |
#native_database_types ⇒ Hash
Returns the native database types supported by DuckDB DuckLake doesn't support PRIMARY KEY constraints, so we return a modified version
379 380 381 382 383 384 385 386 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 379 def native_database_types return NATIVE_DATABASE_TYPES unless ducklake? # DuckLake doesn't support PRIMARY KEY/UNIQUE constraints @native_database_types ||= NATIVE_DATABASE_TYPES.merge( primary_key: 'INTEGER' ) end |
#next_sequence_value(sequence_name) ⇒ String
Generates SQL for getting the next sequence value
493 494 495 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 493 def next_sequence_value(sequence_name) "nextval(#{quote(sequence_name)})" end |
#prefetch_primary_key?(_table_name) ⇒ Boolean
Determines if primary key should be prefetched before insert
345 346 347 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 345 def prefetch_primary_key?(_table_name) false end |
#primary_key(table_name) ⇒ String?
Returns the primary key column name for a table
515 516 517 518 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 515 def primary_key(table_name) pk_columns = primary_keys(table_name) pk_columns.size == 1 ? pk_columns.first : nil end |
#primary_key_definition(table_name) ⇒ nil
Override to prevent Rails schema dumper from detecting sequence defaults as table defaults
523 524 525 526 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 523 def primary_key_definition(table_name) # Always return nil to prevent any table-level defaults from sequence columns nil end |
#primary_key_type_for_schema_dump(table_name) ⇒ Symbol?
Determines the primary key type for schema dumping
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 582 def primary_key_type_for_schema_dump(table_name) pk_column = primary_key(table_name) return nil unless pk_column # Get the actual column definition col_def = columns(table_name).find { |c| c.name == pk_column } return nil unless col_def case col_def.sql_type.to_s.upcase when 'BIGINT' :bigint when 'INTEGER' :integer when 'UUID' :uuid when /^VARCHAR/ :string end end |
#primary_keys(table_name) ⇒ Array<String>
Returns the primary key columns for a table
362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 362 def primary_keys(table_name) # :nodoc: raise ArgumentError, 'table_name cannot be blank' unless table_name.present? results = execute("PRAGMA table_info(#{quote(table_name.to_s)})", 'SCHEMA') results.filter_map do |result| _cid, name, _type, _notnull, _dflt_value, pk = result # pk can be true, false, 1, 0, or nil in DuckDB PRAGMA table_info # true or 1 means it's a primary key, false, 0, or nil means it's not pk_value = pk == true ? 1 : pk [pk_value, name] if [true, 1].include?(pk) end.sort_by(&:first).map(&:last) end |
#raw_connection ⇒ DuckDB::Connection?
Returns the raw DuckDB connection object
219 220 221 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 219 def raw_connection @raw_connection || @connection end |
#release_savepoint(_name = nil) ⇒ Object
DuckDB does not support savepoints.
340 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 340 def release_savepoint(_name = nil) = raise SavepointsNotSupported |
#return_value_after_insert?(column) ⇒ Boolean
Determines if a column value should be returned after insert
313 314 315 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 313 def return_value_after_insert?(column) column.default_function.present? || super end |
#schema_type(column) ⇒ Symbol
Maps DuckDB column types to ActiveRecord schema types Override schema dumping to fix type detection
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 547 def schema_type(column) case column.sql_type when /^BIGINT$/i :bigint when /^INTEGER$/i :integer when /^VARCHAR$/i, /^VARCHAR\(\d+\)$/i :string when /^TIMESTAMP$/i :datetime when /^BOOLEAN$/i :boolean when /^UUID$/i :uuid else super end end |
#serial_sequence(table, column) ⇒ nil
Returns the sequence name for a serial column
353 354 355 356 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 353 def serial_sequence(table, column) # Return sequence name if using sequences, nil otherwise nil end |
#supports_insert_on_duplicate_skip? ⇒ Boolean
Indicates whether the adapter supports INSERT ON DUPLICATE SKIP syntax
306 307 308 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 306 def supports_insert_on_duplicate_skip? false end |
#supports_insert_on_duplicate_update? ⇒ Boolean
Indicates whether the adapter supports INSERT ON DUPLICATE UPDATE syntax
319 320 321 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 319 def supports_insert_on_duplicate_update? false end |
#supports_insert_returning? ⇒ Boolean
Indicates whether the adapter supports INSERT RETURNING for Rails 8 DuckLake does NOT support INSERT...RETURNING, so we check for DuckLake mode
267 268 269 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 267 def supports_insert_returning? !ducklake? end |
#supports_primary_key_type?(type) ⇒ Boolean
Indicates whether the adapter supports a specific primary key type Support Rails id: :uuid convention
481 482 483 484 485 486 487 488 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 481 def supports_primary_key_type?(type) case type when :uuid, :string, :integer, :bigint, :primary_key true else false end end |
#supports_savepoints? ⇒ Boolean
DuckDB does not support savepoints at the SQL level.
325 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 325 def supports_savepoints? = false |
#table_default_value(table_name) ⇒ nil
Override to ensure sequence defaults never appear at table level
531 532 533 534 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 531 def table_default_value(table_name) # Never return defaults at table level - they belong to columns nil end |
#table_options(table_name) ⇒ Hash
Returns table options for schema dumping
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 613 def (table_name) = {} # Check if primary key has sequence default pk_name = primary_key(table_name) pk_column = pk_name ? columns(table_name).find { |c| c.name == pk_name } : nil has_sequence_default = pk_column&.default_function&.include?('nextval(') pk_type = primary_key_type_for_schema_dump(table_name) if has_sequence_default # Force explicit primary key inclusion when sequence is involved # This prevents Rails from putting sequence default at table level [:id] = pk_type || :bigint elsif pk_type && pk_type != :bigint # Set the correct primary key type only when different from default [:id] = pk_type # Rails 5+ default is bigint end # NEVER include defaults at table level - sequence defaults belong to columns end |
#use_insert_returning? ⇒ Boolean
Indicates whether the adapter supports INSERT...RETURNING syntax DuckLake does NOT support INSERT...RETURNING, so we check for DuckLake mode
260 261 262 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 260 def use_insert_returning? !ducklake? end |
#valid_type?(type) ⇒ Boolean
Check if a type is valid for schema dumping
638 639 640 641 642 643 644 645 646 647 648 |
# File 'lib/active_record/connection_adapters/duckdb_adapter.rb', line 638 def valid_type?(type) case type.to_s.to_sym when :string, :text, :integer, :bigint, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean, :uuid, :interval, :bit, :hugeint, :tinyint, :smallint, :utinyint, :usmallint, :uinteger, :ubigint, :uhugeint, :varint, :blob, :list, :struct, :map, :enum, :union, :real, :double, :numeric true else false end end |