* Execute given SQL string. * * Note: it's tempting to just use SPI to execute the string, but that does * not work very well. The really serious problem is that SPI will parse, * analyze, and plan the whole string before executing any of it; of course * this fails if there are any plannable statements referring to objects * created earlier in the script. A lesser annoyance is that SPI ins
| 712 | * could be very long. |
| 713 | */ |
| 714 | void |
| 715 | execute_sql_string(const char *sql) |
| 716 | { |
| 717 | List *raw_parsetree_list; |
| 718 | DestReceiver *dest; |
| 719 | ListCell *lc1; |
| 720 | |
| 721 | /* |
| 722 | * Parse the SQL string into a list of raw parse trees. |
| 723 | */ |
| 724 | raw_parsetree_list = pg_parse_query(sql); |
| 725 | |
| 726 | /* All output from SELECTs goes to the bit bucket */ |
| 727 | dest = CreateDestReceiver(DestNone); |
| 728 | |
| 729 | /* |
| 730 | * Do parse analysis, rule rewrite, planning, and execution for each raw |
| 731 | * parsetree. We must fully execute each query before beginning parse |
| 732 | * analysis on the next one, since there may be interdependencies. |
| 733 | */ |
| 734 | foreach(lc1, raw_parsetree_list) |
| 735 | { |
| 736 | RawStmt *parsetree = lfirst_node(RawStmt, lc1); |
| 737 | MemoryContext per_parsetree_context, |
| 738 | oldcontext; |
| 739 | List *stmt_list; |
| 740 | ListCell *lc2; |
| 741 | |
| 742 | /* |
| 743 | * We do the work for each parsetree in a short-lived context, to |
| 744 | * limit the memory used when there are many commands in the string. |
| 745 | */ |
| 746 | per_parsetree_context = |
| 747 | AllocSetContextCreate(CurrentMemoryContext, |
| 748 | "execute_sql_string per-statement context", |
| 749 | ALLOCSET_DEFAULT_SIZES); |
| 750 | oldcontext = MemoryContextSwitchTo(per_parsetree_context); |
| 751 | |
| 752 | /* Be sure parser can see any DDL done so far */ |
| 753 | CommandCounterIncrement(); |
| 754 | |
| 755 | stmt_list = pg_analyze_and_rewrite(parsetree, |
| 756 | sql, |
| 757 | NULL, |
| 758 | 0, |
| 759 | NULL); |
| 760 | stmt_list = pg_plan_queries(stmt_list, sql, CURSOR_OPT_PARALLEL_OK, NULL); |
| 761 | |
| 762 | foreach(lc2, stmt_list) |
| 763 | { |
| 764 | PlannedStmt *stmt = lfirst_node(PlannedStmt, lc2); |
| 765 | |
| 766 | CommandCounterIncrement(); |
| 767 | |
| 768 | PushActiveSnapshot(GetTransactionSnapshot()); |
| 769 | |
| 770 | if (stmt->utilityStmt == NULL) |
| 771 | { |
no test coverage detected