* transformCreateStmt - * parse analysis for CREATE TABLE * * Returns a List of utility commands to be done in sequence. One of these * will be the transformed CreateStmt, but there may be additional actions * to be done before and after the actual DefineRelation() call. * In addition to normal utility commands such as AlterTableStmt and * IndexStmt, the result list may contain TableLike
| 182 | * - thomas 1997-12-02 |
| 183 | */ |
| 184 | List * |
| 185 | transformCreateStmt(CreateStmt *stmt, const char *queryString) |
| 186 | { |
| 187 | ParseState *pstate; |
| 188 | CreateStmtContext cxt; |
| 189 | List *result; |
| 190 | List *save_alist; |
| 191 | ListCell *elements; |
| 192 | Oid namespaceid; |
| 193 | Oid existing_relid; |
| 194 | ParseCallbackState pcbstate; |
| 195 | |
| 196 | DistributedBy *likeDistributedBy = NULL; |
| 197 | bool bQuiet = false; /* shut up transformDistributedBy messages */ |
| 198 | |
| 199 | /* |
| 200 | * We don't normally care much about the memory consumption of parsing, |
| 201 | * because any memory leaked is leaked into MessageContext which is |
| 202 | * reset between each command. But if a table is heavily partitioned, |
| 203 | * the CREATE TABLE statement can be expanded into hundreds or even |
| 204 | * thousands of CreateStmts, so the leaks start to add up. To reduce |
| 205 | * the memory consumption, we use a temporary memory context that's |
| 206 | * destroyed after processing the CreateStmt for some parts of the |
| 207 | * processing. |
| 208 | */ |
| 209 | cxt.tempCtx = |
| 210 | AllocSetContextCreate(CurrentMemoryContext, |
| 211 | "CreateStmt analyze context", |
| 212 | ALLOCSET_DEFAULT_MINSIZE, |
| 213 | ALLOCSET_DEFAULT_INITSIZE, |
| 214 | ALLOCSET_DEFAULT_MAXSIZE); |
| 215 | |
| 216 | /* |
| 217 | * We must not scribble on the passed-in CreateStmt, so copy it. (This is |
| 218 | * overkill, but easy.) |
| 219 | */ |
| 220 | stmt = copyObject(stmt); |
| 221 | |
| 222 | |
| 223 | /* Set up pstate */ |
| 224 | pstate = make_parsestate(NULL); |
| 225 | pstate->p_sourcetext = queryString; |
| 226 | |
| 227 | /* |
| 228 | * Look up the creation namespace. This also checks permissions on the |
| 229 | * target namespace, locks it against concurrent drops, checks for a |
| 230 | * preexisting relation in that namespace with the same name, and updates |
| 231 | * stmt->relation->relpersistence if the selected namespace is temporary. |
| 232 | */ |
| 233 | setup_parser_errposition_callback(&pcbstate, pstate, |
| 234 | stmt->relation->location); |
| 235 | namespaceid = |
| 236 | RangeVarGetAndCheckCreationNamespace(stmt->relation, NoLock, |
| 237 | &existing_relid); |
| 238 | cancel_parser_errposition_callback(&pcbstate); |
| 239 | |
| 240 | /* |
| 241 | * If the relation already exists and the user specified "IF NOT EXISTS", |
no test coverage detected