diff options
author | Andrew Dunstan <andrew@dunslane.net> | 2009-10-12 19:49:24 +0000 |
---|---|---|
committer | Andrew Dunstan <andrew@dunslane.net> | 2009-10-12 19:49:24 +0000 |
commit | faa1afc6c16631424579548a6e2fafb130f834f4 (patch) | |
tree | c41b0585535ab283ba0a1cc407b58e7be4548a33 /src/backend/parser/parse_utilcmd.c | |
parent | 0adaf4cb312fe3eff83e786d6a0b53ae2cdc9302 (diff) | |
download | postgresql-faa1afc6c16631424579548a6e2fafb130f834f4.tar.gz postgresql-faa1afc6c16631424579548a6e2fafb130f834f4.zip |
CREATE LIKE INCLUDING COMMENTS and STORAGE, and INCLUDING ALL shortcut. Itagaki Takahiro.
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 173 |
1 files changed, 135 insertions, 38 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index f7a122c0d64..7dfdd28601f 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -19,7 +19,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.26 2009/10/06 00:55:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.27 2009/10/12 19:49:24 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -36,6 +36,7 @@ #include "catalog/pg_constraint.h" #include "catalog/pg_opclass.h" #include "catalog/pg_type.h" +#include "commands/comment.h" #include "commands/defrem.h" #include "commands/tablecmds.h" #include "commands/tablespace.h" @@ -101,6 +102,7 @@ static void transformTableConstraint(ParseState *pstate, Constraint *constraint); static void transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, InhRelation *inhrelation); +static char *chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt); static IndexStmt *generateClonedIndexStmt(CreateStmtContext *cxt, Relation parent_index, AttrNumber *attmap); static List *get_opclass(Oid opclass, Oid actual_datatype); @@ -546,10 +548,7 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, TupleDesc tupleDesc; TupleConstr *constr; AclResult aclresult; - bool including_defaults = false; - bool including_constraints = false; - bool including_indexes = false; - ListCell *elem; + char *comment; relation = parserOpenTable(pstate, inhRelation->relation, AccessShareLock); @@ -571,36 +570,6 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, tupleDesc = RelationGetDescr(relation); constr = tupleDesc->constr; - foreach(elem, inhRelation->options) - { - int option = lfirst_int(elem); - - switch (option) - { - case CREATE_TABLE_LIKE_INCLUDING_DEFAULTS: - including_defaults = true; - break; - case CREATE_TABLE_LIKE_EXCLUDING_DEFAULTS: - including_defaults = false; - break; - case CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS: - including_constraints = true; - break; - case CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS: - including_constraints = false; - break; - case CREATE_TABLE_LIKE_INCLUDING_INDEXES: - including_indexes = true; - break; - case CREATE_TABLE_LIKE_EXCLUDING_INDEXES: - including_indexes = false; - break; - default: - elog(ERROR, "unrecognized CREATE TABLE LIKE option: %d", - option); - } - } - /* * Insert the copied attributes into the cxt for the new table definition. */ @@ -642,7 +611,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, /* * Copy default, if present and the default has been requested */ - if (attribute->atthasdef && including_defaults) + if (attribute->atthasdef && + (inhRelation->options & CREATE_TABLE_LIKE_DEFAULTS)) { Node *this_default = NULL; AttrDefault *attrdef; @@ -668,13 +638,34 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, def->cooked_default = this_default; } + + /* Likewise, copy storage if requested */ + if (inhRelation->options & CREATE_TABLE_LIKE_STORAGE) + def->storage = attribute->attstorage; + + /* Likewise, copy comment if requested */ + if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) && + (comment = GetComment(attribute->attrelid, RelationRelationId, + attribute->attnum)) != NULL) + { + CommentStmt *stmt = makeNode(CommentStmt); + + stmt->objtype = OBJECT_COLUMN; + stmt->objname = list_make3(makeString(cxt->relation->schemaname), + makeString(cxt->relation->relname), + makeString(def->colname)); + stmt->objargs = NIL; + stmt->comment = comment; + + cxt->alist = lappend(cxt->alist, stmt); + } } /* * Copy CHECK constraints if requested, being careful to adjust attribute * numbers */ - if (including_constraints && tupleDesc->constr) + if ((inhRelation->options & CREATE_TABLE_LIKE_CONSTRAINTS) && tupleDesc->constr) { AttrNumber *attmap = varattnos_map_schema(tupleDesc, cxt->columns); int ccnum; @@ -694,13 +685,31 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, n->raw_expr = NULL; n->cooked_expr = nodeToString(ccbin_node); cxt->ckconstraints = lappend(cxt->ckconstraints, n); + + /* Copy comment on constraint */ + if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) && + (comment = GetComment(GetConstraintByName(RelationGetRelid( + relation), n->conname), ConstraintRelationId, 0)) != NULL) + { + CommentStmt *stmt = makeNode(CommentStmt); + + stmt->objtype = OBJECT_CONSTRAINT; + stmt->objname = list_make3(makeString(cxt->relation->schemaname), + makeString(cxt->relation->relname), + makeString(n->conname)); + stmt->objargs = NIL; + stmt->comment = comment; + + cxt->alist = lappend(cxt->alist, stmt); + } } } /* * Likewise, copy indexes if requested */ - if (including_indexes && relation->rd_rel->relhasindex) + if ((inhRelation->options & CREATE_TABLE_LIKE_INDEXES) && + relation->rd_rel->relhasindex) { AttrNumber *attmap = varattnos_map_schema(tupleDesc, cxt->columns); List *parent_indexes; @@ -719,6 +728,68 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, /* Build CREATE INDEX statement to recreate the parent_index */ index_stmt = generateClonedIndexStmt(cxt, parent_index, attmap); + /* Copy comment on index */ + if (inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) + { + CommentStmt *stmt; + ListCell *lc; + int i; + + comment = GetComment(parent_index_oid, RelationRelationId, 0); + + if (comment != NULL) + { + /* Assign name for index because CommentStmt requires name. */ + if (index_stmt->idxname == NULL) + index_stmt->idxname = chooseIndexName(cxt->relation, index_stmt); + + stmt = makeNode(CommentStmt); + stmt->objtype = OBJECT_INDEX; + stmt->objname = list_make2(makeString(cxt->relation->schemaname), + makeString(index_stmt->idxname)); + stmt->objargs = NIL; + stmt->comment = comment; + + cxt->alist = lappend(cxt->alist, stmt); + } + + /* Copy comment on index's columns */ + i = 0; + foreach(lc, index_stmt->indexParams) + { + char *attname; + + i++; + comment = GetComment(parent_index_oid, RelationRelationId, i); + if (comment == NULL) + continue; + + /* Assign name for index because CommentStmt requires name. */ + if (index_stmt->idxname == NULL) + index_stmt->idxname = chooseIndexName(cxt->relation, index_stmt); + + attname = ((IndexElem *) lfirst(lc))->name; + + /* expression index has a dummy column name */ + if (attname == NULL) + { + attname = palloc(NAMEDATALEN); + sprintf(attname, "pg_expression_%d", i); + } + + stmt = makeNode(CommentStmt); + stmt->objtype = OBJECT_COLUMN; + stmt->objname = list_make3( + makeString(cxt->relation->schemaname), + makeString(index_stmt->idxname), + makeString(attname)); + stmt->objargs = NIL; + stmt->comment = comment; + + cxt->alist = lappend(cxt->alist, stmt); + } + } + /* Save it in the inh_indexes list for the time being */ cxt->inh_indexes = lappend(cxt->inh_indexes, index_stmt); @@ -735,6 +806,32 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt, } /* + * chooseIndexName + * + * Set name to unnamed index. See also the same logic in DefineIndex. + */ +static char * +chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt) +{ + Oid namespaceId; + + namespaceId = RangeVarGetCreationNamespace(relation); + if (index_stmt->primary) + { + /* no need for column list with pkey */ + return ChooseRelationName(relation->relname, NULL, + "pkey", namespaceId); + } + else + { + IndexElem *iparam = (IndexElem *) linitial(index_stmt->indexParams); + + return ChooseRelationName(relation->relname, iparam->name, + "key", namespaceId); + } +} + +/* * Generate an IndexStmt node using information from an already existing index * "source_idx". Attribute numbers should be adjusted according to attmap. */ |