{"id":407728,"date":"2024-06-29T19:43:42","date_gmt":"2024-06-29T19:43:42","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=407728"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T19:43:42","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=407728","title":{"rendered":"<span>PostgreSQL \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u0427\u0430\u0441\u0442\u044c 5. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 SELECT \u0437\u0430\u043f\u0440\u043e\u0441<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e!<\/p>\n<p>\u041d\u0430 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u0438\u0437\u0443\u0447\u0438\u043b\u0438 \u0446\u0438\u043a\u043b \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430. \u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 <code>SELECT<\/code> \u0437\u0430\u043f\u0440\u043e\u0441. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0430 <code>users<\/code><\/p>\n<pre><code class=\"sql\">create table users(   id integer generated always as identity,   email varchar not null,   name varchar );<\/code><\/pre>\n<p>\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u043d\u0435\u0435:<\/p>\n<pre><code class=\"sql\">select * from users;<\/code><\/pre>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h2>\n<p>\u041f\u0443\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>exec_simple_query<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/tcop\/postgres.c#L992\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a>), \u0442\u0430\u043a \u043a\u0430\u043a \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b <a href=\"https:\/\/www.postgresql.org\/docs\/current\/protocol-flow.html#id-1.10.6.7.4\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438<\/a>.<\/p>\n<h4>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 <\/h4>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0431\u043b\u043e\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438. \u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>pgstat_report_activity<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/utils\/activity\/backend_status.c#L521\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/activity\/backend_status.c<\/a>), \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 (<code>STATE_RUNNING<\/code>) \u0438 \u0441\u044b\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0421\u0430\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0430\u0442\u0443\u0441\u0430<\/p>\n<\/li>\n<li>\n<p>\u0412\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441<\/p>\n<\/li>\n<li>\n<p>\u0412\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441\u0435<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>ResetUsage<\/code> \u0434\u043b\u044f \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0447\u0435\u0442\u0430 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432: \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u0441\u0438\u0433\u043d\u0430\u043b\u044b. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b &lt;sys\/resource.h>. \u0412 \u043d\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u0422\u0430\u043a, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 rusage:<\/p>\n<pre><code class=\"cpp\">struct rusage {     \/* Total amount of user time used.  *\/     struct timeval ru_utime;     \/* Total amount of system time used.  *\/     struct timeval ru_stime;     \/* Maximum resident set size (in kilobytes).  *\/     union     {         long int ru_maxrss;         __syscall_slong_t __ru_maxrss_word;     };     \/* Amount of sharing of text segment memory        with other processes (kilobyte-seconds).  *\/     union     {         long int ru_ixrss;         __syscall_slong_t __ru_ixrss_word;     };     \/* Amount of data segment memory used (kilobyte-seconds).  *\/     union     {         long int ru_idrss;         __syscall_slong_t __ru_idrss_word;     };     \/* Amount of stack memory used (kilobyte-seconds).  *\/          union     {         long int ru_isrss;         __syscall_slong_t __ru_isrss_word;     };     \/* Number of soft page faults (i.e. those serviced by reclaiming        a page from the list of pages awaiting reallocation.  *\/     union     {         long int ru_minflt;         __syscall_slong_t __ru_minflt_word;     };     \/* Number of hard page faults (i.e. those that required I\/O).  *\/     union     {         long int ru_majflt;         __syscall_slong_t __ru_majflt_word;     };     \/* Number of times a process was swapped out of physical memory.  *\/     union     {         long int ru_nswap;         __syscall_slong_t __ru_nswap_word;     };     \/* Number of input operations via the file system.  Note: This        and `ru_oublock' do not include operations with the cache.  *\/     union     {         long int ru_inblock;         __syscall_slong_t __ru_inblock_word;     };     \/* Number of output operations via the file system.  *\/     union     {         long int ru_oublock;         __syscall_slong_t __ru_oublock_word;     };     \/* Number of IPC messages sent.  *\/     union     {         long int ru_msgsnd;         __syscall_slong_t __ru_msgsnd_word;     };     \/* Number of IPC messages received.  *\/     union     {         long int ru_msgrcv;         __syscall_slong_t __ru_msgrcv_word;     };     \/* Number of signals delivered.  *\/     union     {         long int ru_nsignals;         __syscall_slong_t __ru_nsignals_word;     };     \/* Number of voluntary context switches, i.e. because the process        gave up the process before it had to (usually to wait for some        resource to be available).  *\/     union     {         long int ru_nvcsw;         __syscall_slong_t __ru_nvcsw_word;     };     \/* Number of involuntary context switches, i.e. a higher priority process        became runnable or the current process used up its time slice.  *\/    union     {         long int ru_nivcsw;         __syscall_slong_t __ru_nivcsw_word;     }; };<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0439 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>getrusage<\/code> &#8212; \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 (<a href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/getrusage.2.html\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/man7.org\/linux\/man-pages\/man2\/getrusage.2.html<\/u><\/a>).\u00a0<\/p>\n<p>\u0412 Postgres \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e GUC \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a <code>log_*_stats<\/code>. \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b, \u0442\u043e \u043f\u043e \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u0442\u0430\u043f\u0430 \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c <code>log_statement_stats<\/code> \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445, \u0435\u0441\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435) \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043b\u043e\u0433.\u00a0<\/p>\n<p>\u0417\u0430 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>ShowUsage<\/code><\/p>\n<pre><code class=\"cpp\">void ShowUsage(const char *title);<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u201cQUERY STATISTICS\u201d<\/p>\n<pre><code class=\"cpp\">ShowUsage(\"QUERY STATISTICS\");<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043e\u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u043e\u0439 \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043b\u043e\u0433.\u00a0<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0432\u0445\u043e\u0434\u043e\u043c \u0432 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043e\u0431\u043b\u0430\u0441\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ResetUsage<\/code>. \u041e\u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0443 \u043e\u0442\u0441\u0447\u0435\u0442\u0430. \u041f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 ShowUsage \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0414\u043b\u044f <code>exec_simple_query<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"cpp\">if (save_log_statement_stats)     ResetUsage();  \/\/\/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430  if (save_log_statement_stats) ShowUsage(\"QUERY STATISTICS\");<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>\u041d\u0430\u0447\u0430\u043b\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/h4>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f. <\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u0435\u0441\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <code>xact<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/access\/transam\/xact.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/access\/transam\/xact.c<\/a>). \u041d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f Postgres \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0441\u0432\u043e\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: <code>start_xact_command<\/code> \u0438 <code>finish_xact_command<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u00a0\u043d\u0430\u0447\u0430\u043b\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f\u00a0\u2014 \u0437\u0430\u00a0\u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u00a0\u043d\u0438\u0445 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. \u041a\u0430\u043a\u00a0\u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b, \u043e\u043d\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 (\u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\/\u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442) \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430\u043c\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u00a0\u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043d\u0430\u00a0\u0432\u0435\u0441\u044c \u0431\u043b\u043e\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442\u00a0\u0442\u043e\u0433\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u0442\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u00a0\u043d\u0435\u044f\u0432\u043d\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e.<\/p>\n<h4>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0443<\/h4>\n<p>\u041f\u043b\u0430\u043d\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443. \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>CachedPlanSource<\/code>, \u0430 \u0441\u0430\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c (\u0434\u043b\u044f \u0431\u044d\u043a\u044d\u043d\u0434\u0430) \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435.\u00a0<\/p>\n<pre><code class=\"cpp\">typedef struct CachedPlanSource { intmagic;\/* should equal CACHEDPLANSOURCE_MAGIC *\/ struct RawStmt *raw_parse_tree; \/* output of raw_parser(), or NULL *\/ const char *query_string;\/* source text of query *\/ CommandTagcommandTag;\/* 'nuff said *\/ Oid   *param_types;\/* array of parameter type OIDs, or NULL *\/ intnum_params;\/* length of param_types array *\/ ParserSetupHook parserSetup;\/* alternative parameter spec method *\/ void   *parserSetupArg; intcursor_options; \/* cursor options used for planning *\/ boolfixed_result;\/* disallow change in result tupdesc? *\/ TupleDescresultDesc;\/* result type; NULL = doesn't return tuples *\/ MemoryContext context;\/* memory context holding all above *\/ \/* These fields describe the current analyzed-and-rewritten query tree: *\/ List   *query_list;\/* list of Query nodes, or NIL if not valid *\/ List   *relationOids;\/* OIDs of relations the queries depend on *\/ List   *invalItems;\/* other dependencies, as PlanInvalItems *\/ struct OverrideSearchPath *search_path; \/* search_path used for parsing  * and planning *\/ MemoryContext query_context;\/* context holding the above, or NULL *\/ OidrewriteRoleId;\/* Role ID we did rewriting for *\/ boolrewriteRowSecurity; \/* row_security used during rewrite *\/ booldependsOnRLS;\/* is rewritten query specific to the above? *\/ \/* If we have a generic plan, this is a reference-counted link to it: *\/ struct CachedPlan *gplan;\/* generic plan, or NULL if not valid *\/ \/* Some state flags: *\/ boolis_oneshot;\/* is it a \"oneshot\" plan? *\/ boolis_complete;\/* has CompleteCachedPlan been done? *\/ boolis_saved;\/* has CachedPlanSource been \"saved\"? *\/ boolis_valid;\/* is the query_list currently valid? *\/ intgeneration;\/* increments each time we create a plan *\/ \/* If CachedPlanSource has been saved, it is a member of a global list *\/ dlist_nodenode;\/* list link, if is_saved *\/ \/* State kept to help decide whether to use custom or generic plans: *\/ doublegeneric_cost;\/* cost of generic plan, or -1 if not known *\/ doubletotal_custom_cost;\/* total cost of custom plans so far *\/ int64num_custom_plans;\/* # of custom plans included in total *\/ int64num_generic_plans;\/* # of generic plans *\/ } CachedPlanSource;<\/code><\/pre>\n<p>1 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u043c\u0435\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 1 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043d\u0430 \u0435\u0433\u043e \u043f\u043e\u0438\u0441\u043a \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043d\u0438\u0445 (\u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0445) \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f unnnamed_stmt_psrc:<\/p>\n<pre><code class=\"cpp\">\/*  * If an unnamed prepared statement exists, it's stored here.  * We keep it separate from the hashtable kept by commands\/prepare.c  * in order to reduce overhead for short-lived queries.  *\/ static CachedPlanSource *unnamed_stmt_psrc = NULL;<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 SimpleQuery \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043d\u0435\u0439. \u041a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u043b\u0430\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0430 <code>MessageContext<\/code>. \u0412 \u043d\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0417\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <code>parser<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/parser\/parser.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/parser\/parser.c<\/a>). \u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>raw_parser<\/code><\/p>\n<pre><code class=\"cpp\">\/*  * raw_parser  *Given a query in string form, do lexical and grammatical analysis.  *  * Returns a list of raw (un-analyzed) parse trees.  The contents of the  * list have the form required by the specified RawParseMode.  *\/ List * raw_parser(const char *str, RawParseMode mode);<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0440\u0435\u0436\u0438\u043c \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 &#8212; <code>RawParseMethod<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/parser\/parser.h#L37\" rel=\"noopener noreferrer nofollow\">src\/include\/parser\/parser.h<\/a>). \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c SQL \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>RAW_PARSE_DEFAULT<\/code>. \u0412\u0441\u0435\u0433\u043e \u0435\u0441\u0442\u044c 6 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430<\/p>\n<pre><code class=\"cpp\">\/*  * RawParseMode determines the form of the string that raw_parser() accepts:  *  * RAW_PARSE_DEFAULT: parse a semicolon-separated list of SQL commands,  * and return a List of RawStmt nodes.  *  * RAW_PARSE_TYPE_NAME: parse a type name, and return a one-element List  * containing a TypeName node.  *  * RAW_PARSE_PLPGSQL_EXPR: parse a PL\/pgSQL expression, and return  * a one-element List containing a RawStmt node.  *  * RAW_PARSE_PLPGSQL_ASSIGNn: parse a PL\/pgSQL assignment statement,  * and return a one-element List containing a RawStmt node.  \"n\"  * gives the number of dotted names comprising the target ColumnRef.  *\/ typedef enum { RAW_PARSE_DEFAULT = 0, RAW_PARSE_TYPE_NAME, RAW_PARSE_PLPGSQL_EXPR, RAW_PARSE_PLPGSQL_ASSIGN1, RAW_PARSE_PLPGSQL_ASSIGN2, RAW_PARSE_PLPGSQL_ASSIGN3 } RawParseMode;<\/code><\/pre>\n<p>\u0417\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Lex\" rel=\"noopener noreferrer nofollow\">LEX<\/a>. \u041a\u043e\u0434 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043b\u0435\u0436\u0438\u0442 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/parser\/scan.l\" rel=\"noopener noreferrer nofollow\">src\/backend\/parser\/scan.l<\/a><\/p>\n<p>LEX \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Yacc\" rel=\"noopener noreferrer nofollow\">YACC<\/a>. \u041e\u043d \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443. \u0424\u0430\u0439\u043b \u0441 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439 \u043b\u0435\u0436\u0438\u0442 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/parser\/gram.y\" rel=\"noopener noreferrer nofollow\">src\/backend\/parser\/gram.y<\/a><\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437 <code>RawStmt<\/code> &#8212; \u0441\u044b\u0440\u044b\u0445 (as-is) \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>pg_list &#8212; \u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u043c\u0438\u043c\u043e StringInfo, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c &#8212; <code>pg_list<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/nodes\/pg_list.h\" rel=\"noopener noreferrer nofollow\">src\/include\/nodes\/pg_list.h<\/a>). \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0438\u043f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c. <\/p>\n<p>\u0421\u0430\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>List<\/code>. \u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 <code>ListCell<\/code><\/p>\n<pre><code class=\"cpp\">typedef union ListCell { void   *ptr_value; intint_value; Oidoid_value; } ListCell;  typedef struct List { NodeTagtype;\/* T_List, T_IntList, or T_OidList *\/ intlength;\/* number of elements currently present *\/ intmax_length;\/* allocated length of elements[] *\/ ListCell   *elements;\/* re-allocatable array of cells *\/ \/* We may allocate some cells along with the List header: *\/ ListCellinitial_elements[FLEXIBLE_ARRAY_MEMBER]; \/* If elements == initial_elements, it's not a separate allocation *\/ } List;<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u044d\u0433\u0438 <code>T_List<\/code>, <code>T_IntList<\/code> \u0438 <code>T_OidList<\/code>, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u043f\u043e\u043b\u0435 <code>type:<\/code><\/p>\n<pre><code class=\"cpp\">typedef enum NodeTag { \/\/ ...     \/*  * TAGS FOR LIST NODES (pg_list.h)  *\/ T_List, T_IntList, T_OidList     \/\/ ... }<\/code><\/pre>\n<p>\u0427\u0435\u0440\u0435\u0437 \u043c\u0430\u043a\u0440\u043e\u0441 <code>foreach<\/code> \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0418\u0442\u0435\u0440\u0430\u0442\u043e\u0440:<\/p>\n<pre><code class=\"cpp\">#define foreach(cell, lst)\\ for (ForEachState cell##__state = {(lst), 0}; \\  (cell##__state.l != NIL &amp;&amp; \\   cell##__state.i &lt; cell##__state.l->length) ? \\  (cell = &amp;cell##__state.l->elements[cell##__state.i], true) : \\  (cell = NULL, false); \\  cell##__state.i++)<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><code>forboth<\/code>, <code>forthree<\/code>, <code>forfour<\/code>, <code>forfive<\/code> &#8212; \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e 2, 3, 4 \u0438\u043b\u0438 5 \u0441\u043f\u0438\u0441\u043a\u0430\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p><code>lfirst<\/code>&#8212; \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 foreach;<\/p>\n<\/li>\n<li>\n<p><code>linitial<\/code>, <code>lsecond<\/code>, <code>lthird<\/code>, <code>lfourth<\/code>, <code>llast<\/code> &#8212; \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439, \u0432\u0442\u043e\u0440\u043e\u0439, \u0442\u0440\u0435\u0442\u0438\u0439, \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p><code>lappend<\/code> &#8212; \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 NULL:<\/p>\n<pre><code class=\"cpp\">\/*  * The *only* valid representation of an empty list is NIL; in other  * words, a non-NIL list is guaranteed to have length >= 1.  *\/ #define NIL((List *) NULL)<\/code><\/pre>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e, \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u0438 \u0431\u044b\u043b\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043d\u0430 Lisp. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 Lisp-like \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>lcons<\/code> (\u0430\u043d\u0430\u043b\u043e\u0433 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Cons\" rel=\"noopener noreferrer nofollow\">cons<\/a>), \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u0441\u043f\u0438\u0441\u043a\u0430.<\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043d\u0430 LISP \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043d \u043d\u0430 C.<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u044b\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 RawStmt.\u00a0<\/p>\n<pre><code class=\"cpp\">\/*  *RawStmt --- container for any one statement's raw parse tree  *  * Parse analysis converts a raw parse tree headed by a RawStmt node into  * an analyzed statement headed by a Query node.  For optimizable statements,  * the conversion is complex.  For utility statements, the parser usually just  * transfers the raw parse tree (sans RawStmt) into the utilityStmt field of  * the Query node, and all the useful work happens at execution time.  *  * stmt_location\/stmt_len identify the portion of the source text string  * containing this raw statement (useful for multi-statement strings).  *\/ typedef struct RawStmt { NodeTagtype; Node   *stmt;\/* raw parse tree *\/ intstmt_location;\/* start location, or -1 if unknown *\/ intstmt_len;\/* length in bytes; 0 means \"rest of string\" *\/ } RawStmt;<\/code><\/pre>\n<p>\u041a\u043e\u0440\u0435\u043d\u044c \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0435 <code>stmt<\/code> \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>Node<\/code><\/p>\n<pre><code class=\"cpp\">\/*  * The first field of a node of any type is guaranteed to be the NodeTag.  * Hence the type of any node can be gotten by casting it to Node. Declaring  * a variable to be of Node * (instead of void *) can also facilitate  * debugging.  *\/ typedef struct Node { NodeTagtype; } Node;<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>&#171;\u0411\u0430\u0437\u043e\u0432\u043e\u0435&#187; \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f <code>Node<\/code> \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u201c\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u201d.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u043f\u043e\u043b\u0435\u043c \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 <code>RawStmt<\/code> \u0438\u0434\u0435\u0442 \u043f\u043e\u043b\u0435 type \u0442\u0438\u043f\u0430 <code>NodeTag<\/code>.\u00a0<\/p>\n<details class=\"spoiler\">\n<summary>NodeTag<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/*  * The first field of every node is NodeTag. Each node created (with makeNode)  * will have one of the following tags as the value of its first field.  *  * Note that inserting or deleting node types changes the numbers of other  * node types later in the list.  This is no problem during development, since  * the node numbers are never stored on disk.  But don't do it in a released  * branch, because that would represent an ABI break for extensions.  *\/ typedef enum NodeTag { T_Invalid = 0, \/*  * TAGS FOR EXECUTOR NODES (execnodes.h)  *\/ T_IndexInfo, T_ExprContext, T_ProjectionInfo, T_JunkFilter, T_OnConflictSetState, T_MergeActionState, T_ResultRelInfo, T_EState, T_TupleTableSlot,  \/*  * TAGS FOR PLAN NODES (plannodes.h)  *\/ T_Plan, T_Result, T_ProjectSet, T_ModifyTable, T_Append, T_MergeAppend, T_RecursiveUnion, T_BitmapAnd, T_BitmapOr, T_Scan, T_SeqScan, T_SampleScan, T_IndexScan, T_IndexOnlyScan, T_BitmapIndexScan, T_BitmapHeapScan, T_TidScan, T_TidRangeScan, T_SubqueryScan, T_FunctionScan, T_ValuesScan, T_TableFuncScan, T_CteScan, T_NamedTuplestoreScan, T_WorkTableScan, T_ForeignScan, T_CustomScan, T_Join, T_NestLoop, T_MergeJoin, T_HashJoin, T_Material, T_Memoize, T_Sort, T_IncrementalSort, T_Group, T_Agg, T_WindowAgg, T_Unique, T_Gather, T_GatherMerge, T_Hash, T_SetOp, T_LockRows, T_Limit, \/* these aren't subclasses of Plan: *\/ T_NestLoopParam, T_PlanRowMark, T_PartitionPruneInfo, T_PartitionedRelPruneInfo, T_PartitionPruneStepOp, T_PartitionPruneStepCombine, T_PlanInvalItem,  \/*  * TAGS FOR PLAN STATE NODES (execnodes.h)  *  * These should correspond one-to-one with Plan node types.  *\/ T_PlanState, T_ResultState, T_ProjectSetState, T_ModifyTableState, T_AppendState, T_MergeAppendState, T_RecursiveUnionState, T_BitmapAndState, T_BitmapOrState, T_ScanState, T_SeqScanState, T_SampleScanState, T_IndexScanState, T_IndexOnlyScanState, T_BitmapIndexScanState, T_BitmapHeapScanState, T_TidScanState, T_TidRangeScanState, T_SubqueryScanState, T_FunctionScanState, T_TableFuncScanState, T_ValuesScanState, T_CteScanState, T_NamedTuplestoreScanState, T_WorkTableScanState, T_ForeignScanState, T_CustomScanState, T_JoinState, T_NestLoopState, T_MergeJoinState, T_HashJoinState, T_MaterialState, T_MemoizeState, T_SortState, T_IncrementalSortState, T_GroupState, T_AggState, T_WindowAggState, T_UniqueState, T_GatherState, T_GatherMergeState, T_HashState, T_SetOpState, T_LockRowsState, T_LimitState,  \/*  * TAGS FOR PRIMITIVE NODES (primnodes.h)  *\/ T_Alias, T_RangeVar, T_TableFunc, T_Var, T_Const, T_Param, T_Aggref, T_GroupingFunc, T_WindowFunc, T_SubscriptingRef, T_FuncExpr, T_NamedArgExpr, T_OpExpr, T_DistinctExpr, T_NullIfExpr, T_ScalarArrayOpExpr, T_BoolExpr, T_SubLink, T_SubPlan, T_AlternativeSubPlan, T_FieldSelect, T_FieldStore, T_RelabelType, T_CoerceViaIO, T_ArrayCoerceExpr, T_ConvertRowtypeExpr, T_CollateExpr, T_CaseExpr, T_CaseWhen, T_CaseTestExpr, T_ArrayExpr, T_RowExpr, T_RowCompareExpr, T_CoalesceExpr, T_MinMaxExpr, T_SQLValueFunction, T_XmlExpr, T_NullTest, T_BooleanTest, T_CoerceToDomain, T_CoerceToDomainValue, T_SetToDefault, T_CurrentOfExpr, T_NextValueExpr, T_InferenceElem, T_TargetEntry, T_RangeTblRef, T_JoinExpr, T_FromExpr, T_OnConflictExpr, T_IntoClause,  \/*  * TAGS FOR EXPRESSION STATE NODES (execnodes.h)  *  * ExprState represents the evaluation state for a whole expression tree.  * Most Expr-based plan nodes do not have a corresponding expression state  * node, they're fully handled within execExpr* - but sometimes the state  * needs to be shared with other parts of the executor, as for example  * with SubPlanState, which nodeSubplan.c has to modify.  *\/ T_ExprState, T_WindowFuncExprState, T_SetExprState, T_SubPlanState, T_DomainConstraintState,  \/*  * TAGS FOR PLANNER NODES (pathnodes.h)  *\/ T_PlannerInfo, T_PlannerGlobal, T_RelOptInfo, T_IndexOptInfo, T_ForeignKeyOptInfo, T_ParamPathInfo, T_Path, T_IndexPath, T_BitmapHeapPath, T_BitmapAndPath, T_BitmapOrPath, T_TidPath, T_TidRangePath, T_SubqueryScanPath, T_ForeignPath, T_CustomPath, T_NestPath, T_MergePath, T_HashPath, T_AppendPath, T_MergeAppendPath, T_GroupResultPath, T_MaterialPath, T_MemoizePath, T_UniquePath, T_GatherPath, T_GatherMergePath, T_ProjectionPath, T_ProjectSetPath, T_SortPath, T_IncrementalSortPath, T_GroupPath, T_UpperUniquePath, T_AggPath, T_GroupingSetsPath, T_MinMaxAggPath, T_WindowAggPath, T_SetOpPath, T_RecursiveUnionPath, T_LockRowsPath, T_ModifyTablePath, T_LimitPath, \/* these aren't subclasses of Path: *\/ T_EquivalenceClass, T_EquivalenceMember, T_PathKey, T_PathKeyInfo, T_PathTarget, T_RestrictInfo, T_IndexClause, T_PlaceHolderVar, T_SpecialJoinInfo, T_AppendRelInfo, T_RowIdentityVarInfo, T_PlaceHolderInfo, T_MinMaxAggInfo, T_PlannerParamItem, T_RollupData, T_GroupingSetData, T_StatisticExtInfo, T_MergeAction,  \/*  * TAGS FOR MEMORY NODES (memnodes.h)  *\/ T_AllocSetContext, T_SlabContext, T_GenerationContext,  \/*  * TAGS FOR VALUE NODES (value.h)  *\/ T_Integer, T_Float, T_Boolean, T_String, T_BitString,  \/*  * TAGS FOR LIST NODES (pg_list.h)  *\/ T_List, T_IntList, T_OidList,  \/*  * TAGS FOR EXTENSIBLE NODES (extensible.h)  *\/ T_ExtensibleNode,  \/*  * TAGS FOR STATEMENT NODES (mostly in parsenodes.h)  *\/ T_RawStmt, T_Query, T_PlannedStmt, T_InsertStmt, T_DeleteStmt, T_UpdateStmt, T_MergeStmt, T_SelectStmt, T_ReturnStmt, T_PLAssignStmt, T_AlterTableStmt, T_AlterTableCmd, T_AlterDomainStmt, T_SetOperationStmt, T_GrantStmt, T_GrantRoleStmt, T_AlterDefaultPrivilegesStmt, T_ClosePortalStmt, T_ClusterStmt, T_CopyStmt, T_CreateStmt, T_DefineStmt, T_DropStmt, T_TruncateStmt, T_CommentStmt, T_FetchStmt, T_IndexStmt, T_CreateFunctionStmt, T_AlterFunctionStmt, T_DoStmt, T_RenameStmt, T_RuleStmt, T_NotifyStmt, T_ListenStmt, T_UnlistenStmt, T_TransactionStmt, T_ViewStmt, T_LoadStmt, T_CreateDomainStmt, T_CreatedbStmt, T_DropdbStmt, T_VacuumStmt, T_ExplainStmt, T_CreateTableAsStmt, T_CreateSeqStmt, T_AlterSeqStmt, T_VariableSetStmt, T_VariableShowStmt, T_DiscardStmt, T_CreateTrigStmt, T_CreatePLangStmt, T_CreateRoleStmt, T_AlterRoleStmt, T_DropRoleStmt, T_LockStmt, T_ConstraintsSetStmt, T_ReindexStmt, T_CheckPointStmt, T_CreateSchemaStmt, T_AlterDatabaseStmt, T_AlterDatabaseRefreshCollStmt, T_AlterDatabaseSetStmt, T_AlterRoleSetStmt, T_CreateConversionStmt, T_CreateCastStmt, T_CreateOpClassStmt, T_CreateOpFamilyStmt, T_AlterOpFamilyStmt, T_PrepareStmt, T_ExecuteStmt, T_DeallocateStmt, T_DeclareCursorStmt, T_CreateTableSpaceStmt, T_DropTableSpaceStmt, T_AlterObjectDependsStmt, T_AlterObjectSchemaStmt, T_AlterOwnerStmt, T_AlterOperatorStmt, T_AlterTypeStmt, T_DropOwnedStmt, T_ReassignOwnedStmt, T_CompositeTypeStmt, T_CreateEnumStmt, T_CreateRangeStmt, T_AlterEnumStmt, T_AlterTSDictionaryStmt, T_AlterTSConfigurationStmt, T_CreateFdwStmt, T_AlterFdwStmt, T_CreateForeignServerStmt, T_AlterForeignServerStmt, T_CreateUserMappingStmt, T_AlterUserMappingStmt, T_DropUserMappingStmt, T_AlterTableSpaceOptionsStmt, T_AlterTableMoveAllStmt, T_SecLabelStmt, T_CreateForeignTableStmt, T_ImportForeignSchemaStmt, T_CreateExtensionStmt, T_AlterExtensionStmt, T_AlterExtensionContentsStmt, T_CreateEventTrigStmt, T_AlterEventTrigStmt, T_RefreshMatViewStmt, T_ReplicaIdentityStmt, T_AlterSystemStmt, T_CreatePolicyStmt, T_AlterPolicyStmt, T_CreateTransformStmt, T_CreateAmStmt, T_CreatePublicationStmt, T_AlterPublicationStmt, T_CreateSubscriptionStmt, T_AlterSubscriptionStmt, T_DropSubscriptionStmt, T_CreateStatsStmt, T_AlterCollationStmt, T_CallStmt, T_AlterStatsStmt,  \/*  * TAGS FOR PARSE TREE NODES (parsenodes.h)  *\/ T_A_Expr, T_ColumnRef, T_ParamRef, T_A_Const, T_FuncCall, T_A_Star, T_A_Indices, T_A_Indirection, T_A_ArrayExpr, T_ResTarget, T_MultiAssignRef, T_TypeCast, T_CollateClause, T_SortBy, T_WindowDef, T_RangeSubselect, T_RangeFunction, T_RangeTableSample, T_RangeTableFunc, T_RangeTableFuncCol, T_TypeName, T_ColumnDef, T_IndexElem, T_StatsElem, T_Constraint, T_DefElem, T_RangeTblEntry, T_RangeTblFunction, T_TableSampleClause, T_WithCheckOption, T_SortGroupClause, T_GroupingSet, T_WindowClause, T_ObjectWithArgs, T_AccessPriv, T_CreateOpClassItem, T_TableLikeClause, T_FunctionParameter, T_LockingClause, T_RowMarkClause, T_XmlSerialize, T_WithClause, T_InferClause, T_OnConflictClause, T_CTESearchClause, T_CTECycleClause, T_CommonTableExpr, T_MergeWhenClause, T_RoleSpec, T_TriggerTransition, T_PartitionElem, T_PartitionSpec, T_PartitionBoundSpec, T_PartitionRangeDatum, T_PartitionCmd, T_VacuumRelation, T_PublicationObjSpec, T_PublicationTable,  \/*  * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)  *\/ T_IdentifySystemCmd, T_BaseBackupCmd, T_CreateReplicationSlotCmd, T_DropReplicationSlotCmd, T_ReadReplicationSlotCmd, T_StartReplicationCmd, T_TimeLineHistoryCmd,  \/*  * TAGS FOR RANDOM OTHER STUFF  *  * These are objects that aren't part of parse\/plan\/execute node tree  * structures, but we give them NodeTags anyway for identification  * purposes (usually because they are involved in APIs where we want to  * pass multiple object types through the same pointer).  *\/ T_TriggerData,\/* in commands\/trigger.h *\/ T_EventTriggerData,\/* in commands\/event_trigger.h *\/ T_ReturnSetInfo,\/* in nodes\/execnodes.h *\/ T_WindowObjectData,\/* private in nodeWindowAgg.c *\/ T_TIDBitmap,\/* in nodes\/tidbitmap.h *\/ T_InlineCodeBlock,\/* in nodes\/parsenodes.h *\/ T_FdwRoutine,\/* in foreign\/fdwapi.h *\/ T_IndexAmRoutine,\/* in access\/amapi.h *\/ T_TableAmRoutine,\/* in access\/tableam.h *\/ T_TsmRoutine,\/* in access\/tsmapi.h *\/ T_ForeignKeyCacheInfo,\/* in utils\/rel.h *\/ T_CallContext,\/* in nodes\/parsenodes.h *\/ T_SupportRequestSimplify,\/* in nodes\/supportnodes.h *\/ T_SupportRequestSelectivity,\/* in nodes\/supportnodes.h *\/ T_SupportRequestCost,\/* in nodes\/supportnodes.h *\/ T_SupportRequestRows,\/* in nodes\/supportnodes.h *\/ T_SupportRequestIndexCondition, \/* in nodes\/supportnodes.h *\/ T_SupportRequestWFuncMonotonic\/* in nodes\/supportnodes.h *\/  } NodeTag; <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u0442\u0430\u043a, \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#171;\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f&#187;:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 <code>Node<\/code><\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u043e\u043b\u044f <code>type<\/code><\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0441\u0442\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 <\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 RawStmt \u043c\u044b<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 <code>Node<\/code><\/p>\n<\/li>\n<li>\n<p>\u0427\u0438\u0442\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>stmt<\/code><\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>T_RawStmt<\/code><\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0441\u0442\u0443\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043a <code>RawStmt<\/code><\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">\/\/ src\/backend\/tcop\/utility.c LogStmtLevel GetCommandLogLevel(Node *parsetree) { LogStmtLevel lev; switch (nodeTag(parsetree)) { \/* recurse if we're given a RawStmt *\/ case T_RawStmt: lev = GetCommandLogLevel(((RawStmt *) parsetree)-&amp;gt;stmt); break;     \/\/ ... }  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0418\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c<\/h2>\n<h4>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/h4>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f.<\/p>\n<p>\u0412\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. \u042d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c. <\/p>\n<p>\u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e\u00a0\u0435\u0441\u043b\u0438 \u0432\u00a0\u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0442\u043e, \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0\u2014 \u044d\u0442\u043e <code>ROLLBACK<\/code>. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0412\u00a0\u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u00a0\u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>start_xact_command<\/code>.<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430<\/h4>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043d\u0430\u043f\u0448\u043e\u0442. \u0421\u043d\u0430\u043f\u0448\u043e\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u043a\u0430\u043a\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043b\u044f\u00a0\u043d\u0430\u0441 \u0432\u0430\u043b\u0438\u0434\u043d\u044b, \u0430\u00a0\u043a\u0430\u043a\u0438\u0435 \u043d\u0435\u0442. <\/p>\n<p>\u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043a\u043e\u0433\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>DELETE<\/code> \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c. <\/p>\n<\/li>\n<li>\n<p>\u0412\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u043b\u0433\u0438\u0439 <code>SELECT<\/code> \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044c \u043a\u0430\u043a\u00a0\u0441\u0442\u0430\u0440\u044b\u0435, \u0442\u0430\u043a \u0438 \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043b\u0438\u00a0\u0432\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>SELECT FOR UPDATE<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u044b\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a\u00a0\u0434\u0430\u043d\u043d\u044b\u043c Postgres \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"https:\/\/habr.com\/ru\/post\/208400\/\" rel=\"noopener noreferrer nofollow\">MVCC<\/a>. \u0412\u00a0\u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0434\u043b\u044f\u00a0\u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0443\u0436\u0435\u043d \u0441\u043b\u0435\u043f\u043e\u043a. \u042d\u0442\u043e\u0442 \u0441\u043b\u0435\u043f\u043e\u043a \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 Snapshot:<\/p>\n<pre><code class=\"cpp\">typedef struct SnapshotData *Snapshot;  #define InvalidSnapshot((Snapshot) NULL)  \/*  * Struct representing all kind of possible snapshots.  *  * There are several different kinds of snapshots:  * * Normal MVCC snapshots  * * MVCC snapshots taken during recovery (in Hot-Standby mode)  * * Historic MVCC snapshots used during logical decoding  * * snapshots passed to HeapTupleSatisfiesDirty()  * * snapshots passed to HeapTupleSatisfiesNonVacuumable()  * * snapshots used for SatisfiesAny, Toast, Self where no members are  * accessed.  *\/ typedef struct SnapshotData { SnapshotType snapshot_type; \/* type of snapshot *\/  TransactionId xmin;\/* all XID &lt; xmin are visible to me *\/ TransactionId xmax;\/* all XID >= xmax are invisible to me *\/  TransactionId *xip; uint32xcnt;\/* # of xact ids in xip[] *\/  TransactionId *subxip; int32subxcnt;\/* # of xact ids in subxip[] *\/ boolsuboverflowed;\/* has the subxip array overflowed? *\/  booltakenDuringRecovery;\/* recovery-shaped snapshot? *\/ boolcopied;\/* false if it's a static snapshot *\/  CommandIdcurcid;\/* in my xact, CID &lt; curcid are visible *\/  uint32speculativeToken;  struct GlobalVisState *vistest;  uint32active_count;\/* refcount on ActiveSnapshot stack *\/ uint32regd_count;\/* refcount on RegisteredSnapshots *\/ pairingheap_node ph_node;\/* link in the RegisteredSnapshots heap *\/  TimestampTz whenTaken;\/* timestamp when snapshot was taken *\/ XLogRecPtrlsn;\/* position in the WAL stream when taken *\/  uint64snapXactCompletionCount; } SnapshotData;<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430 \u0434\u043b\u044f\u00a0\u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>GetTransactionSnapshot()<\/code>. \u041e\u043d\u0430\u00a0\u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439,\u00a0\u043b\u0438\u0431\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u043d\u0430\u043f\u0448\u043e\u0442.<\/p>\n<p>\u0412\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439, \u0438 \u0434\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0435\u043a. \u0412\u0435\u0440\u0448\u0438\u043d\u0430 \u0441\u0442\u0435\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u00a0\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>ActiveSnapshot<\/code>. \u0414\u043b\u044f\u00a0\u0441\u0442\u0435\u043a\u0430 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430:<\/p>\n<pre><code class=\"cpp\">\/*  * Elements of the active snapshot stack.  *  * Each element here accounts for exactly one active_count on SnapshotData.  *  * NB: the code assumes that elements in this list are in non-increasing  * order of as_level; also, the list must be NULL-terminated.  *\/ typedef struct ActiveSnapshotElt { Snapshotas_snap; intas_level; struct ActiveSnapshotElt *as_next; } ActiveSnapshotElt;  \/* Top of the stack of active snapshots *\/ static ActiveSnapshotElt *ActiveSnapshot = NULL;  \/* Bottom of the stack of active snapshots *\/ static ActiveSnapshotElt *OldestActiveSnapshot = NULL;<\/code><\/pre>\n<h4>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438.\u00a0<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0442\u043e \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 &#8212; <code>per_parsetree_context<\/code>. \u0412\u0440\u0435\u043c\u044f \u0435\u0433\u043e \u0436\u0438\u0437\u043d\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0435\u0439.\u00a0<\/p>\n<blockquote>\n<p>P.S. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u0440\u043e\u043c\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e. \u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>MessageContext<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/blockquote>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0437 \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/h4>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u201c\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f\u201d \u0440\u0430\u0431\u043e\u0442\u0430. \u0417\u0430\u043f\u0440\u043e\u0441 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e. \u0414\u0430\u043b\u0435\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441. \u0418\u043c\u0435\u043d\u043d\u043e \u0441 \u043d\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430: \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435.\u00a0<\/p>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>Query<\/code>:<\/p>\n<pre><code class=\"cpp\">typedef struct Query { NodeTagtype;  CmdTypecommandType;\/* select|insert|update|delete|merge|utility *\/  QuerySource querySource;\/* where did I come from? *\/  uint64queryId;\/* query identifier (can be set by plugins) *\/  boolcanSetTag;\/* do I set the command result tag? *\/  Node   *utilityStmt;\/* non-null if commandType == CMD_UTILITY *\/  intresultRelation; \/* rtable index of target relation for  * INSERT\/UPDATE\/DELETE\/MERGE; 0 for SELECT *\/  boolhasAggs;\/* has aggregates in tlist or havingQual *\/ boolhasWindowFuncs; \/* has window functions in tlist *\/ boolhasTargetSRFs;\/* has set-returning functions in tlist *\/ boolhasSubLinks;\/* has subquery SubLink *\/ boolhasDistinctOn;\/* distinctClause is from DISTINCT ON *\/ boolhasRecursive;\/* WITH RECURSIVE was specified *\/ boolhasModifyingCTE;\/* has INSERT\/UPDATE\/DELETE in WITH *\/ boolhasForUpdate;\/* FOR [KEY] UPDATE\/SHARE was specified *\/ boolhasRowSecurity; \/* rewriter has applied some RLS policy *\/  boolisReturn;\/* is a RETURN statement *\/  List   *cteList;\/* WITH list (of CommonTableExpr's) *\/  List   *rtable;\/* list of range table entries *\/ FromExpr   *jointree;\/* table join tree (FROM and WHERE clauses);  * also USING clause for MERGE *\/  List   *mergeActionList;\/* list of actions for MERGE (only) *\/ boolmergeUseOuterJoin;\/* whether to use outer join *\/  List   *targetList;\/* target list (of TargetEntry) *\/  OverridingKind override;\/* OVERRIDING clause *\/  OnConflictExpr *onConflict; \/* ON CONFLICT DO [NOTHING | UPDATE] *\/  List   *returningList;\/* return-values list (of TargetEntry) *\/  List   *groupClause;\/* a list of SortGroupClause's *\/ boolgroupDistinct;\/* is the group by clause distinct? *\/  List   *groupingSets;\/* a list of GroupingSet's if present *\/  Node   *havingQual;\/* qualifications applied to groups *\/  List   *windowClause;\/* a list of WindowClause's *\/  List   *distinctClause; \/* a list of SortGroupClause's *\/  List   *sortClause;\/* a list of SortGroupClause's *\/  Node   *limitOffset;\/* # of result tuples to skip (int8 expr) *\/ Node   *limitCount;\/* # of result tuples to return (int8 expr) *\/ LimitOption limitOption;\/* limit type *\/  List   *rowMarks;\/* a list of RowMarkClause's *\/  Node   *setOperations;\/* set-operation tree if this is top level of  * a UNION\/INTERSECT\/EXCEPT query *\/  List   *constraintDeps; \/* a list of pg_constraint OIDs that the query  * depends on to be semantically valid *\/  List   *withCheckOptions;\/* a list of WithCheckOption's (added  * during rewrite) *\/  \/*  * The following two fields identify the portion of the source text string  * containing this query.  They are typically only populated in top-level  * Queries, not in sub-queries.  When not set, they might both be zero, or  * both be -1 meaning \"unknown\".  *\/ intstmt_location;\/* start location, or -1 if unknown *\/ intstmt_len;\/* length in bytes; 0 means \"rest of string\" *\/ } Query;<\/code><\/pre>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c <code>analyze<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/parser\/analyze.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/parser\/analyze.c<\/a>).<\/p>\n<p>\u0417\u0430\u00a0\u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0434\u0435\u0440\u0435\u0432\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 <code>Query<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>transformTopLevelStmt<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/parser\/analyze.c#L250\" rel=\"noopener noreferrer nofollow\">src\/backend\/parser\/analyze.c<\/a>). \u041d\u0430\u00a0\u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442: <\/p>\n<ul>\n<li>\n<p><code>RawStmt<\/code>\u00a0\u2014 \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u0430\u00a0\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0448\u0430\u0433\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p><code>ParseState<\/code>\u00a0\u2014 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u00a0\u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u043c\u0443 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">struct ParseState { ParseState *parentParseState;\/* stack link *\/ const char *p_sourcetext;\/* source text, or NULL if not available *\/ List   *p_rtable;\/* range table so far *\/ List   *p_joinexprs;\/* JoinExprs for RTE_JOIN p_rtable entries *\/ List   *p_joinlist;\/* join items so far (will become FromExpr  * node's fromlist) *\/ List   *p_namespace;\/* currently-referenceable RTEs (List of  * ParseNamespaceItem) *\/ boolp_lateral_active;\/* p_lateral_only items visible? *\/ List   *p_ctenamespace; \/* current namespace for common table exprs *\/ List   *p_future_ctes;\/* common table exprs not yet in namespace *\/ CommonTableExpr *p_parent_cte;\/* this query's containing CTE *\/ Relationp_target_relation;\/* INSERT\/UPDATE\/DELETE\/MERGE target rel *\/ ParseNamespaceItem *p_target_nsitem;\/* target rel's NSItem, or NULL *\/ boolp_is_insert;\/* process assignment like INSERT not UPDATE *\/ List   *p_windowdefs;\/* raw representations of window clauses *\/ ParseExprKind p_expr_kind;\/* what kind of expression we're parsing *\/ intp_next_resno;\/* next targetlist resno to assign *\/ List   *p_multiassign_exprs;\/* junk tlist entries for multiassign *\/ List   *p_locking_clause;\/* raw FOR UPDATE\/FOR SHARE info *\/ boolp_locked_from_parent;\/* parent has marked this subquery  * with FOR UPDATE\/FOR SHARE *\/ boolp_resolve_unknowns; \/* resolve unknown-type SELECT outputs as  * type text *\/  QueryEnvironment *p_queryEnv;\/* curr env, incl refs to enclosing env *\/  \/* Flags telling about things found in the query: *\/ boolp_hasAggs; boolp_hasWindowFuncs; boolp_hasTargetSRFs; boolp_hasSubLinks; boolp_hasModifyingCTE;  Node   *p_last_srf;\/* most recent set-returning func\/op found *\/  \/*  * Optional hook functions for parser callbacks.  These are null unless  * set up by the caller of make_parsestate.  *\/ PreParseColumnRefHook p_pre_columnref_hook; PostParseColumnRefHook p_post_columnref_hook; ParseParamRefHook p_paramref_hook; CoerceParamHook p_coerce_param_hook; void   *p_ref_hook_state;\/* common passthrough link for above *\/ };<\/code><\/pre>\n<p>\u0412\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f <code>RawStmt<\/code> \u0432 <code>Query<\/code> &#8212; \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>transformStmt<\/code>.\u00a0<\/p>\n<pre><code class=\"cpp\">\/*  * transformStmt -  *  recursively transform a Parse tree into a Query tree.  *\/ Query* transformStmt(ParseState *pstate, Node *parseTree);<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e <code>transform*<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0443\u0442\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u043b\u044f type \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>Node<\/code>) \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a \u043d\u0435\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.\u00a0<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f (\u043f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f) \u043e\u0431\u044a\u0435\u043a\u0442 ParseState. \u041f\u043e \u043c\u0435\u0440\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, <code>ParseState<\/code> \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0443\u0437\u043b\u0430\u0445 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.<\/p>\n<p>\u042d\u0442\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>transformStmt<\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d <code>switch\/case<\/code>. \u041e\u043d \u043f\u043e\u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0442\u044d\u0433 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e, \u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a.\u00a0<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435 <code>type<\/code> \u0431\u0443\u0434\u0435\u0442 <code>T_SelectStmt<\/code>, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a &#8212; <code>transformSelectStmt<\/code><\/p>\n<pre><code class=\"cpp\">Query * transformStmt(ParseState *pstate, Node *parseTree) { Query   *result;  \/*  * We apply RAW_EXPRESSION_COVERAGE_TEST testing to basic DML statements;  * we can't just run it on everything because raw_expression_tree_walker()  * doesn't claim to handle utility statements.  *\/     switch (nodeTag(parseTree)) {           \/\/ ...           case T_SelectStmt: { SelectStmt *n = (SelectStmt *) parseTree;  if (n->valuesLists) result = transformValuesClause(pstate, n); else if (n->op == SETOP_NONE) result = transformSelectStmt(pstate, n); else result = transformSetOperationStmt(pstate, n); } break;         \/\/ ...     }     return result; }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (<code>SELECT * FROM users<\/code>) \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>transformSelectStmt<\/code>.\u00a0<\/p>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u0430: <code>WITH<\/code>, <code>FROM<\/code>, <code>WHERE<\/code>, <code>HAVING<\/code> \u0438 \u0442.\u0434. \u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u044e\u0449\u0438\u0445\/\u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0445\/\u0443\u0441\u043b\u043e\u0436\u043d\u044f\u044e\u0449\u0438\u0445 <s>\u0436\u0438\u0437\u043d\u044c<\/s> \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c:<\/p>\n<ol>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 <code>FROM<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <code>FROM<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>transformFromClause<\/code>. \u0422\u0430\u043a \u043a\u0430\u043a \u0432\u043e <code>FROM<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 (\u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0434\u0440\u0443\u0433\u043e\u0439 <code>SELECT<\/code>), \u0442\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0441\u0432\u043e\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f.\u00a0<\/p>\n<p>\u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u0432\u0441\u0435 \u043a\u043e\u0441\u0432\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b, \u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a &#8212; <code>transformTableEntry<\/code>.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>RangeTblEntry<\/code>.<\/p>\n<pre><code class=\"cpp\">typedef struct RangeTblEntry { NodeTagtype; RTEKindrtekind; Oidrelid;\/* OID of the relation *\/ charrelkind;\/* relation kind (see pg_class.relkind) *\/ intrellockmode;\/* lock level that query requires on the rel *\/ struct TableSampleClause *tablesample;\/* sampling info, or NULL *\/      Query   *subquery;\/* the sub-query *\/ boolsecurity_barrier;\/* is from security_barrier view? *\/  JoinTypejointype;\/* type of join *\/ intjoinmergedcols; \/* number of merged (JOIN USING) columns *\/ List   *joinaliasvars;\/* list of alias-var expansions *\/ List   *joinleftcols;\/* left-side input column numbers *\/ List   *joinrightcols;\/* right-side input column numbers *\/  Alias   *join_using_alias;  List   *functions;\/* list of RangeTblFunction nodes *\/ boolfuncordinality; \/* is this called WITH ORDINALITY? *\/  TableFunc  *tablefunc;  List   *values_lists;\/* list of expression lists *\/  char   *ctename;\/* name of the WITH list item *\/ Indexctelevelsup;\/* number of query levels up *\/ boolself_reference; \/* is this a recursive self-reference? *\/  List   *coltypes;\/* OID list of column type OIDs *\/ List   *coltypmods;\/* integer list of column typmods *\/ List   *colcollations;\/* OID list of column collation OIDs *\/  char   *enrname;\/* name of ephemeral named relation *\/ Cardinality enrtuples;\/* estimated or actual from caller *\/  Alias   *alias;\/* user-written alias clause, if any *\/ Alias   *eref;\/* expanded reference names *\/ boollateral;\/* subquery, function, or values is LATERAL? *\/ boolinh;\/* inheritance requested? *\/ boolinFromCl;\/* present in FROM clause? *\/ AclModerequiredPerms;\/* bitmask of required access permissions *\/ OidcheckAsUser;\/* if valid, check access as this role *\/ Bitmapset  *selectedCols;\/* columns needing SELECT permission *\/ Bitmapset  *insertedCols;\/* columns needing INSERT permission *\/ Bitmapset  *updatedCols;\/* columns needing UPDATE permission *\/ Bitmapset  *extraUpdatedCols;\/* generated columns being updated *\/ List   *securityQuals;\/* security barrier quals to apply, if any *\/ } RangeTblEntry;<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0430\u0432\u0438\u043b \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f <code>SELECT<\/code> \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435 <code>SELECT<\/code> \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>fireRIRrules<\/code>.<\/p>\n<pre><code class=\"cpp\">\/*  * fireRIRrules -  *Apply all RIR rules on each rangetable entry in the given query  *  * activeRIRs is a list of the OIDs of views we're already processing RIR  * rules for, used to detect\/reject recursion.  *\/ static Query * fireRIRrules(Query *parsetree, List *activeRIRs)<\/code><\/pre>\n<p>\u041e\u043d\u0430 \u0432\u044b\u044f\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c, \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>ApplyRetrieveRule<\/code>.<\/p>\n<pre><code class=\"cpp\">\/*  * ApplyRetrieveRule - expand an ON SELECT rule  *\/ static Query * ApplyRetrieveRule(Query *parsetree,   RewriteRule *rule,   int rt_index,   Relation relation,   List *activeRIRs)<\/code><\/pre>\n<blockquote>\n<p>\u041f\u0440\u0438\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437\u00a0ApplyRetrieveRule \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f fireRIRrules, \u043d\u0430\u00a0\u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430\u00a0\u0434\u0440\u0443\u0433\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<\/blockquote>\n<details class=\"spoiler\">\n<summary>RIR &#8212; Retrieve-Instead-Retrieve<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 Postgres \u0431\u044b\u043b PostQUEL (<a href=\"https:\/\/ru.wikipedia.org\/wiki\/POSTQUEL\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/ru.wikipedia.org\/wiki\/POSTQUEL<\/u><\/a>). \u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 PostgreSQL \u043f\u0440\u0438\u0448\u0435\u043b \u043f\u043e\u0437\u0434\u043d\u0435\u0435. \u041d\u043e \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043c\u043d\u043e\u0433\u043e \u043b\u0435\u0433\u0430\u0441\u0438 \u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0431\u0431\u0440\u0435\u0432\u0438\u0430\u0442\u0443\u0440\u0430 RIR.\u00a0<\/p>\n<p>RIR (Retrieve Instead Retrieve) \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 2 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<pre><code class=\"sql\">retrieve (STAFF.pay) from STAFF where STAFF.name = \"Ivan\"<\/code><\/pre>\n<pre><code class=\"sql\">select STAFF.pay from STAFF where STAFF.name = 'Ivan'<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <code>retrieve<\/code> \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0432 <code>select<\/code>.<\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (<code>VIEW<\/code>) \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f. \u0412 \u0444\u0430\u0439\u043b\u0435 <code>rewriteHandler.c<\/code>\u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f fireRIRrules (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/rewrite\/rewriteHandler.c#L2008\" rel=\"noopener noreferrer nofollow\">src\/backend\/rewrite\/rewriteHandler.c<\/a>). \u0415\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f <code>SELECT<\/code> \u0432 <code>SELECT<\/code> (\u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>VIEW<\/code>) \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/www.postgresql.org\/docs\/6.4\/rules13914.htm\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.postgresql.org\/docs\/6.4\/rules13914.htm<\/u><\/a>\u00a0<\/p>\n<\/div>\n<\/details>\n<ol start=\"3\">\n<li>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u044d\u0433\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u044d\u0433 \u043a\u043e\u043c\u0430\u043d\u0434\u044b (<code>CommandTag<\/code>)\u00a0\u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0432\u0448\u0435\u0433\u043e\u0441\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f <code>INSERT<\/code> \u044d\u0442\u043e \u00abINSERT 0 1\u00bb \u043f\u0440\u0438\u00a0\u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>\u041e\u043d \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441\u00a0\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c <code>CommandComplete<\/code> <a href=\"https:\/\/www.postgresql.org\/docs\/current\/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-COMMANDCOMPLETE\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.postgresql.org\/docs\/current\/protocol\u2011message\u2011formats.html#PROTOCOL\u2011MESSAGE\u2011FORMATS\u2011COMMANDCOMPLETE<\/u><\/a><\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u043d\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h4>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u0442\u0430\u043f\u00a0\u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. <\/p>\n<p>\u0417\u0430\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u043d\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <code>planner<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/optimizer\/plan\/planner.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/optimizer\/plan\/planner.c<\/a>).<\/p>\n<p>\u0412\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0434\u043b\u044f\u00a0\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u00a0\u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>planner<\/code>.<\/p>\n<pre><code class=\"cpp\">PlannedStmt * planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)<\/code><\/pre>\n<blockquote>\n<p>\u041f\u043e \u0444\u0430\u043a\u0442\u0443, \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0445\u0443\u043a\u0430 (\u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430) \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0438\u0431\u043e \u0435\u0433\u043e, \u043b\u0438\u0431\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a (<code>standard_planner<\/code>). \u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430.<\/p>\n<\/blockquote>\n<p>\u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 (<code>ParseState<\/code>) \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>Query<\/code>, \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 &#8212; <code>PlannerGlobal<\/code>.<\/p>\n<pre><code class=\"cpp\">\/*----------  * PlannerGlobal  *Global information for planning\/optimization  *  * PlannerGlobal holds state for an entire planner invocation; this state  * is shared across all levels of sub-Queries that exist in the command being  * planned.  *----------  *\/ typedef struct PlannerGlobal { NodeTagtype; ParamListInfo boundParams;\/* Param values provided to planner() *\/ List   *subplans;\/* Plans for SubPlan nodes *\/ List   *subroots;\/* PlannerInfos for SubPlan nodes *\/ Bitmapset  *rewindPlanIDs;\/* indices of subplans that require REWIND *\/ List   *finalrtable;\/* \"flat\" rangetable for executor *\/ List   *finalrowmarks;\/* \"flat\" list of PlanRowMarks *\/ List   *resultRelations;\/* \"flat\" list of integer RT indexes *\/ List   *appendRelations;\/* \"flat\" list of AppendRelInfos *\/ List   *relationOids;\/* OIDs of relations the plan depends on *\/ List   *invalItems;\/* other dependencies, as PlanInvalItems *\/ List   *paramExecTypes; \/* type OIDs for PARAM_EXEC Params *\/ IndexlastPHId;\/* highest PlaceHolderVar ID assigned *\/ IndexlastRowMarkId;\/* highest PlanRowMark ID assigned *\/ intlastPlanNodeId; \/* highest plan node ID assigned *\/ booltransientPlan;\/* redo plan when TransactionXmin changes? *\/ booldependsOnRole;\/* is plan specific to current role? *\/ boolparallelModeOK; \/* parallel mode potentially OK? *\/ boolparallelModeNeeded; \/* parallel mode actually required? *\/ charmaxParallelHazard;\/* worst PROPARALLEL hazard level *\/ PartitionDirectory partition_directory; \/* partition descriptors *\/ } PlannerGlobal;<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0440\u044f\u0434 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0439. \u041a\u0430\u0436\u0434\u0430\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>pull_up_sublinks<\/code> \u2013 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>ANY<\/code> \u0438\u043b\u0438 <code>EXISTS<\/code> \u0432 <code>JOIN<\/code>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>grouping_planner<\/code>. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u043b\u0430\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.\u00a0<\/p>\n<blockquote>\n<p>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u0442\u0438\u043f\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u043a\u0430\u043a\u00a0\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u0434 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c (<code>UNION<\/code>\/<code>INTERSECT<\/code>\/<code>EXCEPT<\/code>), \u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a.<\/p>\n<\/blockquote>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0443\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0432\u044b\u0437\u043e\u0432 <code>query_planner<\/code>). \u0417\u0430\u0442\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u0443\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u043e \u0432 \u043f\u0443\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0443\u0437\u043b\u044b \u0441 \u044d\u0442\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438.<\/p>\n<pre><code class=\"cpp\">\/*  * If we have grouping and\/or aggregation, consider ways to implement  * that.  We build a new upperrel representing the output of this  * phase.  *\/ if (have_grouping) {     current_rel = create_grouping_paths(root,                                         current_rel,                                         grouping_target,                                         grouping_target_parallel_safe,                                         gset_data);     \/* Fix things up if grouping_target contains SRFs *\/     if (parse->hasTargetSRFs)         adjust_paths_for_srfs(root, current_rel,                               grouping_targets,                               grouping_targets_contain_srfs); }<\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043f\u0443\u0442\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u044b, \u0442\u043e \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0439 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u00a0\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439. \u0417\u0430\u00a0\u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0435\u0448\u0435\u0432\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>get_cheapest_fractional_path<\/code>. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u0434\u043e \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 (\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043e), \u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u00a0\u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0432\u00a0\u043f\u043e\u043b\u0435 <code>cheapest_total_path<\/code> \u043f\u0443\u0442\u044c, \u0438\u043d\u0430\u0447\u0435 \u0432\u00a0\u043c\u0430\u0441\u0441\u0438\u0432\u0435 <code>path_list<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0439 \u0434\u0435\u0448\u0435\u0432\u044b\u0439. <\/p>\n<p>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0443\u0442\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>compare_fractional_path_costs<\/code>.<\/p>\n<pre><code class=\"cpp\">\/*  * compare_fractional_path_costs  *  Return -1, 0, or +1 according as path1 is cheaper, the same cost,  *  or more expensive than path2 for fetching the specified fraction  *  of the total tuples.  *  * If fraction is &lt;= 0 or > 1, we interpret it as 1, ie, we select the  * path with the cheaper total_cost.  *\/ int compare_fractional_path_costs(Path *path1, Path *path2,   double fraction)<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 <code>PlannedStmt<\/code><\/p>\n<pre><code class=\"cpp\">typedef struct PlannedStmt { NodeTagtype; CmdTypecommandType;\/* select|insert|update|delete|merge|utility *\/ uint64queryId;\/* query identifier (copied from Query) *\/ boolhasReturning;\/* is it insert|update|delete RETURNING? *\/ boolhasModifyingCTE;\/* has insert|update|delete in WITH? *\/ boolcanSetTag;\/* do I set the command result tag? *\/ booltransientPlan;\/* redo plan when TransactionXmin changes? *\/ booldependsOnRole;\/* is plan specific to current role? *\/ boolparallelModeNeeded; \/* parallel mode required to execute? *\/ intjitFlags;\/* which forms of JIT should be performed *\/ struct Plan *planTree;\/* tree of Plan nodes *\/ List   *rtable;\/* list of RangeTblEntry nodes *\/    \/* rtable indexes of target relations for INSERT\/UPDATE\/DELETE\/MERGE *\/ List   *resultRelations;\/* integer list of RT indexes, or NIL *\/ List   *appendRelations;\/* list of AppendRelInfo nodes *\/ List   *subplans;\/* Plan trees for SubPlan expressions; note  * that some could be NULL *\/ Bitmapset  *rewindPlanIDs;\/* indices of subplans that require REWIND *\/ List   *rowMarks;\/* a list of PlanRowMark's *\/ List   *relationOids;\/* OIDs of relations the plan depends on *\/ List   *invalItems;\/* other dependencies, as PlanInvalItems *\/ List   *paramExecTypes; \/* type OIDs for PARAM_EXEC Params *\/ Node   *utilityStmt;\/* non-null if this is utility stmt *\/    \/* statement location in source string (copied from Query) *\/ intstmt_location;\/* start location, or -1 if unknown *\/ intstmt_len;\/* length in bytes; 0 means \"rest of string\" *\/ } PlannedStmt;<\/code><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e\u00a0\u043d\u0430\u00a0\u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0448\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0422\u043e\u0433\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<ol>\n<li>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (<code>PlannerInfo<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u00a0\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u00a0\u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u00a0\u2014 <code>build_simple_rel<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/optimizer\/util\/relnode.c#L194\" rel=\"noopener noreferrer nofollow\">src\/backend\/optimizer\/util\/relnode.c<\/a>).<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u00a0\u2014 <code>make_one_rel<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/optimizer\/path\/allpaths.c#L173\" rel=\"noopener noreferrer nofollow\">src\/backend\/optimizer\/path\/allpaths.c<\/a>).<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0431\u043e\u0440 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u043a\u0430\u043a\u00a0\u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0435\u0448\u0435\u0432\u043e\u0433\u043e.<\/p>\n<\/li>\n<\/ol>\n<h4>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430<\/h4>\n<p>\u0420\u0430\u043d\u0435\u0435, \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438 \u0441\u043d\u0430\u043f\u0448\u043e\u0442. \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u00a0\u043d\u0435\u043c \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u00a0\u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u0442\u0435\u043a\u0430.<\/p>\n<p>\u042d\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u2011\u0437\u0430 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0432\u00a0\u043f\u0435\u0440\u0435\u0440\u044b\u0432\u0435 \u043c\u0435\u0436\u0434\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u042d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0443\u0436\u0435 \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0430 \u0432 <a href=\"https:\/\/www.postgresql.org\/message-id\/flat\/5075D8DF.6050500@fuzzy.cz\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0435<\/a> \u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043a\u0430\u0441\u0430\u043b\u0430\u0441\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441\u00a0\u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c <code>LOCK<\/code> \u043f\u0440\u0438\u00a0\u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043e\u0442\u00a0\u0432\u0435\u0440\u0441\u0438\u0438 9.1\u00a0\u043a 9.2.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438\u0437 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>Hi,  I've just noticed a change of LOCK command behavior between 9.1 and 9.2, and I'm not sure whether this is expected or not.  Let's use a very simple table    CREATE TABLE x (id INT);  Say there are two sessions - A and B, where A performs some operations on \"x\" and needs to protect them with an \"ACCESS EXCLUSIVE\" lock (e.g. it might be a pg_bulkload that acquires such locks, and we need to do that explicitly on one or two places).  Session B is attempting to read the data, but is blocked and waits. On 9.1 it sees the commited data (which is what we need) but on 9.2 it sees only data commited at the time of the lock attemt.  Example:  A: BEGIN; A: LOCK x IN ACCESS EXCLUSIVE MODE; A: INSERT INTO x VALUES (100); B: SELECT * FROM x; A: COMMIT;  Now on 9.1, B receives the value \"100\" while on 9.2 it gets no rows. Is this expected? I suspect the snapshot is read at different time or something, but I've checked release notes but I haven't seen anything relevant.  Without getting the commited version of data, the locking is somehow pointless for us (unless using a different lock, not the table itself).  regards Tomas<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0430<\/h4>\n<p>\u041f\u043b\u0430\u043d \u0443 \u043d\u0430\u0441 \u043d\u0430 \u0440\u0443\u043a\u0430\u0445, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0440\u0442\u0430\u043b. \u0412 <code>Simple Query<\/code> \u0432\u0441\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0435. \u0414\u043b\u044f \u043d\u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u044b. <\/p>\n<pre><code class=\"cpp\">\/*  * Create unnamed portal to run the query or queries in. If there  * already is one, silently drop it.  *\/ portal = CreatePortal(\"\", true, true);<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0434\u0435\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>PortalStart<\/code>. \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442\u00a0\u0435\u0433\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438\u00a0\u2014 <code>PortalStrategy<\/code>.<\/p>\n<pre><code class=\"cpp\">\/*  * We have several execution strategies for Portals, depending on what  * query or queries are to be executed.  (Note: in all cases, a Portal  * executes just a single source-SQL query, and thus produces just a  * single result from the user's viewpoint.  However, the rule rewriter  * may expand the single source query to zero or many actual queries.)  *\/ typedef enum PortalStrategy {     \/* single SELECT query *\/   PORTAL_ONE_SELECT,    \/* single INSERT\/UPDATE\/DELETE query with RETURNING clause *\/     PORTAL_ONE_RETURNING, \/* single SELECT query, but has modifying CTEs *\/     PORTAL_ONE_MOD_WITH,   \/* contains UTILITY statement that returns a SELECT-like result (e.g. EXPLAIN, SHOW) *\/     PORTAL_UTIL_SELECT,    \/* all other cases *\/     PORTAL_MULTI_QUERY    } PortalStrategy;<\/code><\/pre>\n<p>\u042d\u0442\u0430\u043f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043a\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 <code>PortalStrategy<\/code>. \u0412\u00a0\u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u0441\u0435 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044e \u0432\u0438\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0445 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439. \u0414\u043b\u044f\u00a0\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>TupleDesc<\/code>.<\/p>\n<pre><code class=\"cpp\">typedef struct TupleDescData { intnatts;\/* number of attributes in the tuple *\/ Oidtdtypeid;\/* composite type ID for tuple type *\/ int32tdtypmod;\/* typmod for tuple type *\/ inttdrefcount;\/* reference count, or -1 if not counting *\/ TupleConstr *constr;\/* constraints, or NULL if none *\/ \/* attrs[N] is the description of Attribute Number N+1 *\/ FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER]; }TupleDescData; typedef struct TupleDescData *TupleDesc;<\/code><\/pre>\n<p>\u0412\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e <code>SELECT<\/code>\u00a0\u2014 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f <code>PORTAL_ONE_SELECT<\/code>. <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u0432\u00a0\u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f (<code>Executor<\/code>). \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f <code>QueryDesc<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/executor\/execdesc.h#L33\" rel=\"noopener noreferrer nofollow\">src\/include\/executor\/execnodes.h<\/a>)\u2011 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 (<code>TupleDesc<\/code> \u0432\u00a0\u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435).<\/p>\n<pre><code class=\"cpp\">typedef struct QueryDesc { \/* These fields are provided by CreateQueryDesc *\/ CmdTypeoperation;\/* CMD_SELECT, CMD_UPDATE, etc. *\/ PlannedStmt *plannedstmt;\/* planner's output (could be utility, too) *\/ const char *sourceText;\/* source text of the query *\/ Snapshotsnapshot;\/* snapshot to use for query *\/ Snapshotcrosscheck_snapshot;\/* crosscheck for RI update\/delete *\/ DestReceiver *dest;\/* the destination for tuple output *\/ ParamListInfo params;\/* param values being passed in *\/ QueryEnvironment *queryEnv; \/* query environment passed in *\/ intinstrument_options; \/* OR of InstrumentOption flags *\/  \/* These fields are set by ExecutorStart *\/ TupleDesctupDesc;\/* descriptor for result tuples *\/ EState   *estate;\/* executor's query-wide state *\/ PlanState  *planstate;\/* tree of per-plan-node state *\/  \/* This field is set by ExecutorRun *\/ boolalready_executed;\/* true if previously executed *\/  \/* This is always set NULL by the core system, but plugins can change it *\/ struct Instrumentation *totaltime;\/* total time spent in ExecutorRun *\/ } QueryDesc;<\/code><\/pre>\n<p>\u0421\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>Executor<\/code>&#8216;\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>EState<\/code>. \u041e\u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0435 <code>estate<\/code> <code>QueryDesc<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/nodes\/execnodes.h#L597\" rel=\"noopener noreferrer nofollow\">src\/include\/nodes\/execnodes.h<\/a>).<\/p>\n<pre><code class=\"cpp\">typedef struct EState { NodeTagtype;  ScanDirection es_direction; \/* current scan direction *\/ Snapshotes_snapshot;\/* time qual to use *\/ Snapshotes_crosscheck_snapshot; \/* crosscheck time qual for RI *\/ List   *es_range_table; \/* List of RangeTblEntry *\/ Indexes_range_table_size;\/* size of the range table arrays *\/ Relation   *es_relations;\/* Array of per-range-table-entry Relation  * pointers, or NULL if not yet opened *\/ struct ExecRowMark **es_rowmarks;\/* Array of per-range-table-entry  * ExecRowMarks, or NULL if none *\/ PlannedStmt *es_plannedstmt;\/* link to top of plan tree *\/ const char *es_sourceText;\/* Source text from QueryDesc *\/  JunkFilter *es_junkFilter;\/* top-level junk filter, if any *\/  \/* If query can insert\/delete tuples, the command ID to mark them with *\/ CommandIdes_output_cid;  \/* Info about target table(s) for insert\/update\/delete queries: *\/ ResultRelInfo **es_result_relations;\/* Array of per-range-table-entry  * ResultRelInfo pointers, or NULL  * if not a target table *\/ List   *es_opened_result_relations; \/* List of non-NULL entries in  * es_result_relations in no  * specific order *\/  PartitionDirectory es_partition_directory;\/* for PartitionDesc lookup *\/  List   *es_tuple_routing_result_relations;  List   *es_trig_target_relations;\/* trigger-only ResultRelInfos *\/  ParamListInfo es_param_list_info;\/* values of external params *\/ ParamExecData *es_param_exec_vals;\/* values of internal params *\/  QueryEnvironment *es_queryEnv;\/* query environment *\/ MemoryContext es_query_cxt; \/* per-query context in which EState lives *\/ List   *es_tupleTable;\/* List of TupleTableSlots *\/ uint64es_processed;\/* # of tuples processed *\/ intes_top_eflags;\/* eflags passed to ExecutorStart *\/ intes_instrument;\/* OR of InstrumentOption flags *\/ booles_finished;\/* true when ExecutorFinish is done *\/ List   *es_exprcontexts;\/* List of ExprContexts within EState *\/ List   *es_subplanstates;\/* List of PlanState for SubPlans *\/ List   *es_auxmodifytables; \/* List of secondary ModifyTableStates *\/ ExprContext *es_per_tuple_exprcontext;  struct EPQState *es_epq_active;  booles_use_parallel_mode;\/* can we use parallel workers? *\/  struct dsa_area *es_query_dsa;  intes_jit_flags; struct JitContext *es_jit; struct JitInstrumentation *es_jit_worker_instr;  List   *es_insert_pending_result_relations; List   *es_insert_pending_modifytables;  List   *es_resultrelinfo_extra; } EState;<\/code><\/pre>\n<h4>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f<\/h4>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u0442\u0430\u043f\u00a0\u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u041f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>DestReceiver<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/tcop\/dest.h#L114\" rel=\"noopener noreferrer nofollow\">src\/include\/tcop\/dest.h<\/a>). \u041f\u043e\u00a0\u0444\u0430\u043a\u0442\u0443 \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u00a0\u2014 \u0432\u00a0\u043d\u0435\u043c \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<pre><code class=\"cpp\">typedef struct _DestReceiver DestReceiver;  struct _DestReceiver { \/* Called for each tuple to be output: *\/ bool(*receiveSlot) (TupleTableSlot *slot, DestReceiver *self); \/* Per-executor-run initialization and shutdown: *\/ void(*rStartup) (DestReceiver *self,  int operation,  TupleDesc typeinfo); void(*rShutdown) (DestReceiver *self); \/* Destroy the receiver object itself (if dynamically allocated) *\/ void(*rDestroy) (DestReceiver *self); \/* CommandDest code for this receiver *\/ CommandDest mydest; \/* Private fields might appear beyond this point... *\/ };<\/code><\/pre>\n<p>\u0412\u00a0\u043a\u043e\u0434\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439:<\/p>\n<ul>\n<li>\n<p><strong>DR_printtup<\/strong> \u0434\u043b\u044f\u00a0DestRemote\u00a0\u2014 \u0432\u044b\u0441\u043b\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f libpq.<\/p>\n<\/li>\n<li>\n<p><strong>donothingDR<\/strong> \u0434\u043b\u044f\u00a0DestNone\u00a0\u2014 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u00a0\u0434\u0435\u043b\u0430\u0442\u044c, \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>debugtupDR<\/strong> \u0434\u043b\u044f\u00a0DestDebug\u00a0\u2014 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u00a0\u044d\u043a\u0440\u0430\u043d\u0435 (\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u044d\u043a\u044d\u043d\u0434).<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 <code>DestRemote<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f <code>DR_printtup<\/code>. \u041f\u043e\u0441\u043b\u0435 \u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430\u00a0\u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u00a0\u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043d\u0430\u00a0\u043f\u043e\u0440\u0442\u0430\u043b. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f\u00a0\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432.<\/p>\n<h4>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u0430<\/h4>\n<p>\u041d\u0430\u00a0\u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0430\u044f \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c\u00a0\u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. <\/p>\n<p>\u041a\u0430\u043a\u00a0\u043c\u044b \u043f\u043e\u043c\u043d\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u00a0\u0441\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u0441, \u0430\u00a0\u043f\u043e\u0440\u0442\u0430\u043b. \u0412\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u0430\u043b\u0430\u00a0\u2014 <code>PortalRun<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/tcop\/pquery.c#L684\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/pquery.c<\/a>)<\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0432\u043e\u044f \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430. \u041e\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442\u00a0\u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u0414\u043b\u044f <code>SELECT<\/code> \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>PortalRunSelect<\/code>. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 (\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a \u0432\u00a0\u043e\u0442\u0432\u0435\u0442\u0435, \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f) \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044e.<\/p>\n<p><code>ExecutorRun<\/code>\u00a0\u2014 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0434\u043b\u044f\u00a0\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430. <\/p>\n<pre><code class=\"cpp\">void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)<\/code><\/pre>\n<blockquote>\n<p>\u041e\u043d, \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438\u043c\u0435\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 (<code>standard_ExecutorRun<\/code>) \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e (<code>ExecutorRun_hook<\/code>)<\/p>\n<\/blockquote>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432\u00a0\u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435. \u041e\u043d \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f:<\/p>\n<ol>\n<li>\n<p>\u0421\u0431\u0440\u043e\u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 (\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u00a0\u043f\u043e\u043b\u0435 <code>es_per_tuple_exprcontext<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430\u00a0\u2014 <code>ExecProcNode<\/code><\/p>\n<ol>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0441\u044f <code>NULL<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u043d\u0435\u00a0\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c\u00a0\u2014 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c <em>\u00abjunk\u00bb<\/em> \u0444\u0438\u043b\u044c\u0442\u0440.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044e.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u00a0\u043b\u0438\u043c\u0438\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439\u00a0\u2014 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>junk \u0444\u0438\u043b\u044c\u0442\u0440<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u00a0\u0440\u044f\u0434\u0443 \u0441\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u00a0\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435\u00a0\u2014 <code>ctid<\/code>, <code>xmin<\/code>, <code>xmax<\/code>, <code>cmin<\/code>, <code>cmax<\/code>, <code>tableoid<\/code>; \u0438\u043b\u0438\u00a0\u044d\u0442\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f\u00a0\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f. \u0422\u0430\u043a\u0438\u0435 \u00ab\u043d\u0438\u043a\u043e\u043c\u0443 \u043d\u0435\u00a0\u043d\u0443\u0436\u043d\u044b\u0435\u00bb \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u00abjunk\u00bb \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438. (Junk\u00a0\u2014 \u043f\u0443\u0441\u0442\u043e\u0439). \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e junk \u0444\u0438\u043b\u044c\u0442\u0440 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f\u00a0\u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. <\/p>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>ExecFilterJunk<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/executor\/execJunk.c#L247\" rel=\"noopener noreferrer nofollow\">src\/backend\/executor\/execJunk.c<\/a>).\u00a0<\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0440\u044b\u0445 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/executor\/execJunk.c#L19\" rel=\"noopener noreferrer nofollow\">TODO<\/a> &#8212;\u00a0<\/p>\n<pre><code class=\"cpp\">\/*-------------------------------------------------------------------------  *XXX this stuff should be rewritten to take advantage  *of ExecProject() and the ProjectionInfo node.  *-cim 6\/3\/91  *   * ...  *  *\/<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f\u0441\u044f \u0432 \u043f\u043e\u043b\u0435 <code>ExecProcNode<\/code><\/p>\n<pre><code class=\"cpp\">\/\/ src\/include\/nodes\/execnodes.h typedef struct PlanState { \/\/ ...  ExecProcNodeMtd ExecProcNode;\/* function to return next tuple *\/ ExecProcNodeMtd ExecProcNodeReal;\/* actual function, if above is a                                          * wrapper *\/ \/\/ ... } PlanState;   \/\/ src\/include\/executor\/executor.h static inline TupleTableSlot * ExecProcNode(PlanState *node) { if (node->chgParam != NULL) \/* something changed? *\/ ExecReScan(node);\/* let ReScan handle this *\/  return node->ExecProcNode(node); }<\/code><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0432 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u043f\u0430\u043f\u043a\u0438 <code>src\/backend\/executor\/node*.c<\/code>.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 <code>LIMIT<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0443\u0437\u0435\u043b <code>LimitState<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/nodes\/execnodes.h#L2721\" rel=\"noopener noreferrer nofollow\">src\/include\/nodes\/execnodes.h<\/a>). \u0424\u0443\u043d\u043a\u0446\u0438\u044f, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0430\u044f \u0435\u0433\u043e \u043b\u043e\u0433\u0438\u043a\u0443, &#8212; <code>ExecLimit<\/code> \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/executor\/nodeLimit.c#L41\" rel=\"noopener noreferrer nofollow\">src\/backend\/executor\/nodeLimit.c<\/a><\/p>\n<pre><code class=\"cpp\">typedef struct LimitState { PlanStateps;\/* its first field is NodeTag *\/ ExprState  *limitOffset;\/* OFFSET parameter, or NULL if none *\/ ExprState  *limitCount;\/* COUNT parameter, or NULL if none *\/ LimitOption limitOption;\/* limit specification type *\/ int64offset;\/* current OFFSET value *\/ int64count;\/* current COUNT, if any *\/ boolnoCount;\/* if true, ignore count *\/ LimitStateCond lstate;\/* state machine status, as above *\/ int64position;\/* 1-based index of last tuple returned *\/ TupleTableSlot *subSlot;\/* tuple last obtained from subplan *\/ ExprState  *eqfunction;\/* tuple equality qual in case of WITH TIES  * option *\/ TupleTableSlot *last_slot;\/* slot for evaluation of ties *\/ } LimitState;<\/code><\/pre>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0417\u0430 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <code>ExecSeqScan<\/code>. \u0415\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>SeqScanState<\/code>.<\/p>\n<pre><code class=\"cpp\">typedef struct SeqScanState { ScanStatess;\/* its first field is NodeTag *\/ Sizepscan_len;\/* size of parallel heap scan descriptor *\/ } SeqScanState;<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f (\u0432\u044b\u0431\u043e\u0440\u043a\u0430 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, CTE, \u0438\u043d\u0434\u0435\u043a\u0441\u0430, \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f; \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438), \u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u043e\u0431\u0449\u0435\u0439. \u041f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>ExecScan<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/executor\/execScan.c#L158\" rel=\"noopener noreferrer nofollow\">src\/backend\/executor\/execScan.c<\/a>).<\/p>\n<pre><code class=\"cpp\">TupleTableSlot * ExecScan(ScanState *node,  ExecScanAccessMtd accessMtd,\/* function returning a tuple *\/  ExecScanRecheckMtd recheckMtd)<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c. \u0414\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e <code>SeqNext<\/code> \u0438 <code>SeqRecheck<\/code>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/executor\/nodeSeqscan.c#L50\" rel=\"noopener noreferrer nofollow\">src\/backend\/executor\/nodeSeqscan.c<\/a>).<\/p>\n<pre><code class=\"cpp\">\/* ----------------------------------------------------------------  *SeqNext  *  *This is a workhorse for ExecSeqScan  * ----------------------------------------------------------------  *\/ static TupleTableSlot * SeqNext(SeqScanState *node);  \/*  * SeqRecheck -- access method routine to recheck a tuple in EvalPlanQual  *\/ static bool SeqRecheck(SeqScanState *node, TupleTableSlot *slot) { \/*  * Note that unlike IndexScan, SeqScan never use keys in heap_beginscan  * (and this is very bad) - so, here we do not check are keys ok or not.  *\/ return true; }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430\u0434 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u043c \u043d\u0435\u00a0\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0430\u0447\u0435, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0438\u0441\u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441. \u0422\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<ol>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>ExecProcNode<\/code>\u00a0\u2014 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0434\u043b\u044f\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u043d\u0430, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0433\u043e\u0441\u044f \u0432\u00a0\u0437\u0430\u043f\u0440\u043e\u0441\u0435. \u0412\u043d\u0443\u0442\u0440\u0438, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f\u0441\u044f \u0432\u00a0\u043f\u043e\u043b\u0435 <code>ExecProcNode<\/code>. \u042d\u0442\u043e \u043a\u043e\u0440\u0435\u043d\u044c \u0434\u0435\u0440\u0435\u0432\u0430 \u043f\u043b\u0430\u043d\u0430. \u0422\u0430\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f <code>ExecSeqScan<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0432\u044b\u0437\u043e\u0432 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u00a0\u2014 <code>ExecScan<\/code>. \u041d\u0430\u00a0\u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438\u00a0\u2014 <code>SeqNext<\/code>, <code>SeqRecheck<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f\u0441\u044f \u0432\u00a0\u043f\u043e\u043b\u0435 <code>scan_getnextslot<\/code>, \u0434\u043b\u044f\u00a0\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0437\u00a0\u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0412\u00a0\u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>heap_getnextslot<\/code>. <\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>heapgettup<\/code>\u00a0\u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f\u00a0\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0437\u00a0\u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u00a0\u043f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0434\u043e\u00a0\u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435\u00a0\u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436.<\/p>\n<\/li>\n<li>\n<p>\u0411\u0443\u0444\u0435\u0440 \u0441\u00a0\u043a\u043e\u0440\u0442\u0435\u0436\u0435\u043c \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0438\u043a\u0442\u043e \u0435\u0433\u043e \u043d\u0435\u00a0\u0432\u044b\u0433\u0440\u0443\u0437\u0438\u043b.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u00abjunk\u00bb \u0444\u0438\u043b\u044c\u0442\u0440 \u0434\u043b\u044f\u00a0\u043e\u0442\u0441\u0435\u0438\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0445 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0440\u0442\u0435\u0436 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044e.<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f heapgettup \u0438 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0438\u0441\u043a\u043e\u043c<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>heapgettup<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/access\/heap\/heapam.c#L508\" rel=\"noopener noreferrer nofollow\">src\/backend\/access\/heap\/heapam.c<\/a>)<\/p>\n<p>\u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0438\u0441\u043a \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u0442\u0430\u0440\u0442\u0430 \u0447\u0442\u0435\u043d\u0438\u044f. \u041e\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f: \u0432\u043f\u0435\u0440\u0435\u0434 \u0438\u043b\u0438 \u043d\u0430\u0437\u0430\u0434.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u0435\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0431\u0435\u0440\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u0430\u044f (\u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430) \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430. \u0418\u0437 \u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430<\/p>\n<\/li>\n<li>\n<p>\u0411\u0443\u0444\u0435\u0440, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0434\u0438\u0441\u043a\u043e\u043c &#8212; \u044d\u0442\u043e \u043a\u0440\u0430\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043c\u0435\u043d\u044c \u0432\u0441\u0435\u0445 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0440\u0438\u0447\u0438\u043d\u044b:<\/p>\n<ul>\n<li>\n<p>\u041d\u0438\u0437\u043a\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 &#8212; IO-bound \u0437\u0430\u0434\u0430\u0447\u0430<\/p>\n<\/li>\n<li>\n<p>\u0411\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u041e\u0421 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0434\u0438\u0441\u043a\u043e\u043c &#8212; \u043d\u0435\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0441\u0431\u0440\u043e\u0441 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u0440\u0438 \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 &#8212; \u0435\u0441\u043b\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0439<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441\u0442\u0430\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b:<\/p>\n<ul>\n<li>\n<p>\u041c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0420\u0443\u0447\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u201c3-\u0441\u043b\u043e\u0439\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u201d<\/p>\n<ul>\n<li>\n<p>\u0421\u043b\u043e\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u044d\u0433\u0430 \u0431\u0443\u0444\u0435\u0440\u0430 \u043d\u0430 \u0435\u0433\u043e Id<\/p>\n<\/li>\n<li>\n<p>\u0421\u043b\u043e\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f Id \u0431\u0443\u0444\u0435\u0440\u0430 \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0432 \u043f\u0430\u043c\u044f\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u0421\u043b\u043e\u0439 \u0431\u0443\u0444\u0435\u0440\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a96\/5f5\/0c2\/a965f50c271c8bd5ad0c9b4dce59de0b.png\" alt=\"\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u0441\u0430\u0439\u0442\u0430 https:\/\/www.interdb.jp\/pg\/pgsql08.html\" title=\"\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u0441\u0430\u0439\u0442\u0430 https:\/\/www.interdb.jp\/pg\/pgsql08.html\" width=\"1542\" height=\"620\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a96\/5f5\/0c2\/a965f50c271c8bd5ad0c9b4dce59de0b.png\"\/><\/p>\n<div><figcaption>\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u0441\u0430\u0439\u0442\u0430 <a href=\"https:\/\/www.interdb.jp\/pg\/pgsql08.html\" rel=\"noopener noreferrer nofollow\">https:\/\/www.interdb.jp\/pg\/pgsql08.html<\/a><\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439:<\/p>\n<ul>\n<li>\n<p><strong>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/strong> &#8212; \u0435\u0434\u0438\u043d\u0438\u0446\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u0441 \u0434\u0438\u0441\u043a\u0430. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0432 Postgres \u0440\u0430\u0432\u043d\u0430 8 \u041a\u0431. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u043e\u043c <code>BlockNumber<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/storage\/block.h#L31\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/block.h<\/a>)<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">typedef uint32 BlockNumber;  #define InvalidBlockNumber((BlockNumber) 0xFFFFFFFF)  #define MaxBlockNumber((BlockNumber) 0xFFFFFFFE)<\/code><\/pre>\n<ul>\n<li>\n<p><strong>\u0411\u0443\u0444\u0435\u0440<\/strong> &#8212; \u0435\u0434\u0438\u043d\u0438\u0446\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041a\u0430\u0436\u0434\u044b\u0439 \u0431\u0443\u0444\u0435\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u0438\u0441\u043a\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u043a\u0443. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>Page<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/storage\/bufpage.h#L78\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/bufpage.h<\/a>)<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">typedef Pointer Page;<\/code><\/pre>\n<ul>\n<li>\n<p><strong>\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u043e\u0432<\/strong> &#8212; \u043c\u043e\u0434\u0443\u043b\u044c, \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0432 \u0441\u0435\u0431\u0435 \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0431\u0443\u0444\u0435\u0440\u0430\u043c\u0438 &#8212; <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/storage\/buffer\/bufmgr.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/buffer\/bufmgr.c<\/a><\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<p><strong>\u0422\u044d\u0433 \u0431\u0443\u0444\u0435\u0440\u0430<\/strong> &#8212; \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0442\u0440\u043e\u0439\u043a\u0438\u00a0 (\u0430\u0434\u0440\u0435\u0441 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0442\u0438\u043f \u0444\u043e\u0440\u043a\u0430, \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b). \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u043e\u0432. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>BufferTag<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/include\/storage\/buf_internals.h#L91\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/buf_internals.h<\/a>)<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">typedef struct buftag { RelFileNode rnode;\/* physical relation identifier *\/ ForkNumberforkNum; BlockNumber blockNum;\/* blknum relative to begin of reln *\/ } BufferTag;<\/code><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>\u041a\u043b\u0438\u0435\u043d\u0442 (\u0431\u044d\u043a\u044d\u043d\u0434) \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0439 \u0431\u0443\u0444\u0435\u0440. \u0412 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u043d \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u044d\u0433\u0430 \u0431\u0443\u0444\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u043e\u0432 \u0438\u0449\u0435\u0442 Id \u0431\u0443\u0444\u0435\u0440\u0430 \u043f\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u0442\u0435\u0433\u0443. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d, \u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0439 \u0431\u0443\u0444\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u0433\u043e\/\u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f Id<\/p>\n<\/li>\n<li>\n<p>Id \u0431\u0443\u0444\u0435\u0440\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0443<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043a\u043b\u0438\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0431\u0443\u0444\u0435\u0440\u043e\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 Id<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u0418\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u0432\u044b\u0447\u043b\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0431\u0443\u0444\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0445. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0435\u0440\u0432\u044b\u0439, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">\/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043f\u0435\u0440\u0435\u0434  if (!scan->rs_inited) {     \/*      * return null immediately if relation is empty      *\/     if (scan->rs_nblocks == 0 || scan->rs_numblocks == 0)     {         Assert(!BufferIsValid(scan->rs_cbuf));         tuple->t_data = NULL;         return;     }     if (scan->rs_base.rs_parallel != NULL)     {         ParallelBlockTableScanDesc pbscan =         (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel;         ParallelBlockTableScanWorker pbscanwork =         scan->rs_parallelworkerdata;          table_block_parallelscan_startblock_init(scan->rs_base.rs_rd,                                                  pbscanwork, pbscan);          page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd,                                                  pbscanwork, pbscan);          \/* Other processes might have already finished the scan. *\/         if (page == InvalidBlockNumber)         {             Assert(!BufferIsValid(scan->rs_cbuf));             tuple->t_data = NULL;             return;         }     }     else         page = scan->rs_startblock; \/* first page *\/     heapgetpage((TableScanDesc) scan, page);     lineoff = FirstOffsetNumber;\/* first offnum *\/     scan->rs_inited = true;     }     else     {         \/* continue from previously returned page\/tuple *\/         page = scan->rs_cblock; \/* current page *\/         lineoff =\/* next offnum *\/             OffsetNumberNext(ItemPointerGetOffsetNumber(&amp;(tuple->t_self)));     }          LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);          dp = BufferGetPage(scan->rs_cbuf);     TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp);     lines = PageGetMaxOffsetNumber(dp);     \/* page and lineoff now reference the physically next tid *\/          linesleft = lines - lineoff + 1; }<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u0418\u0437 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u0442\u0441\u044f \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0430\u044f \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0443<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">while (linesleft > 0) {     if (ItemIdIsNormal(lpp))     {         boolvalid;          tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lpp);         tuple->t_len = ItemIdGetLength(lpp);         ItemPointerSet(&amp;(tuple->t_self), page, lineoff);          \/*          * if current tuple qualifies, return it.          *\/         valid = HeapTupleSatisfiesVisibility(tuple,                                              snapshot,                                              scan->rs_cbuf);          HeapCheckForSerializableConflictOut(valid, scan->rs_base.rs_rd,                                             tuple, scan->rs_cbuf,                                             snapshot);          if (valid &amp;&amp; key != NULL)             HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd),                         nkeys, key, valid);          if (valid)         {             LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);             return;         }     }      \/*      * otherwise move to the next item on the page      *\/     --linesleft;     if (backward)     {         --lpp;\/* move back in this page's ItemId array *\/         --lineoff;     }     else     {         ++lpp;\/* move forward in this page's ItemId array *\/         ++lineoff;     } }<\/code><\/pre>\n<ol start=\"3\">\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u0442\u0435\u0436 \u043d\u0435 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d, \u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f 2 \u0448\u0430\u0433. \u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>NULL<\/code> &#8212; \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">\/*  * if we get here, it means we've exhausted the items on this page and  * it's time to move to the next.  *\/ LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);  \/*  * advance to next\/prior page and detect end of scan  *\/ if (backward) {     finished = (page == scan->rs_startblock) ||         (scan->rs_numblocks != InvalidBlockNumber ? --scan->rs_numblocks == 0 : false);     if (page == 0)         page = scan->rs_nblocks;     page--; } else if (scan->rs_base.rs_parallel != NULL) {     ParallelBlockTableScanDesc pbscan =     (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel;     ParallelBlockTableScanWorker pbscanwork =     scan->rs_parallelworkerdata;      page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd,                                              pbscanwork, pbscan);     finished = (page == InvalidBlockNumber); } else {     page++;     if (page >= scan->rs_nblocks)         page = 0;     finished = (page == scan->rs_startblock) ||         (scan->rs_numblocks != InvalidBlockNumber ? --scan->rs_numblocks == 0 : false);      \/*      * Report our new scan position for synchronization purposes. We      * don't do that when moving backwards, however. That would just      * mess up any other forward-moving scanners.      *      * Note: we do this before checking for end of scan so that the      * final state of the position hint is back at the start of the      * rel.  That's not strictly necessary, but otherwise when you run      * the same query multiple times the starting position would shift      * a little bit backwards on every invocation, which is confusing.      * We don't guarantee any specific ordering in general, though.      *\/     if (scan->rs_base.rs_flags &amp; SO_ALLOW_SYNC)         ss_report_location(scan->rs_base.rs_rd, page); }  \/*  * return NULL if we've exhausted all the pages  *\/ if (finished) {     if (BufferIsValid(scan->rs_cbuf))         ReleaseBuffer(scan->rs_cbuf);     scan->rs_cbuf = InvalidBuffer;     scan->rs_cblock = InvalidBlockNumber;     tuple->t_data = NULL;     scan->rs_inited = false;     return; }  heapgetpage((TableScanDesc) scan, page);  LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);  dp = BufferGetPage(scan->rs_cbuf); TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp); lines = PageGetMaxOffsetNumber((Page) dp); linesleft = lines; if (backward) {     lineoff = lines;     lpp = PageGetItemId(dp, lines); } else {     lineoff = FirstOffsetNumber;     lpp = PageGetItemId(dp, FirstOffsetNumber); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043e\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. \u0414\u043b\u044f\u00a0\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>PortalDrop<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/utils\/mmgr\/portalmem.c#L469\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/mmgr\/portalmem.c<\/a>):<\/p>\n<ul>\n<li>\n<p>\u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u043b\u044f\u00a0\u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 (\u0434\u043b\u044f \u043f\u0440\u043e\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u00a0\u043d\u0435\u043c).<\/p>\n<\/li>\n<li>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0440\u0442\u0430\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u044f\u00a0\u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0432\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043b\u0435 <code>rDestroy<\/code>, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u043d\u0430\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430. \u0412\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u00a0\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u043c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>printtup_destroy<\/code>. \u041e\u043d\u0430 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u00a0\u043d\u0435\u0433\u043e \u043f\u0430\u043c\u044f\u0442\u044c.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u00a0\u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u043f\u0440\u0438\u0441\u043b\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438\u00a0\u0441\u0430\u043c\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e \u0441\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>BEGIN<\/code> \u0438\u043b\u0438 <code>SAVEPOINT<\/code>) \u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043a\u043e\u043c\u043c\u0438\u0442.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0438\u0442\u0430, \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.postgresql.org\/docs\/15\/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-COMMANDCOMPLETE\" rel=\"noopener noreferrer nofollow\">\u043f\u0430\u043a\u0435\u0442<\/a> <code>CommandComplete<\/code>. \u041e\u043d \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043e\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438.<\/p>\n<h2>\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h2>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043a, \u0447\u0442\u043e\u00a0\u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430, \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u0443\u0441\u0442\u044b\u043c. \u042d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0446\u0438\u043a\u043b\u0430. \u0412\u00a0\u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u0430\u044f \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u0441\u044f \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f <code>EmptyQueryResponse<\/code> <a href=\"https:\/\/www.postgresql.org\/docs\/15\/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-EMPTYQUERYRESPONSE\" rel=\"noopener noreferrer nofollow\">\u043f\u0430\u043a\u0435\u0442<\/a>. <\/p>\n<h2>\u041a\u043e\u043d\u0435\u0446<\/h2>\n<p>\u041d\u0430\u00a0\u044d\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/723668\/\"> https:\/\/habr.com\/ru\/articles\/723668\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e!<\/p>\n<p>\u041d\u0430 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u0438\u0437\u0443\u0447\u0438\u043b\u0438 \u0446\u0438\u043a\u043b \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430. \u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 <code>SELECT<\/code> \u0437\u0430\u043f\u0440\u043e\u0441. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0430 <code>users<\/code><\/p>\n<pre><code class=\"sql\">create table users(   id integer generated always as identity,   email varchar not null,   name varchar );<\/code><\/pre>\n<p>\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u043d\u0435\u0435:<\/p>\n<pre><code class=\"sql\">select * from users;<\/code><\/pre>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h2>\n<p>\u041f\u0443\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>exec_simple_query<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/tcop\/postgres.c#L992\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a>), \u0442\u0430\u043a \u043a\u0430\u043a \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b <a href=\"https:\/\/www.postgresql.org\/docs\/current\/protocol-flow.html#id-1.10.6.7.4\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438<\/a>.<\/p>\n<h4>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 <\/h4>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0431\u043b\u043e\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438. \u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>pgstat_report_activity<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/utils\/activity\/backend_status.c#L521\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/activity\/backend_status.c<\/a>), \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 (<code>STATE_RUNNING<\/code>) \u0438 \u0441\u044b\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0421\u0430\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0430\u0442\u0443\u0441\u0430<\/p>\n<\/li>\n<li>\n<p>\u0412\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441<\/p>\n<\/li>\n<li>\n<p>\u0412\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441\u0435<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>ResetUsage<\/code> \u0434\u043b\u044f \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0447\u0435\u0442\u0430 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432: \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u0441\u0438\u0433\u043d\u0430\u043b\u044b. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b &lt;sys\/resource.h>. \u0412 \u043d\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u0422\u0430\u043a, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 rusage:<\/p>\n<pre><code class=\"cpp\">struct rusage {     \/* Total amount of user time used.  *\/     struct timeval ru_utime;     \/* Total amount of system time used.  *\/     struct timeval ru_stime;     \/* Maximum resident set size (in kilobytes).  *\/     union     {         long int ru_maxrss;         __syscall_slong_t __ru_maxrss_word;     };     \/* Amount of sharing of text segment memory        with other processes (kilobyte-seconds).  *\/     union     {         long int ru_ixrss;         __syscall_slong_t __ru_ixrss_word;     };     \/* Amount of data segment memory used (kilobyte-seconds).  *\/     union     {         long int ru_idrss;         __syscall_slong_t __ru_idrss_word;     };     \/* Amount of stack memory used (kilobyte-seconds).  *\/          union     {         long int ru_isrss;         __syscall_slong_t __ru_isrss_word;     };     \/* Number of soft page faults (i.e. those serviced by reclaiming        a page from the list of pages awaiting reallocation.  *\/     union     {         long int ru_minflt;         __syscall_slong_t __ru_minflt_word;     };     \/* Number of hard page faults (i.e. those that required I\/O).  *\/     union     {         long int ru_majflt;         __syscall_slong_t __ru_majflt_word;     };     \/* Number of times a process was swapped out of physical memory.  *\/     union     {         long int ru_nswap;         __syscall_slong_t __ru_nswap_word;     };     \/* Number of input operations via the file system.  Note: This        and `ru_oublock' do not include operations with the cache.  *\/     union     {         long int ru_inblock;         __syscall_slong_t __ru_inblock_word;     };     \/* Number of output operations via the file system.  *\/     union     {         long int ru_oublock;         __syscall_slong_t __ru_oublock_word;     };     \/* Number of IPC messages sent.  *\/     union     {         long int ru_msgsnd;         __syscall_slong_t __ru_msgsnd_word;     };     \/* Number of IPC messages received.  *\/     union     {         long int ru_msgrcv;         __syscall_slong_t __ru_msgrcv_word;     };     \/* Number of signals delivered.  *\/     union     {         long int ru_nsignals;         __syscall_slong_t __ru_nsignals_word;     };     \/* Number of voluntary context switches, i.e. because the process        gave up the process before it had to (usually to wait for some        resource to be available).  *\/     union     {         long int ru_nvcsw;         __syscall_slong_t __ru_nvcsw_word;     };     \/* Number of involuntary context switches, i.e. a higher priority process        became runnable or the current process used up its time slice.  *\/    union     {         long int ru_nivcsw;         __syscall_slong_t __ru_nivcsw_word;     }; };<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0439 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>getrusage<\/code> &#8212; \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 (<a href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/getrusage.2.html\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/man7.org\/linux\/man-pages\/man2\/getrusage.2.html<\/u><\/a>).\u00a0<\/p>\n<p>\u0412 Postgres \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e GUC \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a <code>log_*_stats<\/code>. \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b, \u0442\u043e \u043f\u043e \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u0442\u0430\u043f\u0430 \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c <code>log_statement_stats<\/code> \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445, \u0435\u0441\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435) \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043b\u043e\u0433.\u00a0<\/p>\n<p>\u0417\u0430 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>ShowUsage<\/code><\/p>\n<pre><code class=\"cpp\">void ShowUsage(const char *title);<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u201cQUERY STATISTICS\u201d<\/p>\n<pre><code class=\"cpp\">ShowUsage(\"QUERY STATISTICS\");<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043e\u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u043e\u0439 \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043b\u043e\u0433.\u00a0<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0432\u0445\u043e\u0434\u043e\u043c \u0432 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043e\u0431\u043b\u0430\u0441\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ResetUsage<\/code>. \u041e\u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0443 \u043e\u0442\u0441\u0447\u0435\u0442\u0430. \u041f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 ShowUsage \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0414\u043b\u044f <code>exec_simple_query<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"cpp\">if (save_log_statement_stats)     ResetUsage();  \/\/\/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430  if (save_log_statement_stats) ShowUsage(\"QUERY STATISTICS\");<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>\u041d\u0430\u0447\u0430\u043b\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/h4>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f. <\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u0435\u0441\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <code>xact<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/access\/transam\/xact.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/access\/transam\/xact.c<\/a>). \u041d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f Postgres \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0441\u0432\u043e\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: <code>start_xact_command<\/code> \u0438 <code>finish_xact_command<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u00a0\u043d\u0430\u0447\u0430\u043b\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f\u00a0\u2014 \u0437\u0430\u00a0\u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u00a0\u043d\u0438\u0445 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. \u041a\u0430\u043a\u00a0\u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b, \u043e\u043d\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 (\u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\/\u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442) \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430\u043c\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u00a0\u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043d\u0430\u00a0\u0432\u0435\u0441\u044c \u0431\u043b\u043e\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442\u00a0\u0442\u043e\u0433\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u0442\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u00a0\u043d\u0435\u044f\u0432\u043d\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e.<\/p>\n<h4>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0443<\/h4>\n<p>\u041f\u043b\u0430\u043d\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443. \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>CachedPlanSource<\/code>, \u0430 \u0441\u0430\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c (\u0434\u043b\u044f \u0431\u044d\u043a\u044d\u043d\u0434\u0430) \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435.\u00a0<\/p>\n<pre><code class=\"cpp\">typedef struct CachedPlanSource { intmagic;\/* should equal CACHEDPLANSOURCE_MAGIC *\/ struct RawStmt *raw_parse_tree; \/* output of raw_parser(), or NULL *\/ const char *query_string;\/* source text of query *\/ CommandTagcommandTag;\/* 'nuff said *\/ Oid   *param_types;\/* array of parameter type OIDs, or NULL *\/ intnum_params;\/* length of param_types array *\/ ParserSetupHook parserSetup;\/* alternative parameter spec method *\/ void   *parserSetupArg; intcursor_options; \/* cursor options used for planning *\/ boolfixed_result;\/* disallow change in result tupdesc? *\/ TupleDescresultDesc;\/* result type; NULL = doesn't return tuples *\/ MemoryContext context;\/* memory context holding all above *\/ \/* These fields describe the current analyzed-and-rewritten query tree: *\/ List   *query_list;\/* list of Query nodes, or NIL if not valid *\/ List   *relationOids;\/* OIDs of relations the queries depend on *\/ List   *invalItems;\/* other dependencies, as PlanInvalItems *\/ struct OverrideSearchPath *search_path; \/* search_path used for parsing  * and planning *\/ MemoryContext query_context;\/* context holding the above, or NULL *\/ OidrewriteRoleId;\/* Role ID we did rewriting for *\/ boolrewriteRowSecurity; \/* row_security used during rewrite *\/ booldependsOnRLS;\/* is rewritten query specific to the above? *\/ \/* If we have a generic plan, this is a reference-counted link to it: *\/ struct CachedPlan *gplan;\/* generic plan, or NULL if not valid *\/ \/* Some state flags: *\/ boolis_oneshot;\/* is it a \"oneshot\" plan? *\/ boolis_complete;\/* has CompleteCachedPlan been done? *\/ boolis_saved;\/* has CachedPlanSource been \"saved\"? *\/ boolis_valid;\/* is the query_list currently valid? *\/ intgeneration;\/* increments each time we create a plan *\/ \/* If CachedPlanSource has been saved, it is a member of a global list *\/ dlist_nodenode;\/* list link, if is_saved *\/ \/* State kept to help decide whether to use custom or generic plans: *\/ doublegeneric_cost;\/* cost of generic plan, or -1 if not known *\/ doubletotal_custom_cost;\/* total cost of custom plans so far *\/ int64num_custom_plans;\/* # of custom plans included in total *\/ int64num_generic_plans;\/* # of generic plans *\/ } CachedPlanSource;<\/code><\/pre>\n<p>1 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u043c\u0435\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 1 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043d\u0430 \u0435\u0433\u043e \u043f\u043e\u0438\u0441\u043a \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043d\u0438\u0445 (\u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0445) \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f unnnamed_stmt_psrc:<\/p>\n<pre><code class=\"cpp\">\/*  * If an unnamed prepared statement exists, it's stored here.  * We keep it separate from the hashtable kept by commands\/prepare.c  * in order to reduce overhead for short-lived queries.  *\/ static CachedPlanSource *unnamed_stmt_psrc = NULL;<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 SimpleQuery \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043d\u0435\u0439. \u041a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u043b\u0430\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0430 <code>MessageContext<\/code>. \u0412 \u043d\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0417\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <code>parser<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/parser\/parser.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/parser\/parser.c<\/a>). \u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>raw_parser<\/code><\/p>\n<pre><code class=\"cpp\">\/*  * raw_parser  *Given a query in string form, do lexical and grammatical analysis.  *  * Returns a list of raw (un-analyzed) parse trees.  The contents of the  * list have the form required by the specified RawParseMode.  *\/ List * raw_parser(const char *str, RawParseMode mode);<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0440\u0435\u0436\u0438\u043c \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 &#8212; <code>Raw<\/code><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-407728","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/407728","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=407728"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/407728\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=407728"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=407728"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=407728"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}