~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/backend/commands/tablecmds.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 *
9
9
 *
10
10
 * IDENTIFICATION
11
 
 *        $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.284 2009/05/12 03:11:01 tgl Exp $
 
11
 *        $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.288 2009/06/18 01:27:02 tgl Exp $
12
12
 *
13
13
 *-------------------------------------------------------------------------
14
14
 */
137
137
        List       *constraints;        /* List of NewConstraint */
138
138
        List       *newvals;            /* List of NewColumnValue */
139
139
        bool            new_notnull;    /* T if we added new NOT NULL constraints */
140
 
        bool            new_changeoids; /* T if we added/dropped the OID column */
 
140
        bool            new_changeoids; /* T if we added/dropped the OID column */
141
141
        Oid                     newTableSpace;  /* new tablespace; 0 means no change */
142
142
        /* Objects to rebuild after completing ALTER TYPE operations */
143
143
        List       *changedConstraintOids;      /* OIDs of constraints to rebuild */
187
187
 
188
188
static const struct dropmsgstrings dropmsgstringarray[] = {
189
189
        {RELKIND_RELATION,
190
 
         ERRCODE_UNDEFINED_TABLE,
191
 
         gettext_noop("table \"%s\" does not exist"),
192
 
         gettext_noop("table \"%s\" does not exist, skipping"),
193
 
         gettext_noop("\"%s\" is not a table"),
194
 
         gettext_noop("Use DROP TABLE to remove a table.")},
 
190
                ERRCODE_UNDEFINED_TABLE,
 
191
                gettext_noop("table \"%s\" does not exist"),
 
192
                gettext_noop("table \"%s\" does not exist, skipping"),
 
193
                gettext_noop("\"%s\" is not a table"),
 
194
        gettext_noop("Use DROP TABLE to remove a table.")},
195
195
        {RELKIND_SEQUENCE,
196
 
         ERRCODE_UNDEFINED_TABLE,
197
 
         gettext_noop("sequence \"%s\" does not exist"),
198
 
         gettext_noop("sequence \"%s\" does not exist, skipping"),
199
 
         gettext_noop("\"%s\" is not a sequence"),
200
 
         gettext_noop("Use DROP SEQUENCE to remove a sequence.")},
 
196
                ERRCODE_UNDEFINED_TABLE,
 
197
                gettext_noop("sequence \"%s\" does not exist"),
 
198
                gettext_noop("sequence \"%s\" does not exist, skipping"),
 
199
                gettext_noop("\"%s\" is not a sequence"),
 
200
        gettext_noop("Use DROP SEQUENCE to remove a sequence.")},
201
201
        {RELKIND_VIEW,
202
 
         ERRCODE_UNDEFINED_TABLE,
203
 
         gettext_noop("view \"%s\" does not exist"),
204
 
         gettext_noop("view \"%s\" does not exist, skipping"),
205
 
         gettext_noop("\"%s\" is not a view"),
206
 
         gettext_noop("Use DROP VIEW to remove a view.")},
 
202
                ERRCODE_UNDEFINED_TABLE,
 
203
                gettext_noop("view \"%s\" does not exist"),
 
204
                gettext_noop("view \"%s\" does not exist, skipping"),
 
205
                gettext_noop("\"%s\" is not a view"),
 
206
        gettext_noop("Use DROP VIEW to remove a view.")},
207
207
        {RELKIND_INDEX,
208
 
         ERRCODE_UNDEFINED_OBJECT,
209
 
         gettext_noop("index \"%s\" does not exist"),
210
 
         gettext_noop("index \"%s\" does not exist, skipping"),
211
 
         gettext_noop("\"%s\" is not an index"),
212
 
         gettext_noop("Use DROP INDEX to remove an index.")},
 
208
                ERRCODE_UNDEFINED_OBJECT,
 
209
                gettext_noop("index \"%s\" does not exist"),
 
210
                gettext_noop("index \"%s\" does not exist, skipping"),
 
211
                gettext_noop("\"%s\" is not an index"),
 
212
        gettext_noop("Use DROP INDEX to remove an index.")},
213
213
        {RELKIND_COMPOSITE_TYPE,
214
 
         ERRCODE_UNDEFINED_OBJECT,
215
 
         gettext_noop("type \"%s\" does not exist"),
216
 
         gettext_noop("type \"%s\" does not exist, skipping"),
217
 
         gettext_noop("\"%s\" is not a type"),
218
 
         gettext_noop("Use DROP TYPE to remove a type.")},
 
214
                ERRCODE_UNDEFINED_OBJECT,
 
215
                gettext_noop("type \"%s\" does not exist"),
 
216
                gettext_noop("type \"%s\" does not exist, skipping"),
 
217
                gettext_noop("\"%s\" is not a type"),
 
218
        gettext_noop("Use DROP TYPE to remove a type.")},
219
219
        {'\0', 0, NULL, NULL, NULL, NULL}
220
220
};
221
221
 
256
256
                  bool recurse, bool recursing);
257
257
static void ATRewriteCatalogs(List **wqueue);
258
258
static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
259
 
                                          AlterTableCmd *cmd);
 
259
                  AlterTableCmd *cmd);
260
260
static void ATRewriteTables(List **wqueue);
261
261
static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap);
262
262
static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
272
272
                                ColumnDef *colDef, bool isOid);
273
273
static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
274
274
static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
275
 
                                AlterTableCmd *cmd);
 
275
                          AlterTableCmd *cmd);
276
276
static void ATExecDropNotNull(Relation rel, const char *colName);
277
277
static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
278
278
                                 const char *colName);
290
290
static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
291
291
                           IndexStmt *stmt, bool is_rebuild);
292
292
static void ATExecAddConstraint(List **wqueue,
293
 
                                                                AlteredTableInfo *tab, Relation rel,
294
 
                                                                Node *newConstraint, bool recurse);
 
293
                                        AlteredTableInfo *tab, Relation rel,
 
294
                                        Node *newConstraint, bool recurse);
295
295
static void ATAddCheckConstraint(List **wqueue,
296
 
                                                                 AlteredTableInfo *tab, Relation rel,
297
 
                                                                 Constraint *constr,
298
 
                                                                 bool recurse, bool recursing);
 
296
                                         AlteredTableInfo *tab, Relation rel,
 
297
                                         Constraint *constr,
 
298
                                         bool recurse, bool recursing);
299
299
static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
300
300
                                                  FkConstraint *fkconstraint);
301
301
static void ATExecDropConstraint(Relation rel, const char *constrName,
302
 
                                                                 DropBehavior behavior, 
303
 
                                                                 bool recurse, bool recursing);
 
302
                                         DropBehavior behavior,
 
303
                                         bool recurse, bool recursing);
304
304
static void ATPrepAlterColumnType(List **wqueue,
305
305
                                          AlteredTableInfo *tab, Relation rel,
306
306
                                          bool recurse, bool recursing,
324
324
static void ATExecAddInherit(Relation rel, RangeVar *parent);
325
325
static void ATExecDropInherit(Relation rel, RangeVar *parent);
326
326
static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
327
 
                                                           ForkNumber forkNum, bool istemp);
 
327
                                   ForkNumber forkNum, bool istemp);
328
328
 
329
329
 
330
330
/* ----------------------------------------------------------------
353
353
        Datum           reloptions;
354
354
        ListCell   *listptr;
355
355
        AttrNumber      attnum;
356
 
        static char        *validnsps[] = HEAP_RELOPT_NAMESPACES;
 
356
        static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
357
357
 
358
358
        /*
359
359
         * Truncate relname to appropriate length (probably a waste of time, as
435
435
                                                         &inheritOids, &old_constraints, &parentOidCount);
436
436
 
437
437
        /*
438
 
         * Create a tuple descriptor from the relation schema.  Note that this
 
438
         * Create a tuple descriptor from the relation schema.  Note that this
439
439
         * deals with column names, types, and NOT NULL constraints, but not
440
440
         * default values or CHECK constraints; we handle those below.
441
441
         */
448
448
         * Find columns with default values and prepare for insertion of the
449
449
         * defaults.  Pre-cooked (that is, inherited) defaults go into a list of
450
450
         * CookedConstraint structs that we'll pass to heap_create_with_catalog,
451
 
         * while raw defaults go into a list of RawColumnDefault structs that
452
 
         * will be processed by AddRelationNewConstraints.  (We can't deal with
453
 
         * raw expressions until we can do transformExpr.)
 
451
         * while raw defaults go into a list of RawColumnDefault structs that will
 
452
         * be processed by AddRelationNewConstraints.  (We can't deal with raw
 
453
         * expressions until we can do transformExpr.)
454
454
         *
455
455
         * We can set the atthasdef flags now in the tuple descriptor; this just
456
456
         * saves StoreAttrDefault from having to do an immediate update of the
495
495
        }
496
496
 
497
497
        /*
498
 
         * Create the relation.  Inherited defaults and constraints are passed
499
 
         * in for immediate handling --- since they don't need parsing, they
500
 
         * can be stored immediately.
 
498
         * Create the relation.  Inherited defaults and constraints are passed in
 
499
         * for immediate handling --- since they don't need parsing, they can be
 
500
         * stored immediately.
501
501
         */
502
502
        relationId = heap_create_with_catalog(relname,
503
503
                                                                                  namespaceId,
606
606
        ereport(ERROR,
607
607
                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
608
608
                         errmsg(rentry->nota_msg, relname),
609
 
                         (wentry->kind != '\0') ? errhint(wentry->drophint_msg) : 0));
 
609
           (wentry->kind != '\0') ? errhint("%s", _(wentry->drophint_msg)) : 0));
610
610
}
611
611
 
612
612
/*
622
622
 
623
623
        /*
624
624
         * First we identify all the relations, then we delete them in a single
625
 
         * performMultipleDeletions() call.  This is to avoid unwanted
626
 
         * DROP RESTRICT errors if one of the relations depends on another.
 
625
         * performMultipleDeletions() call.  This is to avoid unwanted DROP
 
626
         * RESTRICT errors if one of the relations depends on another.
627
627
         */
628
628
 
629
629
        /* Determine required relkind */
648
648
                default:
649
649
                        elog(ERROR, "unrecognized drop object type: %d",
650
650
                                 (int) drop->removeType);
651
 
                        relkind = 0;    /* keep compiler quiet */
 
651
                        relkind = 0;            /* keep compiler quiet */
652
652
                        break;
653
653
        }
654
654
 
862
862
#endif
863
863
 
864
864
        /*
865
 
         * If we are asked to restart sequences, find all the sequences,
866
 
         * lock them (we only need AccessShareLock because that's all that
867
 
         * ALTER SEQUENCE takes), and check permissions.  We want to do this
868
 
         * early since it's pointless to do all the truncation work only to fail
869
 
         * on sequence permissions.
 
865
         * If we are asked to restart sequences, find all the sequences, lock them
 
866
         * (we only need AccessShareLock because that's all that ALTER SEQUENCE
 
867
         * takes), and check permissions.  We want to do this early since it's
 
868
         * pointless to do all the truncation work only to fail on sequence
 
869
         * permissions.
870
870
         */
871
871
        if (stmt->restart_seqs)
872
872
        {
878
878
 
879
879
                        foreach(seqcell, seqlist)
880
880
                        {
881
 
                                Oid             seq_relid = lfirst_oid(seqcell);
882
 
                                Relation seq_rel;
 
881
                                Oid                     seq_relid = lfirst_oid(seqcell);
 
882
                                Relation        seq_rel;
883
883
 
884
884
                                seq_rel = relation_open(seq_relid, AccessShareLock);
885
885
 
899
899
        AfterTriggerBeginQuery();
900
900
 
901
901
        /*
902
 
         * To fire triggers, we'll need an EState as well as a ResultRelInfo
903
 
         * for each relation.
 
902
         * To fire triggers, we'll need an EState as well as a ResultRelInfo for
 
903
         * each relation.
904
904
         */
905
905
        estate = CreateExecutorState();
906
906
        resultRelInfos = (ResultRelInfo *)
912
912
 
913
913
                InitResultRelInfo(resultRelInfo,
914
914
                                                  rel,
915
 
                                                  0,                    /* dummy rangetable index */
 
915
                                                  0,    /* dummy rangetable index */
916
916
                                                  CMD_DELETE,   /* don't need any index info */
917
917
                                                  false);
918
918
                resultRelInfo++;
922
922
 
923
923
        /*
924
924
         * Process all BEFORE STATEMENT TRUNCATE triggers before we begin
925
 
         * truncating (this is because one of them might throw an error).
926
 
         * Also, if we were to allow them to prevent statement execution,
927
 
         * that would need to be handled here.
 
925
         * truncating (this is because one of them might throw an error). Also, if
 
926
         * we were to allow them to prevent statement execution, that would need
 
927
         * to be handled here.
928
928
         */
929
929
        resultRelInfo = resultRelInfos;
930
930
        foreach(cell, rels)
996
996
 
997
997
        /*
998
998
         * Lastly, restart any owned sequences if we were asked to.  This is done
999
 
         * last because it's nontransactional: restarts will not roll back if
1000
 
         * we abort later.  Hence it's important to postpone them as long as
 
999
         * last because it's nontransactional: restarts will not roll back if we
 
1000
         * abort later.  Hence it's important to postpone them as long as
1001
1001
         * possible.  (This is also a big reason why we locked and
1002
1002
         * permission-checked the sequences beforehand.)
1003
1003
         */
1004
1004
        if (stmt->restart_seqs)
1005
1005
        {
1006
 
                List   *options = list_make1(makeDefElem("restart", NULL));
 
1006
                List       *options = list_make1(makeDefElem("restart", NULL));
1007
1007
 
1008
1008
                foreach(cell, seq_relids)
1009
1009
                {
1010
 
                        Oid             seq_relid = lfirst_oid(cell);
 
1010
                        Oid                     seq_relid = lfirst_oid(cell);
1011
1011
 
1012
1012
                        AlterSequenceInternal(seq_relid, options);
1013
1013
                }
1361
1361
 
1362
1362
                /*
1363
1363
                 * Now copy the CHECK constraints of this parent, adjusting attnos
1364
 
                 * using the completed newattno[] map.  Identically named constraints
 
1364
                 * using the completed newattno[] map.  Identically named constraints
1365
1365
                 * are merged if possible, else we throw error.
1366
1366
                 */
1367
1367
                if (constr && constr->num_check > 0)
1387
1387
                                        cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
1388
1388
                                        cooked->contype = CONSTR_CHECK;
1389
1389
                                        cooked->name = pstrdup(name);
1390
 
                                        cooked->attnum = 0;             /* not used for constraints */
 
1390
                                        cooked->attnum = 0; /* not used for constraints */
1391
1391
                                        cooked->expr = expr;
1392
1392
                                        cooked->is_local = false;
1393
1393
                                        cooked->inhcount = 1;
2052
2052
                                                RelationGetRelationName(targetrelation))));
2053
2053
 
2054
2054
        /*
2055
 
         * Don't allow ALTER TABLE on composite types.
2056
 
         * We want people to use ALTER TYPE for that.
 
2055
         * Don't allow ALTER TABLE on composite types. We want people to use ALTER
 
2056
         * TYPE for that.
2057
2057
         */
2058
2058
        if (relkind == RELKIND_COMPOSITE_TYPE)
2059
2059
                ereport(ERROR,
2089
2089
        Form_pg_class relform;
2090
2090
 
2091
2091
        /*
2092
 
         * Grab an exclusive lock on the target table, index, sequence or
2093
 
         * view, which we will NOT release until end of transaction.
 
2092
         * Grab an exclusive lock on the target table, index, sequence or view,
 
2093
         * which we will NOT release until end of transaction.
2094
2094
         */
2095
2095
        targetrelation = relation_open(myrelid, AccessExclusiveLock);
2096
2096
 
2166
2166
 * We also reject these commands if there are any pending AFTER trigger events
2167
2167
 * for the rel.  This is certainly necessary for the rewriting variants of
2168
2168
 * ALTER TABLE, because they don't preserve tuple TIDs and so the pending
2169
 
 * events would try to fetch the wrong tuples.  It might be overly cautious
 
2169
 * events would try to fetch the wrong tuples.  It might be overly cautious
2170
2170
 * in other cases, but again it seems better to err on the side of paranoia.
2171
2171
 *
2172
2172
 * REINDEX calls this with "rel" referencing the index to be rebuilt; here
2184
2184
        if (rel->rd_refcnt != expected_refcnt)
2185
2185
                ereport(ERROR,
2186
2186
                                (errcode(ERRCODE_OBJECT_IN_USE),
2187
 
                                 /* translator: first %s is a SQL command, eg ALTER TABLE */
 
2187
                /* translator: first %s is a SQL command, eg ALTER TABLE */
2188
2188
                                 errmsg("cannot %s \"%s\" because "
2189
2189
                                                "it is being used by active queries in this session",
2190
2190
                                                stmt, RelationGetRelationName(rel))));
2193
2193
                AfterTriggerPendingOnRel(RelationGetRelid(rel)))
2194
2194
                ereport(ERROR,
2195
2195
                                (errcode(ERRCODE_OBJECT_IN_USE),
2196
 
                                 /* translator: first %s is a SQL command, eg ALTER TABLE */
 
2196
                /* translator: first %s is a SQL command, eg ALTER TABLE */
2197
2197
                                 errmsg("cannot %s \"%s\" because "
2198
2198
                                                "it has pending trigger events",
2199
2199
                                                stmt, RelationGetRelationName(rel))));
2220
2220
 * expressions that need to be evaluated with respect to the old table
2221
2221
 * schema.
2222
2222
 *
2223
 
 * ATRewriteCatalogs performs phase 2 for each affected table.  (Note that
 
2223
 * ATRewriteCatalogs performs phase 2 for each affected table.  (Note that
2224
2224
 * phases 2 and 3 normally do no explicit recursion, since phase 1 already
2225
2225
 * did it --- although some subcommands have to recurse in phase 2 instead.)
2226
2226
 * Certain subcommands need to be performed before others to avoid
2244
2244
        switch (stmt->relkind)
2245
2245
        {
2246
2246
                case OBJECT_TABLE:
 
2247
 
2247
2248
                        /*
2248
 
                         * For mostly-historical reasons, we allow ALTER TABLE to apply
2249
 
                         * to all relation types.
 
2249
                         * For mostly-historical reasons, we allow ALTER TABLE to apply to
 
2250
                         * all relation types.
2250
2251
                         */
2251
2252
                        break;
2252
2253
 
2363
2364
                        ATPrepAddColumn(wqueue, rel, recurse, cmd);
2364
2365
                        pass = AT_PASS_ADD_COL;
2365
2366
                        break;
2366
 
                case AT_AddColumnToView:        /* add column via CREATE OR REPLACE VIEW */
 
2367
                case AT_AddColumnToView:                /* add column via CREATE OR REPLACE
 
2368
                                                                                 * VIEW */
2367
2369
                        ATSimplePermissions(rel, true);
2368
2370
                        /* Performs own recursion */
2369
2371
                        ATPrepAddColumn(wqueue, rel, recurse, cmd);
2583
2585
                        (tab->subcmds[AT_PASS_ADD_COL] ||
2584
2586
                         tab->subcmds[AT_PASS_ALTER_TYPE] ||
2585
2587
                         tab->subcmds[AT_PASS_COL_ATTRS]))
2586
 
                        AlterTableCreateToastTable(tab->relid, (Datum) 0, false);
 
2588
                        AlterTableCreateToastTable(tab->relid, InvalidOid,
 
2589
                                                                           (Datum) 0, false);
2587
2590
        }
2588
2591
}
2589
2592
 
2597
2600
        switch (cmd->subtype)
2598
2601
        {
2599
2602
                case AT_AddColumn:              /* ADD COLUMN */
2600
 
                case AT_AddColumnToView: /* add column via CREATE OR REPLACE VIEW */
 
2603
                case AT_AddColumnToView:                /* add column via CREATE OR REPLACE
 
2604
                                                                                 * VIEW */
2601
2605
                        ATExecAddColumn(tab, rel, (ColumnDef *) cmd->def, false);
2602
2606
                        break;
2603
2607
                case AT_ColumnDefault:  /* ALTER COLUMN DEFAULT */
3539
3543
                        if (isOid && childatt->attnum != ObjectIdAttributeNumber)
3540
3544
                                ereport(ERROR,
3541
3545
                                                (errcode(ERRCODE_DATATYPE_MISMATCH),
3542
 
                                                 errmsg("child table \"%s\" has a conflicting \"%s\" column",
3543
 
                                                        RelationGetRelationName(rel), colDef->colname)));
 
3546
                                 errmsg("child table \"%s\" has a conflicting \"%s\" column",
 
3547
                                                RelationGetRelationName(rel), colDef->colname)));
3544
3548
 
3545
3549
                        /* Bump the existing child att's inhcount */
3546
3550
                        childatt->attinhcount++;
3690
3694
         * returned by AddRelationNewConstraints, so that the right thing happens
3691
3695
         * when a datatype's default applies.
3692
3696
         *
3693
 
         * We skip this step completely for views.  For a view, we can only get
 
3697
         * We skip this step completely for views.      For a view, we can only get
3694
3698
         * here from CREATE OR REPLACE VIEW, which historically doesn't set up
3695
 
         * defaults, not even for domain-typed columns.  And in any case we mustn't
3696
 
         * invoke Phase 3 on a view, since it has no storage.
 
3699
         * defaults, not even for domain-typed columns.  And in any case we
 
3700
         * mustn't invoke Phase 3 on a view, since it has no storage.
3697
3701
         */
3698
3702
        if (relkind != RELKIND_VIEW && attribute.attnum > 0)
3699
3703
        {
3715
3719
                                                                                                        COERCION_ASSIGNMENT,
3716
3720
                                                                                                        COERCE_IMPLICIT_CAST,
3717
3721
                                                                                                        -1);
3718
 
                        if (defval == NULL)             /* should not happen */
 
3722
                        if (defval == NULL) /* should not happen */
3719
3723
                                elog(ERROR, "failed to coerce base type to domain");
3720
3724
                }
3721
3725
 
3740
3744
        }
3741
3745
 
3742
3746
        /*
3743
 
         * If we are adding an OID column, we have to tell Phase 3 to rewrite
3744
 
         * the table to fix that.
 
3747
         * If we are adding an OID column, we have to tell Phase 3 to rewrite the
 
3748
         * table to fix that.
3745
3749
         */
3746
3750
        if (isOid)
3747
3751
                tab->new_changeoids = true;
3773
3777
/*
3774
3778
 * ALTER TABLE SET WITH OIDS
3775
3779
 *
3776
 
 * Basically this is an ADD COLUMN for the special OID column.  We have
 
3780
 * Basically this is an ADD COLUMN for the special OID column.  We have
3777
3781
 * to cons up a ColumnDef node because the ADD COLUMN code needs one.
3778
3782
 */
3779
3783
static void
4295
4299
        performDeletion(&object, behavior);
4296
4300
 
4297
4301
        /*
4298
 
         * If we dropped the OID column, must adjust pg_class.relhasoids and
4299
 
         * tell Phase 3 to physically get rid of the column.
 
4302
         * If we dropped the OID column, must adjust pg_class.relhasoids and tell
 
4303
         * Phase 3 to physically get rid of the column.
4300
4304
         */
4301
4305
        if (attnum == ObjectIdAttributeNumber)
4302
4306
        {
4410
4414
                                FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
4411
4415
 
4412
4416
                                /*
4413
 
                                 * Note that we currently never recurse for FK constraints,
4414
 
                                 * so the "recurse" flag is silently ignored.
 
4417
                                 * Note that we currently never recurse for FK constraints, so
 
4418
                                 * the "recurse" flag is silently ignored.
4415
4419
                                 *
4416
4420
                                 * Assign or validate constraint name
4417
4421
                                 */
4473
4477
 
4474
4478
        /*
4475
4479
         * Call AddRelationNewConstraints to do the work, making sure it works on
4476
 
         * a copy of the Constraint so transformExpr can't modify the original.
4477
 
         * It returns a list of cooked constraints.
 
4480
         * a copy of the Constraint so transformExpr can't modify the original. It
 
4481
         * returns a list of cooked constraints.
4478
4482
         *
4479
4483
         * If the constraint ends up getting merged with a pre-existing one, it's
4480
4484
         * omitted from the returned list, which is what we want: we do not need
4584
4588
        pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock);
4585
4589
 
4586
4590
        /*
4587
 
         * Validity checks (permission checks wait till we have the column numbers)
 
4591
         * Validity checks (permission checks wait till we have the column
 
4592
         * numbers)
4588
4593
         */
4589
4594
        if (pkrel->rd_rel->relkind != RELKIND_RELATION)
4590
4595
                ereport(ERROR,
4810
4815
                                                                          NULL,         /* no check constraint */
4811
4816
                                                                          NULL,
4812
4817
                                                                          NULL,
4813
 
                                                                          true, /* islocal */
4814
 
                                                                          0); /* inhcount */
 
4818
                                                                          true,         /* islocal */
 
4819
                                                                          0);           /* inhcount */
4815
4820
 
4816
4821
        /*
4817
4822
         * Create the triggers that will enforce the constraint.
5201
5206
        if (on_insert)
5202
5207
        {
5203
5208
                fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
5204
 
                fk_trigger->actions[0] = 'i';
 
5209
                fk_trigger->events = TRIGGER_TYPE_INSERT;
5205
5210
        }
5206
5211
        else
5207
5212
        {
5208
5213
                fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
5209
 
                fk_trigger->actions[0] = 'u';
 
5214
                fk_trigger->events = TRIGGER_TYPE_UPDATE;
5210
5215
        }
5211
 
        fk_trigger->actions[1] = '\0';
5212
5216
 
5213
5217
        fk_trigger->isconstraint = true;
5214
5218
        fk_trigger->deferrable = fkconstraint->deferrable;
5258
5262
        fk_trigger->relation = fkconstraint->pktable;
5259
5263
        fk_trigger->before = false;
5260
5264
        fk_trigger->row = true;
5261
 
        fk_trigger->actions[0] = 'd';
5262
 
        fk_trigger->actions[1] = '\0';
5263
 
 
 
5265
        fk_trigger->events = TRIGGER_TYPE_DELETE;
5264
5266
        fk_trigger->isconstraint = true;
5265
5267
        fk_trigger->constrrel = myRel;
5266
5268
        switch (fkconstraint->fk_del_action)
5311
5313
        fk_trigger->relation = fkconstraint->pktable;
5312
5314
        fk_trigger->before = false;
5313
5315
        fk_trigger->row = true;
5314
 
        fk_trigger->actions[0] = 'u';
5315
 
        fk_trigger->actions[1] = '\0';
 
5316
        fk_trigger->events = TRIGGER_TYPE_UPDATE;
5316
5317
        fk_trigger->isconstraint = true;
5317
5318
        fk_trigger->constrrel = myRel;
5318
5319
        switch (fkconstraint->fk_upd_action)
5400
5401
                /* Don't drop inherited constraints */
5401
5402
                if (con->coninhcount > 0 && !recursing)
5402
5403
                        ereport(ERROR,
5403
 
                                (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5404
 
                                 errmsg("cannot drop inherited constraint \"%s\" of relation \"%s\"",
5405
 
                                                constrName, RelationGetRelationName(rel))));
 
5404
                                        (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
 
5405
                                         errmsg("cannot drop inherited constraint \"%s\" of relation \"%s\"",
 
5406
                                                        constrName, RelationGetRelationName(rel))));
5406
5407
 
5407
5408
                /* Right now only CHECK constraints can be inherited */
5408
5409
                if (con->contype == CONSTRAINT_CHECK)
5459
5460
 
5460
5461
                while (HeapTupleIsValid(tuple = systable_getnext(scan)))
5461
5462
                {
5462
 
                        HeapTuple copy_tuple;
 
5463
                        HeapTuple       copy_tuple;
5463
5464
 
5464
5465
                        con = (Form_pg_constraint) GETSTRUCT(tuple);
5465
5466
 
5472
5473
 
5473
5474
                        found = true;
5474
5475
 
5475
 
                        if (con->coninhcount <= 0)              /* shouldn't happen */
 
5476
                        if (con->coninhcount <= 0)      /* shouldn't happen */
5476
5477
                                elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
5477
5478
                                         childrelid, constrName);
5478
5479
 
5482
5483
                        if (recurse)
5483
5484
                        {
5484
5485
                                /*
5485
 
                                 * If the child constraint has other definition sources,
5486
 
                                 * just decrement its inheritance count; if not, recurse
5487
 
                                 * to delete it.
 
5486
                                 * If the child constraint has other definition sources, just
 
5487
                                 * decrement its inheritance count; if not, recurse to delete
 
5488
                                 * it.
5488
5489
                                 */
5489
5490
                                if (con->coninhcount == 1 && !con->conislocal)
5490
5491
                                {
5506
5507
                        else
5507
5508
                        {
5508
5509
                                /*
5509
 
                                 * If we were told to drop ONLY in this table (no
5510
 
                                 * recursion), we need to mark the inheritors' constraints
5511
 
                                 * as locally defined rather than inherited.
 
5510
                                 * If we were told to drop ONLY in this table (no recursion),
 
5511
                                 * we need to mark the inheritors' constraints as locally
 
5512
                                 * defined rather than inherited.
5512
5513
                                 */
5513
5514
                                con->coninhcount--;
5514
5515
                                con->conislocal = true;
5528
5529
                if (!found)
5529
5530
                        ereport(ERROR,
5530
5531
                                        (errcode(ERRCODE_UNDEFINED_OBJECT),
5531
 
                                         errmsg("constraint \"%s\" of relation \"%s\" does not exist",
5532
 
                                                        constrName,
5533
 
                                                        RelationGetRelationName(childrel))));
 
5532
                                errmsg("constraint \"%s\" of relation \"%s\" does not exist",
 
5533
                                           constrName,
 
5534
                                           RelationGetRelationName(childrel))));
5534
5535
 
5535
5536
                heap_close(childrel, NoLock);
5536
5537
        }
5628
5629
                if (pstate->p_hasWindowFuncs)
5629
5630
                        ereport(ERROR,
5630
5631
                                        (errcode(ERRCODE_WINDOWING_ERROR),
5631
 
                        errmsg("cannot use window function in transform expression")));
 
5632
                          errmsg("cannot use window function in transform expression")));
5632
5633
        }
5633
5634
        else
5634
5635
        {
5745
5746
                if (defaultexpr == NULL)
5746
5747
                        ereport(ERROR,
5747
5748
                                        (errcode(ERRCODE_DATATYPE_MISMATCH),
5748
 
                        errmsg("default for column \"%s\" cannot be cast to type %s",
5749
 
                                   colName, format_type_be(targettype))));
 
5749
                                errmsg("default for column \"%s\" cannot be cast to type %s",
 
5750
                                           colName, format_type_be(targettype))));
5750
5751
        }
5751
5752
        else
5752
5753
                defaultexpr = NULL;
6536
6537
        Datum           repl_val[Natts_pg_class];
6537
6538
        bool            repl_null[Natts_pg_class];
6538
6539
        bool            repl_repl[Natts_pg_class];
6539
 
        static char        *validnsps[] = HEAP_RELOPT_NAMESPACES;
 
6540
        static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
6540
6541
 
6541
6542
        if (defList == NIL)
6542
6543
                return;                                 /* nothing to do */
6555
6556
 
6556
6557
        /* Generate new proposed reloptions (text array) */
6557
6558
        newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
6558
 
                                                                         defList, NULL, validnsps, false, isReset);
 
6559
                                                                   defList, NULL, validnsps, false, isReset);
6559
6560
 
6560
6561
        /* Validate */
6561
6562
        switch (rel->rd_rel->relkind)
6591
6592
        repl_repl[Anum_pg_class_reloptions - 1] = true;
6592
6593
 
6593
6594
        newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
6594
 
                                                                repl_val, repl_null, repl_repl);
 
6595
                                                                 repl_val, repl_null, repl_repl);
6595
6596
 
6596
6597
        simple_heap_update(pgclass, &newtuple->t_self, newtuple);
6597
6598
 
6619
6620
                datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
6620
6621
 
6621
6622
                newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
6622
 
                                                                                 defList, "toast", validnsps, false, isReset);
 
6623
                                                                defList, "toast", validnsps, false, isReset);
6623
6624
 
6624
6625
                (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
6625
6626
 
6749
6750
        RelationOpenSmgr(rel);
6750
6751
 
6751
6752
        /*
6752
 
         * Create and copy all forks of the relation, and schedule unlinking
6753
 
         * of old physical files.
 
6753
         * Create and copy all forks of the relation, and schedule unlinking of
 
6754
         * old physical files.
6754
6755
         *
6755
6756
         * NOTE: any conflict in relfilenode value will be caught in
6756
 
         *               RelationCreateStorage().
 
6757
         * RelationCreateStorage().
6757
6758
         */
6758
6759
        RelationCreateStorage(newrnode, rel->rd_istemp);
6759
6760
 
7163
7164
 
7164
7165
        while (HeapTupleIsValid(parent_tuple = systable_getnext(parent_scan)))
7165
7166
        {
7166
 
                Form_pg_constraint      parent_con = (Form_pg_constraint) GETSTRUCT(parent_tuple);
7167
 
                SysScanDesc                     child_scan;
7168
 
                ScanKeyData                     child_key;
7169
 
                HeapTuple                       child_tuple;
7170
 
                bool                            found = false;
 
7167
                Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(parent_tuple);
 
7168
                SysScanDesc child_scan;
 
7169
                ScanKeyData child_key;
 
7170
                HeapTuple       child_tuple;
 
7171
                bool            found = false;
7171
7172
 
7172
7173
                if (parent_con->contype != CONSTRAINT_CHECK)
7173
7174
                        continue;
7182
7183
 
7183
7184
                while (HeapTupleIsValid(child_tuple = systable_getnext(child_scan)))
7184
7185
                {
7185
 
                        Form_pg_constraint      child_con = (Form_pg_constraint) GETSTRUCT(child_tuple);
7186
 
                        HeapTuple child_copy;
 
7186
                        Form_pg_constraint child_con = (Form_pg_constraint) GETSTRUCT(child_tuple);
 
7187
                        HeapTuple       child_copy;
7187
7188
 
7188
7189
                        if (child_con->contype != CONSTRAINT_CHECK)
7189
7190
                                continue;
7344
7345
        heap_close(catalogRelation, RowExclusiveLock);
7345
7346
 
7346
7347
        /*
7347
 
         * Likewise, find inherited check constraints and disinherit them.
7348
 
         * To do this, we first need a list of the names of the parent's check
 
7348
         * Likewise, find inherited check constraints and disinherit them. To do
 
7349
         * this, we first need a list of the names of the parent's check
7349
7350
         * constraints.  (We cheat a bit by only checking for name matches,
7350
7351
         * assuming that the expressions will match.)
7351
7352
         */
7380
7381
        while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
7381
7382
        {
7382
7383
                Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
7383
 
                bool    match;
7384
 
                ListCell *lc;
 
7384
                bool            match;
 
7385
                ListCell   *lc;
7385
7386
 
7386
7387
                if (con->contype != CONSTRAINT_CHECK)
7387
7388
                        continue;
7388
7389
 
7389
7390
                match = false;
7390
 
                foreach (lc, connames)
 
7391
                foreach(lc, connames)
7391
7392
                {
7392
7393
                        if (strcmp(NameStr(con->conname), (char *) lfirst(lc)) == 0)
7393
7394
                        {
7401
7402
                        /* Decrement inhcount and possibly set islocal to true */
7402
7403
                        HeapTuple       copyTuple = heap_copytuple(constraintTuple);
7403
7404
                        Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
 
7405
 
7404
7406
                        if (copy_con->coninhcount <= 0)         /* shouldn't happen */
7405
7407
                                elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
7406
7408
                                         RelationGetRelid(rel), NameStr(copy_con->conname));
7484
7486
        switch (stmttype)
7485
7487
        {
7486
7488
                case OBJECT_TABLE:
 
7489
 
7487
7490
                        /*
7488
 
                         * For mostly-historical reasons, we allow ALTER TABLE to apply
7489
 
                         * to all relation types.
 
7491
                         * For mostly-historical reasons, we allow ALTER TABLE to apply to
 
7492
                         * all relation types.
7490
7493
                         */
7491
7494
                        break;
7492
7495