* ------------------------------ * Implementation for command: * * ALTER TABLE EXCHANGE PARTITION with table * * Above alter is converted into following sequence of cmds on QD: * * 1. ALTER TABLE DETACH PARTITION ; * 2. ALTER TABLE ATTACH PARTITION ; * 3. ALTER TABLE RENAME TO tmp; * 4. if namespace differ between oldpart
| 436 | * ------------------------------ |
| 437 | */ |
| 438 | static List * |
| 439 | AtExecGPExchangePartition(Relation rel, AlterTableCmd *cmd) |
| 440 | { |
| 441 | GpAlterPartitionCmd *pc = castNode(GpAlterPartitionCmd, cmd->def); |
| 442 | RangeVar *newpartrv = (RangeVar *) pc->arg; |
| 443 | PartitionBoundSpec *boundspec; |
| 444 | RangeVar *oldpartrv; |
| 445 | RangeVar *tmprv; |
| 446 | List *stmts = NIL; |
| 447 | char *newpartname = pstrdup(newpartrv->relname); |
| 448 | char tmpname2[NAMEDATALEN]; |
| 449 | |
| 450 | /* detach oldpart partition cmd construction */ |
| 451 | { |
| 452 | AlterTableStmt *atstmt = makeNode(AlterTableStmt); |
| 453 | GpAlterPartitionId *pid = (GpAlterPartitionId *) pc->partid; |
| 454 | AlterTableCmd *atcmd = makeNode(AlterTableCmd); |
| 455 | PartitionCmd *pcmd = makeNode(PartitionCmd); |
| 456 | char tmpname[NAMEDATALEN]; |
| 457 | Oid partrelid; |
| 458 | Relation partrel; |
| 459 | HeapTuple tuple; |
| 460 | |
| 461 | partrelid = GpFindTargetPartition(rel, pid, false); |
| 462 | Assert(OidIsValid(partrelid)); |
| 463 | partrel = table_open(partrelid, AccessShareLock); |
| 464 | |
| 465 | if (partrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) |
| 466 | ereport(ERROR, |
| 467 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 468 | errmsg("cannot EXCHANGE PARTITION for relation \"%s\" -- partition has children", |
| 469 | RelationGetRelationName(rel)))); |
| 470 | |
| 471 | oldpartrv = makeRangeVar(get_namespace_name(RelationGetNamespace(partrel)), |
| 472 | pstrdup(RelationGetRelationName(partrel)), |
| 473 | pc->location); |
| 474 | |
| 475 | snprintf(tmpname, sizeof(tmpname), "pg_temp_%u", partrelid); |
| 476 | tmprv = makeRangeVar(get_namespace_name(RelationGetNamespace(partrel)), |
| 477 | pstrdup(tmpname), |
| 478 | pc->location); |
| 479 | |
| 480 | /* |
| 481 | * Get the oldpart's boundspec which will be used for attaching |
| 482 | * newpart. Fetch the tuple from the catcache, for speed. Relcache |
| 483 | * doesn't store the part bound hence need to fetch from catalog. |
| 484 | */ |
| 485 | tuple = SearchSysCache1(RELOID, partrelid); |
| 486 | if (HeapTupleIsValid(tuple)) |
| 487 | { |
| 488 | Datum datum; |
| 489 | bool isnull; |
| 490 | |
| 491 | datum = SysCacheGetAttr(RELOID, tuple, |
| 492 | Anum_pg_class_relpartbound, |
| 493 | &isnull); |
| 494 | if (!isnull) |
| 495 | boundspec = stringToNode(TextDatumGetCString(datum)); |
no test coverage detected