lib/sequel/adapters/shared/mysql.rb in sequel-5.8.0 vs lib/sequel/adapters/shared/mysql.rb in sequel-5.9.0

- old
+ new

@@ -17,11 +17,11 @@ module DatabaseMethods include UnmodifiedIdentifiers::DatabaseMethods include Sequel::Database::SplitAlterTable CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}.freeze - COLUMN_DEFINITION_ORDER = [:collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze + COLUMN_DEFINITION_ORDER = [:generated, :collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze # Set the default charset used for CREATE TABLE. You can pass the # :charset option to create_table to override this setting. attr_accessor :default_charset @@ -135,10 +135,15 @@ # MySQL supports CREATE TABLE IF NOT EXISTS syntax. def supports_create_table_if_not_exists? true end + # Generated columns are supported in MariaDB 5.2.0+ and MySQL 5.7.6+. + def supports_generated_columns? + server_version >= (mariadb? ? 50200 : 50706) + end + # MySQL 5+ supports prepared transactions (two-phase commit) using XA def supports_prepared_transactions? server_version >= 50000 end @@ -329,10 +334,27 @@ else super end end + # Add generation clause SQL fragment to column creation SQL. + def column_definition_generated_sql(sql, column) + if (generated_expression = column[:generated_always_as]) + sql << " GENERATED ALWAYS AS (#{literal(generated_expression)})" + case (type = column[:generated_type]) + when nil + # none, database default + when :virtual + sql << " VIRTUAL" + when :stored + sql << (mariadb? ? " PERSISTENT" : " STORED") + else + raise Error, "unsupported :generated_type option: #{type.inspect}" + end + end + end + def column_definition_order COLUMN_DEFINITION_ORDER end # MySQL doesn't allow default values on text columns, so ignore if it the @@ -471,10 +493,14 @@ table = SQL::Identifier.new(im.call(table_name)) table = SQL::QualifiedIdentifier.new(im.call(opts[:schema]), table) if opts[:schema] metadata_dataset.with_sql("DESCRIBE ?", table).map do |row| extra = row.delete(:Extra) if row[:primary_key] = row.delete(:Key) == 'PRI' - row[:auto_increment] = !!(extra.to_s =~ /auto_increment/io) + row[:auto_increment] = !!(extra.to_s =~ /auto_increment/i) + end + if supports_generated_columns? + # Extra field contains VIRTUAL or PERSISTENT for generated columns + row[:generated] = !!(extra.to_s =~ /VIRTUAL|STORED|PERSISTENT/i) end row[:allow_null] = row.delete(:Null) == 'YES' row[:default] = row.delete(:Default) row[:db_type] = row.delete(:Type) row[:type] = schema_column_type(row[:db_type])