CUBRID Engine  latest
load_semantic_helper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * load_semantic_helper.cpp - Helper class for building loaddb types
21  */
22 
23 #include "load_semantic_helper.hpp"
24 
25 #include "error_manager.h"
26 #include "language_support.h"
27 
28 #include <algorithm>
29 #include <cstring>
30 
31 namespace cubload
32 {
33 
35  : m_in_instance_line (true)
36  , m_string_pool_idx (0)
37  , m_string_pool {}
38  , m_string_list ()
40  , m_copy_buf_pool {}
42  , m_constant_pool {}
43  , m_constant_list ()
44  , m_use_qstr_buf (false)
47  , m_qstr_buf_idx (0)
48  , m_qstr_buf_pool {}
50  {
51  //
52  }
53 
55  {
56  clear ();
57  }
58 
59  void
61  {
62  if (m_use_qstr_buf)
63  {
65  }
66  else
67  {
69  {
70  char *qstr_buf_tmp = m_qstr_buf_ptr;
72 
73  // in case we switch from m_qstr_buf_pool to m_qstr_buf
74  // we need to copy accumulated data to the new memory location
75  std::memcpy (m_qstr_buf_ptr, qstr_buf_tmp, m_qstr_buf_idx);
76 
78  m_use_qstr_buf = true;
79  }
80  }
81 
83  }
84 
85  string_type *
87  {
88  return append_list<string_type> (head, tail);
89  }
90 
93  {
94  return append_list<constant_type> (head, tail);
95  }
96 
97  void
99  {
101  {
103  m_use_qstr_buf = false;
104  }
105  else
106  {
108  m_use_qstr_buf = true;
109  }
110 
111  m_qstr_buf_idx = 0;
112  }
113 
114  string_type *
116  {
117  string_type *str = NULL;
118  std::size_t str_size = m_qstr_buf_idx - 1;
119 
120  if (!m_use_qstr_buf)
121  {
122  str = make_string (m_qstr_buf_ptr, str_size, false);
123  }
124  else
125  {
126  str = make_string_and_copy (m_qstr_buf_ptr, str_size);
127  }
128 
129  if (!is_utf8_valid (str))
130  {
131  return NULL;
132  }
133 
134  return str;
135  }
136 
137  string_type *
138  semantic_helper::make_string_by_yytext (const char *text, int text_size)
139  {
140  std::size_t str_size = (std::size_t) text_size;
141  string_type *str = make_string_and_copy (text, str_size);
142 
143  if (!is_utf8_valid (str))
144  {
145  return NULL;
146  }
147 
148  return str;
149  }
150 
151  constant_type *
152  semantic_helper::make_constant (int type, void *val)
153  {
154  constant_type *con = NULL;
155 
157  {
159  con->type = (data_type) type;
160  con->val = val;
161  }
162  else
163  {
164  con = new constant_type ((data_type) type, val);
165 
166  // collect allocated constants in order to free the memory later
167  m_constant_list.push_front (con);
168  }
169 
170  return con;
171  }
172 
173  constant_type *
175  {
176  if (str == NULL || str->val == NULL)
177  {
178  return NULL;
179  }
180 
181  if (strchr (str->val, 'F') != NULL || strchr (str->val, 'f') != NULL)
182  {
183  return make_constant (LDR_FLOAT, str);
184  }
185  else if (strchr (str->val, 'E') != NULL || strchr (str->val, 'e') != NULL)
186  {
187  return make_constant (LDR_DOUBLE, str);
188  }
189  else
190  {
191  return make_constant (LDR_NUMERIC, str);
192  }
193  }
194 
195  constant_type *
197  {
198  return make_constant (LDR_MONETARY, new monetary_type (amount, currency_type));
199  }
200 
201  void
203  {
204  clear ();
205 
206  m_string_pool_idx = 0;
210  }
211 
212  bool
214  {
215  return m_in_instance_line;
216  }
217 
218  void
220  {
222  }
223 
224  void
226  {
227  reset_after_line ();
228 
229  m_in_instance_line = true;
231  m_use_qstr_buf = false;
232  m_qstr_buf_idx = 0;
233  }
234 
235  string_type *
236  semantic_helper::make_string (char *val, std::size_t size, bool need_free_val)
237  {
238  string_type *str = NULL;
239 
241  {
243  str->val = val;
244  str->size = size;
245  str->need_free_val = need_free_val;
246  }
247  else
248  {
249  str = new string_type (val, size, need_free_val);
250 
251  // collect allocated string types in order to free the memory later
252  m_string_list.push_front (str);
253  }
254 
255  return str;
256  }
257 
258  string_type *
259  semantic_helper::make_string_and_copy (const char *src, size_t str_size)
260  {
261  string_type *str;
262 
263  if (use_copy_buf_pool (str_size))
264  {
265  str = make_string (&m_copy_buf_pool[m_copy_buf_pool_idx++][0], str_size, false);
266  }
267  else
268  {
269  // +1 for string null terminator
270  str = make_string (new char[str_size + 1], str_size, true);
271  }
272 
273  std::memcpy (str->val, src, str_size);
274  str->val[str_size] = '\0';
275 
276  return str;
277  }
278 
279  void
281  {
282  m_qstr_buf.extend_to (new_size);
283  // make sure that quoted string buffer points to new memory location
285  }
286 
287  bool
289  {
290  char *invalid_pos = NULL;
291 
292  if (intl_check_string (str->val, (int) str->size, &invalid_pos, LANG_SYS_CODESET) != INTL_UTF8_VALID)
293  {
294  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_INVALID_CHAR, 1, invalid_pos - str->val);
295  return false;
296  }
297 
298  return true;
299  }
300 
301  bool
302  semantic_helper::use_copy_buf_pool (std::size_t str_size)
303  {
305  }
306 
307  void
309  {
310  size_t string_pool_end = std::min (m_string_pool_idx + 1, STRING_POOL_SIZE);
311  for (size_t i = 0; i < string_pool_end; ++i)
312  {
313  // might be that some of the str.val within from m_string_pool where dynamically allocated
314  m_string_pool[i].destroy ();
315  }
316 
317  for (string_type *str : m_string_list)
318  {
319  delete str;
320  }
321  m_string_list.clear ();
322 
323  for (constant_type *con : m_constant_list)
324  {
325  delete con;
326  }
327  m_constant_list.clear ();
328  }
329 
330  template<typename T>
331  T *
332  semantic_helper::append_list (T *head, T *tail)
333  {
334  tail->next = NULL;
335  tail->last = NULL;
336 
337  if (head)
338  {
339  head->last->next = tail;
340  }
341  else
342  {
343  head = tail;
344  }
345 
346  head->last = tail;
347  return head;
348  }
349 
350 } // namespace cubload
static const std::size_t MAX_QUOTED_STR_BUF_SIZE
constant_type * make_real(string_type *str)
cubmem::extensible_block m_qstr_buf
std::forward_list< string_type * > m_string_list
constant_type * make_constant(int type, void *val)
char m_copy_buf_pool[COPY_BUF_POOL_SIZE][MAX_COPY_BUF_SIZE]
constant_type m_constant_pool[CONSTANT_POOL_SIZE]
static const std::size_t STRING_POOL_SIZE
static const std::size_t MAX_COPY_BUF_SIZE
bool is_utf8_valid(string_type *str)
string_type m_string_pool[STRING_POOL_SIZE]
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
string_type * make_string_by_yytext(const char *text, int text_size)
string_type * append_string_list(string_type *head, string_type *tail)
string_type * make_string(char *val, std::size_t size, bool need_free_val)
std::forward_list< constant_type * > m_constant_list
char m_qstr_buf_pool[QUOTED_STR_BUF_POOL_SIZE][MAX_QUOTED_STR_BUF_SIZE]
constant_type * make_monetary_constant(int currency_type, string_type *amount)
#define min(a, b)
#define NULL
Definition: freelistheap.h:34
static const std::size_t COPY_BUF_POOL_SIZE
static const std::size_t QUOTED_STR_BUF_POOL_SIZE
void extend_quoted_string_buffer(size_t new_size)
constant_type * append_constant_list(constant_type *head, constant_type *tail)
void set_in_instance_line(bool in_instance_line)
#define ARG_FILE_LINE
Definition: error_manager.h:44
bool use_copy_buf_pool(std::size_t str_size)
int i
Definition: dynamic_load.c:954
T * append_list(T *head, T *tail)
string_type * make_string_and_copy(const char *src, size_t str_size)
void extend_to(size_t total_bytes)
Definition: mem_block.hpp:346
const block_allocator EXPONENTIAL_STANDARD_BLOCK_ALLOCATOR
Definition: mem_block.cpp:94
#define LANG_SYS_CODESET
INTL_UTF8_VALIDITY intl_check_string(const char *buf, int size, char **pos, const INTL_CODESET codeset)
#define ER_INVALID_CHAR
Definition: error_code.h:1350
static const std::size_t CONSTANT_POOL_SIZE