* Set up the per-query execution_state records for a SQL function. * * The input is a List of Lists of parsed and rewritten, but not planned, * querytrees. The sublist structure denotes the original query boundaries. */
| 556 | * querytrees. The sublist structure denotes the original query boundaries. |
| 557 | */ |
| 558 | static List * |
| 559 | init_execution_state(List *queryTree_list, |
| 560 | SQLFunctionCachePtr fcache, |
| 561 | bool lazyEvalOK) |
| 562 | { |
| 563 | List *eslist = NIL; |
| 564 | execution_state *lasttages = NULL; |
| 565 | ListCell *lc1; |
| 566 | |
| 567 | foreach(lc1, queryTree_list) |
| 568 | { |
| 569 | List *qtlist = lfirst_node(List, lc1); |
| 570 | execution_state *firstes = NULL; |
| 571 | execution_state *preves = NULL; |
| 572 | ListCell *lc2; |
| 573 | |
| 574 | foreach(lc2, qtlist) |
| 575 | { |
| 576 | Query *queryTree = lfirst_node(Query, lc2); |
| 577 | PlannedStmt *stmt; |
| 578 | execution_state *newes; |
| 579 | |
| 580 | /* Plan the query if needed */ |
| 581 | if (queryTree->commandType == CMD_UTILITY) |
| 582 | { |
| 583 | /* Utility commands require no planning. */ |
| 584 | stmt = makeNode(PlannedStmt); |
| 585 | stmt->commandType = CMD_UTILITY; |
| 586 | stmt->canSetTag = queryTree->canSetTag; |
| 587 | stmt->utilityStmt = queryTree->utilityStmt; |
| 588 | stmt->stmt_location = queryTree->stmt_location; |
| 589 | stmt->stmt_len = queryTree->stmt_len; |
| 590 | } |
| 591 | else |
| 592 | stmt = pg_plan_query(queryTree, |
| 593 | fcache->src, |
| 594 | CURSOR_OPT_PARALLEL_OK, |
| 595 | NULL); |
| 596 | |
| 597 | if (IsA(stmt, PlannedStmt)) |
| 598 | ((PlannedStmt*)stmt)->metricsQueryType = FUNCTION_INNER_QUERY; |
| 599 | |
| 600 | /* |
| 601 | * Precheck all commands for validity in a function. This should |
| 602 | * generally match the restrictions spi.c applies. |
| 603 | */ |
| 604 | if (stmt->commandType == CMD_UTILITY) |
| 605 | { |
| 606 | if (IsA(stmt->utilityStmt, CopyStmt) && |
| 607 | ((CopyStmt *) stmt->utilityStmt)->filename == NULL) |
| 608 | ereport(ERROR, |
| 609 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 610 | errmsg("cannot COPY to/from client in an SQL function"))); |
| 611 | |
| 612 | if (IsA(stmt->utilityStmt, TransactionStmt)) |
| 613 | ereport(ERROR, |
| 614 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 615 | /* translator: %s is a SQL statement name */ |
no test coverage detected