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-2024, 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 : : /* Result of parsing is returned in one of these two variables */
21 : : SyncRepConfigData *syncrep_parse_result;
22 : : char *syncrep_parse_error_msg;
23 : :
24 : : static SyncRepConfigData *create_syncrep_config(const char *num_sync,
25 : : List *members, uint8 syncrep_method);
26 : :
27 : : /*
28 : : * Bison doesn't allocate anything that needs to live across parser calls,
29 : : * so we can easily have it use palloc instead of malloc. This prevents
30 : : * memory leaks if we error out during parsing.
31 : : */
32 : : #define YYMALLOC palloc
33 : : #define YYFREE pfree
34 : :
35 : : %}
36 : :
37 : : %expect 0
38 : : %name-prefix="syncrep_yy"
39 : :
40 : : %union
41 : : {
42 : : char *str;
43 : : List *list;
44 : : SyncRepConfigData *config;
45 : : }
46 : :
47 : : %token <str> NAME NUM JUNK ANY FIRST
48 : :
49 : : %type <config> result standby_config
50 : : %type <list> standby_list
51 : : %type <str> standby_name
52 : :
53 : : %start result
54 : :
55 : : %%
56 : : result:
2930 fujii@postgresql.org 57 :CBC 136 : standby_config { syncrep_parse_result = $1; }
58 : : ;
59 : :
60 : : standby_config:
2673 61 : 63 : standby_list { $$ = create_syncrep_config("1", $1, SYNC_REP_PRIORITY); }
62 : 42 : | NUM '(' standby_list ')' { $$ = create_syncrep_config($1, $3, SYNC_REP_PRIORITY); }
63 : 21 : | ANY NUM '(' standby_list ')' { $$ = create_syncrep_config($2, $4, SYNC_REP_QUORUM); }
64 : 10 : | FIRST NUM '(' standby_list ')' { $$ = create_syncrep_config($2, $4, SYNC_REP_PRIORITY); }
65 : : ;
66 : :
67 : : standby_list:
2909 tgl@sss.pgh.pa.us 68 : 136 : standby_name { $$ = list_make1($1); }
69 : 103 : | standby_list ',' standby_name { $$ = lappend($1, $3); }
70 : : ;
71 : :
72 : : standby_name:
73 : 239 : NAME { $$ = $1; }
2909 tgl@sss.pgh.pa.us 74 :UBC 0 : | NUM { $$ = $1; }
75 : : ;
76 : : %%
77 : :
78 : : static SyncRepConfigData *
2673 fujii@postgresql.org 79 :CBC 136 : create_syncrep_config(const char *num_sync, List *members, uint8 syncrep_method)
80 : : {
81 : : SyncRepConfigData *config;
82 : : int size;
83 : : ListCell *lc;
84 : : char *ptr;
85 : :
86 : : /* Compute space needed for flat representation */
2909 tgl@sss.pgh.pa.us 87 : 136 : size = offsetof(SyncRepConfigData, member_names);
88 [ + - + + : 375 : foreach(lc, members)
+ + ]
89 : : {
90 : 239 : char *standby_name = (char *) lfirst(lc);
91 : :
92 : 239 : size += strlen(standby_name) + 1;
93 : : }
94 : :
95 : : /* And transform the data into flat representation */
96 : 136 : config = (SyncRepConfigData *) palloc(size);
97 : :
98 : 136 : config->config_size = size;
2930 fujii@postgresql.org 99 : 136 : config->num_sync = atoi(num_sync);
2673 100 : 136 : config->syncrep_method = syncrep_method;
2909 tgl@sss.pgh.pa.us 101 : 136 : config->nmembers = list_length(members);
102 : 136 : ptr = config->member_names;
103 [ + - + + : 375 : foreach(lc, members)
+ + ]
104 : : {
105 : 239 : char *standby_name = (char *) lfirst(lc);
106 : :
107 : 239 : strcpy(ptr, standby_name);
108 : 239 : ptr += strlen(standby_name) + 1;
109 : : }
110 : :
2930 fujii@postgresql.org 111 : 136 : return config;
112 : : }
|