1 2%{ 3 4/* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 18 19#include <string> 20#include "sql/debug_lo_misc.h" 21#include "sql/debug_lo_parser.h" 22#include "sql/debug_lo_scanner.h" 23#include "sql/debug_lock_order.h" 24#include "mysql/components/services/log_builtins.h" 25#include "mysqld_error.h" 26 27class LO_graph; 28 29void process_arc(LO_parser_param *p, 30 char *from, 31 char *state, 32 char *to, 33 bool recursive, 34 char *operation, 35 int flags, 36 char *constraint, 37 char *comment); 38 39void process_bind(LO_parser_param *p, 40 char *from, 41 char *to, 42 int flags); 43 44void process_node(LO_parser_param *p, 45 char *node, 46 char *operation, 47 int flags); 48 49void LOCK_ORDER_error(YYLTYPE *yyloc, LO_parser_param *p, const char* msg); 50 51#define YYLEX_PARAM param->m_scanner 52 53%} 54 55%pure-parser 56%locations 57 58%lex-param { yyscan_t YYLEX_PARAM } 59%parse-param { struct LO_parser_param *param } 60 61%union 62{ 63 char *m_str; 64 int m_flags; 65} 66 67%start graph 68 69%expect 0 70 71%token ARC_SYM 72%token BIND_SYM 73%token COMMENT_SYM 74%token CONSTRAINT_SYM 75%token DEBUG_SYM 76%token FLAGS_SYM 77%token FROM_SYM 78%token IGNORED_SYM 79%token LOOP_SYM 80%token NODE_SYM 81%token OP_SYM 82%token RECURSIVE_SYM 83%token STATE_SYM 84%token <m_str> STR_SYM 85%token TO_SYM 86%token TRACE_SYM 87%token UNFAIR_SYM 88 89%type <m_flags> opt_arc_flags; 90%type <m_flags> arc_flags; 91%type <m_flags> arc_flag; 92%type <m_flags> opt_bind_flags; 93%type <m_flags> bind_flags; 94%type <m_flags> bind_flag; 95%type <m_flags> node_flag; 96%type <m_str> opt_comment; 97%type <m_str> opt_constraint; 98%type <m_str> opt_state; 99 100%% 101 102graph: 103 list_of_declarations_opt 104 ; 105 106list_of_declarations_opt: 107 /* empty */ 108 | list_of_declarations 109 ; 110 111list_of_declarations: 112 declaration 113 | list_of_declarations declaration 114 ; 115 116opt_arc_flags: 117 /* empty */ 118 { 119 $$ = 0; 120 } 121 | FLAGS_SYM arc_flags 122 { 123 $$ = $2; 124 } 125 ; 126 127arc_flags: 128 arc_flags arc_flag 129 { 130 $$ = $1 | $2; 131 } 132 | arc_flag 133 { 134 $$ = $1; 135 } 136 ; 137 138arc_flag: 139 TRACE_SYM 140 { 141 $$ = LO_FLAG_TRACE; 142 } 143 | DEBUG_SYM 144 { 145 $$ = LO_FLAG_DEBUG; 146 } 147 | LOOP_SYM 148 { 149 $$ = LO_FLAG_LOOP; 150 } 151 | IGNORED_SYM 152 { 153 $$ = LO_FLAG_IGNORED; 154 } 155 ; 156 157opt_bind_flags: 158 /* empty */ 159 { 160 $$ = 0; 161 } 162 | FLAGS_SYM bind_flags 163 { 164 $$ = $2; 165 } 166 ; 167 168bind_flags: 169 bind_flags bind_flag 170 { 171 $$ = $1 | $2; 172 } 173 | bind_flag 174 { 175 $$ = $1; 176 } 177 ; 178 179bind_flag: 180 UNFAIR_SYM 181 { 182 $$ = LO_FLAG_UNFAIR; 183 } 184 ; 185 186node_flag: 187 IGNORED_SYM 188 { 189 $$ = LO_FLAG_IGNORED; 190 } 191 ; 192 193opt_state: 194 /* empty */ 195 { 196 $$ = nullptr; 197 } 198 | STATE_SYM STR_SYM 199 { 200 $$ = $2; 201 } 202 ; 203 204opt_constraint: 205 /* empty */ 206 { 207 $$ = nullptr; 208 } 209 | CONSTRAINT_SYM STR_SYM 210 { 211 $$ = $2; 212 } 213 ; 214 215opt_comment: 216 /* empty */ 217 { 218 $$ = nullptr; 219 } 220 | COMMENT_SYM STR_SYM 221 { 222 $$ = $2; 223 } 224 ; 225 226declaration: 227 arc_declaration 228 | bind_declaration 229 | node_declaration 230 ; 231 232/* 233 Note: can not use the [from] and $from syntax, 234 because this requires a recent bison. 235*/ 236 237arc_declaration: 238 ARC_SYM 239 FROM_SYM 240 STR_SYM /* [from] = 3 */ 241 opt_state /* [state] = 4 */ 242 TO_SYM 243 STR_SYM /* [to] = 6 */ 244 opt_arc_flags /* [flags] = 7 */ 245 opt_constraint /* [constraint] = 8 */ 246 opt_comment /* [comment] = 9 */ 247 { 248 process_arc(param, $3, $4, $6, false, nullptr, $7, $8, $9); 249 } 250 | ARC_SYM 251 FROM_SYM 252 STR_SYM /* [from] = 3 */ 253 opt_state /* [state] = 4 */ 254 TO_SYM 255 STR_SYM /* [to] = 6 */ 256 OP_SYM 257 STR_SYM /* [op] = 8 */ 258 opt_arc_flags /* [flags] = 9 */ 259 opt_constraint /* [constraint] = 10 */ 260 opt_comment /* [comment] = 11 */ 261 { 262 process_arc(param, $3, $4, $6, false, $8, $9, $10, $11); 263 } 264 | ARC_SYM 265 FROM_SYM 266 STR_SYM /* [from] = 3 */ 267 opt_state /* [state] = 4 */ 268 TO_SYM 269 STR_SYM /* [to] = 6 */ 270 RECURSIVE_SYM 271 OP_SYM 272 STR_SYM /* [op] = 9 */ 273 opt_arc_flags /* [flags] = 10 */ 274 opt_constraint /* [constraint] = 11 */ 275 opt_comment /* [comment] == 12 */ 276 { 277 process_arc(param, $3, $4, $6, true, $9, $10, $11, $12); 278 } 279 ; 280 281bind_declaration: 282 BIND_SYM 283 STR_SYM /* [from] = 2 */ 284 TO_SYM 285 STR_SYM /* [to] = 4 */ 286 opt_bind_flags /* [flags] = 5 */ 287 { 288 process_bind(param, $2, $4, $5); 289 } 290 ; 291 292node_declaration: 293 NODE_SYM 294 STR_SYM /* [node] = 2 */ 295 node_flag /* [flag] = 3 */ 296 { 297 process_node(param, $2, nullptr, $3); 298 } 299 | NODE_SYM 300 STR_SYM /* [node] = 2 */ 301 OP_SYM 302 STR_SYM /* [op] = 4 */ 303 node_flag /* [flag] = 5 */ 304 { 305 process_node(param, $2, $4, $5); 306 } 307 ; 308 309%% 310 311void process_arc(LO_parser_param *p, 312 char *from, 313 char *state, 314 char *to, 315 bool recursive, 316 char *operation, 317 int flags, 318 char *constraint, 319 char *comment) 320{ 321 LO_authorised_arc arc; 322 arc.m_from_name = from; 323 arc.m_from_state = state; 324 arc.m_to_name = to; 325 arc.m_op_recursive = recursive; 326 arc.m_to_operation = operation; 327 arc.m_flags = flags; 328 arc.m_constraint = constraint; 329 arc.m_comment = comment; 330 LO_add_authorised_arc(p->m_graph, &arc); 331} 332 333void process_bind(LO_parser_param *p, 334 char *from, 335 char *to, 336 int flags) 337{ 338 LO_authorised_arc arc; 339 arc.m_from_name = from; 340 arc.m_from_state = nullptr; 341 arc.m_to_name = to; 342 arc.m_op_recursive = false; 343 arc.m_to_operation = nullptr; 344 arc.m_flags = LO_FLAG_BIND | flags; 345 arc.m_constraint = nullptr; 346 arc.m_comment = nullptr; 347 LO_add_authorised_arc(p->m_graph, &arc); 348} 349 350void process_node(LO_parser_param *p, 351 char *node, 352 char *operation, 353 int flags) 354{ 355 LO_node_properties prop; 356 prop.m_name = node; 357 prop.m_operation = operation; 358 prop.m_flags = flags; 359 LO_add_node_properties(p->m_graph, &prop); 360} 361 362void LOCK_ORDER_error(YYLTYPE * yylloc_param, LO_parser_param * p, const char* msg) 363{ 364 /* message format = "Lock order dependencies file <%s> (%d:%d) - (%d:%d) : %s" */ 365 LogErr(ERROR_LEVEL, ER_LOCK_ORDER_DEPENDENCIES_SYNTAX, 366 p->m_filename, 367 yylloc_param->first_line, 368 yylloc_param->first_column, 369 yylloc_param->last_line, 370 yylloc_param->last_column, 371 msg); 372} 373 374