* transformDeclareCursorStmt - * transform a DECLARE CURSOR Statement * * DECLARE CURSOR is like other utility statements in that we emit it as a * CMD_UTILITY Query node; however, we must first transform the contained * query. We used to postpone that until execution, but it's really necessary * to do it during the normal parse analysis phase to ensure that side effects * of parser hooks
| 3262 | * of parser hooks happen at the expected time. |
| 3263 | */ |
| 3264 | static Query * |
| 3265 | transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt) |
| 3266 | { |
| 3267 | Query *result; |
| 3268 | Query *query; |
| 3269 | |
| 3270 | pstate->p_is_on_conflict_update = false; |
| 3271 | |
| 3272 | /* |
| 3273 | * Don't allow both SCROLL and NO SCROLL to be specified |
| 3274 | */ |
| 3275 | if ((stmt->options & CURSOR_OPT_SCROLL) && |
| 3276 | (stmt->options & CURSOR_OPT_NO_SCROLL)) |
| 3277 | ereport(ERROR, |
| 3278 | (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), |
| 3279 | /* translator: %s is a SQL keyword */ |
| 3280 | errmsg("cannot specify both %s and %s", |
| 3281 | "SCROLL", "NO SCROLL"))); |
| 3282 | |
| 3283 | if ((stmt->options & CURSOR_OPT_ASENSITIVE) && |
| 3284 | (stmt->options & CURSOR_OPT_INSENSITIVE)) |
| 3285 | ereport(ERROR, |
| 3286 | (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), |
| 3287 | /* translator: %s is a SQL keyword */ |
| 3288 | errmsg("cannot specify both %s and %s", |
| 3289 | "ASENSITIVE", "INSENSITIVE"))); |
| 3290 | |
| 3291 | /* Transform contained query, not allowing SELECT INTO */ |
| 3292 | query = transformStmt(pstate, stmt->query); |
| 3293 | stmt->query = (Node *) query; |
| 3294 | |
| 3295 | /* Grammar should not have allowed anything but SELECT */ |
| 3296 | if (!IsA(query, Query) || |
| 3297 | query->commandType != CMD_SELECT) |
| 3298 | elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR"); |
| 3299 | |
| 3300 | /* Can not support holdable or scrollable PARALLEL RETRIEVE CURSOR at present */ |
| 3301 | if ((stmt->options & CURSOR_OPT_HOLD) && (stmt->options & CURSOR_OPT_PARALLEL_RETRIEVE)) |
| 3302 | ereport(ERROR, |
| 3303 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 3304 | errmsg("DECLARE PARALLEL RETRIEVE CURSOR WITH HOLD ... is not supported"), |
| 3305 | errdetail("Holdable cursors can not be parallel"))); |
| 3306 | |
| 3307 | if ((stmt->options & CURSOR_OPT_SCROLL) && (stmt->options & CURSOR_OPT_PARALLEL_RETRIEVE)) |
| 3308 | ereport(ERROR, |
| 3309 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 3310 | errmsg("SCROLL is not allowed for the PARALLEL RETRIEVE CURSORs"), |
| 3311 | errdetail("Scrollable cursors can not be parallel"))); |
| 3312 | |
| 3313 | /* |
| 3314 | * We also disallow data-modifying WITH in a cursor. (This could be |
| 3315 | * allowed, but the semantics of when the updates occur might be |
| 3316 | * surprising.) |
| 3317 | */ |
| 3318 | if (query->hasModifyingCTE) |
| 3319 | ereport(ERROR, |
| 3320 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 3321 | errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH"))); |
no test coverage detected