* transformStatsStmt - parse analysis for CREATE STATISTICS * * To avoid race conditions, it's important that this function relies only on * the passed-in relid (and not on stmt->relation) to determine the target * relation. */
| 4037 | * relation. |
| 4038 | */ |
| 4039 | CreateStatsStmt * |
| 4040 | transformStatsStmt(Oid relid, CreateStatsStmt *stmt, const char *queryString) |
| 4041 | { |
| 4042 | ParseState *pstate; |
| 4043 | ParseNamespaceItem *nsitem; |
| 4044 | ListCell *l; |
| 4045 | Relation rel; |
| 4046 | |
| 4047 | /* Nothing to do if statement already transformed. */ |
| 4048 | if (stmt->transformed) |
| 4049 | return stmt; |
| 4050 | |
| 4051 | /* Set up pstate */ |
| 4052 | pstate = make_parsestate(NULL); |
| 4053 | pstate->p_sourcetext = queryString; |
| 4054 | |
| 4055 | /* |
| 4056 | * Put the parent table into the rtable so that the expressions can refer |
| 4057 | * to its fields without qualification. Caller is responsible for locking |
| 4058 | * relation, but we still need to open it. |
| 4059 | */ |
| 4060 | rel = relation_open(relid, NoLock); |
| 4061 | nsitem = addRangeTableEntryForRelation(pstate, rel, |
| 4062 | AccessShareLock, |
| 4063 | NULL, false, true); |
| 4064 | |
| 4065 | /* no to join list, yes to namespaces */ |
| 4066 | addNSItemToQuery(pstate, nsitem, false, true, true); |
| 4067 | |
| 4068 | /* take care of any expressions */ |
| 4069 | foreach(l, stmt->exprs) |
| 4070 | { |
| 4071 | StatsElem *selem = (StatsElem *) lfirst(l); |
| 4072 | |
| 4073 | if (selem->expr) |
| 4074 | { |
| 4075 | /* Now do parse transformation of the expression */ |
| 4076 | selem->expr = transformExpr(pstate, selem->expr, |
| 4077 | EXPR_KIND_STATS_EXPRESSION); |
| 4078 | |
| 4079 | /* We have to fix its collations too */ |
| 4080 | assign_expr_collations(pstate, selem->expr); |
| 4081 | } |
| 4082 | } |
| 4083 | |
| 4084 | /* |
| 4085 | * Check that only the base rel is mentioned. (This should be dead code |
| 4086 | * now that add_missing_from is history.) |
| 4087 | */ |
| 4088 | if (list_length(pstate->p_rtable) != 1) |
| 4089 | ereport(ERROR, |
| 4090 | (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), |
| 4091 | errmsg("statistics expressions can refer only to the table being referenced"))); |
| 4092 | |
| 4093 | free_parsestate(pstate); |
| 4094 | |
| 4095 | /* Close relation */ |
| 4096 | table_close(rel, NoLock); |
no test coverage detected