{"id":346181,"date":"2023-03-02T15:06:43","date_gmt":"2023-03-02T15:06:43","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=346181"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2023-03-02T15:06:43","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=346181","title":{"rendered":"<span>PostgreSQL \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u0427\u0430\u0441\u0442\u044c 4. \u0426\u0438\u043a\u043b \u0431\u044d\u043a\u044d\u043d\u0434\u0430<\/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>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 PostgreSQL \u043f\u043e\u0434\u00a0\u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0441\u00a0\u043c\u0435\u0441\u0442\u0430 \u0433\u0434\u0435 <a href=\"https:\/\/habr.com\/ru\/post\/709404\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c<\/a>\u00a0\u2014 \u043f\u0440\u044f\u043c\u043e \u043f\u0435\u0440\u0435\u0434 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c. \u0424\u0430\u0439\u043b \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/tcop\/postgres.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a><\/p>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0414\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/man7.org\/linux\/man-pages\/man3\/setjmp.3.html\" rel=\"noopener noreferrer nofollow\">setjmp<\/a><\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0446\u0438\u043a\u043b\u0430 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u0430 \u0441\u0442\u0435\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0434\u043b\u044f\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043f\u0440\u0438\u00a0\u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u0445. <\/p>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0444\u043b\u0430\u0433\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>DoingCommandRead<\/em>)<\/p>\n<\/li>\n<li>\n<p>\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <em>libpq<\/em> \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <\/p>\n<\/li>\n<li>\n<p>\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u043e\u0442\u044b \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u00a0\u043e\u0448\u0438\u0431\u043a\u0435<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">if (sigsetjmp(local_sigjmp_buf, 1) != 0) {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f }  \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 PG_exception_stack = &amp;local_sigjmp_buf;  \/\/ ...  for (;;) {   \/\/ \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>setjmp<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/man7.org\/linux\/man-pages\/man3\/setjmp.3.html\" rel=\"noopener noreferrer nofollow\">setjmp<\/a>\u00a0\u2014 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f C \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043f\u043e\u00a0\u0441\u0442\u0435\u043a\u0443. \u0427\u0442\u043e\u00a0\u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442? \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e\u00a0\u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432\u0432\u0435\u0440\u0445 \u043f\u043e\u00a0\u0441\u0442\u0435\u043a\u0443 \u043a\u00a0\u043d\u0443\u0436\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432\u00a0\u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442\u00a0goto, \u0433\u0434\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u00a0\u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0444\u0443\u043a\u043d\u0446\u0438\u0438. \u0420\u0430\u0431\u043e\u0442\u0443 \u0441\u00a0\u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">jmp_buf *global_buf;  void doSomeStaff();  \/\/ \u0412\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c 1 int main() {   jmp_buf buf;   if (setjmp(&amp;buf) != 0) {     printf(\"\u0412\u0435\u0440\u043d\u0443\u043b\u0438\u0441\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e!\")     return 1;   }    global_buf = &amp;buf;   doSomeStaff();   return 0; }  void doSomeStaff() {   printf(\"\u0412\u043d\u0443\u0442\u0440\u0438 doSomeStaff\");   longjmp(global_buf, 1); }<\/code><\/pre>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0442\u0438\u043f\u0430 <em>jmp_buf<\/em>, \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0441\u0442\u0435\u043a\u0430, \u0434\u043b\u044f\u00a0\u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. \u0421\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0430\u044f, \u0434\u043b\u044f\u00a0\u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043e\u043a, \u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f, \u0434\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0430\u0434\u0440\u0435\u0441\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <em>setjmp<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f. \u041a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u00a0\u043d\u0435\u0439 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <em>longjmp<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u00a0\u0436\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0438 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d <em>setjmp<\/em>. <\/p>\n<p><strong>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: <em>setjmp<\/em> \u043f\u0440\u0438\u00a0\u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 0, \u0430\u00a0\u0432\u00a0\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u0434\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0435 <em>longjmp<\/em>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0435\u0447\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c 0\u00a0\u0438\u0437 <em>setjmp<\/em>, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u0434 0\u00a0\u0432 <em>longjmp<\/em><\/p>\n<p>\u0421\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>setjmp<\/em>\/<em>longjmp<\/em> \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439\u00a0\u2014 SJLJ. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, SEH \u0438\u043b\u0438\u00a0DWARF. \u0418\u0445 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/wiki.qt.io\/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u041a\u0430\u043a\u00a0\u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/491084\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439<\/a> \u0441\u0442\u0430\u0442\u044c\u0435<\/p>\n<p>P.\u00a0S. \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 <em>sigsetjmp<\/em>\/<em>siglongjmp<\/em> \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043d\u043e\u00a0\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043c\u0430\u0441\u043a\u0443 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u00a0Postgres, \u0442.\u043a. \u0432\u00a0\u043d\u0435\u043c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u0441\u0438\u0433\u043d\u0430\u043b\u0430\u043c\u0438.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432 Postgres<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u00a0Postgres \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a. \u0412 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/elog.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/elog.h<\/a> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0434\u043b\u044f\u00a0try\/catch\/finally \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">#define PG_TRY()  \\   do { \\       sigjmp_buf *_save_exception_stack = PG_exception_stack; \\       ErrorContextCallback *_save_context_stack = error_context_stack; \\       sigjmp_buf _local_sigjmp_buf; \\       bool _do_rethrow = false; \\       if (sigsetjmp(_local_sigjmp_buf, 0) == 0) \\       { \\           PG_exception_stack = &amp;_local_sigjmp_buf  #define PG_CATCH()\\   } \\   else \\   { \\       PG_exception_stack = _save_exception_stack; \\       error_context_stack = _save_context_stack  #define PG_FINALLY() \\   } \\   else \\       _do_rethrow = true; \\   { \\       PG_exception_stack = _save_exception_stack; \\       error_context_stack = _save_context_stack  #define PG_END_TRY()  \\     } \\       if (_do_rethrow) \\               PG_RE_THROW(); \\       PG_exception_stack = _save_exception_stack; \\       error_context_stack = _save_context_stack; \\   } while (0)<\/code><\/pre>\n<p>\u0414\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 \u0438\u0437\u2011\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <em>PG_exception_stack <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/error\/elog.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/error\/elog.c<\/a>), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c try\/catch\/finally \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a<\/p>\n<pre><code class=\"cpp\">PG_TRY(); {   \/\/ \u041e\u0448\u0438\u0431\u043a\u0430   if (!IsValidValue(1))    {     ereport(ERROR,             (errcode(ERRCODE_SOME_ERRCODE),             errmsg(\"value is not valid\")));   } } PG_CATCH(); {     GlobalValue = old_value; } PG_END_TRY();  \/\/ ===================  PG_TRY(); {   fwrite(\"Hello, world!\", sizeof(char), 13, handle) } PG_FINALLY(); {     fclose(handle); } PG_END_TRY();<\/code><\/pre>\n<p>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u00a0\u0443\u0440\u043e\u0432\u043d\u0435\u043c <em>ERROR<\/em><\/p>\n<p>\u041d\u043e\u00a0\u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c PG_CATCH \u0438 PG_FINALLY: \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f if\/else \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f, \u043f\u0440\u0438\u0447\u0435\u043c if\u00a0\u2014 PG_TRY, \u0430\u00a0else\u00a0\u2014 \u0435\u0441\u0442\u044c \u0432\u00a0PG_CATCH \u0438 \u0432\u00a0PG_FINALLY\u00a0\u2014 \u043f\u0440\u0438\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 catch\/finally \u0432\u043c\u0435\u0441\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f if \u0441 2\u00a0else.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043c\u044b \u0432\u0445\u043e\u0434\u0438\u043c \u0432\u00a0\u0446\u0438\u043a\u043b.<\/p>\n<h2>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\/\u0441\u0431\u0440\u043e\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p><em>MessageContext\u00a0\u2014 <\/em>\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u0440\u0438\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><em>input_message<\/em>\u00a0\u2014 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>StringInfo &#8212; \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0432\u043e\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445\u00a0\u2014 <em>StringInfo<\/em>. \u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/lib\/stringinfo.h\" rel=\"noopener noreferrer nofollow\">src\/include\/lib\/stringinfo.h<\/a><\/p>\n<pre><code class=\"cpp\">typedef struct StringInfoData {     \/\/ \u0411\u0443\u0444\u0435\u0440, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0441\u0442\u0440\u043e\u043a\u0443 char   *data;    \/\/ \u0414\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438     intlen;      \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438,      \/\/ \u0442.\u043a. \u043f\u0430\u043c\u044f\u0442\u044c \u0431\u044b\u043b\u0430 \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0447\u0435\u0440\u0435\u0437 palloc     intmaxlen;       \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043d\u0443\u0436\u0434 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.      \/\/ \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f     intcursor; } StringInfoData;  typedef StringInfoData *StringInfo;<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0442\u0438\u043f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u00a0\u0432\u0441\u0435\u043c \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>\u0411\u0443\u0444\u0435\u0440 plain \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f\u00a0\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f).<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0432\u00a0\u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 EXPLAIN \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e StringInfo (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/commands\/explain.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/commands\/explain.c<\/a>):<\/p>\n<pre><code class=\"cpp\">\/\/ 1584 \u0441\u0442\u0440\u043e\u043a\u0430 if (es->format == EXPLAIN_FORMAT_TEXT) {     appendStringInfo(es->str, \"  (cost=%.2f..%.2f rows=%.0f width=%d)\",                      plan->startup_cost, plan->total_cost,                      plan->plan_rows, plan->plan_width); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0421\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441<\/h2>\n<p>\u041f\u0430\u043a\u0435\u0442 <em>ReadyForQuery<\/em> \u0431\u044d\u043a\u044d\u043d\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434 \u043e\u00a0\u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e\u00a0\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0430\u043a\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u043b\u0430\u0433 <em>send_ready_for_query<\/em>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0448\u0430\u0433\u0435) \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d, \u043d\u043e\u00a0\u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0441\u043d\u044f\u0442<\/p>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433. \u0415\u0441\u043b\u0438 \u043e\u043d \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0443 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u044b \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0435 <em>GUC<\/em> \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>ReadyForQuery<\/em> \u043f\u0430\u043a\u0435\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0424\u043b\u0430\u0433 <em>send_ready_for_query<\/em> \u0441\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f\u00a0\u043f\u0435\u0440\u0432\u044b\u0445 3\u00a0\u0448\u0430\u0433\u043e\u0432 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\/\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u0440\u0432\u0430\u043d\u043d\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c xact &#8212; \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0430\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c xact\u00a0\u2014 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/access\/transam\/xact.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/access\/transam\/xact.c<\/a>. <\/p>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>TransactionStateData<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct TransactionStateData { FullTransactionId fullTransactionId;\/* my FullTransactionId *\/ SubTransactionId subTransactionId;\/* my subxact ID *\/ char   *name;\/* savepoint name, if any *\/ intsavepointLevel; \/* savepoint level *\/ TransStatestate;\/* low-level state *\/ TBlockState blockState;\/* high-level state *\/ intnestingLevel;\/* transaction nesting depth *\/ intgucNestLevel;\/* GUC context nesting depth *\/ MemoryContext curTransactionContext;\/* my xact-lifetime context *\/ ResourceOwner curTransactionOwner;\/* my query resources *\/ TransactionId *childXids;\/* subcommitted child XIDs, in XID order *\/ intnChildXids;\/* # of subcommitted child XIDs *\/ intmaxChildXids;\/* allocated size of childXids[] *\/ OidprevUser;\/* previous CurrentUserId setting *\/ intprevSecContext; \/* previous SecurityRestrictionContext *\/ boolprevXactReadOnly;\/* entry-time xact r\/o state *\/ boolstartedInRecovery;\/* did we start in recovery? *\/ booldidLogXid;\/* has xid been included in WAL record? *\/ intparallelModeLevel;\/* Enter\/ExitParallelMode counter *\/ boolchain;\/* start a new block after this one *\/ boolassigned;\/* assigned to top-level XID *\/ struct TransactionStateData *parent;\/* back link to parent *\/ } TransactionStateData;<\/code><\/pre>\n<p>\u0412\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <em>TopTransactionStateData<\/em>, \u0430 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0432 <em>CurrentTransactionState<\/em><\/p>\n<pre><code class=\"cpp\">\/*  * CurrentTransactionState always points to the current transaction state  * block.  It will point to TopTransactionStateData when not in a  * transaction at all, or when in a top-level transaction.  *\/ static TransactionStateData TopTransactionStateData = { .state = TRANS_DEFAULT, .blockState = TBLOCK_DEFAULT, .assigned = false, };  static TransactionState CurrentTransactionState = &amp;TopTransactionStateData;<\/code><\/pre>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f 2 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u043c\u0438: <\/p>\n<ul>\n<li>\n<p><em>TBlockState<\/em> &#8212; \u043e\u0431\u0449\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0431\u0435\u0437 \u0434\u0435\u0442\u0430\u043b\u0435\u0439<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">\/*  *transaction states - transaction state from server perspective  *\/ typedef enum TransState { TRANS_DEFAULT,\/* idle *\/ TRANS_START,\/* transaction starting *\/ TRANS_INPROGRESS,\/* inside a valid transaction *\/ TRANS_COMMIT,\/* commit in progress *\/ TRANS_ABORT,\/* abort in progress *\/ TRANS_PREPARE\/* prepare in progress *\/ } TransState;<\/code><\/pre>\n<ul>\n<li>\n<p><em>TransState<\/em> &#8212; \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">\/*  *transaction block states - transaction state of client queries  *  * Note: the subtransaction states are used only for non-topmost  * transactions; the others appear only in the topmost transaction.  *\/ typedef enum TBlockState { \/* not-in-transaction-block states *\/ TBLOCK_DEFAULT,\/* idle *\/ TBLOCK_STARTED,\/* running single-query transaction *\/  \/* transaction block states *\/ TBLOCK_BEGIN,\/* starting transaction block *\/ TBLOCK_INPROGRESS,\/* live transaction *\/ TBLOCK_IMPLICIT_INPROGRESS, \/* live transaction after implicit BEGIN *\/ TBLOCK_PARALLEL_INPROGRESS, \/* live transaction inside parallel worker *\/ TBLOCK_END,\/* COMMIT received *\/ TBLOCK_ABORT,\/* failed xact, awaiting ROLLBACK *\/ TBLOCK_ABORT_END,\/* failed xact, ROLLBACK received *\/ TBLOCK_ABORT_PENDING,\/* live xact, ROLLBACK received *\/ TBLOCK_PREPARE,\/* live xact, PREPARE received *\/  \/* subtransaction states *\/ TBLOCK_SUBBEGIN,\/* starting a subtransaction *\/ TBLOCK_SUBINPROGRESS,\/* live subtransaction *\/ TBLOCK_SUBRELEASE,\/* RELEASE received *\/ TBLOCK_SUBCOMMIT,\/* COMMIT received while TBLOCK_SUBINPROGRESS *\/ TBLOCK_SUBABORT,\/* failed subxact, awaiting ROLLBACK *\/ TBLOCK_SUBABORT_END,\/* failed subxact, ROLLBACK received *\/ TBLOCK_SUBABORT_PENDING,\/* live subxact, ROLLBACK received *\/ TBLOCK_SUBRESTART,\/* live subxact, ROLLBACK TO received *\/ TBLOCK_SUBABORT_RESTART\/* failed subxact, ROLLBACK TO received *\/ } TBlockState;<\/code><\/pre>\n<p>\u0414\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><em>StartTransactionCommand<\/em>\u00a0\u2014 \u0441\u0442\u0430\u0440\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<p><em>CommitTransactionCommand<\/em>\u00a0\u2014 \u043a\u043e\u043c\u043c\u0438\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<p><em>AbortCurrentTransaction<\/em>\u00a0\u2014 \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u00a0\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 <em>ReadyForQuery<\/em> \u043f\u0430\u043a\u0435\u0442\u0430\u00a0\u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e\u00a0\u043f\u0435\u0440\u0432\u044b\u0435 \u0448\u0430\u0433\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><em>IsTransactionOrTransactionBlock<\/em>\u00a0\u2014 \u041d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f\u00a0\u043b\u0438 \u043c\u044b \u0432\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">bool IsTransactionOrTransactionBlock(void) { TransactionState s = CurrentTransactionState;  if (s->blockState == TBLOCK_DEFAULT) return false;  return true; }<\/code><\/pre>\n<ul>\n<li>\n<p><em>IsAbortedTransactionBlockState<\/em>\u00a0\u2014 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u0430<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">bool IsAbortedTransactionBlockState(void) { TransactionState s = CurrentTransactionState;  if (s->blockState == TBLOCK_ABORT || s->blockState == TBLOCK_SUBABORT) return true;  return false; }<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 3 \u0448\u0430\u0433\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">if (IsAbortedTransactionBlockState()) {     set_ps_display(\"idle in transaction (aborted)\");     pgstat_report_activity(STATE_IDLEINTRANSACTION_ABORTED, NULL);      \/* Start the idle-in-transaction timer *\/     if (IdleInTransactionSessionTimeout > 0)     {         idle_in_transaction_timeout_enabled = true;         enable_timeout_after(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,                              IdleInTransactionSessionTimeout);     } } else if (IsTransactionOrTransactionBlock()) {     set_ps_display(\"idle in transaction\");     pgstat_report_activity(STATE_IDLEINTRANSACTION, NULL);      \/* Start the idle-in-transaction timer *\/     if (IdleInTransactionSessionTimeout > 0)     {         idle_in_transaction_timeout_enabled = true;         enable_timeout_after(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,                              IdleInTransactionSessionTimeout);     } } else {     \/*      * Process incoming notifies (including self-notifies), if      * any, and send relevant messages to the client.  Doing it      * here helps ensure stable behavior in tests: if any notifies      * were received during the just-finished transaction, they'll      * be seen by the client before ReadyForQuery is.      *\/     if (notifyInterruptPending)         ProcessNotifyInterrupt(false);      pgstat_report_stat(false);      set_ps_display(\"idle\");     pgstat_report_activity(STATE_IDLE, NULL);      \/* Start the idle-session timer *\/     if (IdleSessionTimeout > 0)     {         idle_session_timeout_enabled = true;         enable_timeout_after(IDLE_SESSION_TIMEOUT,                              IdleSessionTimeout);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0427\u0442\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h2>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a\u00a0\u0432\u043e\u00a0\u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0439\u0442\u0438 <em>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435<\/em> \u0441\u0438\u0433\u043d\u0430\u043b\u044b. \u0427\u0442\u043e\u0431\u044b \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u043f\u0440\u0438\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0444\u043b\u0430\u0433 <em>DoingCommandRead<\/em>. \u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0430\u00a0\u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e \u0447\u0442\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. <\/p>\n<p>\u0414\u043b\u044f\u00a0\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>ReadCommand<\/em>. \u041f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u043a\u0435\u0442\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>SocketBackend<\/em>. <\/p>\n<p>\u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442. \u041d\u0430\u00a0\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0442\u0438\u043f \u0440\u0435\u0436\u0438\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b: <em>Simple Query<\/em> \u0438\u043b\u0438 <em>Extended Query \u0440\u0435\u0436\u0438\u043c\u044b<\/em>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0447\u0442\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u0430\u043c\u0438 <em>HOLD_CANCEL_INTERRUPTS<\/em> \u0438 <em>RESUME_CANCEL_INTERRUPTS<\/em>. \u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043e\u043d\u0438 \u0440\u0430\u0437\u043c\u0435\u0447\u0430\u044e\u0442 \u043e\u0431\u043b\u0430\u0441\u0442\u044c, \u043f\u0440\u0438\u00a0\u0432\u0445\u043e\u0434\u0435 \u0432\u00a0\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435\u00a0\u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0430\u00a0\u043e\u0442\u043c\u0435\u043d\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<pre><code class=\"cpp\">\/* ----------------  *SocketBackend()Is called for frontend-backend connections  *  *Returns the message type code, and loads message body data into inBuf.  *  *EOF is returned if the connection is lost.  * ----------------  *\/ static int SocketBackend(StringInfo inBuf) { intqtype; intmaxmsglen;  \/*  * Get message type code from the frontend.  *\/ HOLD_CANCEL_INTERRUPTS(); pq_startmsgread(); qtype = pq_getbyte();  if (qtype == EOF)\/* frontend disconnected *\/ { if (IsTransactionState()) ereport(COMMERROR, (errcode(ERRCODE_CONNECTION_FAILURE),  errmsg(\"unexpected EOF on client connection with an open transaction\"))); else { \/*  * Can't send DEBUG log messages to client at this point. Since  * we're disconnecting right away, we don't need to restore  * whereToSendOutput.  *\/ whereToSendOutput = DestNone; ereport(DEBUG1, (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),  errmsg_internal(\"unexpected EOF on client connection\"))); } return qtype; }  \/*  * Validate message type code before trying to read body; if we have lost  * sync, better to say \"command unknown\" than to run out of memory because  * we used garbage as a length word.  We can also select a type-dependent  * limit on what a sane length word could be.  (The limit could be chosen  * more granularly, but it's not clear it's worth fussing over.)  *  * This also gives us a place to set the doing_extended_query_message flag  * as soon as possible.  *\/ switch (qtype) { case 'Q':\/* simple query *\/ maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; break;  case 'F':\/* fastpath function call *\/ maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; break;  case 'X':\/* terminate *\/ maxmsglen = PQ_SMALL_MESSAGE_LIMIT; doing_extended_query_message = false; ignore_till_sync = false; break;  case 'B':\/* bind *\/ case 'P':\/* parse *\/ maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = true; break;  case 'C':\/* close *\/ case 'D':\/* describe *\/ case 'E':\/* execute *\/ case 'H':\/* flush *\/ maxmsglen = PQ_SMALL_MESSAGE_LIMIT; doing_extended_query_message = true; break;  case 'S':\/* sync *\/ maxmsglen = PQ_SMALL_MESSAGE_LIMIT; \/* stop any active skip-till-Sync *\/ ignore_till_sync = false; \/* mark not-extended, so that a new error doesn't begin skip *\/ doing_extended_query_message = false; break;  case 'd':\/* copy data *\/ maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; break;  case 'c':\/* copy done *\/ case 'f':\/* copy fail *\/ maxmsglen = PQ_SMALL_MESSAGE_LIMIT; doing_extended_query_message = false; break;  default:  \/*  * Otherwise we got garbage from the frontend.  We treat this as  * fatal because we have probably lost message boundary sync, and  * there's no good way to recover.  *\/ ereport(FATAL, (errcode(ERRCODE_PROTOCOL_VIOLATION),  errmsg(\"invalid frontend message type %d\", qtype))); maxmsglen = 0;\/* keep compiler quiet *\/ break; }  \/*  * In protocol version 3, all frontend messages have a length word next  * after the type code; we can read the message contents independently of  * the type.  *\/ if (pq_getmessage(inBuf, maxmsglen)) return EOF;\/* suitable message already logged *\/ RESUME_CANCEL_INTERRUPTS();  return qtype; }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0431\u044d\u043a\u044d\u043d\u0434\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u00a0\u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438\u00a0\u0431\u044b\u043b \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u044d\u043a\u044d\u043d\u0434, \u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u00a0\u0438\u0437\u00a0\u0441\u043e\u043a\u0435\u0442\u0430, \u0430\u00a0\u043e\u0442\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e. \u0412\u00a0\u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>ReadCommand<\/em> \u0432\u043c\u0435\u0441\u0442\u043e <em>SocketBackend<\/em> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <em>InteractiveBackend<\/em>.<\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u0435\u0442 \u0431\u0430\u0439\u0442\u044b \u0438\u0437\u00a0STDIN \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432\u00a0\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u043f\u043e\u043a\u0430 \u043d\u0435\u00a0\u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (EOF, \u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0434\u0432\u043e\u0439\u043d\u0430\u044f \u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430)<\/p>\n<pre><code class=\"cpp\">static int InteractiveBackend(StringInfo inBuf) { intc;\/* character read from getc() *\/  \/*  * display a prompt and obtain input from the user  *\/ printf(\"backend> \"); fflush(stdout);  resetStringInfo(inBuf);  \/*  * Read characters until EOF or the appropriate delimiter is seen.  *\/ while ((c = interactive_getc()) != EOF) { if (c == '\\n') { if (UseSemiNewlineNewline) { \/*  * In -j mode, semicolon followed by two newlines ends the  * command; otherwise treat newline as regular character.  *\/ if (inBuf->len > 1 &amp;&amp; inBuf->data[inBuf->len - 1] == '\\n' &amp;&amp; inBuf->data[inBuf->len - 2] == ';') { \/* might as well drop the second newline *\/ break; } } else { \/*  * In plain mode, newline ends the command unless preceded by  * backslash.  *\/ if (inBuf->len > 0 &amp;&amp; inBuf->data[inBuf->len - 1] == '\\\\') { \/* discard backslash from inBuf *\/ inBuf->data[--inBuf->len] = '\\0'; \/* discard newline too *\/ continue; } else { \/* keep the newline character, but end the command *\/ appendStringInfoChar(inBuf, '\\n'); break; } } }  \/* Not newline, or newline treated as regular character *\/ appendStringInfoChar(inBuf, (char) c); }  \/* No input before EOF signal means time to quit. *\/ if (c == EOF &amp;&amp; inBuf->len == 0) return EOF;  \/*  * otherwise we have a user query so process it.  *\/  \/* Add '\\0' to make it look the same as message case. *\/ appendStringInfoChar(inBuf, (char) '\\0');  \/*  * if the query echo flag was given, print the query..  *\/ if (EchoQuery) printf(\"statement: %s\\n\", inBuf->data); fflush(stdout);  return 'Q'; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0439:<\/p>\n<ul>\n<li>\n<p><em>IDLE_IN_TRANSACTION_SESSION_TIMEOUT<\/em>\u00a0\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p><em>IDLE_SESSION_TIMEOUT <\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432\u00a0\u0441\u0435\u0441\u0441\u0438\u0438.<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 (\u0441\u0438\u0433\u043d\u0430\u043b\u044b)<\/h2>\n<p>\u0412\u043e\u00a0\u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u00a0\u0431\u044b\u043b\u0430 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432. \u0417\u0430\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>ProcessInterrupts()<\/em>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0443\u0441\u043b\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f\u00a0\u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u00a0\u0432\u043e\u00a0\u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u043d\u0435\u00a0\u0432\u043e\u0437\u043d\u0438\u043a\u043b\u043e \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0430\u043a\u0440\u043e\u0441 <em>INTERRUPTS_PEDNDING_CONDITION<\/em> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/miscadmin.h\" rel=\"noopener noreferrer nofollow\">src\/include\/miscadmin.h<\/a>)<\/p>\n<pre><code class=\"cpp\">\/* Test whether an interrupt is pending *\/ #ifndef WIN32 #define INTERRUPTS_PENDING_CONDITION() \\ (unlikely(InterruptPending)) #else #define INTERRUPTS_PENDING_CONDITION() \\ (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \\  unlikely(InterruptPending)) #endif<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e\u00a0\u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c <em>unlikely<\/em>. \u041e\u043d \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043e\u00a0\u0442\u043e\u043c, \u0447\u0442\u043e\u00a0\u043a\u0430\u043a\u043e\u0435\u2011\u043b\u0438\u0431\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u00a0\u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. <\/p>\n<p><em>unlikely<\/em>\u00a0\u2014 \u0442\u043e\u0436\u0435 \u043c\u0430\u043a\u0440\u043e\u0441. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 <em>likely<\/em> \u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/c.h\" rel=\"noopener noreferrer nofollow\">src\/include\/c.h<\/a><\/p>\n<pre><code class=\"cpp\">\/*  * Hints to the compiler about the likelihood of a branch. Both likely() and  * unlikely() return the boolean value of the contained expression.  *  * These should only be used sparingly, in very hot code paths. It's very easy  * to mis-estimate likelihoods.  *\/ #if __GNUC__ >= 3 #define likely(x)__builtin_expect((x) != 0, 1) #define unlikely(x) __builtin_expect((x) != 0, 0) #else #define likely(x)((x) != 0) #define unlikely(x) ((x) != 0) #endif<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 <em>ProcessInterrupts<\/em> \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430\u00a0\u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u00a0\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0446\u0438\u044f\u0445.<\/p>\n<ol>\n<li>\n<p><em>CritSectionCount<\/em>\u00a0\u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0435\u043a\u0446\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u00a0\u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 Gist \u0438\u043d\u0434\u0435\u043a\u0441\u0430, \u043c\u044b \u0432\u0445\u043e\u0434\u0438\u043c \u0432\u00a0\u0442\u0430\u043a\u0443\u044e \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0435\u043a\u0446\u0438\u044e (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/access\/gist\/gistbuild.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/access\/gist\/gistbuild.c<\/a>)<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) {   \/\/ ...   START_CRIT_SECTION();      GISTInitBuffer(buffer, F_LEAF);      MarkBufferDirty(buffer);   PageSetLSN(page, GistBuildLSN);      UnlockReleaseBuffer(buffer);      END_CRIT_SECTION();   \/\/ ... }<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p><em>InterruptHoldoffCount<\/em>\u00a0\u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0435\u043a\u0446\u0438\u0439, \u0432\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <em>SIGALRM<\/em> \u0432\u0445\u043e\u0434\u0438\u0442 \u0432\u00a0\u0442\u0430\u043a\u0443\u044e \u0441\u0435\u043a\u0446\u0438\u044e <\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">static void handle_sig_alarm(SIGNAL_ARGS) { \/*  * Bump the holdoff counter, to make sure nothing we call will process  * interrupts directly. No timeout handler should do that, but these  * failures are hard to debug, so better be sure.  *\/ HOLD_INTERRUPTS();  \/\/ ...  RESUME_INTERRUPTS(); }<\/code><\/pre>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 <em>ProcessInterrupts<\/em> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u00a0\u043e\u0431\u0435 \u043c\u044b \u043d\u0435\u00a0\u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u043d\u0438 \u0432\u00a0\u043e\u0434\u043d\u043e\u0439 \u0438\u0437\u00a0\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u00a0\u043a\u043b\u0438\u0435\u043d\u0442\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0432\u00a0\u043b\u043e\u0433 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f GUC \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041f\u0440\u0438\u00a0\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438, \u043e\u043d\u0438 \u043e\u0442\u0441\u044b\u043b\u0430\u044e\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/p>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h2>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0430\u043a\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0438 \u0432\u0441\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b, \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441. \u041d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0431\u0430\u0439\u0442\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f\u00a0\u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0430 \u0438 \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u2011\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b. \u0414\u043b\u044f\u00a0\u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430\u00a0\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b. <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u00a0\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0430 <em>BIND<\/em>, \u0431\u044d\u043a\u044d\u043d\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c <em>BindComplete<\/em> \u0438\u043b\u0438 <em>ErrorResponse<\/em>.<\/p>\n<p>\u0424\u043e\u0440\u043c\u0430\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<ol>\n<li>\n<p><u>\u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442<\/u>\u00a0\u2014 \u0442\u0438\u043f \u043f\u0430\u043a\u0435\u0442\u0430. \u0412\u00a0\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u043e\u043c char. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f\u00a0Bind \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442\u00a0\u2014 \u00abB\u00bb<\/p>\n<\/li>\n<li>\n<p><u>4\u00a0\u0431\u0430\u0439\u0442\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e<\/u> (int32)\u00a0\u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0430\u043c\u043e \u0447\u0438\u0441\u043b\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0442.\u00a0\u0435. 4\u00a0+ \u043a\u043e\u043b\u2011\u0432\u043e \u0431\u0430\u0439\u0442\u043e\u0432 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0421\u0430\u043c\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u00a0\u2014 \u0434\u043b\u044f\u00a0\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u044f: \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u0430\u00a0\u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0435\u0439 \u0447\u0438\u0441\u0435\u043b \u0438 \u0441\u0442\u0440\u043e\u043a<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0432\u0441\u0435\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u00a0\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438: <a href=\"https:\/\/www.postgresql.org\/docs\/15\/protocol-message-formats.html\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.postgresql.org\/docs\/15\/protocol\u2011message\u2011formats.html<\/u><\/a> <\/p>\n<p>\u041f\u0440\u0438\u00a0\u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f 2\u00a0\u0440\u0435\u0436\u0438\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b: Simple Query \u0438 Extended Query<\/p>\n<p><strong>Simple Query<\/strong><\/p>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f: <a href=\"https:\/\/www.postgresql.org\/docs\/current\/protocol-flow.html#id-1.10.6.7.4\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.postgresql.org\/docs\/current\/protocol\u2011flow.html#id-1.10.6.7.4<\/u><\/a><\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442\u00a0\u2014 \u00abQ\u00bb. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437\u00a0\u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443\u00a0\u2014 \u0431\u0435\u0437\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438\u043b\u0438\u00a0\u043a\u0430\u043a\u043e\u0439\u2011\u043b\u0438\u0431\u043e \u0437\u0430\u0449\u0438\u0442\u044b. \u041f\u0440\u0438\u00a0\u0435\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 C\u2011\u0441\u0442\u0440\u043e\u043a\u043e\u0439 (\u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u0438 \u0438\u0433\u0440\u0430\u0435\u0442 \u0437\u043b\u0443\u044e \u0448\u0443\u0442\u043a\u0443). <\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u00a0\u0441\u0435\u0431\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 <code>;<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>INSERT<\/em> \u0438 <em>SELECT<\/em> \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c\u0441\u044f \u0432\u00a0\u043e\u0434\u043d\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438.<\/p>\n<p><strong>Extended Query<\/strong><\/p>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f: <a href=\"https:\/\/www.postgresql.org\/docs\/current\/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.postgresql.org\/docs\/current\/protocol\u2011flow.html#PROTOCOL\u2011FLOW\u2011EXT\u2011QUERY<\/u><\/a><\/p>\n<p>\u042d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439:<\/p>\n<ol>\n<li>\n<p><strong>PARSE<\/strong>\u00a0\u2014 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441, \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0432 \u0435\u0433\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u0432 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0435 (\u0438\u043b\u0438 \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u043e\u0433\u043e) \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0412\u00a0SQL \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0447\u0435\u0440\u0435\u0437 <em>PREPARE<\/em> \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li>\n<p><strong>BIND<\/strong>\u00a0\u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0430\u043b (\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043b\u0438\u00a0\u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439), \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0432 \u0432\u00a0\u043d\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li>\n<p><strong>EXECUTE<\/strong>\u00a0\u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0440\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u0430\u043b\u0430 (\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438).<\/p>\n<\/li>\n<\/ol>\n<p>\u0411\u043e\u043b\u044c\u0448\u0435 \u043e\u00a0\u0441\u0430\u043c\u043e\u043c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 \u0432\u00a0\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438: <a href=\"https:\/\/www.postgresql.org\/docs\/15\/protocol.html\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.postgresql.org\/docs\/15\/protocol.html<\/u><\/a> <\/p>\n<\/div>\n<\/details>\n<h3>Simple Query<\/h3>\n<p>\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 Simple Query \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f. \u041d\u043e\u00a0\u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u00a0\u2014 WALSender, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u00a0\u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435.<\/p>\n<pre><code class=\"cpp\">case 'Q':\/* simple query *\/   {       const char *query_string;          \/* Set statement_timestamp() *\/       SetCurrentStatementStartTimestamp();          query_string = pq_getmsgstring(&amp;input_message);       pq_getmsgend(&amp;input_message);          if (am_walsender)       {           if (!exec_replication_command(query_string))               exec_simple_query(query_string);       }       else           exec_simple_query(query_string);          send_ready_for_query = true;   }   break;<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0430\u043a\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/replication\/walsender_private.h\" rel=\"noopener noreferrer nofollow\">src\/include\/replication\/walsender_private.h<\/a><\/p>\n<pre><code class=\"cpp\">extern void replication_scanner_init(const char *query_string); extern void replication_scanner_finish(void); extern bool replication_scanner_is_replication_command(void);<\/code><\/pre>\n<p>\u041d\u043e\u00a0\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u00a0\u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043d\u0435\u00a0\u043d\u0430\u0439\u0442\u0438. \u041e\u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0440\u044b <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Lex\" rel=\"noopener noreferrer nofollow\">LEX<\/a> (\u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440) \u0438 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Yacc\" rel=\"noopener noreferrer nofollow\">YACC<\/a> (\u043f\u0430\u0440\u0441\u0435\u0440) <\/p>\n<p>LEX \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u044b \u0438\u0437\u00a0\u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0430\u00a0YACC \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u0437\u00a0\u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e. \u0424\u0430\u0439\u043b \u0441\u00a0\u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c \u0434\u043b\u044f\u00a0\u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/replication\/repl_scanner.l\" rel=\"noopener noreferrer nofollow\">src\/backend\/replication\/repl_scanner.l<\/a>. \u0421\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f\u00a0\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code class=\"cpp\">\/*  * Check to see if the first token of a command is a WalSender keyword.  *  * To keep repl_scanner.l minimal, we don't ask it to know every construct  * that the core lexer knows.  Therefore, we daren't lex more than the  * first token of a general SQL command.  That will usually look like an  * IDENT token here, although some other cases are possible.  *\/ bool replication_scanner_is_replication_command(void) { intfirst_token = replication_yylex();  switch (first_token) { case K_IDENTIFY_SYSTEM: case K_BASE_BACKUP: case K_START_REPLICATION: case K_CREATE_REPLICATION_SLOT: case K_DROP_REPLICATION_SLOT: case K_TIMELINE_HISTORY: case K_SHOW: \/* Yes; push back the first token so we can parse later. *\/ repl_pushed_back_token = first_token; return true; default: \/* Nope; we don't bother to push back the token. *\/ return false; } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>Parse<\/h3>\n<p>\u0412\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0443\u0436\u043d\u043e \u043d\u0435\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043d\u043e\u00a0\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0422\u0430\u043a \u043a\u0430\u043a\u00a0\u0442\u0438\u043f\u044b \u0432\u00a0Postgres \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u0442\u043e \u0438 \u0442\u0438\u043f\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432\u00a0\u0432\u0438\u0434\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. <\/p>\n<pre><code class=\"cpp\">case 'P':\/* parse *\/     {         const char *stmt_name;         const char *query_string;         intnumParams;         Oid   *paramTypes = NULL;              forbidden_in_wal_sender(firstchar);              \/* Set statement_timestamp() *\/         SetCurrentStatementStartTimestamp();              stmt_name = pq_getmsgstring(&amp;input_message);         query_string = pq_getmsgstring(&amp;input_message);         numParams = pq_getmsgint(&amp;input_message, 2);         if (numParams > 0)         {             paramTypes = (Oid *) palloc(numParams * sizeof(Oid));             for (int i = 0; i &lt; numParams; i++)                 paramTypes[i] = pq_getmsgint(&amp;input_message, 4);         }         pq_getmsgend(&amp;input_message);              exec_parse_message(query_string, stmt_name,                            paramTypes, numParams);     }     break;<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <em>forbidden_in_wal_sender<\/em>. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 <em>WALSender<\/em> \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 &#8212; \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <em>Simple Query<\/em>.<\/p>\n<pre><code class=\"cpp\">\/*  * Throw an error if we're a WAL sender process.  *  * This is used to forbid anything else than simple query protocol messages  * in a WAL sender process.  'firstchar' specifies what kind of a forbidden  * message was received, and is used to construct the error message.  *\/ static void forbidden_in_wal_sender(char firstchar) { if (am_walsender) { if (firstchar == 'F') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION),  errmsg(\"fastpath function calls not supported in a replication connection\"))); else ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION),  errmsg(\"extended query protocol not supported in a replication connection\"))); } } <\/code><\/pre>\n<h3>Bind<\/h3>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 <em>BIND<\/em> \u043f\u0430\u043a\u0435\u0442\u0430 (\u043a\u0430\u043a \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438) \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u044b\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<pre><code class=\"cpp\">case 'B':\/* bind *\/     forbidden_in_wal_sender(firstchar);        \/* Set statement_timestamp() *\/     SetCurrentStatementStartTimestamp();        \/*      * this message is complex enough that it seems best to put      * the field extraction out-of-line      *\/     exec_bind_message(&amp;input_message);     break;<\/code><\/pre>\n<h3>Execute<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u0448\u0435\u043b <em>EXECUTE<\/em> \u043f\u0430\u043a\u0435\u0442, \u0442\u043e \u0438\u0437 \u043d\u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430. \u041e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"cpp\">case 'E':\/* execute *\/     {         const char *portal_name;         intmax_rows;            forbidden_in_wal_sender(firstchar);            \/* Set statement_timestamp() *\/         SetCurrentStatementStartTimestamp();            portal_name = pq_getmsgstring(&amp;input_message);         max_rows = pq_getmsgint(&amp;input_message, 4);         pq_getmsgend(&amp;input_message);            exec_execute_message(portal_name, max_rows);     }     break;<\/code><\/pre>\n<h3>Fastpath function call<\/h3>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0430 <em>FASTPATH<\/em> \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u0430 \u043d\u0430\u0440\u0443\u0436\u0443. \u0418\u043c\u0435\u043d\u043d\u043e: \u0441\u0442\u0430\u0440\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0438 \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.<\/p>\n<pre><code class=\"cpp\">case 'F':\/* fastpath function call *\/     forbidden_in_wal_sender(firstchar);        \/* Set statement_timestamp() *\/     SetCurrentStatementStartTimestamp();        \/* Report query to various monitoring facilities. *\/     pgstat_report_activity(STATE_FASTPATH, NULL);     set_ps_display(\"&lt;FASTPATH>\");        \/* start an xact for this function invocation *\/     start_xact_command();        \/*      * Note: we may at this point be inside an aborted      * transaction.  We can't throw error for that until we've      * finished reading the function-call message, so      * HandleFunctionRequest() must check for it after doing so.      * Be careful not to do anything that assumes we're inside a      * valid transaction here.      *\/        \/* switch back to message context *\/     MemoryContextSwitchTo(MessageContext);        HandleFunctionRequest(&amp;input_message);        \/* commit the function-invocation transaction *\/     finish_xact_command();        send_ready_for_query = true;     break;<\/code><\/pre>\n<p>P.S. \u0412 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u0434, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0449\u0438\u0439 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 (\u043d\u0435 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438), \u0445\u043e\u0442\u044f \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0438\u0437 switch\u2019\u0430, \u0442.\u043a. \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a\u043e \u0432\u0441\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430.<\/p>\n<h3>Close<\/h3>\n<p>\u0412 \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0430\u043b\u044b \u0438 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b. \u041e\u043d\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u043a\u0435\u0442 <em>CLOSE<\/em> \u0438 \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u0430\u044f SQL \u043a\u043e\u043c\u0430\u043d\u0434\u0430.\u00a0\u00a0<\/p>\n<p>\u0412 \u043f\u0430\u043a\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0434\u043b\u044f \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0438 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435.\u00a0<\/p>\n<pre><code class=\"cpp\">case 'C':\/* close *\/     {         intclose_type;         const char *close_target;            forbidden_in_wal_sender(firstchar);            close_type = pq_getmsgbyte(&amp;input_message);         close_target = pq_getmsgstring(&amp;input_message);         pq_getmsgend(&amp;input_message);            switch (close_type)         {             case 'S':                 if (close_target[0] != '\\0')                     DropPreparedStatement(close_target, false);                 else                 {                     \/* special-case the unnamed statement *\/                     drop_unnamed_stmt();                 }                 break;             case 'P':                 {                     Portalportal;                        portal = GetPortalByName(close_target);                     if (PortalIsValid(portal))                         PortalDrop(portal, false);                 }                 break;             default:                 ereport(ERROR,                         (errcode(ERRCODE_PROTOCOL_VIOLATION),                          errmsg(\"invalid CLOSE message subtype %d\",                                 close_type)));                 break;         }            if (whereToSendOutput == DestRemote)             pq_putemptymessage('3');\/* CloseComplete *\/     }     break;<\/code><\/pre>\n<h3>Describe<\/h3>\n<p>\u041e\u0442\u00a0\u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u043e\u0432 \u0438 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0440\u0442\u0430\u043b\u00a0\u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u00a0\u0442.\u00a0\u0434.).<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u00a0\u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u00a0\u0436\u0435 \u043a\u0430\u043a\u00a0\u0438 \u0432 <em>CLOSE<\/em>, \u0432 <em>DESCRIBE<\/em> \u043f\u0430\u043a\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0434\u043b\u044f\u00a0\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435<\/p>\n<pre><code class=\"cpp\">case 'D':\/* describe *\/     {         intdescribe_type;         const char *describe_target;            forbidden_in_wal_sender(firstchar);            \/* Set statement_timestamp() (needed for xact) *\/         SetCurrentStatementStartTimestamp();            describe_type = pq_getmsgbyte(&amp;input_message);         describe_target = pq_getmsgstring(&amp;input_message);         pq_getmsgend(&amp;input_message);            switch (describe_type)         {             case 'S':                 exec_describe_statement_message(describe_target);                 break;             case 'P':                 exec_describe_portal_message(describe_target);                 break;             default:                 ereport(ERROR,                         (errcode(ERRCODE_PROTOCOL_VIOLATION),                          errmsg(\"invalid DESCRIBE message subtype %d\",                                 describe_type)));                 break;         }     }     break;<\/code><\/pre>\n<h3>Flush<\/h3>\n<p>\u0412\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u043e\u00a0\u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c \u0431\u0443\u0444\u0435\u0440\u0435 \u043c\u043e\u0433\u043b\u0430 \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u044c\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f. \u0414\u043b\u044f\u00a0\u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0431\u0440\u043e\u0441\u0430 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <em>FLUSH<\/em><\/p>\n<pre><code class=\"css\">case 'H':\/* flush *\/     pq_getmsgend(&amp;input_message);     if (whereToSendOutput == DestRemote)         pq_flush();     break;<\/code><\/pre>\n<h3>Sync<\/h3>\n<p><em>SYNC<\/em> \u043f\u0430\u043a\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f\u00a0\u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. \u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u0430\u044f\u00a0\u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043c\u043c\u0438\u0442\u0430<\/p>\n<pre><code class=\"cpp\">case 'S':\/* sync *\/     pq_getmsgend(&amp;input_message);     finish_xact_command();     send_ready_for_query = true;     break;<\/code><\/pre>\n<h3>Terminate<\/h3>\n<p>\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e 2\u00a0\u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u043e\u0431\u043e\u0440\u0432\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f. \u041e\u0431\u0430 \u044d\u0442\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f \u0443\u0447\u0442\u0435\u043d\u044b.<\/p>\n<pre><code class=\"cpp\">    \/*      * 'X' means that the frontend is closing down the socket. EOF      * means unexpected loss of frontend connection. Either way,      * perform normal shutdown.      *\/ case EOF:      \/* for the statistics collector *\/     pgStatSessionEndCause = DISCONNECT_CLIENT_EOF;      \/* FALLTHROUGH *\/  case 'X':      \/*      * Reset whereToSendOutput to prevent ereport from attempting      * to send any more messages to client.      *\/     if (whereToSendOutput == DestRemote)         whereToSendOutput = DestNone;      \/*      * NOTE: if you are tempted to add more code here, DON'T!      * Whatever you had in mind to do should be set up as an      * on_proc_exit or on_shmem_exit callback, instead. Otherwise      * it will fail to be called during other backend-shutdown      * scenarios.      *\/     proc_exit(0);<\/code><\/pre>\n<h3>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e<\/h3>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b\u0441\u044f \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b \u043a\u043e\u043c\u0430\u043d\u0434 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u00a0\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c. \u0422\u0430\u043a\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0433\u043d\u043e\u0440\u0443\u0440\u0443\u044e\u0442\u0441\u044f.<\/p>\n<pre><code class=\"cpp\">case 'd':\/* copy data *\/ case 'c':\/* copy done *\/ case 'f':\/* copy fail *\/      \/*      * Ac!cept but ignore these messages, per protocol spec; we      * probably got here because a COPY failed, and the frontend      * is still sending data.      *\/     break;<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u0430\u043a\u0435\u0442\u0430.<\/p>\n<pre><code class=\"cpp\">default:     ereport(FATAL,             (errcode(ERRCODE_PROTOCOL_VIOLATION),              errmsg(\"invalid frontend message type %d\",                     firstchar)));<\/code><\/pre>\n<h2>\u041a\u043e\u043d\u0435\u0446<\/h2>\n<p>\u041d\u0430\u00a0\u044d\u0442\u043e\u043c \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f (\u0435\u0441\u043b\u0438 \u043d\u0435\u00a0\u0431\u044b\u043b\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\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\/post\/714840\/\"> https:\/\/habr.com\/ru\/post\/714840\/<\/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>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 PostgreSQL \u043f\u043e\u0434\u00a0\u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0441\u00a0\u043c\u0435\u0441\u0442\u0430 \u0433\u0434\u0435 <a href=\"https:\/\/habr.com\/ru\/post\/709404\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c<\/a>\u00a0\u2014 \u043f\u0440\u044f\u043c\u043e \u043f\u0435\u0440\u0435\u0434 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c. \u0424\u0430\u0439\u043b \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/tcop\/postgres.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a><\/p>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0414\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/man7.org\/linux\/man-pages\/man3\/setjmp.3.html\" rel=\"noopener noreferrer nofollow\">setjmp<\/a><\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0446\u0438\u043a\u043b\u0430 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u0430 \u0441\u0442\u0435\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0434\u043b\u044f\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043f\u0440\u0438\u00a0\u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u0445. <\/p>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0444\u043b\u0430\u0433\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>DoingCommandRead<\/em>)<\/p>\n<\/li>\n<li>\n<p>\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <em>libpq<\/em> \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <\/p>\n<\/li>\n<li>\n<p>\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u043e\u0442\u044b \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u00a0\u043e\u0448\u0438\u0431\u043a\u0435<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">if (sigsetjmp(local_sigjmp_buf, 1) != 0) {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f }  \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 PG_exception_stack = &amp;local_sigjmp_buf;  \/\/ ...  for (;;) {   \/\/ \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>setjmp<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/man7.org\/linux\/man-pages\/man3\/setjmp.3.html\" rel=\"noopener noreferrer nofollow\">setjmp<\/a>\u00a0\u2014 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f C \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043f\u043e\u00a0\u0441\u0442\u0435\u043a\u0443. \u0427\u0442\u043e\u00a0\u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442? \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e\u00a0\u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432\u0432\u0435\u0440\u0445 \u043f\u043e\u00a0\u0441\u0442\u0435\u043a\u0443 \u043a\u00a0\u043d\u0443\u0436\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432\u00a0\u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442\u00a0goto, \u0433\u0434\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u00a0\u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0444\u0443\u043a\u043d\u0446\u0438\u0438. \u0420\u0430\u0431\u043e\u0442\u0443 \u0441\u00a0\u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">jmp_buf *global_buf;  void doSomeStaff();  \/\/ \u0412\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c 1 int main() {   jmp_buf buf;   if (setjmp(&amp;buf) != 0) {     printf(\"\u0412\u0435\u0440\u043d\u0443\u043b\u0438\u0441\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e!\")     return 1;   }    global_buf = &amp;buf;   doSomeStaff();   return 0; }  void doSomeStaff() {   printf(\"\u0412\u043d\u0443\u0442\u0440\u0438 doSomeStaff\");   longjmp(global_buf, 1); }<\/code><\/pre>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0442\u0438\u043f\u0430 <em>jmp_buf<\/em>, \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0441\u0442\u0435\u043a\u0430, \u0434\u043b\u044f\u00a0\u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. \u0421\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0430\u044f, \u0434\u043b\u044f\u00a0\u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043e\u043a, \u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f, \u0434\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0430\u0434\u0440\u0435\u0441\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <em>setjmp<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f. \u041a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u00a0\u043d\u0435\u0439 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <em>longjmp<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u00a0\u0436\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0438 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d <em>setjmp<\/em>. <\/p>\n<p><strong>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: <em>setjmp<\/em> \u043f\u0440\u0438\u00a0\u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 0, \u0430\u00a0\u0432\u00a0\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u0434\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0435 <em>longjmp<\/em>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0435\u0447\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c 0\u00a0\u0438\u0437 <em>setjmp<\/em>, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u0434 0\u00a0\u0432 <em>longjmp<\/em><\/p>\n<p>\u0421\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>setjmp<\/em>\/<em>longjmp<\/em> \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439\u00a0\u2014 SJLJ. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, SEH \u0438\u043b\u0438\u00a0DWARF. \u0418\u0445 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/wiki.qt.io\/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u041a\u0430\u043a\u00a0\u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/491084\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439<\/a> \u0441\u0442\u0430\u0442\u044c\u0435<\/p>\n<p>P.\u00a0S. \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 <em>sigsetjmp<\/em>\/<em>siglongjmp<\/em> \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043d\u043e\u00a0\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043c\u0430\u0441\u043a\u0443 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u00a0Postgres, \u0442.\u043a. \u0432\u00a0\u043d\u0435\u043c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u0441\u0438\u0433\u043d\u0430\u043b\u0430\u043c\u0438.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432 Postgres<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u00a0Postgres \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a. \u0412 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/elog.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/elog.h<\/a> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0434\u043b\u044f\u00a0try\/catch\/finally \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">#define PG_TRY()  \\   do { \\       sigjmp_buf *_save_exception_stack = PG_exception_stack; \\       ErrorContextCallback *_save_context_stack = error_context_stack; \\       sigjmp_buf _local_sigjmp_buf; \\       bool _do_rethrow = false; \\       if (sigsetjmp(_local_sigjmp_buf, 0) == 0) \\       { \\           PG_exception_stack = &amp;_local_sigjmp_buf  #define PG_CATCH()\\   } \\   else \\   { \\       PG_exception_stack = _save_exception_stack; \\       error_context_stack = _save_context_stack  #define PG_FINALLY() \\   } \\   else \\       _do_rethrow = true; \\   { \\       PG_exception_stack = _save_exception_stack; \\       error_context_stack = _save_context_stack  #define PG_END_TRY()  \\     } \\       if (_do_rethrow) \\               PG_RE_THROW(); \\       PG_exception_stack = _save_exception_stack; \\       error_context_stack = _save_context_stack; \\   } while (0)<\/code><\/pre>\n<p>\u0414\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 \u0438\u0437\u2011\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <em>PG_exception_stack <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/error\/elog.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/error\/elog.c<\/a>), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c try\/catch\/finally \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a<\/p>\n<pre><code class=\"cpp\">PG_TRY(); {   \/\/ \u041e\u0448\u0438\u0431\u043a\u0430   if (!IsValidValue(1))    {     ereport(ERROR,             (errcode(ERRCODE_SOME_ERRCODE),             errmsg(\"value is not valid\")));   } } PG_CATCH(); {     GlobalValue = old_value; } PG_END_TRY();  \/\/ ===================  PG_TRY(); {   fwrite(\"Hello, world!\", sizeof(char), 13, handle) } PG_FINALLY(); {     fclose(handle); } PG_END_TRY();<\/code><\/pre>\n<p>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u00a0\u0443\u0440\u043e\u0432\u043d\u0435\u043c <em>ERROR<\/em><\/p>\n<p>\u041d\u043e\u00a0\u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c PG_CATCH \u0438 PG_FINALLY: \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f if\/else \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f, \u043f\u0440\u0438\u0447\u0435\u043c if\u00a0\u2014 PG_TRY, \u0430\u00a0else\u00a0\u2014 \u0435\u0441\u0442\u044c \u0432\u00a0PG_CATCH \u0438 \u0432\u00a0PG_FINALLY\u00a0\u2014 \u043f\u0440\u0438\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 catch\/finally \u0432\u043c\u0435\u0441\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f if \u0441 2\u00a0else.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043c\u044b \u0432\u0445\u043e\u0434\u0438\u043c \u0432\u00a0\u0446\u0438\u043a\u043b.<\/p>\n<h2>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\/\u0441\u0431\u0440\u043e\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p><em>MessageContext\u00a0\u2014 <\/em>\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u0440\u0438\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><em>input_message<\/em>\u00a0\u2014 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>StringInfo &#8212; \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0432\u043e\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445\u00a0\u2014 <em>StringInfo<\/em>. \u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/lib\/stringinfo.h\" rel=\"noopener noreferrer nofollow\">src\/include\/lib\/stringinfo.h<\/a><\/p>\n<pre><code class=\"cpp\">typedef struct StringInfoData {     \/\/ \u0411\u0443\u0444\u0435\u0440, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0441\u0442\u0440\u043e\u043a\u0443 char   *data;    \/\/ \u0414\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438     intlen;      \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438,      \/\/ \u0442.\u043a. \u043f\u0430\u043c\u044f\u0442\u044c \u0431\u044b\u043b\u0430 \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0447\u0435\u0440\u0435\u0437 palloc     intmaxlen;       \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043d\u0443\u0436\u0434 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.      \/\/ \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f     intcursor; } StringInfoData;  typedef StringInfoData *StringInfo;<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0442\u0438\u043f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u00a0\u0432\u0441\u0435\u043c \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>\u0411\u0443\u0444\u0435\u0440 plain \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f\u00a0\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f).<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0432\u00a0\u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 EXPLAIN \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e StringInfo (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_15_STABLE\/src\/backend\/commands\/explain.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/commands\/explain.c<\/a>):<\/p>\n<pre><code class=\"cpp\">\/\/ 1584 \u0441\u0442\u0440\u043e\u043a\u0430 if (es->format == EXPLAIN_FORMAT_TEXT) {     appendStringInfo(es->str, \"  (cost=%.2f..%.2f rows=%.0f width=%d)\",                      plan->startup_cost, plan->total_cost,                      plan->plan_rows, plan->plan_width); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0421\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441<\/h2>\n<p>\u041f\u0430\u043a\u0435\u0442 <em>ReadyForQuery<\/em> \u0431\u044d\u043a\u044d\u043d\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434 \u043e\u00a0\u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e\u00a0\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0430\u043a\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u043b\u0430\u0433 <em>send_ready_for_query<\/em>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0448\u0430\u0433\u0435) \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d, \u043d\u043e\u00a0\u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0441\u043d\u044f\u0442<\/p>\n<p>\u0412\u00a0\u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433. \u0415\u0441\u043b\u0438 \u043e\u043d \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0443 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u044b \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0435 <em>GUC<\/em> \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>ReadyForQuery<\/em> \u043f\u0430\u043a\u0435\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0424\u043b\u0430\u0433 <em>send_ready_for_query<\/em> \u0441\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f\u00a0\u043f\u0435\u0440\u0432\u044b\u0445 3\u00a0\u0448\u0430\u0433\u043e\u0432 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\/\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u0440\u0432\u0430\u043d\u043d\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c xact &#8212; \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0430\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c xact\u00a0\u2014 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/access\/transam\/xact.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/access\/transam\/xact.c<\/a>. <\/p>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>TransactionStateData<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct TransactionStateData { FullTransactionId fullTransactionId;\/* my FullTransactionId *\/ SubTransactionId subTransactionId;\/* my subxact ID *\/ char   *name;\/* savepoint name, if any *\/ intsavepointLevel; \/* savepoint level *\/ TransStatestate;\/* low-level state *\/ TBlockState blockState;\/* high-level state *\/ intnestingLevel;\/* transaction nesting depth *\/ intgucNestLevel;\/* GUC context nesting depth *\/ MemoryContext curTransactionContext;\/* my xact-lifetime context *\/ ResourceOwner curTransactionOwner;\/* my query resources *\/ TransactionId *childXids;\/* subcommitted child XIDs, in XID order *\/ intnChildXids;\/* # of subcommitted child XIDs *\/ intmaxChildXids;\/* allocated size of childXids[] *\/ OidprevUser;\/* previous CurrentUserId setting *\/ intprevSecContext; \/* previous SecurityRestrictionContext *\/ boolprevXactReadOnly;\/* entry-time xact r\/o state *\/ boolstartedInRecovery;\/* did we start in recovery? *\/ booldidLogXid;\/* has xid been included in WAL record? *\/ intparallelModeLevel;\/* Enter\/ExitParallelMode counter *\/ boolchain;\/* start a new block after this one *\/ boolassigned;\/* assigned to top-level XID *\/ struct TransactionStateData *parent;\/* back link to parent *\/ } TransactionStateData;<\/code><\/pre>\n<p>\u0412\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <em>TopTransactionStateData<\/em>, \u0430 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0432 <em>CurrentTransactionState<\/em><\/p>\n<pre><code class=\"cpp\">\/*  * CurrentTransactionState always points to the current transaction state  * block.  It will point to TopTransactionStateData when not in a  * transaction at all, or when in a top-level transaction.  *\/ static TransactionStateData TopTransactionStateData = { .state = TRANS_DEFAULT, .blockState = TBLOCK_DEFAULT, .assigned = false, };  static TransactionState CurrentTransactionState = &amp;TopTransactionStateData;<\/code><\/pre>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f 2 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u043c\u0438: <\/p>\n<ul>\n<li>\n<p><em>TBlockState<\/em> &#8212; \u043e\u0431\u0449\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0431\u0435\u0437 \u0434\u0435\u0442\u0430\u043b\u0435\u0439<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">\/*  *transaction states - transaction state from server perspective  *\/ typedef enum TransState { TRANS_DEFAULT,\/* idle *\/ TRANS_START,\/* transaction starting *\/ TRANS_INPROGRESS,\/* inside a valid transaction *\/ TRANS_COMMIT,\/* commit in progress *\/ TRANS_ABORT,\/* abort in progress *\/ TRANS_PREPARE\/* prepare in progress *\/ } TransState;<\/code><\/pre>\n<ul>\n<li>\n<p><em>TransState<\/em> &#8212; \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"cpp\">\/*  *transaction block states - transaction state of client queries  *  * Note: the subtransaction states are used only for non-topmost  * transactions; the others appear only in the topmost transaction.  *\/ typedef enum TBlockState { \/* not-in-transaction-block states *\/ TBLOCK_DEFAULT,\/* idle *\/ TBLOCK_STARTED,\/* running single-query transaction *\/  \/* transaction block states *\/ TBLOCK_BEGIN,\/* starting transaction block *\/ TBLOCK_INPROGRESS,\/* live transaction *\/ TBLOCK_IMPLICIT_INPROGRESS, \/* live transaction after implicit BEGIN *\/ TBLOCK_PARALLEL_INPROGRESS, \/* live transaction inside parallel worker *\/ TBLOCK_END,\/* COMMIT received *\/ TBLOCK_ABORT,\/* failed xact, awaiting ROLLBACK *\/ TBLOCK_ABORT_END,\/* failed xact, ROLLBACK received *\/ TBLOCK_ABORT_PENDING,\/* live xact,<\/code><\/pre>\n<\/div>\n<\/details>\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-346181","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346181","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=346181"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346181\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=346181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=346181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=346181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}