Re: Support for N synchronous standby servers - take 2
От | Kyotaro HORIGUCHI |
---|---|
Тема | Re: Support for N synchronous standby servers - take 2 |
Дата | |
Msg-id | 20160226.105325.168253404.horiguchi.kyotaro@lab.ntt.co.jp обсуждение исходный текст |
Ответ на | Re: Support for N synchronous standby servers - take 2 (Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>) |
Ответы |
Re: Support for N synchronous standby servers - take 2
(Masahiko Sawada <sawada.mshk@gmail.com>)
|
Список | pgsql-hackers |
At Fri, 26 Feb 2016 10:38:22 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> wrote in <20160226.103822.12680005.horiguchi.kyotaro@lab.ntt.co.jp> > Hello, Thanks for the new patch. > > > At Fri, 26 Feb 2016 08:52:54 +0900, Masahiko Sawada <sawada.mshk@gmail.com> wrote in <CAD21AoAZKFVu8-MVhkJ3ywAiJmb=P-HSbJTGi=gK1La73KjS6Q@mail.gmail.com> > > Previous patch could not parse one character standby name correctly. > > Attached latest patch. > > I haven't looked it in detail but it won't work as you > expected. flex compains as the following for v12 patch. > > syncgroup_scanner.l:80: warning, rule cannot be matched > syncgroup_scanner.l:84: warning, rule cannot be matched Making it independent from postgres body then compile it with -DYYDEBUG and set yydebug = 1 would give you valuable information and make testing of the parser far easier. | $ flex test2.l; bison -v test2.y; gcc -g -DYYDEBUG -o ltest2 test2.tab.c | $ echo '1[aa,bb,cc]' | ./ltest2 | Starting parse | Entering state 0 | Reading a token: Next token is token NAME () | Shifting token NAME () | ... | Entering state 4 | Next token is token '[' () | syntax error at or near "[" in "(null) regards, -- Kyotaro Horiguchi NTT Open Source Software Center %{ //#include "postgres.h" /* No reason to constrain amount of data slurped */ #define YY_READ_BUF_SIZE 16777216 #define BUFSIZE 8192 /* Handles to the buffer that the lexer uses internally */ static YY_BUFFER_STATE scanbufhandle; /* Functions for handling double quoted string */ static void init_xd_string(void); static void addlit_xd_string(char *ytext, int yleng); static void addlitchar_xd_string(unsigned char ychar); char *scanbuf; char *xd_string; int xd_size; /* actual size of xd_string */ int xd_len; /* string length of xd_string */ %} %option 8bit /* %option never-interactive*/ /* %option nounput*/ /* %option noinput*/ %option noyywrap %option warn /* %option prefix="syncgroup_yy" */ /** <xd> delimited identifiers (double-quoted identifiers)*/ %x xd space [ \t\n\r\f] non_newline [^\n\r] whitespace ({space}+) self [\[\]\,] asterisk \* /** Basically all ascii characteres except for {self} and {whitespace} are allowed* to be used for node name. These specialcharater could be used by double-quoted.*//* excluding ' ', '\"', '*', ',', '[', ']' */ node_name [\x21\x23-\x29\x29-\x2b\x2d-\x5a\x5c\x5e-\x7e] /* excluding '\"' */ dquoted_name [\x20\x21\x23-\x7e] /* Double-quoted string */ dquote \" xdstart {dquote} xddouble {dquote}{dquote} xdstop {dquote} xdinside {dquoted_name}+ %% {whitespace} { /* ignore */ } {xdstart} { init_xd_string(); BEGIN(xd); } <xd>{xddouble} { addlitchar_xd_string('\"'); } <xd>{xdinside} { addlit_xd_string(yytext, yyleng); } <xd>{xdstop} { xd_string[xd_len] = '\0'; yylval.str = xd_string; BEGIN(INITIAL); return NAME; } {node_name}+ { yylval.str = strdup(yytext); return NAME; } [1-9][0-9]* { yylval.str = yytext; return NUM; } {asterisk} { yylval.str = strdup(yytext); return AST; } {self} { return yytext[0]; } . { // ereport(ERROR, // (errcode(ERRCODE_SYNTAX_ERROR), // errmsg("syntax error: unexpected character \"%s\"", yytext))); fprintf(stderr, "syntaxerror: unexpected character \"%s\"", yytext); exit(1);} %% void yyerror(const char *message) { // ereport(ERROR, // (errcode(ERRCODE_SYNTAX_ERROR), // errmsg("%s at or near \"%s\" in \"%s\"", message, // yytext, scanbuf)));fprintf(stderr, "%s at or near \"%s\" in \"%s\"", message, yytext, scanbuf);exit(1); } void syncgroup_scanner_init(const char *str) {Size slen = strlen(str); /* * Might be left over after ereport() */if (YY_CURRENT_BUFFER) yy_delete_buffer(YY_CURRENT_BUFFER); /* * Make a scan buffer with special termination needed by flex. */scanbuf = (char *) palloc(slen + 2);memcpy(scanbuf, str,slen);scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); } void syncgroup_scanner_finish(void) {yy_delete_buffer(scanbufhandle);scanbufhandle = NULL; } static void init_xd_string() {xd_string = palloc(sizeof(char) * BUFSIZE);xd_size = BUFSIZE;xd_len = 0; } static void addlit_xd_string(char *ytext, int yleng) {/* enlarge buffer if needed */if ((xd_len + yleng) > xd_size) xd_string = repalloc(xd_string, xd_size + BUFSIZE); memcpy(xd_string + xd_len, ytext, yleng);xd_len += yleng; } static void addlitchar_xd_string(unsigned char ychar) {/* enlarge buffer if needed */if ((xd_len + 1) > xd_size) xd_string = repalloc(xd_string, xd_size + BUFSIZE); xd_string[xd_len] = ychar;xd_len += 1; } %{ /*-------------------------------------------------------------------------** syncgroup_gram.y - Parser forsynchronous replication group** Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group* Portions Copyright(c) 1994, Regents of the University of California*** IDENTIFICATION* src/backend/replication/syncgroup_gram.y**-------------------------------------------------------------------------*/ //#include "postgres.h" //#include "replication/syncrep.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #define palloc malloc #define repalloc realloc #define pfree free #define SYNC_REP_GROUP_MAIN 0x01 #define SYNC_REP_GROUP_NAME 0x02 #define SYNC_REP_GROUP_GROUP 0x04 #define SYNC_REP_METHOD_PRIORITY 0 struct SyncGroupNode; typedef struct SyncGroupNode SyncGroupNode; struct SyncGroupNode {/* Common information */int type;char *name;SyncGroupNode *next; /* Same group, next name node */ /* For group ndoe */int sync_method; /* priority */int wait_num;SyncGroupNode *members; /* member of its group */ }; static SyncGroupNode *create_name_node(char *name); static SyncGroupNode *add_node(SyncGroupNode *node_list, SyncGroupNode *node); static SyncGroupNode *create_group_node(char *wait_num, SyncGroupNode *node_list); static void yyerror(const char *message);typedef int Size; /** Bison doesn't allocate anything that needs to live across parser calls,* so we can easily have it use palloc insteadof malloc. This prevents* memory leaks if we error out during parsing. Note this only works with* bison >= 2.0. However, in bison 1.875 the default is to use alloca()* if possible, so there's not really much problem anyhow, at leastif* you're building with gcc.*/ #define YYMALLOC palloc #define YYFREE pfreeSyncGroupNode *SyncRepStandbys; %} %expect 0/*%name-prefix="syncgroup_yy"*/ %union {char *str;SyncGroupNode *expr; } %token <str> NAME NUM %token <str> AST %type <expr> result sync_list sync_list_ast sync_element sync_element_ast sync_node_group sync_group_old sync_group %start result %% result: sync_node_group { SyncRepStandbys = $1; } ; sync_node_group: sync_group_old { $$ = $1; } | sync_group { $$ = $1;} ; sync_group_old: sync_list { $$ = create_group_node("1", $1); } | sync_list_ast { $$ = create_group_node("1", $1); } ; sync_group: NUM '[' sync_list ']' { $$ = create_group_node($1, $3); } | NUM '[' sync_list_ast ']' { $$ = create_group_node($1, $3); } ; sync_list: sync_element { $$ = $1;} | sync_list ',' sync_element { $$ = add_node($1,$3);} ; sync_list_ast: sync_element_ast { $$ = $1;} | sync_list ',' sync_element_ast { $$ = add_node($1,$3);} ; sync_element: NAME { $$ = create_name_node($1); } | NUM { $$ = create_name_node($1); } ; sync_element_ast: AST { $$ = create_name_node($1); } ; %% static SyncGroupNode * create_name_node(char *name) {SyncGroupNode *name_node = (SyncGroupNode *)malloc(sizeof(SyncGroupNode)); /* Common information */name_node->type = SYNC_REP_GROUP_NAME;name_node->name = strdup(name);name_node->next = NULL; /* For GROUP node */name_node->sync_method = 0;name_node->wait_num = 0;name_node->members = NULL;// name_node->SyncRepGetSyncedLsnsFn= NULL;// name_node->SyncRepGetSyncStandbysFn = NULL; return name_node; } static SyncGroupNode * create_group_node(char *wait_num, SyncGroupNode *node_list) {SyncGroupNode *group_node = (SyncGroupNode *)malloc(sizeof(SyncGroupNode)); /* For NAME node */group_node->type = SYNC_REP_GROUP_GROUP | SYNC_REP_GROUP_MAIN;group_node->name = "main";group_node->next= NULL; /* For GROUP node */group_node->sync_method = SYNC_REP_METHOD_PRIORITY;group_node->wait_num = atoi(wait_num);group_node->members= node_list;// group_node->SyncRepGetSyncedLsnsFn = SyncRepGetSyncedLsnsUsingPriority;// group_node->SyncRepGetSyncStandbysFn = SyncRepGetSyncStandbysUsingPriority; return group_node; } static SyncGroupNode * add_node(SyncGroupNode *node_list, SyncGroupNode *node) {SyncGroupNode *tmp = node_list; /* Add node to tailing of node_list */while(tmp->next != NULL) tmp = tmp->next; tmp->next = node;return node_list; } void indent(int level) { int i; for (i = 0 ; i < level * 2 ; i++) putc(' ', stdout); } static void dump_syncgroupnode(SyncGroupNode *def, int level) { char *typelabel[] = {"MAIN", "NAME", "GROUP"}; SyncGroupNode *p; if (def == NULL) return; switch(def->type) { case SYNC_REP_GROUP_NAME: indent(level); puts("{"); indent(level+1); printf("NODE_TYPE: SYNC_REP_GROUP_NAME\n"); indent(level+1); printf("NAME: %s\n", def->name); indent(level); puts("}"); if (def->next) dump_syncgroupnode(def->next, level); break; case SYNC_REP_GROUP_GROUP | SYNC_REP_GROUP_MAIN: indent(level); puts("{"); indent(level+1); printf("NODE_TYPE: SYNC_REP_GROUP_GROUP | SYNC_REP_GROUP_MAIN\n"); indent(level+1); printf("NAME: %s\n", def->name); indent(level+1); printf("SYNC_METHOD: PRIORITY\n"); indent(level+1); printf("WAIT_NUM: %d\n", def->wait_num); indent(level+1); if (def->members) dump_syncgroupnode(def->members,level+1); indent(level); puts("}"); if (def->next) dump_syncgroupnode(def->next,level); break; default: fprintf(stderr, "ERR\n"); exit(1); } level--; } int main(void) { yydebug = 1; yyparse(); dump_syncgroupnode(SyncRepStandbys, 0); } //#include "syncgroup_scanner.c" #include "lex.yy.c"
В списке pgsql-hackers по дате отправления:
Предыдущее
От: Kyotaro HORIGUCHIДата:
Сообщение: Re: Support for N synchronous standby servers - take 2