MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_gtid_misc.cc
1 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or
4  modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation; version 2 of the
6  License.
7 
8  This program is distributed in the hope that it will be useful, but
9  WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16  02110-1301 USA */
17 
18 #include "rpl_gtid.h"
19 
20 #include <ctype.h>
21 
22 #include "mysqld_error.h"
23 #ifndef MYSQL_CLIENT
24 #include "sql_class.h"
25 #endif // ifndef MYSQL_CLIENT
26 
27 enum_return_status Gtid::parse(Sid_map *sid_map, const char *text)
28 {
29  DBUG_ENTER("Gtid::parse");
30  rpl_sid sid;
31  const char *s= text;
32 
33  SKIP_WHITESPACE();
34 
35  // parse sid
36  if (sid.parse(s) == RETURN_STATUS_OK)
37  {
38  rpl_sidno sidno_var= sid_map->add_sid(sid);
39  if (sidno_var <= 0)
40  RETURN_REPORTED_ERROR;
41  s += Uuid::TEXT_LENGTH;
42 
43  SKIP_WHITESPACE();
44 
45  // parse colon
46  if (*s == ':')
47  {
48  s++;
49 
50  SKIP_WHITESPACE();
51 
52  // parse gno
53  rpl_gno gno_var= parse_gno(&s);
54  if (gno_var > 0)
55  {
56  SKIP_WHITESPACE();
57  if (*s == '\0')
58  {
59  sidno= sidno_var;
60  gno= gno_var;
61  RETURN_OK;
62  }
63  else
64  DBUG_PRINT("info", ("expected end of string, found garbage '%.80s' "
65  "at char %d in '%s'",
66  s, (int)(s - text), text));
67  }
68  else
69  DBUG_PRINT("info", ("GNO was zero or invalid (%lld) at char %d in '%s'",
70  gno_var, (int)(s - text), text));
71  }
72  else
73  DBUG_PRINT("info", ("missing colon at char %d in '%s'",
74  (int)(s - text), text));
75  }
76  else
77  DBUG_PRINT("info", ("not a uuid at char %d in '%s'",
78  (int)(s - text), text));
79  BINLOG_ERROR(("Malformed GTID specification: %.200s", text),
80  (ER_MALFORMED_GTID_SPECIFICATION, MYF(0), text));
81  RETURN_REPORTED_ERROR;
82 }
83 
84 
85 int Gtid::to_string(const rpl_sid &sid, char *buf) const
86 {
87  DBUG_ENTER("Gtid::to_string");
88  char *s= buf + sid.to_string(buf);
89  *s= ':';
90  s++;
91  s+= format_gno(s, gno);
92  DBUG_RETURN((int)(s - buf));
93 }
94 
95 
96 int Gtid::to_string(const Sid_map *sid_map, char *buf) const
97 {
98  DBUG_ENTER("Gtid::to_string");
99  int ret= to_string(sid_map->sidno_to_sid(sidno), buf);
100  DBUG_RETURN(ret);
101 }
102 
103 
104 bool Gtid::is_valid(const char *text)
105 {
106  DBUG_ENTER("Gtid::is_valid");
107  const char *s= text;
108  SKIP_WHITESPACE();
109  if (!rpl_sid::is_valid(s))
110  {
111  DBUG_PRINT("info", ("not a uuid at char %d in '%s'",
112  (int)(s - text), text));
113  DBUG_RETURN(false);
114  }
115  s += Uuid::TEXT_LENGTH;
116  SKIP_WHITESPACE();
117  if (*s != ':')
118  {
119  DBUG_PRINT("info", ("missing colon at char %d in '%s'",
120  (int)(s - text), text));
121  DBUG_RETURN(false);
122  }
123  s++;
124  SKIP_WHITESPACE();
125  if (parse_gno(&s) <= 0)
126  {
127  DBUG_PRINT("info", ("GNO was zero or invalid at char %d in '%s'",
128  (int)(s - text), text));
129  DBUG_RETURN(false);
130  }
131  SKIP_WHITESPACE();
132  if (*s != 0)
133  {
134  DBUG_PRINT("info", ("expected end of string, found garbage '%.80s' "
135  "at char %d in '%s'",
136  s, (int)(s - text), text));
137  DBUG_RETURN(false);
138  }
139  DBUG_RETURN(true);
140 }
141 
142 
143 #ifndef DBUG_OFF
144 void check_return_status(enum_return_status status, const char *action,
145  const char *status_name, int allow_unreported)
146 {
147  if (status != RETURN_STATUS_OK)
148  {
149  DBUG_ASSERT(allow_unreported || status == RETURN_STATUS_REPORTED_ERROR);
150  if (status == RETURN_STATUS_REPORTED_ERROR)
151  {
152 #if !defined(MYSQL_CLIENT) && !defined(DBUG_OFF)
153  THD *thd= current_thd;
154  DBUG_ASSERT(thd == NULL ||
155  thd->get_stmt_da()->status() == Diagnostics_area::DA_ERROR);
156 #endif
157  }
158  DBUG_PRINT("info", ("%s error %d (%s)", action, status, status_name));
159  }
160 }
161 #endif // ! DBUG_OFF