Age Owner Branch data TLA Line data Source code
1 : : %{
2 : : /*-------------------------------------------------------------------------
3 : : *
4 : : * syncrep_gram.y - Parser for synchronous_standby_names
5 : : *
6 : : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/replication/syncrep_gram.y
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "nodes/pg_list.h"
18 : : #include "replication/syncrep.h"
19 : :
20 : : #include "syncrep_gram.h"
21 : :
22 : : static SyncRepConfigData *create_syncrep_config(const char *num_sync,
23 : : List *members, uint8 syncrep_method);
24 : :
25 : : /*
26 : : * Bison doesn't allocate anything that needs to live across parser calls,
27 : : * so we can easily have it use palloc instead of malloc. This prevents
28 : : * memory leaks if we error out during parsing.
29 : : */
30 : : #define YYMALLOC palloc
31 : : #define YYFREE pfree
32 : :
33 : : %}
34 : :
35 : : %parse-param {SyncRepConfigData **syncrep_parse_result_p}
36 : : %parse-param {char **syncrep_parse_error_msg_p}
37 : : %parse-param {yyscan_t yyscanner}
38 : : %lex-param {char **syncrep_parse_error_msg_p}
39 : : %lex-param {yyscan_t yyscanner}
40 : : %pure-parser
41 : : %expect 0
42 : : %name-prefix="syncrep_yy"
43 : :
44 : : %union
45 : : {
46 : : char *str;
47 : : List *list;
48 : : SyncRepConfigData *config;
49 : : }
50 : :
51 : : %token <str> NAME NUM JUNK ANY FIRST
52 : :
53 : : %type <config> result standby_config
54 : : %type <list> standby_list
55 : : %type <str> standby_name
56 : :
57 : : %start result
58 : :
59 : : %%
60 : : result:
61 : : standby_config {
225 peter@eisentraut.org 62 :CBC 76 : *syncrep_parse_result_p = $1;
63 : : (void) yynerrs; /* suppress compiler warning */
64 : : }
65 : : ;
66 : :
67 : : standby_config:
3183 fujii@postgresql.org 68 : 58 : standby_list { $$ = create_syncrep_config("1", $1, SYNC_REP_PRIORITY); }
69 : 12 : | NUM '(' standby_list ')' { $$ = create_syncrep_config($1, $3, SYNC_REP_PRIORITY); }
70 : 4 : | ANY NUM '(' standby_list ')' { $$ = create_syncrep_config($2, $4, SYNC_REP_QUORUM); }
71 : 2 : | FIRST NUM '(' standby_list ')' { $$ = create_syncrep_config($2, $4, SYNC_REP_PRIORITY); }
72 : : ;
73 : :
74 : : standby_list:
3419 tgl@sss.pgh.pa.us 75 : 76 : standby_name { $$ = list_make1($1); }
76 : 30 : | standby_list ',' standby_name { $$ = lappend($1, $3); }
77 : : ;
78 : :
79 : : standby_name:
80 : 106 : NAME { $$ = $1; }
3419 tgl@sss.pgh.pa.us 81 :UBC 0 : | NUM { $$ = $1; }
82 : : ;
83 : : %%
84 : :
85 : : static SyncRepConfigData *
3183 fujii@postgresql.org 86 :CBC 76 : create_syncrep_config(const char *num_sync, List *members, uint8 syncrep_method)
87 : : {
88 : : SyncRepConfigData *config;
89 : : int size;
90 : : ListCell *lc;
91 : : char *ptr;
92 : :
93 : : /* Compute space needed for flat representation */
3419 tgl@sss.pgh.pa.us 94 : 76 : size = offsetof(SyncRepConfigData, member_names);
95 [ + - + + : 182 : foreach(lc, members)
+ + ]
96 : : {
97 : 106 : char *standby_name = (char *) lfirst(lc);
98 : :
99 : 106 : size += strlen(standby_name) + 1;
100 : : }
101 : :
102 : : /* And transform the data into flat representation */
103 : 76 : config = (SyncRepConfigData *) palloc(size);
104 : :
105 : 76 : config->config_size = size;
3440 fujii@postgresql.org 106 : 76 : config->num_sync = atoi(num_sync);
3183 107 : 76 : config->syncrep_method = syncrep_method;
3419 tgl@sss.pgh.pa.us 108 : 76 : config->nmembers = list_length(members);
109 : 76 : ptr = config->member_names;
110 [ + - + + : 182 : foreach(lc, members)
+ + ]
111 : : {
112 : 106 : char *standby_name = (char *) lfirst(lc);
113 : :
114 : 106 : strcpy(ptr, standby_name);
115 : 106 : ptr += strlen(standby_name) + 1;
116 : : }
117 : :
3440 fujii@postgresql.org 118 : 76 : return config;
119 : : }
|