不可優(yōu)化語句包括DDL浓领、DCL等玉凯。與DML語句不同,它們的處理方式是為每一個類型的語句提供相應的處理函數(shù)联贩。
PostgreSQL在SQL語法解析時漫仆,對于所有的SQL語句都會生成相應的Statement數(shù)據(jù)結(jié)構(gòu)。例如泪幌,SELECT語句有對應的SelectStmt數(shù)據(jù)結(jié)構(gòu)盲厌,CREATE TABLE語句有對應的CreateStmt語句玄渗。解析的結(jié)果就是一個ParseTree的鏈表,鏈上的每一個節(jié)點都是一個Statement的數(shù)據(jù)結(jié)構(gòu)狸眼。
在語義分析階段藤树,會對Statement進行分析轉(zhuǎn)換。具體的轉(zhuǎn)換過程在函數(shù)transformStmt
中拓萌,這里不展開敘述岁钓。分析的結(jié)果是將ParseTree轉(zhuǎn)換成便于優(yōu)化器工作的QueryTree。而對于不可優(yōu)化語句微王,在分析階段只是簡單的創(chuàng)建一個Query對象屡限,并將具體的Statement掛載到Query::utilityStmt
字段上,并將Query::commandType
字段設(shè)置為CMD_UTILITY
炕倘。
在查詢重寫階段钧大,不可優(yōu)化語句被直接跳過,不需要重寫罩旋。
在查詢優(yōu)化階段啊央,不可優(yōu)化語句不需要規(guī)劃路徑,被直接掛載到生成的PlannedStmt
上涨醋。
因此瓜饥,對于不可優(yōu)化語句,執(zhí)行器得到的計劃樹中只有SQL語法解析后的Statement數(shù)據(jù)結(jié)構(gòu)浴骂。該計劃樹在函數(shù)PortalDefineQuery
中被設(shè)置到Portal上乓土。
在PortalStart
中選擇執(zhí)行策略時,對于不可優(yōu)化語句溯警,只有返回元組時(參見函數(shù)UtilityReturnsTuples
)才會選擇PORTAL_UTIL_SELECT
,否則選擇PORTAL_MULTI_QUERY
趣苏。
在PortalRun
階段,執(zhí)行流程最終會進入到函數(shù)ProcessUtility
中梯轻,對不同的Statement執(zhí)行特定的處理邏輯食磕。
針對各種不同的査詢樹,査詢編譯器在執(zhí)行處理前會做一些額外的處理對査詢樹進行分析檩淋、處理與轉(zhuǎn)換芬为。例如萄金,創(chuàng)建表的語句會用函數(shù)transformCreateStmt
進行査詢樹的處理蟀悦。這些處理過程可能會在當前操作之前和之后增加一些新的操作(例如在創(chuàng)建表的操作之前增加創(chuàng)建serial序列表操作、之后增加創(chuàng)建觸發(fā)器用于外鍵約束操作等)氧敢,也可能會執(zhí)行對數(shù)據(jù)結(jié)構(gòu)的處理操作(例如將CreateStmt
節(jié)點tableElts字段中CONST_CHECK類型的Constraint
節(jié)點轉(zhuǎn)存到CreateStmt
的ccmstraints鏈表中等)罩锐。由于這些處理過程會產(chǎn)生一些新的操作枫攀,因此最終會生成一個由多個操作構(gòu)成的鏈表。因此,執(zhí)行過程需要依次掃描該鏈表,為每一個原子操作調(diào)用相應的處理函數(shù)存崖。
下面是創(chuàng)建表進入到執(zhí)行階段時的函數(shù)棧調(diào)用:
transformCreateStmt parse_utilcmd.c:171
ProcessUtilitySlow utility.c:996
standard_ProcessUtility utility.c:923
ProcessUtility utility.c:360
PortalRunUtility pquery.c:1178
PortalRunMulti pquery.c:1324
PortalRun pquery.c:799
exec_simple_query postgres.c:1145
PostgresMain postgres.c:4182
BackendRun postmaster.c:4358
BackendStartup postmaster.c:4030
ServerLoop postmaster.c:1707
PostmasterMain postmaster.c:1380
main main.c:228
start 0x00007fff709083d5
從實現(xiàn)上看,ProcessUtility
只作為入口選擇函數(shù),它會根據(jù)輸人的節(jié)點類型調(diào)用相應的處理過程蜗帜。