View source
<?php
function schema_pgsql_engine_type_map() {
$map = array(
'varchar:normal' => 'varchar',
'char:normal' => 'character',
'text:tiny' => 'text',
'text:small' => 'text',
'text:medium' => 'text',
'text:big' => 'text',
'text:normal' => 'text',
'int:tiny' => 'smallint',
'int:small' => 'smallint',
'int:medium' => 'int',
'int:big' => 'bigint',
'int:normal' => 'int',
'float:tiny' => 'real',
'float:small' => 'real',
'float:medium' => 'real',
'float:big' => 'double precision',
'float:normal' => 'real',
'numeric:normal' => 'numeric',
'blob:big' => 'bytea',
'blob:normal' => 'bytea',
'datetime:normal' => 'timestamp',
'serial:tiny' => 'serial',
'serial:small' => 'serial',
'serial:medium' => 'serial',
'serial:big' => 'bigserial',
'serial:normal' => 'serial',
);
return $map;
}
function schema_pgsql_schema_type_map() {
static $map;
if (!isset($map)) {
$map = array_flip(db_type_map());
$map['character varying'] = 'varchar:normal';
$map['integer'] = 'int:normal';
}
return $map;
}
function schema_pgsql_inspect($tbl_name = NULL) {
global $db_url;
$schema = drupal_get_schema(NULL, TRUE);
$tables = array();
$url = parse_url(is_array($db_url) ? $db_url['default'] : $db_url);
$database = substr($url['path'], 1);
$sql = 'SELECT * FROM information_schema.COLUMNS ' . 'WHERE table_catalog=\'%s\' AND table_schema=\'public\'';
if (isset($tbl_name)) {
$sql .= 'AND table_name = \'%s\' ';
}
$sql .= 'ORDER BY table_name, ordinal_position';
$res = db_query($sql, $database, $tbl_name);
while ($r = db_fetch_array($res)) {
$col = array();
$r['table_name'] = schema_unprefix_table($r['table_name']);
if (!isset($schema[$r['table_name']])) {
continue;
}
$numeric = !is_null($r['numeric_scale']);
list($col['type'], $col['size']) = schema_schema_type($r['data_type'], $r['table_name'], $r['column_name'], 'pgsql');
if (!$numeric && $r['character_maximum_length']) {
$col['length'] = $r['character_maximum_length'];
}
$col['not null'] = $r['is_nullable'] == 'YES' ? FALSE : TRUE;
if (!is_null($r['column_default'])) {
if (strpos($r['column_default'], '::') !== FALSE) {
list($col['default'], $def_type) = explode('::', $r['column_default']);
}
else {
$col['default'] = $r['column_default'];
$def_type = '';
}
if ($numeric) {
if (strpos($col['default'], 'nextval(\'') !== FALSE && $def_type == 'regclass)') {
$col['type'] = 'serial';
unset($col['default']);
}
else {
if ($col['type'] == 'float') {
$col['default'] = floatval($col['default']);
}
else {
$col['default'] = intval($col['default']);
}
}
}
else {
$col['default'] = substr($col['default'], 1, -1);
}
}
switch ($r['domain_name']) {
case 'int_unsigned':
case 'smallint_unsigned':
case 'bigint_unsigned':
$col['unsigned'] = 1;
break;
}
if (isset($r['check_clause']) && $r['check_clause'] == '((' . $r['column_name'] . ' => 0))') {
$col['unsigned'] = 1;
}
$tables[$r['table_name']]['fields'][$r['column_name']] = $col;
$tables[$r['table_name']]['name'] = $r['table_name'];
}
$res = db_query('SELECT ccu.*, cc.check_clause ' . 'FROM information_schema.constraint_column_usage ccu ' . 'INNER JOIN information_schema.check_constraints cc ' . ' ON ccu.constraint_name=cc.constraint_name ' . 'WHERE table_schema=\'public\'');
while ($r = db_fetch_array($res)) {
$r['table_name'] = schema_unprefix_table($r['table_name']);
if (!isset($schema[$r['table_name']])) {
continue;
}
if ($r['check_clause'] == '((' . $r['column_name'] . ' >= 0))') {
$tables[$r['table_name']]['fields'][$r['column_name']]['unsigned'] = TRUE;
}
}
$res = db_query('SELECT n.nspname, c.relname AS tblname, ' . ' c2.relname AS indname, i.indisprimary, i.indisunique, ' . ' pg_get_indexdef(i.indexrelid) AS inddef ' . 'FROM pg_class c, pg_class c2, pg_index i, pg_namespace n ' . 'WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid AND ' . ' c.relnamespace=n.oid AND n.nspname=\'public\' ' . 'ORDER BY c2.relname');
while ($r = db_fetch_array($res)) {
$r['tblname'] = schema_unprefix_table($r['tblname']);
$r['indname'] = schema_unprefix_table($r['indname']);
if (!isset($schema[$r['tblname']])) {
continue;
}
if (preg_match('@CREATE(?: UNIQUE)? INDEX \\w+ ON "?(\\w+)"?(?: USING \\w+)? \\((.*)\\)@', $r['inddef'], $m)) {
list($all, $table, $keys) = $m;
$name = $r['indname'];
if (preg_match('@^' . $r['tblname'] . '_(.*)_(?:idx|key)$@', $name, $m)) {
$name = $m[1];
}
preg_match_all('@((?:"?\\w+"?)|(?:substr\\(\\(?"?(\\w+)\\"?.*?, 1, (\\d+)\\)))(?:, |$)@', $keys, $m);
foreach ($m[1] as $idx => $colname) {
if ($m[2][$idx]) {
$key = array(
$m[2][$idx],
intval($m[3][$idx]),
);
}
else {
$key = str_replace('"', '', $colname);
}
if ($r['indisprimary'] == 't') {
$tables[$r['tblname']]['primary key'][] = $key;
}
else {
if ($r['indisunique'] == 't') {
$tables[$r['tblname']]['unique keys'][$name][] = $key;
}
else {
$tables[$r['tblname']]['indexes'][$name][] = $key;
}
}
}
}
else {
watchdog('schema', 'unrecognized pgsql index definition: @stmt', array(
'@stmt' => $r['inddef'],
));
}
}
return $tables;
}