14 if (!defined(
'ADODB_DIR'))
die();
31 $len = $fieldobj->max_length;
33 $is_serial = is_object($fieldobj) && !empty($fieldobj->primary_key) && !empty($fieldobj->unique) &&
34 !empty($fieldobj->has_default) && substr($fieldobj->default_value,0,8) ==
'nextval(';
36 switch (strtoupper($t)) {
43 if ($len <= $this->blobSize)
return 'C';
68 case 'INTEGER':
return !$is_serial ?
'I' :
'R';
70 case 'INT2':
return !$is_serial ?
'I2' :
'R';
71 case 'INT4':
return !$is_serial ?
'I4' :
'R';
73 case 'INT8':
return !$is_serial ?
'I8' :
'R';
81 case 'DOUBLE PRECISION':
93 case 'C':
return 'VARCHAR';
95 case 'X':
return 'TEXT';
97 case 'C2':
return 'VARCHAR';
98 case 'X2':
return 'TEXT';
100 case 'B':
return 'BYTEA';
102 case 'D':
return 'DATE';
104 case 'T':
return 'TIMESTAMP';
106 case 'L':
return 'BOOLEAN';
107 case 'I':
return 'INTEGER';
108 case 'I1':
return 'SMALLINT';
109 case 'I2':
return 'INT2';
110 case 'I4':
return 'INT4';
111 case 'I8':
return 'INT8';
113 case 'F':
return 'FLOAT8';
114 case 'N':
return 'NUMERIC';
134 list($lines,$pkey) = $this->
_GenFields($flds);
135 $alter =
'ALTER TABLE ' . $tabname . $this->addCol .
' ';
136 foreach($lines as $v) {
137 if (($not_null = preg_match(
'/NOT NULL/i',$v))) {
138 $v = preg_replace(
'/NOT NULL/i',
'',$v);
140 if (preg_match(
'/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
141 list(,$colname,$default) = $matches;
142 $sql[] = $alter . str_replace(
'DEFAULT '.$default,
'',$v);
143 $sql[] =
'UPDATE '.$tabname.
' SET '.$colname.
'='.$default;
144 $sql[] =
'ALTER TABLE '.$tabname.
' ALTER COLUMN '.$colname.
' SET DEFAULT ' . $default;
146 $sql[] = $alter . $v;
149 list($colname) = explode(
' ',$v);
150 $sql[] =
'ALTER TABLE '.$tabname.
' ALTER COLUMN '.$colname.
' SET NOT NULL';
159 return array(sprintf($this->dropIndex, $this->
TableName($idxname), $this->
TableName($tabname)));
186 $has_alter_column = 8.0 <= (float) @$this->serverInfo[
'version'];
188 if ($has_alter_column) {
191 list($lines,$pkey) = $this->
_GenFields($flds);
193 $alter =
'ALTER TABLE ' . $tabname . $this->alterCol .
' ';
194 foreach($lines as $v) {
195 if ($not_null = preg_match(
'/NOT NULL/i',$v)) {
196 $v = preg_replace(
'/NOT NULL/i',
'',$v);
200 else if ($set_null = preg_match(
'/NULL/i',$v)) {
205 $v = preg_replace(
'/(?<!DEFAULT)\sNULL/i',
'',$v);
208 if (preg_match(
'/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
210 list(,$colname,$default) = $matches;
212 if ($this->connection) {
213 $old_coltype = $this->connection->MetaType($existing[strtoupper($colname)]);
218 $v = preg_replace(
'/^' . preg_quote($colname) .
'\s/',
'', $v);
219 $t = trim(str_replace(
'DEFAULT '.$default,
'',$v));
222 if ( $old_coltype ==
'L' && $t ==
'INTEGER' ) {
223 $sql[] = $alter .
' DROP DEFAULT';
224 $sql[] = $alter .
" TYPE $t USING ($colname::BOOL)::INT";
225 $sql[] = $alter .
" SET DEFAULT $default";
228 else if ( $old_coltype ==
'I' && $t ==
'BOOLEAN' ) {
229 if( strcasecmp(
'NULL', trim($default)) != 0 ) {
230 $default = $this->connection->qstr($default);
232 $sql[] = $alter .
' DROP DEFAULT';
233 $sql[] = $alter .
" TYPE $t USING CASE WHEN $colname = 0 THEN false ELSE true END";
234 $sql[] = $alter .
" SET DEFAULT $default";
238 $sql[] = $alter .
" TYPE $t";
239 $sql[] = $alter .
" SET DEFAULT $default";
245 preg_match (
'/^\s*(\S+)\s+(.*)$/',$v,$matches);
246 list (,$colname,$rest) = $matches;
248 $sql[] = $alter .
' TYPE ' . $rest;
251 # list($colname) = explode(' ',$v); 254 $sql[] = $alter .
' SET NOT NULL';
258 $sql[] = $alter .
' DROP NOT NULL';
266 if ($this->
debug) ADOConnection::outp(
"AlterColumnSQL needs a complete table-definiton for PostgreSQL");
285 $has_drop_column = 7.3 <= (float) @$this->serverInfo[
'version'];
286 if (!$has_drop_column && !$tableflds) {
287 if ($this->
debug) ADOConnection::outp(
"DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3");
290 if ($has_drop_column) {
310 if ($dropflds && !is_array($dropflds)) $dropflds = explode(
',',$dropflds);
313 if (!$dropflds || !in_array($fld->name,$dropflds)) {
315 if (preg_match(
'/'.$fld->name.
' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
316 in_array($fld->type,array(
'varchar',
'char',
'text',
'bytea'))) {
317 $copyflds[] =
"to_number($fld->name,'S9999999999999D99')";
319 $copyflds[] = $fld->name;
322 if ($fld->primary_key && $fld->has_default &&
323 preg_match(
"/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) {
324 $seq_name = $matches[1];
325 $seq_fld = $fld->name;
329 $copyflds = implode(
', ',$copyflds);
331 $tempname = $tabname.
'_tmp';
333 $aSql[] =
"SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname";
334 $aSql = array_merge($aSql,$this->
DropTableSQL($tabname));
335 $aSql = array_merge($aSql,$this->
CreateTableSQL($tabname,$tableflds,$tableoptions));
336 $aSql[] =
"INSERT INTO $tabname SELECT $copyflds FROM $tempname";
337 if ($seq_name && $seq_fld) {
338 $seq_name = $tabname.
'_'.$seq_fld.
'_seq';
339 $aSql[] =
"SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname";
341 $aSql[] =
"DROP TABLE $tempname";
343 foreach($this->
MetaIndexes($tabname) as $idx_name => $idx_data)
345 if (substr($idx_name,-5) !=
'_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data[
'columns'])))) {
346 $aSql = array_merge($aSql,$this->
CreateIndexSQL($idx_name,$tabname,$idx_data[
'columns'],
347 $idx_data[
'unique'] ? array(
'UNIQUE') : False));
359 if ($drop_seq)
$sql[] = $drop_seq;
365 function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
372 if (strlen($fdefault)) $suffix .=
" DEFAULT $fdefault";
373 if ($fnotnull) $suffix .=
' NOT NULL';
374 if ($fconstraint) $suffix .=
' '.$fconstraint;
383 $tabname = $this->connection->quote(
'%'.$tabname.
'%');
385 $seq = $this->connection->GetOne(
"SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
388 if (!$seq || $this->connection->GetOne(
"SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) {
391 return "DROP SEQUENCE ".$seq;
396 if (!empty($this->schema)) {
397 $rename_from = $this->
TableName($tabname);
399 $this->schema =
false;
401 $this->schema = $schema_save;
402 return array (sprintf($this->renameTable, $rename_from, $rename_to));
405 return array (sprintf($this->renameTable, $this->
TableName($tabname),$this->
TableName($newname)));
441 function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
445 if ( isset($idxoptions[
'REPLACE']) || isset($idxoptions[
'DROP']) ) {
446 $sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
447 if ( isset($idxoptions[
'DROP']) )
451 if ( empty ($flds) ) {
455 $unique = isset($idxoptions[
'UNIQUE']) ?
' UNIQUE' :
'';
457 $s =
'CREATE' . $unique .
' INDEX ' . $idxname .
' ON ' . $tabname .
' ';
459 if (isset($idxoptions[
'HASH']))
462 if ( isset($idxoptions[$this->upperName]) )
463 $s .= $idxoptions[$this->upperName];
465 if ( is_array($flds) )
466 $flds = implode(
', ',$flds);
467 $s .=
'(' . $flds .
')';
475 if (strlen($fsize) && $ty !=
'X' && $ty !=
'B' && $ty !=
'I' && strpos($ftype,
'(') ===
false) {
476 $ftype .=
"(".$fsize;
477 if (strlen($fprec)) $ftype .=
",".$fprec;
_GenFields($flds, $widespacing=false)
MetaColumns($tab, $upper=true, $schema=false)
DropIndexSQL($idxname, $tabname=NULL)
MetaIndexes($table, $primary=false, $owner=false)
MetaType($t, $len=-1, $fieldobj=false)
CreateIndexSQL($idxname, $tabname, $flds, $idxoptions=false)
DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
_DropAutoIncrement($tabname)
_recreate_copy_table($tabname, $dropflds, $tableflds, $tableoptions='')
AddColumnSQL($tabname, $flds)
_GetSize($ftype, $ty, $fsize, $fprec)
AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
CreateTableSQL($tabname, $flds, $tableoptions=array())
RenameTableSQL($tabname, $newname)
_IndexSQL($idxname, $tabname, $flds, $idxoptions)
debug($variable='', $name=' *variable *', $line=' *line *', $file=' *file *', $recursiveDepth=3, $debugLevel=E_DEBUG)
_CreateSuffix($fname, &$ftype, $fnotnull, $fdefault, $fautoinc, $fconstraint, $funsigned)