fix for bug #488: Postgres errors when upgrading to 1.4 beta

This commit is contained in:
Ralf Becker 2007-05-12 16:58:47 +00:00
parent 32864e955a
commit 7f64e2d175
3 changed files with 68 additions and 26 deletions

View File

@ -210,18 +210,21 @@ class ADODB2_postgres extends ADODB_DataDict {
{ {
if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds); if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds);
$copyflds = array(); $copyflds = array();
foreach($this->MetaColumns($tabname) as $fld) { foreach(($meta=$this->MetaColumns($tabname)) as $fld) {
if (!$dropflds || !in_array($fld->name,$dropflds)) { if (!$dropflds || !in_array($fld->name,$dropflds)) {
// we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one // we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one
if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) && if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
in_array($fld->type,array('varchar','char','text','bytea'))) { in_array($fld->type,array('varchar','char','text','bytea'))) {
$copyflds[] = "to_number($fld->name,'S9999999999999D99')"; $copyflds[] = "to_number($fld->name,'S9999999999999D99')";
} elseif (preg_match('/'.$fld->name.' ([\w]+)/i',$tableflds,$matches) &&
strtoupper($fld->type) != ($type = $this->ActualType($matches[1]))) {
$copyflds[] = "CAST($fld->name AS $type)";
} else { } else {
$copyflds[] = $fld->name; $copyflds[] = $fld->name;
} }
// identify the sequence name and the fld its on // identify the sequence name and the fld its on
if ($fld->primary_key && $fld->has_default && if ($fld->primary_key && $fld->has_default &&
preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) { preg_match("/nextval\('([^']+)'::(text|regclass)\)/",$fld->default_value,$matches)) {
$seq_name = $matches[1]; $seq_name = $matches[1];
$seq_fld = $fld->name; $seq_fld = $fld->name;
} }

View File

@ -165,7 +165,7 @@ a different OID if a database must be reloaded. */
$cols = $this->MetaColumns($table); $cols = $this->MetaColumns($table);
$fld = $cols[strtoupper($column)]; $fld = $cols[strtoupper($column)];
if ($fld->primary_key && $fld->has_default && if ($fld->primary_key && $fld->has_default &&
preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) { preg_match("/nextval\('([^']+)'::(text|regclass)\)/",$fld->default_value,$matches)) {
$ret = $this->GetOne($sql='SELECT currval('.$this->qstr($matches[1]).')'); $ret = $this->GetOne($sql='SELECT currval('.$this->qstr($matches[1]).')');
} }
} }

View File

@ -32,46 +32,66 @@
*/ */
var $m_oTranslator; var $m_oTranslator;
/** /**
* @var egw_db-object $m_odb db-object * egw_db-object
*
* @var egw_db
*/ */
var $m_odb; var $m_odb;
/** /**
* @var adodb-object $adodb reference to the global ADOdb object * reference to the global ADOdb object
*
* @var ADOConnection
*/ */
var $adodb; var $adodb;
/** /**
* @var datadictionary-object $dict adodb's datadictionary object for the used db-type * adodb's datadictionary object for the used db-type
*
* @var ADODB_DataDict
*/ */
var $dict; var $dict;
/** /**
* @var $debug=0 0=Off, 1=some, eg. primary function calls, 2=lots incl. the SQL used * Debuglevel: 0=Off, 1=some, eg. primary function calls, 2=lots incl. the SQL used
*
* @var int
*/ */
var $debug = 0; var $debug = 0;
/** /**
* @var array $max_index_length db => max. length of indexes pairs (if there is a considerable low limit for a db) * Arry with db => max. length of indexes pairs (if there is a considerable low limit for a db)
*
* @var array
*/ */
var $max_index_length=array( var $max_index_length=array(
'sapdb' => 32, 'sapdb' => 32,
'oracle' => 30, 'oracle' => 30,
); );
/** /**
* @var string $sType type of the database, set by the the constructor * type of the database, set by the the constructor: 'mysql','pgsql','mssql','sapdb'
*
* @var string
*/ */
var $sType; var $sType;
/** /**
* @var int $max_varchar_length maximum length of a varchar column, everything above get converted to text * maximum length of a varchar column, everything above get converted to text
*
* @var int
*/ */
var $max_varchar_length = 255; var $max_varchar_length = 255;
/** /**
* @var string $system_charset system-charset if set * system-charset if set
*
* @var string
*/ */
var $system_charset; var $system_charset;
/** /**
* @var array $capabilities reference to the array of the db-class * reference to the capabilities array of the db-class
*
* @var array
*/ */
var $capabilities; var $capabilities;
/** /**
* @var int $pgsql_old_seq preserve value of old sequences in PostgreSQL * preserve value of old sequences in PostgreSQL
*
* @var int
*/ */
var $pgsql_old_seq; var $pgsql_old_seq;
@ -80,6 +100,7 @@
* *
* @param string $dbms type of the database: 'mysql','pgsql','mssql','sapdb' * @param string $dbms type of the database: 'mysql','pgsql','mssql','sapdb'
* @param object $db=null database class, if null we use $GLOBALS['egw']->db * @param object $db=null database class, if null we use $GLOBALS['egw']->db
* @return schema_proc
*/ */
function schema_proc($dbms=False,$db=null) function schema_proc($dbms=False,$db=null)
{ {
@ -501,7 +522,7 @@
if (!is_array($options)) $options = $options ? array($options) : array(); if (!is_array($options)) $options = $options ? array($options) : array();
if ($bUnique) $options[] = 'UNIQUE'; if ($bUnique) $options[] = 'UNIQUE';
$aSql = $this->dict->CreateIndexSQL($name,$sTableName,$aColumnNames,$options); $aSql = $this->dict->CreateIndexSQL($sIdxName,$sTableName,$aColumnNames,$options);
return $this->ExecuteSQLArray($aSql,2,'CreateIndexSQL(%1,%2,%3,%4) sql=%5',False,$name,$sTableName,$aColumnNames,$options,$aSql); return $this->ExecuteSQLArray($aSql,2,'CreateIndexSQL(%1,%2,%3,%4) sql=%5',False,$name,$sTableName,$aColumnNames,$options,$aSql);
} }
@ -518,6 +539,7 @@
if (is_array($aColumnNames)) if (is_array($aColumnNames))
{ {
$indexes = $this->dict->MetaIndexes($sTableName); $indexes = $this->dict->MetaIndexes($sTableName);
if ($indexes === False) if ($indexes === False)
{ {
// if MetaIndexes is not availible for the DB, we try the name the index was created with // if MetaIndexes is not availible for the DB, we try the name the index was created with
@ -605,13 +627,26 @@
elseif (isset($old_table_def['fd'][$name])) // existing column, use its value => column-name in query elseif (isset($old_table_def['fd'][$name])) // existing column, use its value => column-name in query
{ {
$value = $name; $value = $name;
if ($this->sType == 'pgsql') // some postgres specific code
{
// this is eg. necessary to change a varchar into an int column under postgres // this is eg. necessary to change a varchar into an int column under postgres
if ($this->sType == 'pgsql' && if (in_array($old_table_def['fd'][$name]['type'],array('char','varchar','text','blob')) &&
in_array($old_table_def['fd'][$name]['type'],array('char','varchar','text','blob')) &&
in_array($data['type'],array('int','decimal'))) in_array($data['type'],array('int','decimal')))
{ {
$value = "to_number($name,'S9999999999999D99')"; $value = "to_number($name,'S9999999999999D99')";
} }
// blobs cant be casted to text
elseif($old_table_def['fd'][$name]['type'] == 'blob' && $data['type'] == 'text')
{
$value = "ENCODE($value,'escape')";
}
// cast everything which is a different type
elseif($old_table_def['fd'][$name]['type'] != $data['type'] && ($type_translated = $this->TranslateType($data['type'])))
{
$value = "CAST($value AS $type_translated)";
}
}
} }
else // new column => use default value or NULL else // new column => use default value or NULL
{ {
@ -622,6 +657,7 @@
else else
{ {
$value = $this->m_odb->quote(isset($data['default']) ? $data['default'] : '',$data['type']); $value = $this->m_odb->quote(isset($data['default']) ? $data['default'] : '',$data['type']);
}
if ($this->sType == 'pgsql') if ($this->sType == 'pgsql')
{ {
// fix for postgres error "no '<' operator for type 'unknown'" // fix for postgres error "no '<' operator for type 'unknown'"
@ -631,7 +667,6 @@
} }
} }
} }
}
$blob_column_included = $blob_column_included || in_array($data['type'],array('blob','text','longtext')); $blob_column_included = $blob_column_included || in_array($data['type'],array('blob','text','longtext'));
$auto_column_included = $auto_column_included || $data['type'] == 'auto'; $auto_column_included = $auto_column_included || $data['type'] == 'auto';
$select[] = $value; $select[] = $value;
@ -1188,6 +1223,10 @@
} }
if ($column->has_default) if ($column->has_default)
{ {
if (preg_match("/^'(.*)'::.*$/",$column->default_value,$matches)) // postgres
{
$column->default_value = $matches[1];
}
$definition['fd'][$name]['default'] = $column->default_value; $definition['fd'][$name]['default'] = $column->default_value;
} }
if ($column->not_null) if ($column->not_null)