* transformReturningList - * handle a RETURNING clause in INSERT/UPDATE/DELETE */
| 2956 | * handle a RETURNING clause in INSERT/UPDATE/DELETE |
| 2957 | */ |
| 2958 | static List * |
| 2959 | transformReturningList(ParseState *pstate, List *returningList) |
| 2960 | { |
| 2961 | List *rlist; |
| 2962 | int save_next_resno; |
| 2963 | |
| 2964 | if (returningList == NIL) |
| 2965 | return NIL; /* nothing to do */ |
| 2966 | |
| 2967 | /* |
| 2968 | * We need to assign resnos starting at one in the RETURNING list. Save |
| 2969 | * and restore the main tlist's value of p_next_resno, just in case |
| 2970 | * someone looks at it later (probably won't happen). |
| 2971 | */ |
| 2972 | save_next_resno = pstate->p_next_resno; |
| 2973 | pstate->p_next_resno = 1; |
| 2974 | |
| 2975 | /* transform RETURNING identically to a SELECT targetlist */ |
| 2976 | rlist = transformTargetList(pstate, returningList, EXPR_KIND_RETURNING); |
| 2977 | |
| 2978 | /* |
| 2979 | * Complain if the nonempty tlist expanded to nothing (which is possible |
| 2980 | * if it contains only a star-expansion of a zero-column table). If we |
| 2981 | * allow this, the parsed Query will look like it didn't have RETURNING, |
| 2982 | * with results that would probably surprise the user. |
| 2983 | */ |
| 2984 | if (rlist == NIL) |
| 2985 | ereport(ERROR, |
| 2986 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 2987 | errmsg("RETURNING must have at least one column"), |
| 2988 | parser_errposition(pstate, |
| 2989 | exprLocation(linitial(returningList))))); |
| 2990 | |
| 2991 | /* mark column origins */ |
| 2992 | markTargetListOrigins(pstate, rlist); |
| 2993 | |
| 2994 | /* resolve any still-unresolved output columns as being type text */ |
| 2995 | if (pstate->p_resolve_unknowns) |
| 2996 | resolveTargetListUnknowns(pstate, rlist); |
| 2997 | |
| 2998 | /* restore state */ |
| 2999 | pstate->p_next_resno = save_next_resno; |
| 3000 | |
| 3001 | return rlist; |
| 3002 | } |
| 3003 | |
| 3004 | |
| 3005 | /* |
no test coverage detected