View | Details | Raw Unified | Return to bug 248979
Collapse All | Expand All

(-)lib/Horde/Db/Adapter/Postgresql/Schema.php (-36 / +51 lines)
Lines 3-14 Link Here
3
 * Copyright 2007 Maintainable Software, LLC
3
 * Copyright 2007 Maintainable Software, LLC
4
 * Copyright 2008-2017 Horde LLC (http://www.horde.org/)
4
 * Copyright 2008-2017 Horde LLC (http://www.horde.org/)
5
 *
5
 *
6
 * See the enclosed file LICENSE for license information (BSD). If you
7
 * did not receive this file, see http://www.horde.org/licenses/bsd.
8
 *
6
 * @author     Mike Naberezny <mike@maintainable.com>
9
 * @author     Mike Naberezny <mike@maintainable.com>
7
 * @author     Derek DeVries <derek@maintainable.com>
10
 * @author     Derek DeVries <derek@maintainable.com>
8
 * @author     Chuck Hagenbuch <chuck@horde.org>
11
 * @author     Chuck Hagenbuch <chuck@horde.org>
9
 * @author     Jan Schneider <jan@horde.org>
12
 * @author     Jan Schneider <jan@horde.org>
10
 * @license    http://www.horde.org/licenses/bsd
11
 * @category   Horde
13
 * @category   Horde
14
 * @license    http://www.horde.org/licenses/bsd
12
 * @package    Db
15
 * @package    Db
13
 * @subpackage Adapter
16
 * @subpackage Adapter
14
 */
17
 */
Lines 21-28 Link Here
21
 * @author     Derek DeVries <derek@maintainable.com>
24
 * @author     Derek DeVries <derek@maintainable.com>
22
 * @author     Chuck Hagenbuch <chuck@horde.org>
25
 * @author     Chuck Hagenbuch <chuck@horde.org>
23
 * @author     Jan Schneider <jan@horde.org>
26
 * @author     Jan Schneider <jan@horde.org>
24
 * @license    http://www.horde.org/licenses/bsd
25
 * @category   Horde
27
 * @category   Horde
28
 * @copyright  2007 Maintainable Software, LLC
29
 * @copyright  2008-2017 Horde LLC
30
 * @license    http://www.horde.org/licenses/bsd
26
 * @package    Db
31
 * @package    Db
27
 * @subpackage Adapter
32
 * @subpackage Adapter
28
 */
33
 */
Lines 383-394 Link Here
383
    {
388
    {
384
        /* @todo See if we can get this from information_schema instead */
389
        /* @todo See if we can get this from information_schema instead */
385
        return $this->selectAll('
390
        return $this->selectAll('
386
            SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
391
          SELECT a.attname, format_type(a.atttypid, a.atttypmod),
387
              FROM pg_attribute a LEFT JOIN pg_attrdef d
392
            pg_get_expr(d.adbin, d.adrelid) AS adsrc, a.attnotnull
388
                ON a.attrelid = d.adrelid AND a.attnum = d.adnum
393
          FROM pg_attribute a
389
             WHERE a.attrelid = ' . $this->quote($tableName) . '::regclass
394
          LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
390
               AND a.attnum > 0 AND NOT a.attisdropped
395
          WHERE a.attrelid = ' . $this->quote($tableName) . '::regclass
391
             ORDER BY a.attnum', $name);
396
            AND a.attnum > 0 AND NOT a.attisdropped
397
          ORDER BY a.attnum;', $name);
392
    }
398
    }
393
399
394
    /**
400
    /**
Lines 1057-1069 Link Here
1057
                $quotedSequence = $this->quoteSequenceName($sequence);
1063
                $quotedSequence = $this->quoteSequenceName($sequence);
1058
                $quotedTable = $this->quoteTableName($table);
1064
                $quotedTable = $this->quoteTableName($table);
1059
                $quotedPk = $this->quoteColumnName($pk);
1065
                $quotedPk = $this->quoteColumnName($pk);
1060
1066
                if ($this->postgresqlVersion() >= 100000) {
1061
                $sql = sprintf('SELECT setval(%s, (SELECT COALESCE(MAX(%s) + (SELECT increment_by FROM %s), (SELECT min_value FROM %s)) FROM %s), false)',
1067
                    $sql = sprintf('
1062
                               $quotedSequence,
1068
                        SELECT setval(
1063
                               $quotedPk,
1069
                            %s,
1064
                               $sequence,
1070
                            (SELECT COALESCE(
1065
                               $sequence,
1071
                                MAX(%s) + (SELECT increment_by FROM pg_sequences WHERE schemaname=ANY(CURRENT_SCHEMAS(false)) AND sequencename=%s),
1066
                               $quotedTable);
1072
                                (SELECT min_value FROM pg_sequences WHERE schemaname=ANY(CURRENT_SCHEMAS(false)) AND sequencename=%s)
1073
                             ) FROM %s),
1074
                             false
1075
                         )',
1076
                         $quotedSequence,
1077
                         $quotedPk,
1078
                         $quotedSequence,
1079
                         $quotedSequence,
1080
                         $quotedTable
1081
                    );
1082
                } else {
1083
                    $sql = sprintf(
1084
                        'SELECT setval(%s, (SELECT COALESCE(MAX(%s) + (SELECT increment_by FROM %s), (SELECT min_value FROM %s)) FROM %s), false)',
1085
                        $quotedSequence,
1086
                        $quotedPk,
1087
                        $sequence,
1088
                        $sequence,
1089
                        $quotedTable
1090
                    );
1091
                }
1067
                $this->selectValue($sql, 'Reset sequence');
1092
                $this->selectValue($sql, 'Reset sequence');
1068
            } else {
1093
            } else {
1069
                if ($this->_logger) {
1094
                if ($this->_logger) {
Lines 1103-1130 Link Here
1103
        $result = $this->selectOne($sql, 'PK and serial sequence');
1128
        $result = $this->selectOne($sql, 'PK and serial sequence');
1104
1129
1105
        if (!$result) {
1130
        if (!$result) {
1106
            // If that fails, try parsing the primary key's default value.
1107
            // Support the 7.x and 8.0 nextval('foo'::text) as well as
1108
            // the 8.1+ nextval('foo'::regclass).
1109
            $sql = "
1131
            $sql = "
1110
            SELECT attr.attname,
1132
              SELECT c.column_name, c.ordinal_position,
1111
              CASE
1133
                  pg_get_serial_sequence(t.table_name, c.column_name) as relname
1112
                WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
1134
              FROM information_schema.key_column_usage AS c
1113
                  substr(split_part(def.adsrc, '''', 2),
1135
              LEFT JOIN information_schema.table_constraints AS t
1114
                         strpos(split_part(def.adsrc, '''', 2), '.')+1)
1136
                ON t.constraint_name = c.constraint_name
1115
                ELSE split_part(def.adsrc, '''', 2)
1137
              WHERE t.table_name = '$table' AND t.constraint_type = 'PRIMARY KEY';";
1116
              END AS relname
1117
            FROM pg_class       t
1118
            JOIN pg_attribute   attr ON (t.oid = attrelid)
1119
            JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)
1120
            JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])
1121
            WHERE t.oid = '$table'::regclass
1122
              AND cons.contype = 'p'
1123
              AND def.adsrc ~* 'nextval'";
1124
1125
            $result = $this->selectOne($sql, 'PK and custom sequence');
1138
            $result = $this->selectOne($sql, 'PK and custom sequence');
1126
        }
1139
        }
1127
1140
1141
        if (!$result) {
1142
            return array(null, null);
1143
        }
1144
1128
        // [primary_key, sequence]
1145
        // [primary_key, sequence]
1129
        return array($result['attname'], $result['relname']);
1146
        return array($result['attname'], $result['relname']);
1130
    }
1147
    }
Lines 1138-1146 Link Here
1138
    {
1155
    {
1139
        if (!$this->_version) {
1156
        if (!$this->_version) {
1140
            try {
1157
            try {
1141
                $version = $this->selectValue('SELECT version()');
1158
                $this->_version = $this->selectValue('SHOW server_version_num');
1142
                if (preg_match('/PostgreSQL (\d+)\.(\d+)\.(\d+)/', $version, $matches))
1143
                    $this->_version = ($matches[1] * 10000) + ($matches[2] * 100) + $matches[3];
1144
            } catch (Exception $e) {
1159
            } catch (Exception $e) {
1145
                return 0;
1160
                return 0;
1146
            }
1161
            }

Return to bug 248979