def column_metadata_to_column_info(col)
def column_metadata_to_column_info(col)
sql_type, type_name, precision, scale =
case col.data_type
when :char
[SQL_CHAR, col.charset_form == :nchar ? "NCHAR" : "CHAR", col.data_size, nil]
when :varchar2
[SQL_VARCHAR, col.charset_form == :nchar ? "NVARCHAR2" : "VARCHAR2", col.data_size, nil]
when :raw
[SQL_VARBINARY, "RAW", col.data_size, nil]
when :long
[SQL_LONGVARCHAR, "LONG", 4000, nil]
when :long_raw
[SQL_LONGVARBINARY, "LONG RAW", 4000, nil]
when :clob
[SQL_CLOB, col.charset_form == :nchar ? "NCLOB" : "CLOB", 4000, nil]
when :blob
[SQL_BLOB, "BLOB", 4000, nil]
when :bfile
[SQL_BLOB, "BFILE", 4000, nil]
when :number
if col.scale == -127 && col.precision != 0
# To convert from binary to decimal precision, multiply n by 0.30103.
[SQL_FLOAT, "FLOAT", (col.precision * 0.30103).ceil , nil]
elsif col.precision == 0
# NUMBER or calculated value (eg. col * 1.2).
[SQL_NUMERIC, "NUMBER", 38, nil]
else
[SQL_NUMERIC, "NUMBER", col.precision, col.scale]
end
when :binary_float
# (23 * 0.30103).ceil => 7
[SQL_FLOAT, "BINARY_FLOAT", 7, nil]
when :binary_double
# (52 * 0.30103).ceil => 16
[SQL_DOUBLE, "BINARY_DOUBLE", 16, nil]
when :date
# yyyy-mm-dd hh:mi:ss
[SQL_DATE, "DATE", 19, nil]
when :timestamp
# yyyy-mm-dd hh:mi:ss.SSSS
[SQL_TIMESTAMP, "TIMESTAMP", 20 + col.fsprecision, nil]
when :timestamp_tz
# yyyy-mm-dd hh:mi:ss.SSSS +HH:MM
[SQL_TIMESTAMP, "TIMESTAMP WITH TIME ZONE", 27 + col.fsprecision, nil]
when :timestamp_ltz
# yyyy-mm-dd hh:mi:ss.SSSS
[SQL_TIMESTAMP, "TIMESTAMP WITH LOCAL TIME ZONE", 20 + col.fsprecision, nil]
when :interval_ym
# yyyy-mm
[SQL_OTHER, 'INTERVAL YEAR TO MONTH', col.lfprecision + 3, nil]
when :interval_ds
# dd hh:mi:ss.SSSSS
[SQL_OTHER, 'INTERVAL DAY TO SECOND', col.lfprecision + 10 + col.fsprecision, nil]
else
[SQL_OTHER, col.data_type.to_s, nil, nil]
end
{'name' => col.name,
'sql_type' => sql_type,
'type_name' => type_name,
'nullable' => col.nullable?,
'precision' => precision,
'scale' => scale,
'dbi_type' => NoTypeConversion,
}
end