* Transform any expressions present in the partition key * * Returns a transformed PartitionSpec, as well as the strategy code */
| 20915 | * Returns a transformed PartitionSpec, as well as the strategy code |
| 20916 | */ |
| 20917 | static PartitionSpec * |
| 20918 | transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) |
| 20919 | { |
| 20920 | PartitionSpec *newspec; |
| 20921 | ParseState *pstate; |
| 20922 | ParseNamespaceItem *nsitem; |
| 20923 | ListCell *l; |
| 20924 | |
| 20925 | newspec = makeNode(PartitionSpec); |
| 20926 | |
| 20927 | newspec->strategy = partspec->strategy; |
| 20928 | newspec->partParams = NIL; |
| 20929 | newspec->location = partspec->location; |
| 20930 | newspec->gpPartDef = partspec->gpPartDef; |
| 20931 | newspec->subPartSpec = partspec->subPartSpec; |
| 20932 | |
| 20933 | /* Parse partitioning strategy name */ |
| 20934 | if (pg_strcasecmp(partspec->strategy, "hash") == 0) |
| 20935 | *strategy = PARTITION_STRATEGY_HASH; |
| 20936 | else if (pg_strcasecmp(partspec->strategy, "list") == 0) |
| 20937 | *strategy = PARTITION_STRATEGY_LIST; |
| 20938 | else if (pg_strcasecmp(partspec->strategy, "range") == 0) |
| 20939 | *strategy = PARTITION_STRATEGY_RANGE; |
| 20940 | else |
| 20941 | ereport(ERROR, |
| 20942 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 20943 | errmsg("unrecognized partitioning strategy \"%s\"", |
| 20944 | partspec->strategy))); |
| 20945 | |
| 20946 | /* Check valid number of columns for strategy */ |
| 20947 | if (*strategy == PARTITION_STRATEGY_LIST && |
| 20948 | list_length(partspec->partParams) != 1) |
| 20949 | ereport(ERROR, |
| 20950 | (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), |
| 20951 | errmsg("cannot use \"list\" partition strategy with more than one column"))); |
| 20952 | |
| 20953 | /* |
| 20954 | * In GPDB, the dispatcher does the transformation and the QEs get |
| 20955 | * already-transformed expressions. So all we had to do here was parse |
| 20956 | * the strategy name |
| 20957 | */ |
| 20958 | if (Gp_role == GP_ROLE_EXECUTE) |
| 20959 | return partspec; |
| 20960 | |
| 20961 | /* |
| 20962 | * Create a dummy ParseState and insert the target relation as its sole |
| 20963 | * rangetable entry. We need a ParseState for transformExpr. |
| 20964 | */ |
| 20965 | pstate = make_parsestate(NULL); |
| 20966 | nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, |
| 20967 | NULL, false, true); |
| 20968 | addNSItemToQuery(pstate, nsitem, true, true, true); |
| 20969 | |
| 20970 | /* take care of any partition expressions */ |
| 20971 | foreach(l, partspec->partParams) |
| 20972 | { |
| 20973 | PartitionElem *pelem = castNode(PartitionElem, lfirst(l)); |
| 20974 |
no test coverage detected