CUBRID Engine  latest
parse_evaluate.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  * parse_evaluate.c - Helper functions to interprets tree and
21  * returns its result as a DB_VALUE
22  */
23 
24 #ident "$Id$"
25 
26 #include "config.h"
27 
28 #include <assert.h>
29 
30 #include "porting.h"
31 #include "error_manager.h"
32 #include "parser.h"
33 #include "cursor.h"
34 #include "memory_alloc.h"
35 #include "memory_hash.h"
36 #include "parser_message.h"
37 #include "execute_statement.h"
38 #include "object_domain.h"
39 #include "object_primitive.h"
40 #include "object_template.h"
41 #include "work_space.h"
42 #include "virtual_object.h"
43 #include "server_interface.h"
44 #include "arithmetic.h"
45 #include "parser_support.h"
46 #include "view_transform.h"
47 #include "network_interface_cl.h"
48 #include "transform.h"
49 #include "dbtype.h"
50 
51 /* associates labels with DB_VALUES */
53 
54 static int pt_is_table_op (const PT_OP_TYPE op);
56 static DB_VALUE *pt_set_table_to_db (PARSER_CONTEXT * parser, PT_NODE * subquery_in, DB_VALUE * db_value, int is_seq);
57 #if defined(ENABLE_UNUSED_FUNCTION)
58 static int pt_make_label_list (const void *key, void *data, void *args);
59 #endif /* ENABLE_UNUSED_FUNCTION */
60 static int pt_free_label (const void *key, void *data, void *args);
61 static int pt_associate_label_with_value (const char *label, DB_VALUE * val);
62 static void pt_evaluate_tree_internal (PARSER_CONTEXT * parser, PT_NODE * tree, DB_VALUE * db_values, int values_count,
63  bool having_serial);
64 
65 
66 /*
67  * pt_is_table_op () -
68  * return: 1, if its a table operator, 0 otherwise.
69  * op(in): an expression operator
70  */
71 
72 static int
74 {
75  switch (op)
76  {
77  case PT_GE_SOME:
78  case PT_GT_SOME:
79  case PT_LT_SOME:
80  case PT_LE_SOME:
81  case PT_GE_ALL:
82  case PT_GT_ALL:
83  case PT_LT_ALL:
84  case PT_LE_ALL:
85  case PT_EQ_SOME:
86  case PT_NE_SOME:
87  case PT_EQ_ALL:
88  case PT_NE_ALL:
89  case PT_IS_IN:
90  case PT_IS_NOT_IN:
91  return 1;
92 
93  default:
94  return 0;
95  }
96 }
97 
98 /*
99  * pt_query_to_set_table () -
100  * return: if node is a query, returns a table to set function
101  * on that query. Otherwise, returns node.
102  * parser(in):
103  * node(in):
104  */
105 
106 static PT_NODE *
108 {
109  PT_NODE *result;
110 
111  result = node;
112  if (node && PT_IS_QUERY_NODE_TYPE (node->node_type))
113  {
114  result = parser_new_node (parser, PT_FUNCTION);
115  result->line_number = node->line_number;
116  result->column_number = node->column_number;
118  result->info.function.arg_list = node;
119  }
120 
121  return result;
122 }
123 
124 /*
125  * pt_set_table_to_db () - add subquery elements into a DB_VALUE set/multiset
126  * return: db_value if all OK, NULL otherwise.
127  * parser(in): handle to parser context
128  * subquery(in): the subquery to be inserted
129  * db_value(out): a set or multiset value container
130  */
131 
132 static DB_VALUE *
134 {
135  DB_VALUE *vals = NULL, *e_val;
136  QFILE_LIST_ID *list_id = NULL;
138  int cursor_status, degree = 0, col;
139  PT_NODE *select_list = NULL, *subquery;
140  QUERY_ID query_id_self = parser->query_id;
141  int error = NO_ERROR;
142 
143  subquery = parser_copy_tree (parser, subquery_in);
144 
145  subquery = mq_translate (parser, subquery);
146  if (subquery == NULL)
147  {
148  return NULL;
149  }
150 
151  query_id_self = parser->query_id;
152  parser->query_id = NULL_QUERY_ID;
153  error = do_select (parser, subquery);
154  if (error == NO_ERROR)
155  {
156  list_id = (QFILE_LIST_ID *) subquery->etc;
157  select_list = pt_get_select_list (parser, subquery);
158  }
159  else
160  {
161  PT_ERRORc (parser, subquery, db_error_string (3));
162  error = -1;
163  }
164 
165  if (error == NO_ERROR)
166  {
167  degree = pt_length_of_select_list (select_list, EXCLUDE_HIDDEN_COLUMNS);
168  if ((vals = (DB_VALUE *) malloc (degree * sizeof (DB_VALUE))) == NULL)
169  {
171  error = -1;
172  }
173  for (col = 0; vals && col < degree; col++)
174  {
175  db_make_null (&vals[col]);
176  }
177  }
178 
179  if (!(error < 0))
180  {
181  /*
182  * the above select resulted in a list file put on subquery->etc
183  * open it and add the elements to the set.
184  */
185  if (cursor_open (&cursor_id, list_id, false, false))
186  {
187  int idx;
188  DB_SET *collection;
189 
190  cursor_id.query_id = parser->query_id;
191 
192  cursor_status = cursor_next_tuple (&cursor_id);
193 
194  idx = 0;
195  collection = db_get_set (db_value);
196 
197  while (error >= 0 && cursor_status == DB_CURSOR_SUCCESS)
198  {
199  error = cursor_get_tuple_value_list (&cursor_id, degree, vals);
200 
201  for (e_val = vals, col = 0; error >= 0 && col < degree; e_val++, col++, idx++)
202  {
203  if (is_seq)
204  {
205  error = db_seq_put (collection, idx, e_val);
206  }
207  else
208  {
209  error = db_set_add (collection, e_val);
210  }
211  }
212 
213  if (error >= 0)
214  {
215  cursor_status = cursor_next_tuple (&cursor_id);
216  }
217  }
218 
219  if (error >= 0 && cursor_status != DB_CURSOR_END)
220  {
221  error = ER_GENERIC_ERROR;
222  }
223  cursor_close (&cursor_id);
224  }
225  }
226 
227  cursor_free_self_list_id (list_id);
228 
229  pt_end_query (parser, query_id_self);
230 
231  if (vals)
232  {
233  for (col = 0; col < degree; col++)
234  {
235  pr_clear_value (&vals[col]);
236  }
237  free_and_init (vals);
238  }
239 
240  if (error != NO_ERROR)
241  {
242  PT_ERRORc (parser, subquery, db_error_string (3));
243  db_value = NULL;
244  }
245 
246  parser_free_tree (parser, subquery);
247 
248  return db_value;
249 }
250 
251 /*
252  * pt_eval_path_expr () - evaluate a path expr into a db_value
253  * return: 1 if all OK, 0 otherwise
254  * parser(in): the parser context
255  * tree(in): a path expression
256  * val(out): a newly set DB_VALUE if successful, untouched otherwise
257  */
258 bool
260 {
261  bool result = true;
262  PT_NODE *arg1, *arg2;
263  DB_VALUE val1, *valp;
264  DB_OBJECT *obj1;
265  const char *nam2;
266  const char *label;
267  int is_class = 0;
268 
269  assert (parser != NULL);
270  db_make_null (&val1);
271 
272  if (tree == NULL || val == NULL)
273  {
274  return false;
275  }
276 
277  switch (tree->node_type)
278  {
279  case PT_DOT_:
280  if ((arg1 = tree->info.dot.arg1) != NULL && (arg2 = tree->info.dot.arg2) != NULL && arg2->node_type == PT_NAME
281  && (nam2 = arg2->info.name.original) != NULL)
282  {
283  pt_evaluate_tree (parser, arg1, &val1, 1);
284  if (pt_has_error (parser))
285  {
287  result = false;
288  }
289  else if (DB_VALUE_TYPE (&val1) == DB_TYPE_NULL)
290  {
291  result = true;
292  }
293  else if (DB_VALUE_TYPE (&val1) == DB_TYPE_OBJECT && (obj1 = db_get_object (&val1)) != NULL)
294  {
295  int error;
296 
297  error = db_get (obj1, nam2, val);
298  if (error == ER_AU_SELECT_FAILURE || error == ER_AU_AUTHORIZATION_FAILURE)
299  {
300  DB_OBJECT *class_op;
301 
302  class_op = db_get_class (obj1);
304  ((class_op) ? db_get_class_name (class_op) : pt_short_print (parser, arg1)));
305  }
306 
307  result = (error == NO_ERROR);
308  }
309  else
310  {
311  result = false;
312  }
313  }
314  break;
315 
316  case PT_NAME:
317  /* find & return obj associated with this label */
318  label = tree->info.name.original;
319  if (!label)
320  {
321  PT_ERRORf (parser, tree, "Internal error evaluate(%d)", __LINE__);
322  break;
323  }
324  obj1 = tree->info.name.db_object;
325 
326  switch (tree->info.name.meta_class)
327  {
328  case PT_PARAMETER:
329  valp = pt_find_value_of_label (label);
330  if (valp)
331  {
332  (void) db_value_clone (valp, val);
333  }
334  else
335  {
337  }
338  break;
339 
340  case PT_OID_ATTR:
341  case PT_VID_ATTR:
342  db_make_object (val, obj1);
343  break;
344 
345  case PT_TRIGGER_OID:
346  db_make_object (val, obj1);
347  /* check if this is really a path expression */
348  if (((nam2 = tree->info.name.original) != NULL) && (nam2[0] != '\0'))
349  {
350  result = (db_get (obj1, nam2, val) == NO_ERROR);
351  }
352  break;
353 
354  case PT_META_CLASS:
355  case PT_CLASSOID_ATTR:
356  /* object is the class itself */
357  db_make_object (val, obj1);
358  is_class = db_is_any_class (obj1);
359  if (is_class < 0)
360  {
361  result = false;
362  }
363  else if (!is_class)
364  {
366  pt_short_print (parser, tree));
367  }
368  break;
369 
370  case PT_SHARED:
371  {
372  DB_ATTRIBUTE *s_attr;
373 
374  s_attr = (DB_ATTRIBUTE *) db_get_shared_attribute (obj1, label);
375  if (s_attr)
376  {
377  valp = (DB_VALUE *) db_attribute_default (s_attr);
378  }
379  else
380  {
381  valp = NULL;
382  }
383 
384  if (valp != NULL)
385  {
386  (void) db_value_clone (valp, val);
387  }
388  else
389  {
391  }
392  }
393  break;
394 
395  case PT_META_ATTR:
396  case PT_NORMAL:
397  default:
398  if (db_get (obj1, label, val) != NO_ERROR)
399  {
401  pt_short_print (parser, tree));
402  }
403  }
404  break;
405 
406  default:
407  PT_INTERNAL_ERROR (parser, "name evaluate");
408  break;
409  }
410 
411  return (result && !pt_has_error (parser));
412 }
413 
414 /*
415  * pt_get_one_tuple_from_list_id () - return 1st tuple of a given list_id
416  * return: 1 if all OK, 0 otherwise
417  * parser(in): the parser context
418  * tree(in): a select/union/difference/intersection
419  * vals(out): an array of DB_VALUEs
420  * cnt(in): number of columns in the requested tuple
421  */
422 int
424 {
425  QFILE_LIST_ID *list_id;
427  int result = 0;
428  PT_NODE *select_list;
429 
430  assert (parser != NULL);
431 
432  if (!tree || !vals || !(list_id = (QFILE_LIST_ID *) (tree->etc))
433  || !(select_list = pt_get_select_list (parser, tree)))
434  return result;
435 
436  if (cursor_open (&cursor_id, list_id, false, tree->info.query.oids_included))
437  {
438  /* succesfully opened a cursor */
439  cursor_id.query_id = parser->query_id;
440 
441  if (cursor_next_tuple (&cursor_id) != DB_CURSOR_SUCCESS
442  || cursor_get_tuple_value_list (&cursor_id, cnt, vals) != NO_ERROR)
443  {
444  /*
445  * This isn't really an error condition, especially when we are in an
446  * esql context. Just say that we didn't succeed, which should be
447  * enough to keep upper levels from trying to do anything with the
448  * result, but don't report an error.
449  */
450  result = 0;
451  }
452  else if (cursor_next_tuple (&cursor_id) == DB_CURSOR_SUCCESS)
453  {
454  char query_prefix[65], *p;
455 
456  p = parser_print_tree (parser, tree);
457  if (p == NULL)
458  {
459  query_prefix[0] = '\0';
460  }
461  else
462  {
463  strncpy (query_prefix, p, 60);
464  if (query_prefix[59])
465  {
466  query_prefix[60] = '\0';
467  strcat (query_prefix, "...");
468  }
469  }
470 
471  PT_ERRORmf (parser, select_list, MSGCAT_SET_PARSER_RUNTIME, MSGCAT_RUNTIME_YIELDS_GT_ONE_ROW, query_prefix);
472  }
473  else
474  {
475  result = 1; /* all OK */
476  }
477 
478  cursor_close (&cursor_id);
479  }
480 
481  return result;
482 }
483 
484 /*
485  * pt_associate_label_with_value () - enter a label with associated value
486  * into label_table
487  * return: NO_ERROR on success, non-zero for ERROR
488  * label(in): a string (aka interpreter variable) to be associated with val
489  * val(in): the DB_VALUE to be associated with label
490  */
491 
492 static int
493 pt_associate_label_with_value (const char *label, DB_VALUE * val)
494 {
495  const char *key;
496  DB_VALUE *oldval;
497  MOP mop;
498 
499  /* create label table if non-existent */
500  if (!pt_Label_table)
501  {
502  pt_Label_table =
504 
505  if (!pt_Label_table)
506  {
507  assert (er_errid () != NO_ERROR);
508  return er_errid ();
509  }
510  }
511 
512  assert (label != NULL && val != NULL);
513 
514  /* see if we already have a value for this label */
515  oldval = (DB_VALUE *) mht_get (pt_Label_table, label);
516  if (oldval == NULL)
517  {
518  /* create a copy of the label */
519  key = ws_copy_string ((char *) label);
520  if (key == NULL)
521  {
523  }
524 
525  /* enter {label, val} as a {key, value} pair into label_table */
526  if (mht_put (pt_Label_table, (char *) key, (void *) val) == NULL)
527  {
528  assert (er_errid () != NO_ERROR);
529  return er_errid ();
530  }
531 
532  if (DB_VALUE_TYPE ((DB_VALUE *) val) == DB_TYPE_OBJECT)
533  {
534  mop = db_get_object (val);
535  ws_add_label_value_to_mop (mop, val);
536  }
537  }
538  else
539  {
540  /* Sigh, the old key value was allocated too and needs to be freed or reused. We don't currently have a way to
541  * get the current key pointer in the table. mht_put has the undocumented behavior that if the key already exists
542  * in the table, it will continue to use the old key and ignore the one passed in. We rely on this here by
543  * passing in the label string which we don't own. If this mht_put behavior changes, then the only safe way will
544  * be to add a new mht_ function that allows us to get a pointer to the key so we can free it. */
545  if (mht_put_data (pt_Label_table, (char *) label, (void *) val) == NULL)
546  {
547  assert (er_errid () != NO_ERROR);
548  return er_errid ();
549  }
550 
551  if (DB_VALUE_TYPE ((DB_VALUE *) val) == DB_TYPE_OBJECT)
552  {
553  mop = db_get_object (val);
554  if (ws_add_label_value_to_mop (mop, val) != NO_ERROR)
555  {
556  assert (er_errid () != NO_ERROR);
557  return er_errid ();
558  }
559  }
560 
561  if (DB_VALUE_TYPE (oldval) == DB_TYPE_OBJECT)
562  {
563  mop = db_get_object (oldval);
564  ws_remove_label_value_from_mop (mop, oldval);
565  }
566 
567  /* if the insertion went well, free the old value */
568  db_value_free (oldval);
569  }
570 
571  return NO_ERROR;
572 }
573 
574 /*
575  * pt_associate_label_with_value_check_reference () - enter a label with
576  * associated value into label_table
577  * return: NO_ERROR on success, non-zero for ERROR
578  * label(in): a string (aka interpreter variable) to be associated with val
579  * val(in): the DB_VALUE to be associated with label
580  *
581  * Note:
582  * If it is passed an instance pointer in the val parameter the function also
583  * checks that it does not point to a reusable OID class instance. This is
584  * done in order to prevent accidental modifications on a different instance
585  * if the OID is reused.
586  */
587 
588 int
590 {
591  int is_ref = pt_is_reference_to_reusable_oid (val);
592  if (is_ref < 0)
593  {
594  return is_ref;
595  }
596  if (is_ref > 0)
597  {
600  }
601  return pt_associate_label_with_value (label, val);
602 }
603 
604 /*
605  * pt_is_reference_to_reusable_oid () - Returns true if the value passed in
606  * is an instance of a reusable OID class
607  * return: < 0 if error, > 0 if the value is an instance of a reusable OID
608  * class, == 0 otherwise
609  * val(in):
610  * Note:
611  * Instances of reusable OID classes are non-referable. References to such
612  * instances should be only used internally by the server/client process with
613  * great care.
614  */
615 int
617 {
618  DB_OBJECT *obj_class = NULL;
619  DB_TYPE vtype = DB_TYPE_NULL;
620 
621  int ret_val = false;
622 
623  if (val == NULL)
624  {
625  return 0;
626  }
627 
628  vtype = DB_VALUE_TYPE (val);
629 
630  if (vtype == DB_TYPE_OBJECT)
631  {
632  DB_OBJECT *obj = db_get_object (val);
633  int is_class = 0;
634 
635  if (obj == NULL)
636  {
637  return 0;
638  }
639 
640  is_class = db_is_class (obj);
641  if (is_class < 0)
642  {
643  return is_class;
644  }
645  if (is_class > 0)
646  {
647  return 0;
648  }
649 
650  obj_class = db_get_class (obj);
651  if (obj_class == NULL)
652  {
653  return 0;
654  }
655  }
656  else if (vtype == DB_TYPE_POINTER)
657  {
658  DB_OTMPL *obj_tmpl = (DB_OTMPL *) db_get_pointer (val);
659 
660  if (obj_tmpl == NULL)
661  {
662  return 0;
663  }
664 
665  obj_class = obj_tmpl->classobj;
666  if (obj_class == NULL)
667  {
668  return 0;
669  }
670  }
671  else
672  {
673  return 0;
674  }
675 
676  ret_val = sm_check_reuse_oid_class (obj_class);
677 
678  if (ret_val < NO_ERROR)
679  {
680  return ret_val;
681  }
682 
683  if (ret_val != 0)
684  {
685  return 1;
686  }
687 
688  return 0;
689 }
690 
691 /*
692  * pt_find_value_of_label () - find label in label_table &
693  * return its associated value
694  * return: the DB_VALUE associated with label if found, NULL otherwise.
695  * label(in): a string (aka interpreter variable) to be used as a search key
696  *
697  * Note :
698  * The value returned here is "owned" by the table and will be freed
699  * if another assignment is made to this label. If the lifespan of
700  * the reference in the calling function is long and can span statement
701  * boundaries, you may need to copy the value.
702  */
703 
704 DB_VALUE *
705 pt_find_value_of_label (const char *label)
706 {
707  DB_VALUE *db_valp;
708 
709  if (!pt_Label_table || !label)
710  {
711  return NULL;
712  }
713  else
714  {
715  db_valp = (DB_VALUE *) mht_get (pt_Label_table, label);
716  if (db_valp != NULL && DB_VALUE_TYPE (db_valp) == DB_TYPE_OBJECT)
717  {
718  db_valp = vid_flush_and_rehash_lbl (db_valp);
719  }
720  return db_valp;
721  }
722 }
723 
724 #if defined(ENABLE_UNUSED_FUNCTION)
725 /*
726  * pt_make_label_list () - adds key value to a list of names
727  * return: NO_ERROR (keep going) or allocation error
728  * key(in): search key to the interpreter variable table
729  * data(in): a DB_VALUE associated with the key (not used)
730  * args(in): generic pointer to the list
731  *
732  * Note :
733  * called by pt_find_labels() and should not be called directly.
734  */
735 
736 static int
737 pt_make_label_list (const void *key, void *data, void *args)
738 {
739  DB_NAMELIST **list = (DB_NAMELIST **) args;
740  DB_NAMELIST *new_;
741 
742  assert (key != NULL);
743 
744  new_ = (DB_NAMELIST *) db_ws_alloc (sizeof (DB_NAMELIST));
745  if (new_ == NULL)
746  {
747  assert (er_errid () != NO_ERROR);
748  return er_errid ();
749  }
750 
751  new_->name = ws_copy_string ((char *) key);
752  if (new_->name == NULL)
753  {
754  db_ws_free (new_);
755 
756  assert (er_errid () != NO_ERROR);
757  return er_errid ();
758  }
759 
760  new_->next = *list;
761  *list = new_;
762 
763  return (NO_ERROR);
764 }
765 
766 /*
767  * pt_find_labels () - Sets a pointer to a list of all session interpreter
768  * variable labels
769  * return: NO_ERROR on success, non-zero for ERROR
770  * list(in): address of pointer to list of interpreter variable labels
771  *
772  * Note :
773  * The list returned by this function must later be freed by nlist_free.
774  */
775 
776 int
777 pt_find_labels (DB_NAMELIST ** list)
778 {
779  int error = NO_ERROR;
780 
781  *list = NULL;
782 
783  if (pt_Label_table)
784  {
785  /* notice that we are checking for true instead of NO_ERROR. The function mht_map() requires true for normal
786  * processing. Non-true values should be considered errors. We change true to NO_ERROR for our return value
787  * here so the caller doesn't get confused. */
788  if ((error = mht_map (pt_Label_table, pt_make_label_list, (void *) list)) != NO_ERROR)
789  {
790  nlist_free (*list);
791  *list = NULL;
792  }
793  else
794  {
795  error = NO_ERROR;
796  }
797  }
798 
799  return (error);
800 }
801 #endif /* ENABLE_UNUSED_FUNCTION */
802 
803 /*
804  * do_drop_variable () - remove interpreter variable(s) from the label table
805  * return: NO_ERROR on success, non-zero for ERROR
806  * parser(in): the parser context
807  * stmt(in): a drop variable statement
808  */
809 
810 int
812 {
813  PT_NODE *lbl;
814 
815  assert (parser != NULL);
816 
817  if (!stmt || stmt->node_type != PT_DROP_VARIABLE)
818  {
819  return NO_ERROR;
820  }
821 
822  for (lbl = stmt->info.drop_variable.var_names; lbl && lbl->node_type == PT_NAME; lbl = lbl->next)
823  {
824  if (!pt_Label_table || (mht_rem (pt_Label_table, lbl->info.name.original, pt_free_label, NULL) != NO_ERROR))
825  {
827  }
828  }
829 
830  return NO_ERROR;
831 }
832 
833 /*
834  * pt_free_label () - release all memory occupied by an interpreter variable
835  * return: NO_ERROR
836  * key(in): an interpreter variable used as a search key
837  * data(in): a DB_VALUE associated with the key
838  * args(in): NULL (not used here, but needed by mht_map)
839  */
840 
841 static int
842 pt_free_label (const void *key, void *data, void *args)
843 {
844  DB_VALUE *val = (DB_VALUE *) data;
845  MOP mop;
846 
847  if (key != NULL)
848  {
849  ws_free_string ((char *) key);
850  if (DB_VALUE_TYPE (val) == DB_TYPE_OBJECT)
851  {
852  mop = db_get_object (val);
854  }
855  db_value_free ((DB_VALUE *) data);
856  }
857 
858  return NO_ERROR;
859 }
860 
861 /*
862  * pt_free_label_table () - release all memory occupied by the label_table
863  * return: none
864  */
865 
866 void
868 {
869  if (!pt_Label_table)
870  {
871  return;
872  }
873 
874  mht_map (pt_Label_table, pt_free_label, NULL);
875  mht_destroy (pt_Label_table);
876  pt_Label_table = NULL;
877 }
878 
879 /*
880  * pt_final () - deallocate all resources used by the parser
881  * return: none
882  */
883 void
885 {
888 }
889 
890 /*
891  * pt_evaluate_tree () - interprets tree & returns its result as a DB_VALUE
892  * return: none
893  * parser(in): handle to the parser used to process & derive tree
894  * tree(in): an abstract syntax tree form of a CUBRID insert_value
895  * db_values(out): array of newly set DB_VALUEs if successful, untouched
896  * otherwise
897  * values_count(in): number of values to store in db_value array.
898  */
899 
900 void
902 {
903  pt_evaluate_tree_internal (parser, tree, db_values, values_count, false);
904 }
905 
906 /*
907  * pt_evaluate_tree_internal () -
908  * return: none
909  * parser(in):
910  * tree(in):
911  * db_values(in): array of newly set DB_VALUEs if successful, untouched
912  * otherwise
913  * values_count(in): Number of values to store in db_value.
914  * set_insert(in):
915  */
916 void
918  bool having_serial)
919 {
920  int error = NO_ERROR;
921  PT_NODE *arg1, *arg2, *arg3, *temp;
922  PT_NODE *or_next;
923  DB_VALUE *val, opd1, opd2, opd3;
924  PT_OP_TYPE op;
925  PT_TYPE_ENUM type1, type2, type3;
926  TP_DOMAIN *domain;
927  PT_MISC_TYPE qualifier = (PT_MISC_TYPE) 0;
928  QUERY_ID query_id_self = parser->query_id;
929  MOP serial_mop;
930  DB_IDENTIFIER *serial_oid_p;
931  int cached_num;
932  int r = 0;
933  int error_code;
934  bool opd2_set_null = false;
935 
936  assert (parser != NULL);
937 
938  if (tree == NULL || db_values == NULL || pt_has_error (parser))
939  {
940  return;
941  }
942  if (values_count > 1 && tree->node_type != PT_SELECT && tree->node_type != PT_INTERSECTION
943  && tree->node_type != PT_UNION && tree->node_type != PT_DIFFERENCE)
944  {
945  /* Only a query can return more than one value */
947  pt_short_print (parser, tree));
948  return;
949  }
950 
951  switch (tree->node_type)
952  {
953  case PT_HOST_VAR:
954  case PT_VALUE:
955  val = pt_value_to_db (parser, tree);
956  if (val)
957  {
958  (void) db_value_clone (val, db_values);
959  }
960  break;
961 
962  case PT_DOT_:
963  case PT_NAME:
964  if (!pt_eval_path_expr (parser, tree, db_values) && !pt_has_error (parser))
965  {
967  pt_short_print (parser, tree));
968  }
969  break;
970 
971  case PT_TUPLE_VALUE:
972  {
974  int index = tree->info.tuple_value.index;
975  if (cursor_id == NULL)
976  {
978  pt_short_print (parser, tree));
979  break;
980  }
981  error = cursor_get_tuple_value (cursor_id, index, db_values);
982  if (error != NO_ERROR)
983  {
984  PT_ERRORc (parser, tree, er_msg ());
985  }
986  break;
987  }
988 
989  case PT_INSERT_VALUE:
990  if (tree->info.insert_value.is_evaluated)
991  {
992  /* Node was already evaluated, just copy the stored value */
993  (void) db_value_clone (&tree->info.insert_value.value, db_values);
994  }
995  else
996  {
997  /* evaluate original node */
998  pt_evaluate_tree_having_serial (parser, tree->info.insert_value.original_node, db_values, values_count);
999  }
1000  break;
1001 
1002  case PT_EXPR:
1003  if (tree->info.expr.op == PT_FUNCTION_HOLDER)
1004  {
1005  if (pt_evaluate_function (parser, tree->info.expr.arg1, db_values) != NO_ERROR)
1006  {
1008  pt_short_print (parser, tree));
1009  }
1010  break;
1011  }
1012  if (tree->or_next)
1013  {
1014  /* The expression tree has 'or_next' filed. Evaluate it after converting to 'OR' tree. */
1015 
1016  /* save 'or_next' */
1017  or_next = tree->or_next;
1018  tree->or_next = NULL;
1019 
1020  /* make 'OR' tree */
1021  temp = parser_new_node (parser, PT_EXPR);
1022  temp->type_enum = PT_TYPE_LOGICAL;
1023  temp->info.expr.op = PT_OR;
1024  temp->info.expr.arg1 = tree;
1025  temp->info.expr.arg2 = or_next;
1026 
1027  /* evaluate the 'OR' tree */
1028  pt_evaluate_tree (parser, temp, db_values, 1);
1029 
1030  /* delete 'OR' node */
1031  temp->info.expr.arg1 = temp->info.expr.arg2 = NULL;
1032  temp->next = temp->or_next = NULL;
1033  parser_free_tree (parser, temp);
1034 
1035  /* restore 'or_next' */
1036  tree->or_next = or_next;
1037  }
1038  else
1039  { /* if (tree->or_next) */
1040  op = tree->info.expr.op;
1041 
1042  /* If the an operand is a query, and the context is a table query (quantified comparison), rewrite the query
1043  * into something we can actually handle here, a table to set conversion. */
1044  if (pt_is_table_op (op))
1045  {
1046  tree->info.expr.arg2 = pt_query_to_set_table (parser, tree->info.expr.arg2);
1047  }
1048  else if (op == PT_EXISTS)
1049  {
1050  tree->info.expr.arg1 = pt_query_to_set_table (parser, tree->info.expr.arg1);
1051  }
1052 
1053  arg1 = tree->info.expr.arg1;
1054  if (op == PT_BETWEEN || op == PT_NOT_BETWEEN)
1055  {
1056  /* special handling for PT_BETWEEN and PT_NOT_BETWEEN */
1057  assert (tree->info.expr.arg2->node_type == PT_EXPR);
1058  arg2 = tree->info.expr.arg2->info.expr.arg1;
1059  arg3 = tree->info.expr.arg2->info.expr.arg2;
1060  }
1061  else
1062  {
1063  arg2 = tree->info.expr.arg2;
1064  arg3 = tree->info.expr.arg3;
1065  }
1066 
1067  if (op == PT_NEXT_VALUE || op == PT_CURRENT_VALUE)
1068  {
1069  if (!having_serial)
1070  {
1071  /* Serial not allowed in current context */
1073  pt_short_print (parser, tree));
1074  break;
1075  }
1076  serial_mop = pt_resolve_serial (parser, arg1);
1077  if (serial_mop != NULL)
1078  {
1079  serial_oid_p = db_identifier (serial_mop);
1080  if (serial_oid_p != NULL)
1081  {
1082  error = do_get_serial_cached_num (&cached_num, serial_mop);
1083  }
1084  else
1085  {
1086  error = ER_FAILED;
1087  }
1088  if (error == NO_ERROR)
1089  {
1090  if (op == PT_CURRENT_VALUE)
1091  {
1092  error = serial_get_current_value (db_values, serial_oid_p, cached_num);
1093  }
1094  else
1095  {
1096  int num_alloc;
1097 
1098  val = pt_value_to_db (parser, arg2);
1099  num_alloc = db_get_int (val);
1100  if (num_alloc < 1)
1101  {
1102  PT_ERRORm (parser, tree, MSGCAT_SET_PARSER_SEMANTIC,
1104  return;
1105  }
1106  else
1107  {
1108  error =
1109  serial_get_next_value (db_values, serial_oid_p, cached_num, num_alloc, GENERATE_SERIAL);
1110  }
1111  }
1112  }
1113 
1114  if (error != NO_ERROR)
1115  {
1116  switch (er_errid ())
1117  {
1120  return;
1123  break;
1126  break;
1129  break;
1132  default:
1133  error_code = MSGCAT_SEMANTIC_SERIAL_IO_ERROR;
1134  break;
1135  }
1136 
1137  PT_ERRORmf (parser, tree, MSGCAT_SET_PARSER_SEMANTIC, error_code, arg1->info.name.original);
1138  }
1139  }
1140  else
1141  {
1143  arg1->info.name.original);
1144  }
1145  return;
1146  }
1147 
1148  db_make_null (&opd1);
1149  db_make_null (&opd2);
1150  db_make_null (&opd3);
1151 
1152  /* evaluate operands */
1153  if (!arg1 && op == PT_UNIX_TIMESTAMP)
1154  {
1155  pr_clone_value (&parser->sys_datetime, &opd1);
1156  }
1157  else
1158  {
1159  pt_evaluate_tree_having_serial (parser, arg1, &opd1, 1);
1160  }
1162  if (arg2 && !pt_has_error (parser))
1163  {
1164  pt_evaluate_tree_having_serial (parser, arg2, &opd2, 1);
1165  type2 = arg2->type_enum;
1166  }
1167  else
1168  {
1169  INTL_CODESET opd1_cs = DB_IS_NULL (&opd1) ? LANG_SYS_CODESET : db_get_string_codeset (&opd1);
1170  int opd1_coll = DB_IS_NULL (&opd1) ? LANG_SYS_COLLATION : db_get_string_collation (&opd1);
1171 
1172  switch (op)
1173  {
1174  case PT_TRIM:
1175  case PT_LTRIM:
1176  case PT_RTRIM:
1177  if (type1 == PT_TYPE_NCHAR || type1 == PT_TYPE_VARNCHAR)
1178  {
1179  db_make_varnchar (&opd2, 1, " ", 1, opd1_cs, opd1_coll);
1180  type2 = PT_TYPE_VARNCHAR;
1181  }
1182  else
1183  {
1184  db_make_varchar (&opd2, 1, " ", 1, opd1_cs, opd1_coll);
1185  type2 = PT_TYPE_VARCHAR;
1186  }
1187  break;
1188  case PT_FROM_UNIXTIME:
1189  db_make_null (&opd2);
1190  opd2_set_null = true;
1191  break;
1192  default:
1193  db_make_null (&opd2);
1194  break;
1195  } /* switch (op) */
1196  }
1197  if (arg3 && !pt_has_error (parser))
1198  {
1199  pt_evaluate_tree_having_serial (parser, arg3, &opd3, 1);
1200  type3 = arg3->type_enum;
1201  }
1202  else
1203  {
1204  INTL_CODESET opd1_cs = DB_IS_NULL (&opd1) ? LANG_SYS_CODESET : db_get_string_codeset (&opd1);
1205  int opd1_coll = DB_IS_NULL (&opd1) ? LANG_SYS_COLLATION : db_get_string_collation (&opd1);
1206 
1207  switch (op)
1208  {
1209  case PT_REPLACE:
1210  case PT_TRANSLATE:
1211  if (type1 == PT_TYPE_NCHAR || type1 == PT_TYPE_VARNCHAR)
1212  {
1213  db_make_varnchar (&opd3, 1, "", 0, opd1_cs, opd1_coll);
1214  type3 = PT_TYPE_VARNCHAR;
1215  }
1216  else
1217  {
1218  db_make_varchar (&opd3, 1, "", 0, opd1_cs, opd1_coll);
1219  type3 = PT_TYPE_VARCHAR;
1220  }
1221  break;
1222  case PT_LPAD:
1223  case PT_RPAD:
1224  if (type1 == PT_TYPE_NCHAR || type1 == PT_TYPE_VARNCHAR)
1225  {
1226  db_make_varnchar (&opd3, 1, " ", 1, opd1_cs, opd1_coll);
1227  type2 = PT_TYPE_VARNCHAR;
1228  }
1229  else
1230  {
1231  db_make_varchar (&opd3, 1, " ", 1, opd1_cs, opd1_coll);
1232  type2 = PT_TYPE_VARCHAR;
1233  }
1234  break;
1235  default:
1236  db_make_null (&opd3);
1237  break;
1238  } /* switch (op) */
1239  }
1240  if (pt_has_error (parser))
1241  {
1242  pr_clear_value (&opd1);
1243  pr_clear_value (&opd2);
1244  pr_clear_value (&opd3);
1245  break;
1246  }
1247 
1248  /* try to evaluate the expression */
1249  if (op == PT_TRIM || op == PT_EXTRACT || op == PT_SUBSTRING || op == PT_EQ)
1250  {
1251  qualifier = tree->info.expr.qualifier;
1252  }
1253  domain = pt_node_to_db_domain (parser, tree, NULL);
1254  domain = tp_domain_cache (domain);
1255 
1256  /* PT_BETWEEN_xxxx, PT_ASSIGN, PT_LIKE_ESCAPE do not need to be evaluated and will return 0 from
1257  * 'pt_evaluate_db_value_expr()' */
1258  if (!pt_is_between_range_op (op) && op != PT_ASSIGN && op != PT_LIKE_ESCAPE && op != PT_CURRENT_VALUE)
1259  {
1260  if (!pt_evaluate_db_value_expr (parser, tree, op, &opd1, opd2_set_null ? NULL : &opd2, &opd3, db_values,
1261  domain, arg1, arg2, arg3, qualifier))
1262  {
1264  pt_short_print (parser, tree));
1265  }
1266  }
1267 
1268  db_value_clear (&opd1);
1269  db_value_clear (&opd2);
1270  db_value_clear (&opd3);
1271  } /* if (tree->or_next) */
1272  break;
1273 
1274  case PT_SELECT:
1275  case PT_UNION:
1276  case PT_DIFFERENCE:
1277  case PT_INTERSECTION:
1278  /* cannot directly evaluate tree, since this may modify it */
1279  temp = parser_copy_tree (parser, tree);
1280 
1281  temp = mq_translate (parser, temp);
1282 
1283  if (temp == NULL)
1284  {
1285  if (!pt_has_error (parser))
1286  {
1287  PT_ERRORc (parser, tree, db_error_string (3));
1288  }
1289  break;
1290  }
1291 
1292  query_id_self = parser->query_id;
1293  parser->query_id = NULL_QUERY_ID;
1294  error = do_select (parser, temp);
1295  if (error == NO_ERROR)
1296  {
1297  /* If there isn't a value from the select, but the select succeeded, return a NULL instead of an error. It
1298  * might break something if an error were returned. */
1299  if (pt_get_one_tuple_from_list_id (parser, temp, db_values, values_count) == 0)
1300  {
1301  for (r = 0; r < values_count; r++)
1302  {
1303  db_make_null (&db_values[r]);
1304  }
1305  }
1306 
1307  cursor_free_self_list_id (temp->etc);
1308  pt_end_query (parser, query_id_self);
1309  }
1310  else
1311  {
1312  if (!pt_has_error (parser))
1313  {
1314  PT_ERRORc (parser, tree, db_error_string (3));
1315  }
1316  parser->query_id = query_id_self;
1317  }
1318 
1319  parser_free_tree (parser, temp);
1320  break;
1321 
1322  case PT_INSERT:
1323  assert (tree->info.insert.value_clauses != NULL);
1324  if (tree->info.insert.value_clauses->next != NULL)
1325  {
1326  error = ER_DO_INSERT_TOO_MANY;
1327  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
1328  if (!pt_has_error (parser))
1329  {
1330  PT_ERRORc (parser, tree, db_error_string (3));
1331  }
1332  break;
1333  }
1334 
1335  /* Execute insert */
1336  error = do_insert (parser, tree);
1337  if (error >= NO_ERROR)
1338  {
1339  if ((val = (DB_VALUE *) (tree->etc)) == NULL)
1340  {
1341  PT_INTERNAL_ERROR (parser, "do_insert returns NULL result");
1342  }
1343  else
1344  {
1345  /* do_insert returns at most one value, inserts with selects are not allowed to be nested */
1346  (void) db_value_clone (val, db_values);
1347  }
1348  db_value_free (val);
1349  tree->etc = NULL;
1350  }
1351  else if (!pt_has_error (parser))
1352  {
1353  PT_ERRORc (parser, tree, db_error_string (3));
1354  }
1355  break;
1356 
1357  case PT_METHOD_CALL:
1358  error = do_call_method (parser, tree);
1359  if (error >= NO_ERROR)
1360  {
1361  if ((val = (DB_VALUE *) (tree->etc)) != NULL)
1362  { /* do_call_method returns at most one value */
1363  if (db_value_clone (val, db_values) != NO_ERROR)
1364  {
1365  db_make_null (db_values);
1366  }
1367  pr_free_ext_value (val);
1368  }
1369  else
1370  {
1371  db_make_null (db_values);
1372  }
1373  }
1374  else if (!pt_has_error (parser))
1375  {
1376  PT_ERRORc (parser, tree, db_error_string (3));
1377  }
1378  break;
1379 
1380  case PT_FUNCTION:
1381  switch (tree->info.function.function_type)
1382  {
1383  /* we have a set/multiset/sequence constructor function call. build the set/multiset/sequence using the
1384  * function arguments as the set/multiset/sequence element building blocks. */
1385  case F_SET:
1386  db_make_set (db_values, db_set_create_basic (NULL, NULL));
1387  if (!db_get_set (db_values))
1388  {
1390  return;
1391  }
1392 
1393  if (pt_set_value_to_db (parser, &tree->info.function.arg_list, db_values, &tree->data_type) == NULL
1394  && !pt_has_error (parser))
1395  {
1396  PT_ERRORc (parser, tree, db_error_string (3));
1397  }
1398  return;
1399 
1400  case F_MULTISET:
1402  if (!db_get_set (db_values))
1403  {
1405  return;
1406  }
1407 
1408  if (pt_set_value_to_db (parser, &tree->info.function.arg_list, db_values, &tree->data_type) == NULL
1409  && !pt_has_error (parser))
1410  {
1411  PT_ERRORc (parser, tree, db_error_string (3));
1412  }
1413  return;
1414 
1415  case F_SEQUENCE:
1416  db_make_sequence (db_values, db_seq_create (NULL, NULL, 0));
1417  if (!db_get_set (db_values))
1418  {
1420  return;
1421  }
1422 
1423  if (pt_seq_value_to_db (parser, tree->info.function.arg_list, db_values, &tree->data_type) == NULL
1424  && !pt_has_error (parser))
1425  {
1426  PT_ERRORc (parser, tree, db_error_string (3));
1427  }
1428  return;
1429 
1430  case F_TABLE_SET:
1431  db_make_set (db_values, db_set_create_basic (NULL, NULL));
1432  if (!db_get_set (db_values))
1433  {
1435  return;
1436  }
1437 
1438  if (pt_set_table_to_db (parser, tree->info.function.arg_list, db_values, 0) == NULL && !pt_has_error (parser))
1439  {
1440  PT_ERRORc (parser, tree, db_error_string (3));
1441  }
1442  return;
1443 
1444  case F_TABLE_MULTISET:
1446  if (!db_get_set (db_values))
1447  {
1449  return;
1450  }
1451  if (pt_set_table_to_db (parser, tree->info.function.arg_list, db_values, 0) == NULL && !pt_has_error (parser))
1452  {
1453  PT_ERRORc (parser, tree, db_error_string (3));
1454  }
1455  return;
1456 
1457  case F_TABLE_SEQUENCE:
1458  db_make_sequence (db_values, db_seq_create (NULL, NULL, 0));
1459  if (!db_get_set (db_values))
1460  {
1462  return;
1463  }
1464  if (pt_set_table_to_db (parser, tree->info.function.arg_list, db_values, 1) == NULL && !pt_has_error (parser))
1465  {
1466  PT_ERRORc (parser, tree, db_error_string (3));
1467  }
1468  return;
1469 
1470  default:
1472  pt_short_print (parser, tree));
1473  break;
1474  }
1475  break;
1476 
1477  default:
1479  pt_short_print (parser, tree));
1480  break;
1481  }
1482 }
1483 
1484 /*
1485  * pt_evaluate_tree_having_serial () -
1486  * return:
1487  * parser(in):
1488  * tree(in):
1489  * db_values(in):
1490  * values_count(in):
1491  */
1492 void
1494 {
1495  pt_evaluate_tree_internal (parser, tree, db_value, vals_cnt, true);
1496 }
DB_OBJECT * pt_resolve_serial(PARSER_CONTEXT *parser, PT_NODE *serial_name_node)
PT_NODE * next
Definition: parse_tree.h:3447
PT_NAME_INFO name
Definition: parse_tree.h:3318
#define MSGCAT_SEMANTIC_SERIAL_NOT_DEFINED
void parser_final(void)
PT_NODE * arg_list
Definition: parse_tree.h:2258
#define NO_ERROR
Definition: error_code.h:46
#define MSGCAT_SEMANTIC_SERIAL_NUM_ALLOC_INVALID
DB_COLLECTION * db_get_set(const DB_VALUE *value)
#define LANG_SYS_COLLATION
int cursor_get_tuple_value(CURSOR_ID *cursor_id_p, int index, DB_VALUE *value_p)
Definition: cursor.c:1734
int serial_get_next_value(DB_VALUE *value, OID *oid_p, int cached_num, int num_alloc, int is_auto_increment)
int do_get_serial_cached_num(int *cached_num, MOP serial_obj)
PT_STATEMENT_INFO info
Definition: parse_tree.h:3487
#define PT_ERRORm(parser, node, setNo, msgNo)
Definition: parse_tree.h:63
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
int do_drop_variable(PARSER_CONTEXT *parser, PT_NODE *stmt)
DB_SET * db_seq_create(MOP classop, const char *name, int size)
Definition: db_set.c:252
PT_MISC_TYPE
Definition: parse_tree.h:983
int do_call_method(PARSER_CONTEXT *parser, PT_NODE *statement)
PT_NODE * mq_translate(PARSER_CONTEXT *parser, PT_NODE *volatile node)
int db_get_int(const DB_VALUE *value)
#define ER_QPROC_DB_SERIAL_NOT_FOUND
Definition: error_code.h:964
#define ER_REFERENCE_TO_NON_REFERABLE_NOT_ALLOWED
Definition: error_code.h:1231
DB_TYPE
Definition: dbtype_def.h:670
#define ER_FAILED
Definition: error_code.h:47
int db_make_varchar(DB_VALUE *value, const int max_char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
int db_seq_put(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:745
#define MSGCAT_SEMANTIC_OUT_OF_MEMORY
int db_get_string_collation(const DB_VALUE *value)
DB_VALUE * pt_seq_value_to_db(PARSER_CONTEXT *parser, PT_NODE *values, DB_VALUE *db_value, PT_NODE **el_types)
Definition: parse_dbi.c:979
#define MSGCAT_RUNTIME_YIELDS_GT_ONE_ROW
#define ER_DB_NO_MODIFICATIONS
Definition: error_code.h:683
PT_NODE * arg3
Definition: parse_tree.h:2202
int mht_rem(MHT_TABLE *ht, const void *key, int(*rem_func)(const void *key, void *data, void *args), void *func_args)
Definition: memory_hash.c:1952
int cursor_next_tuple(CURSOR_ID *cursor_id_p)
Definition: cursor.c:1482
PT_NODE * pt_get_select_list(PARSER_CONTEXT *parser, PT_NODE *query)
Definition: query_result.c:404
int db_value_clone(DB_VALUE *src, DB_VALUE *dest)
Definition: db_macro.c:1564
const void * mht_put(MHT_TABLE *ht, const void *key, void *data)
Definition: memory_hash.c:1778
enum pt_type_enum PT_TYPE_ENUM
Definition: parse_tree.h:962
void nlist_free(DB_NAMELIST *list)
Definition: work_space.c:4344
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
PT_EXPR_INFO expr
Definition: parse_tree.h:3299
int db_is_any_class(MOP obj)
Definition: db_info.c:356
int do_select(PARSER_CONTEXT *parser, PT_NODE *statement)
PT_MISC_TYPE meta_class
Definition: parse_tree.h:2552
PT_TYPE_ENUM pt_db_to_type_enum(const DB_TYPE t)
Definition: parse_dbi.c:2595
#define MSGCAT_RUNTIME_UNKNOWN_VARIABLE
#define cursor_free_self_list_id(list_id)
Definition: cursor.h:108
int db_make_sequence(DB_VALUE *value, DB_C_SET *set)
#define ER_QPROC_SERIAL_ALREADY_EXIST
Definition: error_code.h:966
DB_DOMAIN * pt_node_to_db_domain(PARSER_CONTEXT *parser, PT_NODE *node, const char *class_name)
Definition: parse_dbi.c:2244
int er_errid(void)
DB_VALUE * vid_flush_and_rehash_lbl(DB_VALUE *value)
DB_SET * db_set_create_multi(MOP classop, const char *name)
Definition: db_set.c:192
int pt_evaluate_function(PARSER_CONTEXT *parser, PT_NODE *func, DB_VALUE *dbval_res)
void db_ws_free(void *ptr)
Definition: quick_fit.c:194
void pt_final_packing_buf(void)
PT_NODE * data_type
Definition: parse_tree.h:3453
void ws_free_string(const char *str)
Definition: work_space.c:3480
PT_DOT_INFO dot
Definition: parse_tree.h:3287
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
PT_NODE * arg2
Definition: parse_tree.h:2086
int pt_associate_label_with_value_check_reference(const char *label, DB_VALUE *val)
static DB_OBJECT * is_class(OID *obj_oid, OID *class_oid)
Definition: compactdb.c:637
FUNC_TYPE function_type
Definition: parse_tree.h:2259
int pr_free_ext_value(DB_VALUE *value)
PT_TYPE_ENUM type_enum
Definition: parse_tree.h:3457
void pt_report_to_ersys(const PARSER_CONTEXT *parser, const PT_ERROR_TYPE error_type)
Definition: query_result.c:287
PT_NODE * or_next
Definition: parse_tree.h:3448
DB_VALUE * pt_set_value_to_db(PARSER_CONTEXT *parser, PT_NODE **values, DB_VALUE *db_value, PT_NODE **el_types)
Definition: parse_dbi.c:1033
char oids_included
Definition: parse_tree.h:2750
void mht_destroy(MHT_TABLE *ht)
Definition: memory_hash.c:1140
const char * name
Definition: dbtype_def.h:431
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
Definition: db_set.h:35
PT_NODE * arg2
Definition: parse_tree.h:2198
PT_FUNCTION_INFO function
Definition: parse_tree.h:3301
DB_OBJECT * db_object
Definition: parse_tree.h:2546
#define PT_ERRORmf2(parser, node, setNo, msgNo, arg1, arg2)
Definition: parse_tree.h:65
#define MSGCAT_RUNTIME_OUT_OF_MEMORY
#define assert(x)
PT_MISC_TYPE qualifier
Definition: parse_tree.h:2204
#define PT_IS_QUERY_NODE_TYPE(x)
Definition: parse_tree.h:115
DB_ATTRIBUTE * db_get_shared_attribute(DB_OBJECT *obj, const char *name)
Definition: db_info.c:849
int db_make_set(DB_VALUE *value, DB_C_SET *set)
void pt_evaluate_tree(PARSER_CONTEXT *parser, PT_NODE *tree, DB_VALUE *db_values, int values_count)
int db_make_multiset(DB_VALUE *value, DB_C_SET *set)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
static PT_NODE * pt_query_to_set_table(PARSER_CONTEXT *parser, PT_NODE *node)
DB_IDENTIFIER * db_identifier(DB_OBJECT *obj)
Definition: db_admin.c:2629
static int pt_is_table_op(const PT_OP_TYPE op)
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define MSGCAT_SET_PARSER_RUNTIME
bool pt_eval_path_expr(PARSER_CONTEXT *parser, PT_NODE *tree, DB_VALUE *val)
static void pt_evaluate_tree_internal(PARSER_CONTEXT *parser, PT_NODE *tree, DB_VALUE *db_values, int values_count, bool having_serial)
int pt_get_one_tuple_from_list_id(PARSER_CONTEXT *parser, PT_NODE *tree, DB_VALUE *vals, int cnt)
unsigned int intl_identifier_mht_1strlowerhash(const void *key, const unsigned int ht_size)
const char * original
Definition: parse_tree.h:2544
#define ER_QPROC_SERIAL_RANGE_OVERFLOW
Definition: error_code.h:967
#define ER_QPROC_CANNOT_FETCH_SERIAL
Definition: error_code.h:968
int db_value_free(DB_VALUE *value)
Definition: db_macro.c:1610
void pt_evaluate_tree_having_serial(PARSER_CONTEXT *parser, PT_NODE *tree, DB_VALUE *db_value, int vals_cnt)
PT_NODE_TYPE node_type
Definition: parse_tree.h:3439
#define MSGCAT_RUNTIME_VAR_NOT_DEFINED
const char * db_error_string(int level)
Definition: db_admin.c:2116
static int pt_free_label(const void *key, void *data, void *args)
PT_NODE * parser_copy_tree(PARSER_CONTEXT *parser, const PT_NODE *tree)
DB_OBJECT * db_get_object(const DB_VALUE *value)
QUERY_ID query_id
Definition: cursor.h:54
void * mht_get(MHT_TABLE *ht, const void *key)
Definition: memory_hash.c:1419
SP_PARSER_CTX * parser
PT_NODE * arg1
Definition: parse_tree.h:2197
struct db_namelist * next
Definition: dbtype_def.h:430
#define NULL
Definition: freelistheap.h:34
const char * er_msg(void)
int db_is_class(MOP obj)
Definition: db_info.c:310
DB_OBJECT * db_get_class(MOP obj)
Definition: db_info.c:589
PT_NODE * value_clauses
Definition: parse_tree.h:2334
void pt_free_label_table(void)
int mht_compare_identifiers_equal(const void *key1, const void *key2)
Definition: memory_hash.c:755
int pt_is_reference_to_reusable_oid(DB_VALUE *val)
int db_set_add(DB_SET *set, DB_VALUE *value)
Definition: db_set.c:465
void pt_end_query(PARSER_CONTEXT *parser, QUERY_ID query_id_self)
TP_DOMAIN * tp_domain_cache(TP_DOMAIN *transient)
#define PT_ERRORc(parser, node, msg)
Definition: parse_tree.h:55
const void * mht_put_data(MHT_TABLE *ht, const void *key, void *data)
Definition: memory_hash.c:1756
DB_SET * db_set_create_basic(MOP classop, const char *name)
Definition: db_set.c:134
MHT_TABLE * mht_create(const char *name, int est_size, unsigned int(*hash_func)(const void *key, unsigned int ht_size), int(*cmp_func)(const void *key1, const void *key2))
Definition: memory_hash.c:894
PT_NODE * arg1
Definition: parse_tree.h:2085
PT_QUERY_INFO query
Definition: parse_tree.h:3325
int pt_is_between_range_op(PT_OP_TYPE op)
int pr_clear_value(DB_VALUE *value)
#define MSGCAT_RUNTIME_UNKNOWN_SHARED_ATTR
DB_VALUE * pt_find_value_of_label(const char *label)
PT_TUPLE_VALUE_INFO tuple_value
Definition: parse_tree.h:3352
struct db_domain_info::general_info general_info
char * pt_short_print(PARSER_CONTEXT *parser, const PT_NODE *node)
#define MSGCAT_SEMANTIC_SERIAL_VALUE_OVERFLOW
#define ER_DO_INSERT_TOO_MANY
Definition: error_code.h:890
PT_NODE * parser_new_node(PARSER_CONTEXT *parser, PT_NODE_TYPE node_type)
static void error(const char *msg)
Definition: gencat.c:331
static DB_VALUE * pt_set_table_to_db(PARSER_CONTEXT *parser, PT_NODE *subquery_in, DB_VALUE *db_value, int is_seq)
#define MSGCAT_SET_ERROR
#define ARG_FILE_LINE
Definition: error_manager.h:44
CURSOR_ID * cursor_p
Definition: parse_tree.h:3207
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
void parser_free_tree(PARSER_CONTEXT *parser, PT_NODE *tree)
#define ER_AU_SELECT_FAILURE
Definition: error_code.h:221
#define MSGCAT_SET_PARSER_SEMANTIC
DB_VALUE sys_datetime
Definition: parse_tree.h:3580
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define MSGCAT_RUNTIME__CAN_NOT_EVALUATE
PT_OP_TYPE
Definition: parse_tree.h:1320
int do_insert(PARSER_CONTEXT *parser, PT_NODE *root_statement)
int sm_check_reuse_oid_class(MOP op)
#define DB_CURSOR_SUCCESS
Definition: dbtype_def.h:166
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
int db_get(DB_OBJECT *object, const char *attpath, DB_VALUE *value)
Definition: db_obj.c:233
void * db_ws_alloc(size_t size)
Definition: quick_fit.c:73
DB_VALUE * db_attribute_default(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1209
int db_make_varnchar(DB_VALUE *value, const int max_nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
void * etc
Definition: parse_tree.h:3450
void cursor_close(CURSOR_ID *cursor_id_p)
Definition: cursor.c:1381
char * parser_print_tree(PARSER_CONTEXT *parser, const PT_NODE *node)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int pt_length_of_select_list(PT_NODE *list, int hidden_col)
int mht_map(const MHT_TABLE *ht, int(*map_func)(const void *key, void *data, void *args), void *func_args)
Definition: memory_hash.c:2199
int db_make_null(DB_VALUE *value)
#define DB_IS_NULL(value)
Definition: dbtype.h:63
PT_OP_TYPE op
Definition: parse_tree.h:2200
int serial_get_current_value(DB_VALUE *value, OID *oid_p, int cached_num)
#define MSGCAT_RUNTIME_IS_NOT_AUTHORIZED_ON
#define PT_INTERNAL_ERROR(parser, what)
Definition: parse_tree.h:112
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
static int pt_associate_label_with_value(const char *label, DB_VALUE *val)
PT_DROP_VARIABLE_INFO drop_variable
Definition: parse_tree.h:3292
#define ER_AU_AUTHORIZATION_FAILURE
Definition: error_code.h:220
#define pt_has_error(parser)
Definition: parser.h:507
#define MSGCAT_SEMANTIC_SERIAL_IO_ERROR
#define LANG_SYS_CODESET
char * ws_copy_string(const char *str)
Definition: work_space.c:3457
int pt_evaluate_db_value_expr(PARSER_CONTEXT *parser, PT_NODE *expr, PT_OP_TYPE op, DB_VALUE *arg1, DB_VALUE *arg2, DB_VALUE *arg3, DB_VALUE *result, TP_DOMAIN *domain, PT_NODE *o1, PT_NODE *o2, PT_NODE *o3, PT_MISC_TYPE qualifier)
#define MSGCAT_SEMANTIC_SERIAL_ALREADY_EXIST
int ws_add_label_value_to_mop(MOP mop, DB_VALUE *val)
Definition: work_space.c:5237
static MHT_TABLE * pt_Label_table
int column_number
Definition: parse_tree.h:3442
DB_C_POINTER db_get_pointer(const DB_VALUE *value)
#define DB_CURSOR_END
Definition: dbtype_def.h:167
void ws_remove_label_value_from_mop(MOP mop, DB_VALUE *val)
Definition: work_space.c:5182
DB_VALUE * pt_value_to_db(PARSER_CONTEXT *parser, PT_NODE *value)
Definition: parse_dbi.c:1088
bool cursor_open(CURSOR_ID *cursor_id_p, QFILE_LIST_ID *list_id_p, bool updatable, bool is_oid_included)
Definition: cursor.c:1194
PT_INSERT_INFO insert
Definition: parse_tree.h:3309
#define PT_ERRORf(parser, node, msg, arg1)
Definition: parse_tree.h:57
int db_get_string_codeset(const DB_VALUE *value)
QUERY_ID query_id
Definition: parse_tree.h:3559
const char ** p
Definition: dynamic_load.c:945
#define PT_ERRORmf(parser, node, setNo, msgNo, arg1)
Definition: parse_tree.h:64
int cursor_get_tuple_value_list(CURSOR_ID *cursor_id_p, int size, DB_VALUE *value_list_p)
Definition: cursor.c:1778
DB_VALUE * db_values
Definition: esql_cli.c:356
PT_INSERT_VALUE_INFO insert_value
Definition: parse_tree.h:3310
PT_NODE * original_node
Definition: parse_tree.h:3227
#define ER_QPROC_CANNOT_UPDATE_SERIAL
Definition: error_code.h:969