CUBRID Engine  latest
scanner_support.c
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  * scanner_support.c - scanner support functions
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <math.h>
28 
29 #include "porting.h"
30 #include "parser_message.h"
31 
32 #define JP_MAXNAME 256
33 
34 #include "parser.h"
35 #include "chartype.h"
36 #include "language_support.h"
37 #include "intl_support.h"
38 #include "csql_grammar_scan.h"
39 #include "memory_alloc.h"
40 #include "misc_string.h"
41 
42 #define IS_WHITE_CHAR(c) \
43  ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\0')
44 
45 
46 #define IS_HINT_ON_TABLE(h) \
47  ((h) & (PT_HINT_INDEX_SS | PT_HINT_INDEX_LS))
48 
49 static char *pt_trim_as_identifier (char *name);
50 
55 extern "C"
56 {
57  extern int yycolumn;
58  extern int csql_yyget_lineno ();
59 }
60 extern int yycolumn_end;
61 
62 /*
63  * pt_makename () -
64  * return:
65  * name(in):
66  */
67 char *
68 pt_makename (const char *name)
69 {
70  return pt_append_string (this_parser, NULL, name);
71 }
72 
73 /*
74  * pt_trim_as_identifier () - trim double quotes,
75  * square brackets, or backtick symbol
76  * return:
77  * name(in):
78  */
79 static char *
81 {
82  char *tmp_name;
83  size_t len;
84 
85  len = strlen (name);
86  if (len >= 2
87  && ((name[0] == '[' && name[len - 1] == ']') || (name[0] == '`' && name[len - 1] == '`')
88  || (name[0] == '"' && name[len - 1] == '"')))
89  {
90  tmp_name = pt_makename (name);
91  tmp_name[len - 1] = '\0';
92  tmp_name += 1;
93 
94  return tmp_name;
95  }
96  else
97  {
98  return name;
99  }
100 }
101 
102 /*
103  * pt_parser_line_col () - set line and column of node allocated to
104  * current parse position
105  * return:
106  * node(in): a PT_NODE ptr
107  */
108 void
110 {
111  if (node == NULL)
112  return;
113 
114  node->line_number = csql_yyget_lineno ();
115  node->column_number = yycolumn;
116 }
117 
118 /*
119  * pt_nextchar () - called by the scanner
120  * return: c the next character from input. -1 at end of file
121  */
122 int
124 {
125  int c = (this_parser->next_char) (this_parser);
126  return c;
127 }
128 
129 
130 /*
131  * pt_cleanup_hint () - cleanup hint arg_list
132  * parser(in): parser context
133  * hint_table(in): hint table to cleanup
134  */
135 void
137 {
138  int i;
139  for (i = 0; hint_table[i].tokens; i++)
140  {
141  if (hint_table[i].arg_list != NULL)
142  {
143  parser_free_node (parser, hint_table[i].arg_list);
144  hint_table[i].arg_list = NULL;
145  }
146  }
147 }
148 
149 /*
150  * pt_get_hint () - get hint value from hint table
151  * text(in): hint text
152  * hint_table(in): hint info structure list
153  * node(in): node which will take hint context
154  */
155 void
156 pt_get_hint (const char *text, PT_HINT hint_table[], PT_NODE * node)
157 {
158  int i;
159 
160  /* read hint info */
161  for (i = 0; hint_table[i].tokens; i++)
162  {
163  if (stristr (text, hint_table[i].tokens))
164  {
165 
166  switch (hint_table[i].hint)
167  {
168  case PT_HINT_NONE:
169  break;
170  case PT_HINT_ORDERED: /* force join left-to-right */
171 
172 /* TEMPORARY COMMENTED CODE: DO NOT REMOVE ME !!! */
173 #if 0
174  node->info.query.q.select.ordered = hint_table[i].arg_list;
175  hint_table[i].arg_list = NULL;
176 #endif /* 0 */
177  if (node->node_type == PT_SELECT)
178  {
179  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
180  }
181  else if (node->node_type == PT_DELETE)
182  {
183  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
184  }
185  else if (node->node_type == PT_UPDATE)
186  {
187  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
188  }
189  break;
190  case PT_HINT_NO_INDEX_SS: /* disable index skip scan */
191  if (node->node_type == PT_SELECT)
192  {
193  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
194  }
195  break;
196  case PT_HINT_INDEX_SS:
197  if (node->node_type == PT_SELECT)
198  {
199  if (hint_table[i].arg_list != NULL && PT_IS_NULL_NODE (hint_table[i].arg_list))
200  {
201  /* For INDEX_SS(), just ignore index skip scan hint */
202  node->info.query.q.select.hint =
204  node->info.query.q.select.index_ss = NULL;
205  }
206  else
207  {
208  node->info.query.q.select.hint =
209  (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
210  node->info.query.q.select.index_ss = hint_table[i].arg_list;
211  hint_table[i].arg_list = NULL;
212  }
213  }
214  break;
215 #if 0
216  case PT_HINT_Y: /* not used */
217  break;
218 #endif /* 0 */
219  case PT_HINT_USE_NL: /* force nl-join */
220  if (node->node_type == PT_SELECT)
221  {
222  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
223  node->info.query.q.select.use_nl = hint_table[i].arg_list;
224  hint_table[i].arg_list = NULL;
225  }
226  else if (node->node_type == PT_DELETE)
227  {
228  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
229  node->info.delete_.use_nl_hint = hint_table[i].arg_list;
230  hint_table[i].arg_list = NULL;
231  }
232  else if (node->node_type == PT_UPDATE)
233  {
234  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
235  node->info.update.use_nl_hint = hint_table[i].arg_list;
236  hint_table[i].arg_list = NULL;
237  }
238  break;
239  case PT_HINT_USE_IDX: /* force idx-join */
240  if (node->node_type == PT_SELECT)
241  {
242  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
243  node->info.query.q.select.use_idx = hint_table[i].arg_list;
244  hint_table[i].arg_list = NULL;
245  }
246  else if (node->node_type == PT_DELETE)
247  {
248  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
249  node->info.delete_.use_idx_hint = hint_table[i].arg_list;
250  hint_table[i].arg_list = NULL;
251  }
252  else if (node->node_type == PT_UPDATE)
253  {
254  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
255  node->info.update.use_idx_hint = hint_table[i].arg_list;
256  hint_table[i].arg_list = NULL;
257  }
258  break;
259  case PT_HINT_USE_MERGE: /* force m-join */
260  if (node->node_type == PT_SELECT)
261  {
262  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
263  node->info.query.q.select.use_merge = hint_table[i].arg_list;
264  hint_table[i].arg_list = NULL;
265  }
266  else if (node->node_type == PT_DELETE)
267  {
268  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
269  node->info.delete_.use_merge_hint = hint_table[i].arg_list;
270  hint_table[i].arg_list = NULL;
271  }
272  else if (node->node_type == PT_UPDATE)
273  {
274  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
275  node->info.update.use_merge_hint = hint_table[i].arg_list;
276  hint_table[i].arg_list = NULL;
277  }
278  break;
279 #if 0
280  case PT_HINT_USE_HASH: /* not used */
281  break;
282 #endif /* 0 */
283  case PT_HINT_RECOMPILE: /* recompile */
284  node->flag.recompile = 1;
285  break;
286  case PT_HINT_LK_TIMEOUT: /* lock timeout */
287  if (node->node_type == PT_SELECT)
288  {
289  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
290  node->info.query.q.select.waitsecs_hint = hint_table[i].arg_list;
291  }
292  else if (node->node_type == PT_UPDATE)
293  {
294  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
295  node->info.update.waitsecs_hint = hint_table[i].arg_list;
296  }
297  else if (node->node_type == PT_DELETE)
298  {
299  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
300  node->info.delete_.waitsecs_hint = hint_table[i].arg_list;
301  }
302  else if (node->node_type == PT_INSERT)
303  {
304  node->info.insert.hint = (PT_HINT_ENUM) (node->info.insert.hint | hint_table[i].hint);
305  node->info.insert.waitsecs_hint = hint_table[i].arg_list;
306  }
307  else if (node->node_type == PT_MERGE)
308  {
309  node->info.merge.hint = (PT_HINT_ENUM) (node->info.merge.hint | hint_table[i].hint);
310  node->info.merge.waitsecs_hint = hint_table[i].arg_list;
311  }
312  hint_table[i].arg_list = NULL;
313  break;
314  case PT_HINT_NO_LOGGING: /* no logging */
315  if (node->node_type == PT_UPDATE)
316  {
317  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
318  }
319  else if (node->node_type == PT_DELETE)
320  {
321  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
322  }
323  else if (node->node_type == PT_INSERT)
324  {
325  node->info.insert.hint = (PT_HINT_ENUM) (node->info.insert.hint | hint_table[i].hint);
326  }
327  else if (node->node_type == PT_MERGE)
328  {
329  node->info.merge.hint = (PT_HINT_ENUM) (node->info.merge.hint | hint_table[i].hint);
330  }
331  hint_table[i].arg_list = NULL;
332  break;
333  case PT_HINT_QUERY_CACHE: /* query_cache */
334  if (PT_IS_QUERY_NODE_TYPE (node->node_type))
335  {
336  node->info.query.hint = (PT_HINT_ENUM) (node->info.query.hint | hint_table[i].hint);
337  node->info.query.qcache_hint = hint_table[i].arg_list;
338  if (node->info.query.qcache_hint)
339  {
340  if (atoi (node->info.query.qcache_hint->info.name.original))
341  node->info.query.flag.do_cache = 1;
342  else
343  node->info.query.flag.do_not_cache = 1;
344  }
345  else
346  {
347  node->info.query.flag.do_cache = 1;
348  }
349  }
350  hint_table[i].arg_list = NULL;
351  break;
353  if (PT_IS_QUERY_NODE_TYPE (node->node_type))
354  {
355  node->info.query.hint = (PT_HINT_ENUM) (node->info.query.hint | hint_table[i].hint);
356  node->info.query.qcache_hint = hint_table[i].arg_list;
357  /* force not use the query cache */
358  node->info.query.flag.reexecute = 1;
359  node->info.query.flag.do_cache = 0;
360  node->info.query.flag.do_not_cache = 1;
361  }
362  hint_table[i].arg_list = NULL;
363  break;
364  case PT_HINT_REEXECUTE: /* reexecute */
365  if (PT_IS_QUERY_NODE_TYPE (node->node_type))
366  {
367  node->info.query.hint = (PT_HINT_ENUM) (node->info.query.hint | hint_table[i].hint);
368  node->info.query.flag.reexecute = 1;
369  }
370  break;
371  case PT_HINT_JDBC_CACHE: /* jdbc cache */
372  if (node->node_type == PT_SELECT)
373  {
374  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
375  node->info.query.q.select.jdbc_life_time = hint_table[i].arg_list;
376  hint_table[i].arg_list = NULL;
377  }
378  break;
379  case PT_HINT_USE_IDX_DESC: /* descending index scan */
380  case PT_HINT_NO_COVERING_IDX: /* do not use covering index scan */
381  case PT_HINT_NO_IDX_DESC: /* do not use descending index scan */
382  if (node->node_type == PT_SELECT)
383  {
384  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
385  }
386  else if (node->node_type == PT_DELETE)
387  {
388  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
389  }
390  else if (node->node_type == PT_UPDATE)
391  {
392  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
393  }
394  break;
395  case PT_HINT_INSERT_MODE:
396  if (node->node_type == PT_INSERT)
397  {
398  node->info.insert.hint = (PT_HINT_ENUM) (node->info.insert.hint | hint_table[i].hint);
399  node->info.insert.insert_mode = hint_table[i].arg_list;
400  hint_table[i].arg_list = NULL;
401  }
402  break;
405  if (node->node_type == PT_SELECT)
406  {
407  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
408  }
409  else if (node->node_type == PT_DELETE)
410  {
411  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
412  }
413  else if (node->node_type == PT_UPDATE)
414  {
415  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
416  }
417  break;
419  if (node->node_type == PT_MERGE)
420  {
421  node->info.merge.hint = (PT_HINT_ENUM) (node->info.merge.hint | hint_table[i].hint);
422  node->info.merge.update.index_hint = hint_table[i].arg_list;
423  hint_table[i].arg_list = NULL;
424  }
425  break;
427  if (node->node_type == PT_MERGE)
428  {
429  node->info.merge.hint = (PT_HINT_ENUM) (node->info.merge.hint | hint_table[i].hint);
430  node->info.merge.insert.index_hint = hint_table[i].arg_list;
431  hint_table[i].arg_list = NULL;
432  }
433  break;
435  if (node->node_type == PT_SELECT)
436  {
437  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
438  }
439  break;
441  if (node->node_type == PT_SELECT)
442  {
443  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
444  }
445  break;
447  if (node->node_type == PT_ALTER)
448  {
449  node->info.alter.hint = (PT_HINT_ENUM) (node->info.alter.hint | hint_table[i].hint);
450  }
451  break;
452  case PT_HINT_NO_INDEX_LS: /* disable loose index scan */
453  if (node->node_type == PT_SELECT)
454  {
455  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
456  }
457  break;
458  case PT_HINT_INDEX_LS: /* enable loose index scan */
459  if (node->node_type == PT_SELECT)
460  {
461  if (hint_table[i].arg_list != NULL && PT_IS_NULL_NODE (hint_table[i].arg_list))
462  {
463  /* For INDEX_LS(), just ignore loose index scan hint */
464  node->info.query.q.select.hint =
466  node->info.query.q.select.index_ls = NULL;
467  }
468  else
469  {
470  node->info.query.q.select.hint =
472  node->info.query.q.select.index_ls = hint_table[i].arg_list;
473  hint_table[i].arg_list = NULL;
474  }
475  }
476  break;
479  if (node->node_type == PT_SELECT)
480  {
481  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
482  }
483  break;
486  if (node->node_type == PT_SELECT)
487  {
488  /* SELECT_KEY_INFO hint can work if it has one and only one index name as argument. Same for
489  * SELECT_BTREE_NODE_INFO. Ignore hint if this condition is not met. */
490  if (hint_table[i].arg_list == NULL || hint_table[i].arg_list->next != NULL)
491  {
492  break;
493  }
494  node->info.query.q.select.hint = (PT_HINT_ENUM) (node->info.query.q.select.hint | hint_table[i].hint);
495  node->info.query.q.select.using_index = hint_table[i].arg_list;
496  hint_table[i].arg_list = NULL;
497  }
498  break;
499  case PT_HINT_USE_SBR: /* statement-based replication */
500  if (node->node_type == PT_INSERT)
501  {
502  node->info.insert.hint = (PT_HINT_ENUM) (node->info.insert.hint | hint_table[i].hint);
503  }
504  else if (node->node_type == PT_DELETE)
505  {
506  node->info.delete_.hint = (PT_HINT_ENUM) (node->info.delete_.hint | hint_table[i].hint);
507  }
508  else if (node->node_type == PT_UPDATE)
509  {
510  node->info.update.hint = (PT_HINT_ENUM) (node->info.update.hint | hint_table[i].hint);
511  }
512  break;
513  default:
514  break;
515  }
516  }
517  } /* for (i = ... ) */
518 }
519 
520 /*
521  * pt_check_hint () - search hint comment from hint table
522  * text(in): hint comment
523  * hint_table(in): hint info structure list
524  * result_hint(in): found result
525  * prev_is_white_char(in): flag indicates prev char
526  */
527 void
528 pt_check_hint (const char *text, PT_HINT hint_table[], PT_HINT_ENUM * result_hint, bool prev_is_white_char)
529 {
530  int i, j, len, count;
531  PT_HINT_ENUM hint;
532  char hint_buf[JP_MAXNAME];
533  char *hint_p, *arg_start, *arg_end, *temp;
534  PT_NODE *arg;
535  bool has_parenthesis;
536 
537  for (i = 0; hint_table[i].tokens; i++)
538  {
539  count = 0; /* init */
540  hint = PT_HINT_NONE; /* init */
541  strncpy (hint_buf, text, JP_MAXNAME);
542  hint_buf[JP_MAXNAME - 1] = '\0';
543  hint_p = ustr_casestr (hint_buf, hint_table[i].tokens);
544 
545  while (hint_p)
546  {
547  has_parenthesis = false;
548  len = (int) strlen (hint_table[i].tokens);
549  /* check token before */
550  if ((count == 0 && (prev_is_white_char || (hint_p > hint_buf && IS_WHITE_CHAR (*(hint_p - 1)))))
551  || IS_WHITE_CHAR (*(hint_p - 1)))
552  {
553  hint_p += len; /* consume token */
554  /* check token after */
555  if (IS_WHITE_CHAR (*(hint_p)))
556  { /* no arguments */
557  /* found specified hint */
558  hint = hint_table[i].hint;
559  }
560  else if (*(hint_p) == '(')
561  { /* need to check for argument */
562  has_parenthesis = true;
563  hint_p++; /* consume '(' */
564  arg_start = hint_p;
565  arg_end = strstr (arg_start, ")");
566  /* check arguments */
567  if (arg_end && ((len = CAST_STRLEN (arg_end - arg_start)) > 0))
568  {
569  for (j = 0; j < len; j++)
570  {
571  if (hint_p[j] == '(')
572  {
573  /* illegal hint expression */
574  break;
575  }
576  if (hint_p[j] == ',')
577  { /* found delimiter */
578  hint_p[j] = '\0'; /* replace ',' */
579  /* trim space around found spec name */
580  for (; arg_start < &(hint_p[j]); arg_start++)
581  {
582  if (!IS_WHITE_CHAR (*arg_start))
583  {
584  break;
585  }
586  }
587  for (temp = &(hint_p[j - 1]); temp > arg_start; temp--)
588  {
589  if (!IS_WHITE_CHAR (*temp))
590  {
591  break;
592  }
593  *temp = '\0'; /* counsume space */
594  }
595  /* add specified spec */
596  if (arg_start < &(hint_p[j]))
597  {
598  arg = parser_new_node (this_parser, PT_NAME);
599  if (arg)
600  {
601  temp = strstr (arg_start, ".");
602  if (temp && temp < &(hint_p[j]) && !IS_HINT_ON_TABLE (hint_table[i].hint))
603  {
604  *temp = '\0';
605  arg->info.name.resolved = pt_trim_as_identifier (arg_start);
607  *temp++ = '.';
608  arg->info.name.original = pt_trim_as_identifier (temp);
610  }
611  else
612  {
613  arg->info.name.original = pt_trim_as_identifier (arg_start);
615  }
617  hint_table[i].arg_list = parser_append_node (arg, hint_table[i].arg_list);
618  }
619  }
620  arg_start = &(hint_p[j + 1]);
621  }
622  } /* for (j = ... ) */
623 
624  if (j < len)
625  {
626  /* error occurs. free alloced nodes */
627  if (hint_table[i].arg_list)
628  {
629  parser_free_tree (this_parser, hint_table[i].arg_list);
630  hint_table[i].arg_list = NULL;
631  }
632  /* consume illegal hint expression */
633  hint_p += j + 1;
634  }
635  else
636  { /* OK */
637  /* check last argument */
638  hint_p[j] = '\0'; /* replace ')' */
639  /* trim space around found spec name */
640  for (; arg_start < &(hint_p[j]); arg_start++)
641  {
642  if (!IS_WHITE_CHAR (*arg_start))
643  {
644  break;
645  }
646  }
647  for (temp = &(hint_p[j - 1]); temp > arg_start; temp--)
648  {
649  if (!IS_WHITE_CHAR (*temp))
650  {
651  break;
652  }
653  *temp = '\0'; /* counsume space */
654  }
655  if (arg_start < &(hint_p[j]))
656  {
657  arg = parser_new_node (this_parser, PT_NAME);
658  if (arg)
659  {
660  temp = strstr (arg_start, ".");
661  if (temp && temp < &(hint_p[j]) && !IS_HINT_ON_TABLE (hint_table[i].hint))
662  {
663  *temp = '\0';
664  arg->info.name.resolved = pt_trim_as_identifier (arg_start);
666  *temp++ = '.';
667  arg->info.name.original = pt_trim_as_identifier (temp);
669  }
670  else
671  {
672  arg->info.name.original = pt_trim_as_identifier (arg_start);
674  }
676  hint_table[i].arg_list = parser_append_node (arg, hint_table[i].arg_list);
677  }
678  }
679 
680  hint_p += len; /* consume arguments */
681  hint_p++; /* consume ')' */
682  }
683  }
684 
685  /* found specified hint */
686  if (hint_table[i].arg_list)
687  {
688  hint = hint_table[i].hint;
689  }
690  else if (has_parenthesis && IS_HINT_ON_TABLE (hint_table[i].hint))
691  {
692  /*
693  * INDEX_SS() or INDEX_LS() means do not apply
694  * hint, use special node to mark this.
695  */
696  arg = parser_new_node (this_parser, PT_VALUE);
697  if (arg)
698  {
699  arg->type_enum = PT_TYPE_NULL;
700  }
701  hint_table[i].arg_list = arg;
702  }
703  }
704  }
705  else
706  {
707  /* not found specified hint */
708  hint_p += len; /* consume token */
709  }
710 
711  /* check for found specified hint */
712  if (hint & hint_table[i].hint)
713  {
714  /* save hint and immediately stop */
715  *result_hint = (PT_HINT_ENUM) (*result_hint | hint);
716  break;
717  }
718 
719  count++;
720 
721  /* step to next */
722  hint_p = ustr_casestr (hint_p, hint_table[i].tokens);
723 
724  } /* while (hint_p) */
725  } /* for (i = ... ) */
726 }
int yycolumn_end
PT_NAME_INFO name
Definition: parse_tree.h:3318
PT_HINT_ENUM hint
Definition: parse_tree.h:2877
PT_UPDATE_INFO update
Definition: parse_tree.h:3353
PT_MERGE_INFO merge
Definition: parse_tree.h:3315
#define IS_HINT_ON_TABLE(h)
PT_STATEMENT_INFO info
Definition: parse_tree.h:3487
PT_HINT_ENUM hint
Definition: parse_tree.h:1745
PT_NODE * using_index
Definition: parse_tree.h:2693
PT_NODE * waitsecs_hint
Definition: parse_tree.h:2701
PT_NODE * waitsecs_hint
Definition: parse_tree.h:2339
static char * pt_trim_as_identifier(char *name)
PT_NODE * arg_list
Definition: parse_tree.h:1744
int parser_output_host_index
PT_NODE * index_hint
Definition: parse_tree.h:2931
void pt_cleanup_hint(PARSER_CONTEXT *parser, PT_HINT hint_table[])
PT_HINT_ENUM hint
Definition: parse_tree.h:2340
PT_HINT_ENUM hint
Definition: parse_tree.h:2074
PT_MISC_TYPE meta_class
Definition: parse_tree.h:2552
int parser_input_host_index
struct pt_query_info::@123 flag
union pt_query_info::@124 q
char * pt_makename(const char *name)
#define CAST_STRLEN
Definition: porting.h:470
struct pt_merge_info::@125 update
#define PT_IS_NULL_NODE(e)
Definition: parse_tree.h:122
PT_NODE * jdbc_life_time
Definition: parse_tree.h:2702
PT_NODE * insert_mode
Definition: parse_tree.h:2343
PT_INT_FUNCTION next_char
Definition: parse_tree.h:3532
int csql_yyget_lineno()
char * stristr(const char *s, const char *find)
Definition: porting.c:1242
PT_NODE * index_ss
Definition: parse_tree.h:2698
#define JP_MAXNAME
PT_TYPE_ENUM type_enum
Definition: parse_tree.h:3457
PT_NODE * use_merge_hint
Definition: parse_tree.h:2071
void pt_check_hint(const char *text, PT_HINT hint_table[], PT_HINT_ENUM *result_hint, bool prev_is_white_char)
PT_ALTER_INFO alter
Definition: parse_tree.h:3268
PT_HINT_ENUM
Definition: parse_tree.h:1161
PT_NODE * use_nl_hint
Definition: parse_tree.h:2871
#define PT_IS_QUERY_NODE_TYPE(x)
Definition: parse_tree.h:115
#define IS_WHITE_CHAR(c)
const char * tokens
Definition: parse_tree.h:1743
const char * original
Definition: parse_tree.h:2544
PT_HINT_ENUM hint
Definition: parse_tree.h:2707
PT_NODE_TYPE node_type
Definition: parse_tree.h:3439
unsigned do_cache
Definition: parse_tree.h:2763
PT_HINT_ENUM hint
Definition: parse_tree.h:1828
PT_NODE * use_merge_hint
Definition: parse_tree.h:2873
SP_PARSER_CTX * parser
#define NULL
Definition: freelistheap.h:34
PT_NODE * use_nl_hint
Definition: parse_tree.h:2069
unsigned recompile
Definition: parse_tree.h:3461
char * pt_append_string(const PARSER_CONTEXT *parser, const char *old_string, const char *new_tail)
Definition: parse_tree.c:980
PT_NODE * qcache_hint
Definition: parse_tree.h:2772
PARSER_CONTEXT * this_parser
PT_QUERY_INFO query
Definition: parse_tree.h:3325
int yycolumn
PT_NODE * use_idx
Definition: parse_tree.h:2697
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
PT_NODE * use_idx_hint
Definition: parse_tree.h:2872
PT_NODE * parser_append_node(PT_NODE *node, PT_NODE *list)
unsigned do_not_cache
Definition: parse_tree.h:2764
PT_NODE * parser_new_node(PARSER_CONTEXT *parser, PT_NODE_TYPE node_type)
void parser_free_node(const PARSER_CONTEXT *parser, PT_NODE *node)
Definition: parse_tree.c:869
void pt_parser_line_col(PT_NODE *node)
PT_NODE * waitsecs_hint
Definition: parse_tree.h:2944
PT_NODE * index_ls
Definition: parse_tree.h:2699
void parser_free_tree(PARSER_CONTEXT *parser, PT_NODE *tree)
PT_NODE * use_idx_hint
Definition: parse_tree.h:2070
struct pt_merge_info::@126 insert
#define strlen(s1)
Definition: intl_support.c:43
char * ustr_casestr(const char *s1, const char *s2)
Definition: misc_string.c:41
PT_DELETE_INFO delete_
Definition: parse_tree.h:3285
PT_NODE * waitsecs_hint
Definition: parse_tree.h:2067
PT_NODE * ordered
Definition: parse_tree.h:2695
int i
Definition: dynamic_load.c:954
PT_NODE * use_merge
Definition: parse_tree.h:2700
int pt_nextchar(void)
PT_HINT_ENUM hint
Definition: parse_tree.h:2945
const char * resolved
Definition: parse_tree.h:2545
PT_NODE * use_nl
Definition: parse_tree.h:2696
int column_number
Definition: parse_tree.h:3442
struct parser_node::@132 flag
PT_SELECT_INFO select
Definition: parse_tree.h:2781
int parser_statement_OK
PT_INSERT_INFO insert
Definition: parse_tree.h:3309
unsigned reexecute
Definition: parse_tree.h:2762
void pt_get_hint(const char *text, PT_HINT hint_table[], PT_NODE *node)
PT_NODE * waitsecs_hint
Definition: parse_tree.h:2869
PT_HINT_ENUM hint
Definition: parse_tree.h:2776