ruby-on-railspostgresqlvirtual-column

Rails PostgreSQL check if column is virtual


PostgreSQL 12 has a cool Generated Columns feature but I can't check whether column is virtual or not in Rails.

For reference, MySQL Adapter in Rails allows you to do like

MyModel.supports_virtual_columns?
=> true
MyModel.columns.last.virtual?
=> false

But in PostgreSQL Adapter you can't do the same despite it does support Generated fields?

Rails v.5.1.7


Solution

  • The fact that PostgreSQL 12 implements generated columns doesn't mean that you're going to have the interface through the Rails PostgreSQLAdapter to check whether a column is virtual or not because it's not implemented (yet).

    If you see in the ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter the code for supports_virtual_columns? is pretty simple:

    def supports_virtual_columns?
      mariadb? || database_version >= "5.7.5"
    end
    

    While the code to check if a column is virtual or not is stated as:

    def virtual?
      /\b(?:VIRTUAL|STORED|PERSISTENT)\b/.match?(extra)
    end
    

    Which checks if the Extra value returned from a

    SHOW FULL FIELDS FROM table_name;
    

    query for that column matches with VIRTUAL, STORED or PERSISTENT, if so, it returns true.

    But this doesn't exist in the PostgreSQL counterpart. supports_virtual_columns? will return false in any adapter where this feature isn't developed, as it's defined in the ActiveRecord::ConnectionAdapters::AbstractAdapter to return false:

    # Does this adapter support virtual columns?
    def supports_virtual_columns?
      false
    end