PostgreSQL在何处处理 sql查询之二
在exec_simple_query中,代码如下:
1 /* 2 * exec_simple_query 3 * 4 * Execute a "simple Query" protocol message. 5 */ 6 static void 7 exec_simple_query(const char *query_string) 8 { 9 CommandDest dest = whereToSendOutput; 10 MemoryContext oldcontext; 11 List *parsetree_list; 12 ListCell *parsetree_item; 13 14 15 bool save_log_statement_stats = log_statement_stats; 16 bool was_logged = false; 17 bool isTopLevel; 18 char msec_str[32]; 19 20 21 /* 22 * Report query to various monitoring facilities. 23 */ 24 debug_query_string = query_string; 25 26 pgstat_report_activity(STATE_RUNNING, query_string); 27 28 TRACE_POSTGRESQL_QUERY_START(query_string); 29 30 /* 31 * We use save_log_statement_stats so ShowUsage doesn't report incorrect 32 * results because ResetUsage wasn't called. 33 */ 34 if (save_log_statement_stats) 35 ResetUsage(); 36 37 /* 38 * Start up a transaction command. All queries generated by the 39 * query_string will be in this same command block, *unless* we find a 40 * BEGIN/COMMIT/ABORT statement; we have to force a new xact command after 41 * one of those, else bad things will happen in xact.c. (Note that this 42 * will normally change current memory context.) 43 */ 44 start_xact_command(); 45 46 /* 47 * Zap any pre-existing unnamed statement. (While not strictly necessary, 48 * it seems best to define simple-Query mode as if it used the unnamed 49 * statement and portal; this ensures we recover any storage used by prior 50 * unnamed operations.) 51 */ 52 drop_unnamed_stmt(); 53 54 /* 55 * Switch to appropriate context for constructing parsetrees. 56 */ 57 oldcontext = MemoryContextSwitchTo(MessageContext); 58 59 /* 60 * Do basic parsing of the query or queries (this should be safe even if 61 * we are in aborted transaction state!) 62 */ 63 parsetree_list = pg_parse_query(query_string); 64 65 /* Log immediately if dictated by log_statement */ 66 if (check_log_statement(parsetree_list)) 67 { 68 ereport(LOG, 69 (errmsg("statement: %s", query_string), 70 errhidestmt(true), 71 errdetail_execute(parsetree_list))); 72 was_logged = true; 73 } 74 75 /* 76 * Switch back to transaction context to enter the loop. 77 */ 78 MemoryContextSwitchTo(oldcontext); 79 80 /* 81 * We'll tell PortalRun it's a top-level command iff there's exactly one 82 * raw parsetree. If more than one, it's effectively a transaction block 83 * and we want PreventTransactionChain to reject unsafe commands. (Note: 84 * we're assuming that query rewrite cannot add commands that are 85 * significant to PreventTransactionChain.) 86 */ 87 isTopLevel = (list_length(parsetree_list) == 1); 88 89 /* 90 * Run through the raw parsetree(s) and process each one. 91 */ 92 foreach(parsetree_item, parsetree_list) 93 { 94 Node *parsetree = (Node *) lfirst(parsetree_item); 95 96 bool snapshot_set = false; 97 const char *commandTag; 98 char completionTag[COMPLETION_TAG_BUFSIZE]; 99 List *querytree_list, 100 *plantree_list; 101 Portal portal; 102 DestReceiver *receiver; 103 int16 format; 104 105 /* 106 * Get the command name for use in status display (it also becomes the 107 * default completion tag, down inside PortalRun). Set ps_status and 108 * do any special start-of-SQL-command processing needed by the 109 * destination. 110 */ 111 commandTag = CreateCommandTag(parsetree); 112 113 //fprintf(stderr,"commandTag is :%s\n",commandTag); 114 115 set_ps_display(commandTag, false); 116 117 BeginCommand(commandTag, dest); 118 119 //fprintf(stderr,"BeginCommand finished.\n"); 120 121 /* 122 * If we are in an aborted transaction, reject all commands except 123 * COMMIT/ABORT. It is important that this test occur before we try 124 * to do parse analysis, rewrite, or planning, since all those phases 125 * try to do database accesses, which may fail in abort state. (It 126 * might be safe to allow some additional utility commands in this 127 * state, but not many...) 128 */ 129 if (IsAbortedTransactionBlockState() && 130 !IsTransactionExitStmt(parsetree)) 131 ereport(ERROR, 132 (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION), 133 errmsg("current transaction is aborted, " 134 "commands ignored until end of transaction block"), 135 errdetail_abort())); 136 137 /* Make sure we are in a transaction command */ 138 start_xact_command(); 139 140 /* If we got a cancel signal in parsing or prior command, quit */ 141 CHECK_FOR_INTERRUPTS(); 142 143 /* 144 * Set up a snapshot if parse analysis/planning will need one. 145 */ 146 if (analyze_requires_snapshot(parsetree)) 147 { 148 PushActiveSnapshot(GetTransactionSnapshot()); 149 snapshot_set = true; 150 } 151 152 /* 153 * OK to analyze, rewrite, and plan this query. 154 * 155 * Switch to appropriate context for constructing querytrees (again, 156 * these must outlive the execution context). 157 */ 158 oldcontext = MemoryContextSwitchTo(MessageContext); 159 160 querytree_list = pg_analyze_and_rewrite(parsetree, query_string, 161 NULL, 0); 162 163 plantree_list = pg_plan_queries(querytree_list, 0, NULL); 164 165 /* If we got a cancel signal in analysis or planning, quit */ 166 CHECK_FOR_INTERRUPTS(); 167 168 /* 169 * Create unnamed portal to run the query or queries in. If there 170 * already is one, silently drop it. 171 */ 172 portal = CreatePortal("", true, true); 173 /* Don't display the portal in pg_cursors */ 174 portal->visible = false; 175 176 /* 177 * We don't have to copy anything into the portal, because everything 178 * we are passing here is in MessageContext, which will outlive the 179 * portal anyway. 180 */ 181 PortalDefineQuery(portal, 182 NULL, 183 query_string, 184 commandTag, 185 plantree_list, 186 NULL); 187 188 /* 189 * Start the portal. 190 * 191 * If we took a snapshot for parsing/planning, the portal may be able 192 * to reuse it for the execution phase. Currently, this will only 193 * happen in PORTAL_ONE_SELECT mode. But even if PortalStart doesn't 194 * end up being able to do this, keeping the parse/plan snapshot 195 * around until after we start the portal doesn't cost much. 196 */ 197 PortalStart(portal, NULL, 0, snapshot_set); 198 199 /* Done with the snapshot used for parsing/planning */ 200 if (snapshot_set) 201 PopActiveSnapshot(); 202 203 /* 204 * Select the appropriate output format: text unless we are doing a 205 * FETCH from a binary cursor. (Pretty grotty to have to do this here 206 * --- but it avoids grottiness in other places. Ah, the joys of 207 * backward compatibility...) 208 */ 209 format = 0; /* TEXT is default */ 210 if (IsA(parsetree, FetchStmt)) 211 { 212 FetchStmt *stmt = (FetchStmt *) parsetree; 213 214 if (!stmt->ismove) 215 { 216 Portal fportal = GetPortalByName(stmt->portalname); 217 218 if (PortalIsValid(fportal) && 219 (fportal->cursorOptions & CURSOR_OPT_BINARY)) 220 format = 1; /* BINARY */ 221 } 222 } 223 PortalSetResultFormat(portal, 1, &format); 224 225 /* 226 * Now we can create the destination receiver object. 227 */ 228 receiver = CreateDestReceiver(dest); 229 if (dest == DestRemote) 230 SetRemoteDestReceiverParams(receiver, portal); 231 232 /* 233 * Switch back to transaction context for execution. 234 */ 235 MemoryContextSwitchTo(oldcontext); 236 237 /* 238 * Run the portal to completion, and then drop it (and the receiver). 239 */ 240 (void) PortalRun(portal, 241 FETCH_ALL, 242 isTopLevel, 243 receiver, 244 receiver, 245 completionTag); 246 247 (*receiver->rDestroy) (receiver); 248 249 PortalDrop(portal, false); 250 251 if (IsA(parsetree, TransactionStmt)) 252 { 253 /* 254 * If this was a transaction control statement, commit it. We will 255 * start a new xact command for the next command (if any). 256 */ 257 finish_xact_command(); 258 } 259 else if (lnext(parsetree_item) == NULL) 260 { 261 /* 262 * If this is the last parsetree of the query string, close down 263 * transaction statement before reporting command-complete. This 264 * is so that any end-of-transaction errors are reported before 265 * the command-complete message is issued, to avoid confusing 266 * clients who will expect either a command-complete message or an 267 * error, not one and then the other. But for compatibility with 268 * historical Postgres behavior, we do not force a transaction 269 * boundary between queries appearing in a single query string. 270 */ 271 finish_xact_command(); 272 } 273 else 274 { 275 /* 276 * We need a CommandCounterIncrement after every query, except 277 * those that start or end a transaction block. 278 */ 279 CommandCounterIncrement(); 280 } 281 282 /* 283 * Tell client that we're done with this query. Note we emit exactly 284 * one EndCommand report for each raw parsetree, thus one for each SQL 285 * command the client sent, regardless of rewriting. (But a command 286 * aborted by error will not send an EndCommand report at all.) 287 */ 288 EndCommand(completionTag, dest); 289 } /* end loop over parsetrees */ 290 291 292 293 294 /* 295 * Close down transaction statement, if one is open. 296 */ 297 finish_xact_command(); 298 299 /* 300 * If there were no parsetrees, return EmptyQueryResponse message. 301 */ 302 if (!parsetree_list) 303 NullCommand(dest); 304 305 /* 306 * Emit duration logging if appropriate. 307 */ 308 switch (check_log_duration(msec_str, was_logged)) 309 { 310 case 1: 311 ereport(LOG, 312 (errmsg("duration: %s ms", msec_str), 313 errhidestmt(true))); 314 break; 315 case 2: 316 ereport(LOG, 317 (errmsg("duration: %s ms statement: %s", 318 msec_str, query_string), 319 errhidestmt(true), 320 errdetail_execute(parsetree_list))); 321 break; 322 } 323 324 if (save_log_statement_stats) 325 ShowUsage("QUERY STATISTICS"); 326 327 TRACE_POSTGRESQL_QUERY_DONE(query_string); 328 329 debug_query_string = NULL; 334 335 }
其中,从 portal = CreatePortal("", true, true); 这一句开始,就是准备要执行了。
转载于:https://www.cnblogs.com/gaojian/archive/2013/05/22/3092073.html
PostgreSQL在何处处理 sql查询之二相关推荐
- PostgreSQL在何处处理 sql查询之二十二
接前面. 回到程序调用关系上来: estimate_rel_size -> RelationGetNumberOfBlocks->RelationGetNumberOfBlocksINFo ...
- PostgreSQL在何处处理 sql查询之二十一
接前面: 回到mdopen上来,看看是谁调用了 mdopen,又获得了什么. /** mdnblocks() -- Get the number of blocks stored in a relat ...
- PostgreSQL在何处处理 sql查询之五十二
开始 /** Ready to do the primary planning.*/final_rel = make_one_rel(root, joinlist); 展开: /** make_one ...
- PostgreSQL在何处处理 sql查询之十二
接前面,对 subquery_planner,进行进一步的分析: /*--------------------* subquery_planner* Invokes the planner on a ...
- PostgreSQL在何处处理 sql查询之六十二
对 RelOptInfo * make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) 函数进行研究: 看看 inner ...
- PostgreSQL在何处处理 sql查询之五十一
继续分析 query_planner: /** query_planner* Generate a path (that is, a simplified plan) for a basic quer ...
- PostgreSQL在何处处理 sql查询之四十七
再次上溯: /*--------------------* subquery_planner* Invokes the planner on a subquery. We recurse to her ...
- PostgreSQL在何处处理 sql查询
如果我开一个psql窗口,来输入sql文,它在数据库的何处被解析?在何处被"真正"处理? postgres.c 的 int PostgresMain(int argc, char ...
- PostgreSQL在何处处理 sql查询之五十四
接前面,从 cheapeast_path 的角度,关注 query_planner 函数,对其进行简化: void query_planner(PlannerInfo *root, List *tli ...
最新文章
- 面试高频——JUC并发工具包快速上手(超详细总结)
- python标准异常
- 提高Excel中VBA效率的四种方法
- python 柱状图-【python】【数据分析】3D柱状图就是这么好看
- PHP $_REQUEST获取表单提交的代码
- 小余学调度:调度指令票系列讲解1(持续更新中ing)
- kafka 0.9 java开发_kafka 0.9 java producer and consumer demo
- 【电设控制与图像训练题】【激光打靶】【openmv测试代码以及效果】
- python对非it上班族有用吗_非专业人士学Python有用吗?
- delphi idtcpclient 发送十六进制00_91413足球推荐分析 法甲 04:00 南特 VS 巴黎圣日尔曼...
- python 配置文件对比_Python3实现配置文件差异对比脚本
- LR录制脚本后,中文显示的是乱码,怎么解决?
- composer killed while updating or install
- ubuntu第三方源导致软件无法安装的问题
- HttpPrinter-网页打印控件
- 【区间选点问题】 N个闭区间,最少需要多少个点,让每个闭区间都有一个点
- 【Unity】用Lerp()实现类杀戮尖塔手牌变化
- uiautomator2+adb shell input tap 实现微博自动取消关注
- 疫情大考,文旅央企华侨城出台有力措施保障游客安全
- 哈工大计算机网络week4学习总结
热门文章
- MYSQL常用操作速查
- 前端ajax传递json格式参数,后端springboot接收
- 电脑开机提示计算机无法启动不了,电脑无法启动并出现“System Halted”如何解决?...
- 查看php项目tp版本,tp5.1如何查看版本号
- vue3中setup()函数的使用一
- centos 删除crontab_Centos7:利用crontab定时执行任务
- tensorflow sigmoid 如何计算训练数据的正确率_“来自蒙娜丽莎的凝视”— 结合 TensorFlow.js 和深度学习实现...
- extmail如何登陆mysql_rhel5.4下postfix+mysql+extmail中mysql密码怎么设置?
- php载入内存的是本地代码吗,常量和静态变量会先载入内存后在进行执行php代码...
- 算法导论 练习9.3-8两个有序数组的中位数