* Sort the list of GpPartitionBoundSpecs based first on START, if START does * not exist, use END. After sort, if any stmt contains an implicit START or * END, deduce the value and update the corresponding list of CreateStmts. */
| 326 | * END, deduce the value and update the corresponding list of CreateStmts. |
| 327 | */ |
| 328 | static void |
| 329 | deduceImplicitRangeBounds(ParseState *pstate, Relation parentrel, List *stmts, CreateStmtOrigin origin) |
| 330 | { |
| 331 | PartitionKey key = RelationGetPartitionKey(parentrel); |
| 332 | /* GPDB_14_MERGE_FIXEME: most places use true for new api, need to check */ |
| 333 | PartitionDesc desc = RelationGetPartitionDesc(parentrel, true); |
| 334 | |
| 335 | list_sort_arg(stmts, qsort_stmt_cmp, key); |
| 336 | |
| 337 | /* |
| 338 | * This works slightly differenly, depending on whether this is a |
| 339 | * CREATE TABLE command to create a whole new table, or an ALTER TABLE |
| 340 | * ADD PARTTION to add to an existing table. |
| 341 | */ |
| 342 | if (origin != ORIGIN_GP_CLASSIC_ALTER_GEN) |
| 343 | { |
| 344 | /* |
| 345 | * CREATE TABLE, there are no existing partitions. We deduce the |
| 346 | * missing START/END bounds based on the other partitions defined in |
| 347 | * the same command. |
| 348 | */ |
| 349 | CreateStmt *prevstmt = NULL; |
| 350 | ListCell *lc; |
| 351 | |
| 352 | foreach(lc, stmts) |
| 353 | { |
| 354 | Node *n = lfirst(lc); |
| 355 | CreateStmt *stmt; |
| 356 | |
| 357 | Assert(IsA(n, CreateStmt)); |
| 358 | stmt = (CreateStmt *) n; |
| 359 | |
| 360 | if (stmt->partbound->is_default) |
| 361 | continue; |
| 362 | |
| 363 | if (!stmt->partbound->lowerdatums) |
| 364 | { |
| 365 | if (prevstmt) |
| 366 | { |
| 367 | if (prevstmt->partbound->upperdatums) |
| 368 | stmt->partbound->lowerdatums = prevstmt->partbound->upperdatums; |
| 369 | else |
| 370 | ereport(ERROR, |
| 371 | (errcode(ERRCODE_INVALID_TABLE_DEFINITION), |
| 372 | errmsg("cannot derive starting value of partition based upon ending of previous partition"), |
| 373 | parser_errposition(pstate, stmt->partbound->location))); |
| 374 | } |
| 375 | else |
| 376 | { |
| 377 | ColumnRef *minvalue = makeNode(ColumnRef); |
| 378 | minvalue->location = -1; |
| 379 | minvalue->fields = lcons(makeString("minvalue"), NIL); |
| 380 | stmt->partbound->lowerdatums = list_make1(minvalue); |
| 381 | } |
| 382 | |
| 383 | } |
| 384 | if (!stmt->partbound->upperdatums) |
| 385 | { |
no test coverage detected