MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
table_session_connect.cc
1 /* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #include "table_session_connect.h"
17 
18 static const TABLE_FIELD_TYPE field_types[]=
19 {
20  {
21  { C_STRING_WITH_LEN("PROCESSLIST_ID") },
22  { C_STRING_WITH_LEN("int(11)") },
23  { NULL, 0}
24  },
25  {
26  { C_STRING_WITH_LEN("ATTR_NAME") },
27  { C_STRING_WITH_LEN("varchar(32)") },
28  { NULL, 0}
29  },
30  {
31  { C_STRING_WITH_LEN("ATTR_VALUE") },
32  { C_STRING_WITH_LEN("varchar(1024)") },
33  { NULL, 0}
34  },
35  {
36  { C_STRING_WITH_LEN("ORDINAL_POSITION") },
37  { C_STRING_WITH_LEN("int(11)") },
38  { NULL, 0}
39  }
40 };
41 
43 { 4, field_types };
44 
45 table_session_connect::table_session_connect(const PFS_engine_table_share *share) :
47 {}
48 
65 bool parse_length_encoded_string(const char **ptr,
66  char *dest, uint dest_size,
67  uint *copied_len,
68  const char *start_ptr, uint input_length,
69  bool copy_data,
70  const CHARSET_INFO *from_cs,
71  uint nchars_max)
72 {
73  ulong copy_length, data_length;
74  const char *well_formed_error_pos= NULL, *cannot_convert_error_pos= NULL,
75  *from_end_pos= NULL;
76 
77  copy_length= data_length= net_field_length((uchar **) ptr);
78 
79  /* we don't tolerate NULL as a length */
80  if (data_length == NULL_LENGTH)
81  return true;
82 
83  if (*ptr - start_ptr + data_length > input_length)
84  return true;
85 
86  copy_length= well_formed_copy_nchars(&my_charset_utf8_bin, dest, dest_size,
87  from_cs, *ptr, data_length, nchars_max,
88  &well_formed_error_pos,
89  &cannot_convert_error_pos,
90  &from_end_pos);
91  *copied_len= copy_length;
92  (*ptr)+= data_length;
93 
94  return false;
95 }
96 
121 bool read_nth_attr(const char *connect_attrs,
122  uint connect_attrs_length,
123  const CHARSET_INFO *connect_attrs_cs,
124  uint ordinal,
125  char *attr_name, uint max_attr_name,
126  uint *attr_name_length,
127  char *attr_value, uint max_attr_value,
128  uint *attr_value_length)
129 {
130  uint idx;
131  const char *ptr;
132 
133  for (ptr= connect_attrs, idx= 0;
134  (uint)(ptr - connect_attrs) < connect_attrs_length && idx <= ordinal;
135  idx++)
136  {
137  uint copy_length;
138  /* do the copying only if we absolutely have to */
139  bool fill_in_attr_name= idx == ordinal;
140  bool fill_in_attr_value= idx == ordinal;
141 
142  /* read the key */
143  if (parse_length_encoded_string(&ptr,
144  attr_name, max_attr_name, &copy_length,
145  connect_attrs,
146  connect_attrs_length,
147  fill_in_attr_name,
148  connect_attrs_cs, 32) ||
149  !copy_length
150  )
151  return false;
152 
153  if (idx == ordinal)
154  *attr_name_length= copy_length;
155 
156  /* read the value */
157  if (parse_length_encoded_string(&ptr,
158  attr_value, max_attr_value, &copy_length,
159  connect_attrs,
160  connect_attrs_length,
161  fill_in_attr_value,
162  connect_attrs_cs, 1024))
163  return false;
164 
165  if (idx == ordinal)
166  *attr_value_length= copy_length;
167 
168  if (idx == ordinal)
169  return true;
170  }
171 
172  return false;
173 }
174 
175 void table_session_connect::make_row(PFS_thread *pfs, uint ordinal)
176 {
177  pfs_lock lock;
178  PFS_thread_class *safe_class;
179 
180  m_row_exists= false;
181 
182  /* Protect this reader against thread termination */
183  pfs->m_lock.begin_optimistic_lock(&lock);
184  safe_class= sanitize_thread_class(pfs->m_class);
185  if (unlikely(safe_class == NULL))
186  return;
187 
188  /* Filtering threads must be done under the protection of the optimistic lock. */
189  if (! thread_fits(pfs))
190  return;
191 
192  /* populate the row */
193  if (read_nth_attr(pfs->m_session_connect_attrs,
196  ordinal,
197  m_row.m_attr_name, (uint) sizeof(m_row.m_attr_name),
199  m_row.m_attr_value, (uint) sizeof(m_row.m_attr_value),
201  {
202  /* we don't expect internal threads to have connection attributes */
203  DBUG_ASSERT(pfs->m_processlist_id != 0);
204 
205  m_row.m_ordinal_position= ordinal;
207  }
208  else
209  return;
210 
211  if (pfs->m_lock.end_optimistic_lock(& lock))
212  m_row_exists= true;
213 }
214 
216  unsigned char *buf,
217  Field **fields,
218  bool read_all)
219 {
220  Field *f;
221 
222  if (unlikely(!m_row_exists))
223  return HA_ERR_RECORD_DELETED;
224 
225  /* Set the null bits */
226  DBUG_ASSERT(table->s->null_bytes == 1);
227  buf[0]= 0;
228 
229  for (; (f= *fields) ; fields++)
230  {
231  if (read_all || bitmap_is_set(table->read_set, f->field_index))
232  {
233  switch(f->field_index)
234  {
235  case FO_PROCESS_ID:
236  if (m_row.m_process_id != 0)
238  else
239  f->set_null();
240  break;
241  case FO_ATTR_NAME:
244  break;
245  case FO_ATTR_VALUE:
249  else
250  f->set_null();
251  break;
252  case FO_ORDINAL_POSITION:
254  break;
255  default:
256  DBUG_ASSERT(false);
257  }
258  }
259  }
260  return 0;
261 }
262 
263 bool
264 table_session_connect::thread_fits(PFS_thread *thread)
265 {
266  return true;
267 }
268