Module: ActiveRecord::ConnectionAdapters::Redshift::SchemaStatements

Included in:
ActiveRecord::ConnectionAdapters::RedshiftAdapter
Defined in:
lib/active_record/connection_adapters/redshift/schema_statements.rb

Instance Method Summary collapse

Instance Method Details

#columns(table_name) ⇒ Object

Returns the list of all column definitions for a table.



58
59
60
61
62
63
64
65
66
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 58

def columns(table_name)
  column_definitions(table_name.to_s).map do |column_name, type, default, notnull, oid, fmod, encoding|
    default_value = extract_value_from_default(default)
    type = determine_primary_key_type_conversion(type, default)
     = (column_name, type, oid, fmod, encoding)
    default_function = extract_default_function(default_value, default)
    new_column(column_name, default_value, , notnull == false, table_name, default_function)
  end
end

#create_database(name, options = {}) ⇒ Object

Create a new Redshift database. Options include :owner and :connection_limit Example:

create_database config[:database], config
create_database 'foo_development', encoding: 'unicode'


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 29

def create_database(name, options = {})
  options = { encoding: 'utf8' }.merge!(options.symbolize_keys)

  option_string = options.inject("") do |memo, (key, value)|
    memo += case key
            when :owner
              " OWNER = \"#{value}\""
            when :connection_limit
              " CONNECTION LIMIT = #{value}"
            else
              ''
            end
  end

  execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
end

#create_table(table_name, comment: nil, **options) ⇒ Object



46
47
48
49
50
51
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 46

def create_table(table_name, comment: nil, **options)
  options[:options] ||= ''
  options[:options] += "DISTKEY(#{options.delete(:distkey)}) " if options.key?(:distkey)
  options[:options] += "SORTKEY(#{options.delete(:sortkey)}) " if options.key?(:sortkey)
  super
end

#determine_primary_key_type_conversion(type, default) ⇒ Object



68
69
70
71
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 68

def determine_primary_key_type_conversion(type, default)
  return 'primary_key' if (type == 'integer' && default.to_s.starts_with?('"identity"'))
  type
end

#fetch_type_metadata(column_name, sql_type, oid, fmod, encoding) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 140

def (column_name, sql_type, oid, fmod, encoding)
  cast_type = get_oid_type(oid, fmod, column_name, sql_type)
  simple_type = SqlTypeMetadata.new(
    sql_type: sql_type,
    type: cast_type.type,
    limit: cast_type.limit,
    precision: cast_type.precision,
    scale: cast_type.scale,
  )
  RedshiftSQLTypeMetadata.new(simple_type, oid: oid, fmod: fmod, encoding: encoding)
end

#foreign_keys(table_name) ⇒ Object

TODO: This entire method block for ‘t2.oid::regclass::text’ to ‘t2.relname’



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 111

def foreign_keys(table_name)
  fk_info = select_all(<<-SQL.strip_heredoc, 'SCHEMA')
    SELECT t2.relname AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete
    FROM pg_constraint c
    JOIN pg_class t1 ON c.conrelid = t1.oid
    JOIN pg_class t2 ON c.confrelid = t2.oid
    JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
    JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
    JOIN pg_namespace t3 ON c.connamespace = t3.oid
    WHERE c.contype = 'f'
      AND t1.relname = #{quote(table_name)}
      AND t3.nspname = ANY (current_schemas(false))
    ORDER BY c.conname
  SQL

  fk_info.map do |row|
    options = {
      column: row['column'],
      name: row['name'],
      primary_key: row['primary_key']
    }

    options[:on_delete] = extract_foreign_key_action(row['on_delete'])
    options[:on_update] = extract_foreign_key_action(row['on_update'])

    ForeignKeyDefinition.new(table_name, row['to_table'], options)
  end
end

#indexesObject



53
54
55
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 53

def indexes(*)
  []
end

#new_column(name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil) ⇒ Object

:nodoc:



73
74
75
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 73

def new_column(name, default,  = nil, null = true, table_name = nil, default_function = nil) # :nodoc:
  RedshiftColumn.new(name, default, , null, table_name, default_function)
end

#primary_keys(table) ⇒ Object

Returns just a table’s primary key



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 98

def primary_keys(table)
  pks = query(<<-end_sql, 'SCHEMA')
    SELECT DISTINCT attr.attname
    FROM pg_attribute attr
    INNER JOIN pg_depend dep ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid
    INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = any(cons.conkey)
    WHERE cons.contype = 'p'
      AND dep.refobjid = '#{quote_table_name(table)}'::regclass
  end_sql
  pks.present? ? pks[0] : pks
end

#table_distkey(table_name) ⇒ Object

:nodoc:



88
89
90
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 88

def table_distkey(table_name) # :nodoc:
  select_value("SELECT \"column\" FROM pg_table_def WHERE tablename = #{quote(table_name)} AND distkey = true")
end

#table_options(table_name) ⇒ Object

:nodoc:



77
78
79
80
81
82
83
84
85
86
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 77

def table_options(table_name) # :nodoc:
  {}.tap do |options|
    if (distkey = table_distkey(table_name)).present?
      options[:distkey] = distkey
    end
    if (sortkey = table_sortkey(table_name)).present?
      options[:sortkey] = sortkey
    end
  end
end

#table_sortkey(table_name) ⇒ Object

:nodoc:



92
93
94
95
# File 'lib/active_record/connection_adapters/redshift/schema_statements.rb', line 92

def table_sortkey(table_name) # :nodoc:
  columns = select_values("SELECT \"column\" FROM pg_table_def WHERE tablename = #{quote(table_name)} AND sortkey > 0 ORDER BY sortkey ASC")
  columns.present? ? columns.join(', ') : nil
end