CUBRID Engine  latest
query_evaluator.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  * query_evaluator.c - Predicate evaluator
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <string.h>
29 
30 #include "system_parameter.h"
31 #include "error_manager.h"
32 #include "heap_file.h"
33 #include "fetch.h"
34 #include "list_file.h"
35 #include "object_primitive.h"
36 #include "object_representation.h"
37 #include "regu_var.hpp"
38 #include "set_object.h"
39 #include "xasl.h"
40 #include "dbtype.h"
41 #include "query_executor.h"
42 #include "dbtype.h"
43 #include "thread_entry.hpp"
44 #include "xasl_predicate.hpp"
45 
46 #define UNKNOWN_CARD -2 /* Unknown cardinality of a set member */
47 
50 static DB_LOGICAL eval_value_rel_cmp (DB_VALUE * dbval1, DB_VALUE * dbval2, REL_OP rel_operator,
51  const COMP_EVAL_TERM * et_comp);
52 static DB_LOGICAL eval_some_eval (DB_VALUE * item, DB_SET * set, REL_OP rel_operator);
53 static DB_LOGICAL eval_all_eval (DB_VALUE * item, DB_SET * set, REL_OP rel_operator);
54 static int eval_item_card_set (DB_VALUE * item, DB_SET * set, REL_OP rel_operator);
56  REL_OP rel_operator);
58  REL_OP rel_operator);
59 static int eval_item_card_sort_list (THREAD_ENTRY * thread_p, DB_VALUE * item, QFILE_LIST_ID * list_id);
63  QFILE_LIST_ID * list_id2);
71  QFILE_LIST_ID * list_id2);
73  QFILE_LIST_ID * list_id2);
75  QFILE_LIST_ID * list_id2);
77  QFILE_LIST_ID * list_id2);
79  REL_OP rel_operator);
81  REL_OP rel_operator);
83  QFILE_LIST_ID * list_id2, REL_OP rel_operator);
84 static DB_LOGICAL eval_set_list_cmp (THREAD_ENTRY * thread_p, const COMP_EVAL_TERM * et_comp, val_descr * vd,
85  DB_VALUE * dbval1, DB_VALUE * dbval2);
86 
87 /*
88  * eval_negative () - negate the result
89  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
90  * res(in): result
91  */
92 static DB_LOGICAL
94 {
95  /* negate the result */
96  if (res == V_TRUE)
97  {
98  return V_FALSE;
99  }
100  else if (res == V_FALSE)
101  {
102  return V_TRUE;
103  }
104 
105  /* V_ERROR, V_UNKNOWN */
106  return res;
107 }
108 
109 /*
110  * eval_logical_result () - evaluate the given two results
111  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
112  * res1(in): first result
113  * res2(in): second result
114  */
115 static DB_LOGICAL
117 {
118  if (res1 == V_ERROR || res2 == V_ERROR)
119  {
120  return V_ERROR;
121  }
122 
123  if (res1 == V_TRUE && res2 == V_TRUE)
124  {
125  return V_TRUE;
126  }
127  else if (res1 == V_FALSE || res2 == V_FALSE)
128  {
129  return V_FALSE;
130  }
131 
132  return V_UNKNOWN;
133 }
134 
135 /*
136  * Predicate Evaluation
137  */
138 
139 /*
140  * eval_value_rel_cmp () - Compare two db_values according to the given
141  * relational operator
142  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
143  * dbval1(in): first db_value
144  * dbval2(in): second db_value
145  * rel_operator(in): Relational operator
146  * et_comp(in): compound evaluation term
147  */
148 static DB_LOGICAL
149 eval_value_rel_cmp (DB_VALUE * dbval1, DB_VALUE * dbval2, REL_OP rel_operator, const COMP_EVAL_TERM * et_comp)
150 {
151  int result;
152  bool comparable = true;
153  DB_TYPE vtype1, vtype2;
154  TP_DOMAIN *dom;
155 
156  /*
157  * we get here for either an ordinal comparison or a set comparison.
158  * Set comparisons are R_SUBSET, R_SUBSETEQ, R_SUPERSET, R_SUPSERSETEQ.
159  * All others are ordinal comparisons.
160  */
161 
162  /* tp_value_compare_with_error () does coercion */
163  switch (rel_operator)
164  {
165  case R_SUBSET:
166  case R_SUBSETEQ:
167  case R_SUPERSET:
168  case R_SUPERSETEQ:
169  /* do set comparison */
170  result = tp_set_compare (dbval1, dbval2, 1, 0);
171  break;
172 
173  default:
174  /* check for constant values to coerce 1-time, then reduce many-times coerce at tp_value_compare_with_error () */
175  if (et_comp != NULL)
176  {
177  assert (et_comp->lhs != NULL);
178  assert (et_comp->rhs != NULL);
179 
180 #if 0 /* TODO - do not delete me for future */
181  /* check iff value_1 is constant to coerce */
183  {
185  vtype1 = DB_VALUE_DOMAIN_TYPE (dbval1);
186  vtype2 = DB_VALUE_DOMAIN_TYPE (dbval2);
187  if (vtype1 != vtype2)
188  {
189  if (vtype1 == DB_TYPE_OBJECT)
190  {
191  ; /* do nothing */
192  }
193  else if (TP_IS_CHAR_TYPE (vtype1) && TP_IS_NUMERIC_TYPE (vtype2))
194  {
195  /* try to coerce value_1 to double */
197  (void) tp_value_coerce (dbval1, dbval1, dom);
198  }
199  else if (TP_IS_CHAR_TYPE (vtype1) && TP_IS_DATE_OR_TIME_TYPE (vtype2))
200  {
201  /* vtype2 is the date or time type, try to coerce value_1 */
202  dom = tp_domain_resolve_default (vtype2);
203  (void) tp_value_coerce (dbval1, dbval1, dom);
204  }
205  else if (TP_IS_NUMERIC_TYPE (vtype1) && TP_IS_NUMERIC_TYPE (vtype2)
206  && tp_more_general_type (vtype1, vtype2) < 0)
207  {
208  /* vtype2 is more general, try to coerce value_1 */
209  dom = tp_domain_resolve_default (vtype2);
210  (void) tp_value_coerce (dbval1, dbval1, dom);
211  }
212  }
213  }
214 #endif
215 
216  /* check iff value_2 is constant to coerce */
218  {
220  vtype1 = DB_VALUE_DOMAIN_TYPE (dbval1);
221  vtype2 = DB_VALUE_DOMAIN_TYPE (dbval2);
222  if (vtype1 != vtype2)
223  {
224  if (vtype2 == DB_TYPE_OBJECT)
225  {
226  ; /* do nothing */
227  }
228  else if (TP_IS_NUMERIC_TYPE (vtype1) && TP_IS_CHAR_TYPE (vtype2))
229  {
230  /* try to coerce value_2 to double */
232  (void) tp_value_coerce (dbval2, dbval2, dom);
233  }
234  else if (TP_IS_DATE_OR_TIME_TYPE (vtype1) && TP_IS_CHAR_TYPE (vtype2))
235  {
236  /* vtype1 is the date or time type, try to coerce value_2 */
237  dom = tp_domain_resolve_default (vtype1);
238  (void) tp_value_coerce (dbval2, dbval2, dom);
239  }
240  else if (TP_IS_NUMERIC_TYPE (vtype1) && TP_IS_NUMERIC_TYPE (vtype2)
241  && tp_more_general_type (vtype1, vtype2) > 0)
242  {
243  /* vtype1 is more general, try to coerce value_2 */
244  dom = tp_domain_resolve_default (vtype1);
245  (void) tp_value_coerce (dbval2, dbval2, dom);
246  }
247  }
248  }
249 
250  }
251 
252  if (rel_operator == R_EQ_TORDER)
253  {
254  /* do total order comparison */
255  result = tp_value_compare_with_error (dbval1, dbval2, 1, 1, &comparable);
256  }
257  else
258  {
259  /* do ordinal comparison, but NULL's still yield UNKNOWN */
260  result = tp_value_compare_with_error (dbval1, dbval2, 1, 0, &comparable);
261  }
262  break;
263  }
264 
265  if (!comparable)
266  {
267  return V_ERROR;
268  }
269 
270  if (result == DB_UNK && rel_operator != R_NULLSAFE_EQ)
271  {
272  return V_UNKNOWN;
273  }
274 
275  switch (rel_operator)
276  {
277  case R_EQ:
278  return ((result == DB_EQ) ? V_TRUE : V_FALSE);
279  case R_EQ_TORDER:
280  return ((result == DB_EQ) ? V_TRUE : V_FALSE);
281  case R_LT:
282  return ((result == DB_LT) ? V_TRUE : V_FALSE);
283  case R_LE:
284  return (((result == DB_LT) || (result == DB_EQ)) ? V_TRUE : V_FALSE);
285  case R_GT:
286  return ((result == DB_GT) ? V_TRUE : V_FALSE);
287  case R_GE:
288  return (((result == DB_GT) || (result == DB_EQ)) ? V_TRUE : V_FALSE);
289  case R_NE:
290  return ((result != DB_EQ) ? V_TRUE : V_FALSE);
291  case R_SUBSET:
292  return ((result == DB_SUBSET) ? V_TRUE : V_FALSE);
293  case R_SUBSETEQ:
294  return (((result == DB_SUBSET) || (result == DB_EQ)) ? V_TRUE : V_FALSE);
295  case R_SUPERSET:
296  return ((result == DB_SUPERSET) ? V_TRUE : V_FALSE);
297  case R_SUPERSETEQ:
298  return (((result == DB_SUPERSET) || (result == DB_EQ)) ? V_TRUE : V_FALSE);
299  case R_NULLSAFE_EQ:
300  if (result == DB_EQ)
301  {
302  return V_TRUE;
303  }
304  else
305  {
306  if (DB_IS_NULL (dbval1))
307  {
308  if (DB_IS_NULL (dbval2))
309  {
310  return V_TRUE;
311  }
312  else
313  {
314  return V_FALSE;
315  }
316  }
317  else
318  {
319  return V_FALSE;
320  }
321  }
322  break;
323  default:
324  return V_ERROR;
325  }
326 }
327 
328 /*
329  * eval_some_eval () -
330  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN, V_ERROR)
331  * item(in): db_value item
332  * set(in): collection of elements
333  * rel_operator(in): relational comparison operator
334  */
335 
336 static DB_LOGICAL
337 eval_some_eval (DB_VALUE * item, DB_SET * set, REL_OP rel_operator)
338 {
339  int i;
340  DB_LOGICAL res, t_res;
341  DB_VALUE elem_val;
342 
343  PRIM_SET_NULL (&elem_val);
344 
345  res = V_FALSE;
346 
347  for (i = 0; i < set_size (set); i++)
348  {
349  if (set_get_element (set, i, &elem_val) != NO_ERROR)
350  {
351  return V_ERROR;
352  }
353 
354  t_res = eval_value_rel_cmp (item, &elem_val, rel_operator, NULL);
355  pr_clear_value (&elem_val);
356  if (t_res == V_TRUE)
357  {
358  return V_TRUE;
359  }
360  else if (t_res == V_ERROR)
361  {
362  return V_ERROR;
363  }
364  else if (t_res == V_UNKNOWN)
365  {
366  res = V_UNKNOWN; /* never returns here. we should proceed */
367  }
368  }
369 
370  return res;
371 }
372 
373 /*
374  * eval_all_eval () -
375  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN, V_ERROR)
376  * item(in): db_value item
377  * set(in): collection of elements
378  * rel_operator(in): relational comparison operator
379  *
380  * Note: This routine tries to determine whether a specific relation
381  * as determined by the relational operator rel_operator holds between
382  * the given bound item value and all the members of the
383  * given set of elements. The set can be a basic set, multi_set
384  * or sequence. It returns V_TRUE, V_FALSE, V_UNKNOWN using the
385  * following reasoning:
386  *
387  * V_TRUE: - if all the values in the set are determined
388  * to hold the relationship, or
389  * - the set is empty
390  * V_FALSE: - if there exists a value in the set which is
391  * determined not hold the relationship.
392  * V_UNKNOWN: - set is homogeneous and set element type is not
393  * comparable with the item type
394  * - set has no value determined to fail to hold the
395  * rel. and at least one value which can not be
396  * determined to hold the relationship.
397  * V_ERROR: - an error occurred.
398  *
399  */
400 static DB_LOGICAL
401 eval_all_eval (DB_VALUE * item, DB_SET * set, REL_OP rel_operator)
402 {
403  DB_LOGICAL some_res;
404 
405  /*
406  * use the some quantifier first on a negated relational operator
407  * then find the result boolean value for the all quantifier
408  */
409  switch (rel_operator)
410  {
411  case R_LT:
412  rel_operator = R_GE;
413  break;
414 
415  case R_LE:
416  rel_operator = R_GT;
417  break;
418 
419  case R_GT:
420  rel_operator = R_LE;
421  break;
422 
423  case R_GE:
424  rel_operator = R_LT;
425  break;
426 
427  case R_EQ:
428  case R_EQ_TORDER:
429  rel_operator = R_NE;
430  break;
431 
432  case R_NE:
433  rel_operator = R_EQ;
434  break;
435 
436  default:
437  return V_ERROR;
438  }
439 
440  some_res = eval_some_eval (item, set, rel_operator);
441  /* negate the some result */
442  return eval_negative (some_res);
443 }
444 
445 /*
446  * eval_item_card_set () -
447  * return: int (cardinality)
448  * >= 0 : normal cardinality
449  * ER_FAILED : ERROR
450  * UNKNOWN_CARD : unknown cardinality value
451  * item(in): db_value item
452  * set(in): collection of elements
453  * rel_operator(in): relational comparison operator
454  *
455  * Note: This routine returns the number of set elements (cardinality)
456  * which are determined to hold the given relationship with the
457  * specified item value. If the relationship is the equality
458  * relationship, the returned value means the cardinality of the
459  * given element in the set and must always be less than equal
460  * to 1 for the case of basic sets.
461  */
462 static int
463 eval_item_card_set (DB_VALUE * item, DB_SET * set, REL_OP rel_operator)
464 {
465  int num, i;
466  DB_LOGICAL res;
467  DB_VALUE elem_val;
468 
469  PRIM_SET_NULL (&elem_val);
470 
471  num = 0;
472 
473  for (i = 0; i < set_size (set); i++)
474  {
475  if (set_get_element (set, i, &elem_val) != NO_ERROR)
476  {
477  return ER_FAILED;
478  }
479  if (db_value_is_null (&elem_val))
480  {
481  pr_clear_value (&elem_val);
482  return UNKNOWN_CARD;
483  }
484 
485  res = eval_value_rel_cmp (item, &elem_val, rel_operator, NULL);
486  pr_clear_value (&elem_val);
487 
488  if (res == V_ERROR)
489  {
490  return ER_FAILED;
491  }
492 
493  if (res == V_TRUE)
494  {
495  num++;
496  }
497  }
498 
499  return num;
500 }
501 
502 /*
503  * List File Related Evaluation
504  */
505 
506 /*
507  * eval_some_list_eval () -
508  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN, V_ERROR)
509  * item(in): db_value item
510  * list_id(in): list file identifier
511  * rel_operator(in): relational comparison operator
512  *
513  * Note: This routine tries to determine whether a specific relation
514  * as determined by the relational operator rel_operator holds between
515  * the given bound item value and at least one member of the
516  * given list of elements. It returns V_TRUE, V_FALSE,
517  * V_UNKNOWN, V_ERROR using the following reasoning:
518  *
519  * V_TRUE: - there exists a value in the list that is
520  * determined to hold the relationship.
521  * V_FALSE: - all the values in the list are determined not
522  * to hold the relationship, or
523  * - the list is empty
524  * V_UNKNOWN: - list has no value determined to hold the rel.
525  * and at least one value which can not be
526  * determined to fail to hold the relationship.
527  * V_ERROR: - an error occurred.
528  *
529  * Note: The IN relationship can be stated as item has the equality rel. with
530  * one of the list elements.
531  */
532 static DB_LOGICAL
534 {
535  DB_LOGICAL res, t_res;
536  QFILE_LIST_SCAN_ID s_id;
537  QFILE_TUPLE_RECORD tplrec = { NULL, 0 };
538  DB_VALUE list_val;
539  SCAN_CODE qp_scan;
540  PR_TYPE *pr_type;
541  OR_BUF buf;
542  int length;
543  char *ptr;
544 
545  /* assert */
546  if (list_id->type_list.domp == NULL)
547  {
548  return V_ERROR;
549  }
550 
551  PRIM_SET_NULL (&list_val);
552 
553  if (list_id->tuple_cnt == 0)
554  {
555  return V_FALSE; /* empty set */
556  }
557 
558  if (qfile_open_list_scan (list_id, &s_id) != NO_ERROR)
559  {
560  return V_ERROR;
561  }
562 
563  pr_type = list_id->type_list.domp[0]->type;
564  if (pr_type == NULL)
565  {
566  qfile_close_scan (thread_p, &s_id);
567  return V_ERROR;
568  }
569 
570  res = V_FALSE;
571  while ((qp_scan = qfile_scan_list_next (thread_p, &s_id, &tplrec, PEEK)) == S_SUCCESS)
572  {
573  if (qfile_locate_tuple_value (tplrec.tpl, 0, &ptr, &length) == V_UNBOUND)
574  {
575  res = V_UNKNOWN;
576  }
577  else
578  {
579  OR_BUF_INIT (buf, ptr, length);
580 
581  if (pr_type->data_readval (&buf, &list_val, list_id->type_list.domp[0], -1, true, NULL, 0) != NO_ERROR)
582  {
583  qfile_close_scan (thread_p, &s_id);
584  return V_ERROR;
585  }
586 
587  t_res = eval_value_rel_cmp (item, &list_val, rel_operator, NULL);
588  if (t_res == V_TRUE || t_res == V_ERROR)
589  {
590  pr_clear_value (&list_val);
591  qfile_close_scan (thread_p, &s_id);
592  return t_res;
593  }
594  else if (t_res == V_UNKNOWN)
595  {
596  res = V_UNKNOWN;
597  }
598  pr_clear_value (&list_val);
599  }
600  }
601 
602  qfile_close_scan (thread_p, &s_id);
603 
604  return (qp_scan == S_END) ? res : V_ERROR;
605 }
606 
607 /*
608  * eval_all_list_eval () -
609  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN, V_ERROR)
610  * item(in): db_value
611  * list_id(in): list file identifier
612  * rel_operator(in): relational comparison operator
613  *
614  * Note: This routine tries to determine whether a specific relation
615  * as determined by the relational operator rel_operator holds between
616  * the given db_value and all the members of the
617  * given list of elements. It returns V_TRUE, V_FALSE, V_UNKNOWN
618  * or V_ERROR using following reasoning:
619  *
620  * V_TRUE: - if all the values in the list are determined
621  * to hold the relationship, or
622  * - the list is empty
623  * V_FALSE: - if there exists a value in the list which is
624  * determined not hold the relationship.
625  * V_UNKNOWN: - list has no value determined to fail to hold the
626  * rel. and at least one value which can not be
627  * determined to hold the relationship.
628  * V_ERROR: - an error occurred.
629  *
630  */
631 static DB_LOGICAL
633 {
634  DB_LOGICAL some_res;
635 
636  /* first use some quantifier on a negated relational operator */
637  switch (rel_operator)
638  {
639  case R_LT:
640  rel_operator = R_GE;
641  break;
642  case R_LE:
643  rel_operator = R_GT;
644  break;
645  case R_GT:
646  rel_operator = R_LE;
647  break;
648  case R_GE:
649  rel_operator = R_LT;
650  break;
651  case R_EQ:
652  case R_EQ_TORDER:
653  rel_operator = R_NE;
654  break;
655  case R_NE:
656  rel_operator = R_EQ;
657  break;
658  default:
659  return V_ERROR;
660  }
661 
662  some_res = eval_some_list_eval (thread_p, item, list_id, rel_operator);
663  /* negate the result */
664  return eval_negative (some_res);
665 }
666 
667 /*
668  * eval_item_card_sort_list () -
669  * return: int (cardinality, UNKNOWN_CARD, ER_FAILED for error cases)
670  * item(in): db_value item
671  * list_id(in): list file identifier
672  *
673  * Note: This routine returns the number of set elements (cardinality)
674  * which are determined to hold the equality relationship with
675  * specified item value. The list file values must have already
676  * been sorted.
677  */
678 static int
680 {
681  QFILE_LIST_SCAN_ID s_id;
682  QFILE_TUPLE_RECORD tplrec = { NULL, 0 };
683  DB_VALUE list_val;
684  SCAN_CODE qp_scan;
685  PR_TYPE *pr_type;
686  OR_BUF buf;
687  DB_LOGICAL rc;
688  int length;
689  int card;
690  char *ptr;
691 
692  /* assert */
693  if (list_id->type_list.domp == NULL)
694  {
695  return ER_FAILED;
696  }
697 
698  PRIM_SET_NULL (&list_val);
699  card = 0;
700 
701  if (qfile_open_list_scan (list_id, &s_id) != NO_ERROR)
702  {
703  return ER_FAILED;
704  }
705 
706  pr_type = list_id->type_list.domp[0]->type;
707  if (pr_type == NULL)
708  {
709  qfile_close_scan (thread_p, &s_id);
710  return ER_FAILED;
711  }
712 
713  while ((qp_scan = qfile_scan_list_next (thread_p, &s_id, &tplrec, PEEK)) == S_SUCCESS)
714  {
715  if (qfile_locate_tuple_value (tplrec.tpl, 0, &ptr, &length) == V_UNBOUND)
716  {
717  qfile_close_scan (thread_p, &s_id);
718  return UNKNOWN_CARD;
719  }
720 
721  OR_BUF_INIT (buf, ptr, length);
722 
723  pr_type->data_readval (&buf, &list_val, list_id->type_list.domp[0], -1, true, NULL, 0);
724 
725  rc = eval_value_rel_cmp (item, &list_val, R_LT, NULL);
726  if (rc == V_ERROR)
727  {
728  pr_clear_value (&list_val);
729  qfile_close_scan (thread_p, &s_id);
730  return ER_FAILED;
731  }
732  else if (rc == V_TRUE)
733  {
734  pr_clear_value (&list_val);
735  continue;
736  }
737 
738  rc = eval_value_rel_cmp (item, &list_val, R_EQ, NULL);
739  pr_clear_value (&list_val);
740 
741  if (rc == V_ERROR)
742  {
743  qfile_close_scan (thread_p, &s_id);
744  return ER_FAILED;
745  }
746  else if (rc == V_TRUE)
747  {
748  card++;
749  }
750  else
751  {
752  break;
753  }
754  }
755 
756  qfile_close_scan (thread_p, &s_id);
757 
758  return (qp_scan == S_END) ? card : ER_FAILED;
759 }
760 
761 /*
762  * eval_sub_multi_set_to_sort_list () -
763  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
764  * set1(in): DB_SET representation
765  * list_id(in): Sorted LIST FILE identifier
766  *
767  * Note: Find if given multi_set is a subset of the given list file.
768  * The list file must be of one column and treated like a
769  * multi_set. The routine uses the same semantics of finding
770  * subset relationship between two multi_sets.
771  *
772  * Note: in a sorted list file of one column , ALL the NULL values, tuples
773  * appear at the beginning of the list file.
774  */
775 static DB_LOGICAL
777 {
778  int i, k, card, card1, card2;
779  DB_LOGICAL res;
780  DB_LOGICAL rc;
781  DB_VALUE elem_val, elem_val2;
782  int found;
783 
784  PRIM_SET_NULL (&elem_val);
785  PRIM_SET_NULL (&elem_val2);
786 
787  card = set_size (set1);
788  if (card == 0)
789  {
790  return V_TRUE; /* empty set */
791  }
792 
793  res = V_TRUE;
794  for (i = 0; i < card; i++)
795  {
796  if (set_get_element (set1, i, &elem_val) != NO_ERROR)
797  {
798  return V_ERROR;
799  }
800  if (db_value_is_null (&elem_val))
801  {
802  return V_UNKNOWN;
803  }
804 
805  /* search for the value to see if value has already been considered */
806  found = false;
807  for (k = 0; !found && k < i; k++)
808  {
809  if (set_get_element (set1, k, &elem_val2) != NO_ERROR)
810  {
811  pr_clear_value (&elem_val);
812  return V_ERROR;
813  }
814  if (db_value_is_null (&elem_val2))
815  {
816  pr_clear_value (&elem_val2);
817  continue;
818  }
819 
820  rc = eval_value_rel_cmp (&elem_val, &elem_val2, R_EQ, NULL);
821  if (rc == V_ERROR)
822  {
823  pr_clear_value (&elem_val);
824  pr_clear_value (&elem_val2);
825  return V_ERROR;
826  }
827  else if (rc == V_TRUE)
828  {
829  found = true;
830  }
831  pr_clear_value (&elem_val2);
832  }
833 
834  if (found)
835  {
836  pr_clear_value (&elem_val);
837  continue;
838  }
839 
840  card1 = eval_item_card_set (&elem_val, set1, R_EQ);
841  if (card1 == ER_FAILED)
842  {
843  pr_clear_value (&elem_val);
844  return V_ERROR;
845  }
846  else if (card1 == UNKNOWN_CARD)
847  {
848  pr_clear_value (&elem_val);
849  return V_UNKNOWN;
850  }
851 
852  card2 = eval_item_card_sort_list (thread_p, &elem_val, list_id);
853  if (card2 == ER_FAILED)
854  {
855  pr_clear_value (&elem_val);
856  return V_ERROR;
857  }
858  else if (card2 == UNKNOWN_CARD)
859  {
860  pr_clear_value (&elem_val);
861  return V_UNKNOWN;
862  }
863 
864  if (card1 > card2)
865  {
866  pr_clear_value (&elem_val);
867  return V_FALSE;
868  }
869  }
870 
871  pr_clear_value (&elem_val);
872  return res;
873 }
874 
875 /*
876  * eval_sub_sort_list_to_multi_set () -
877  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
878  * list_id(in): Sorted LIST FILE identifier
879  * set(in): DB_SETrepresentation
880  *
881  * Note: Find if the given list file is a subset of the given multi_set
882  * The list file must be of one column and treated like a
883  * multi_set. The routine uses the same semantics of finding
884  * subset relationship between two multi_sets.
885  *
886  * Note: in a sorted list file of one column , ALL the NULL values, tuples
887  * appear at the beginning of the list file.
888  */
889 static DB_LOGICAL
891 {
892  int card1, card2;
893  DB_LOGICAL res, rc;
894  DB_VALUE list_val, list_val2;
895  QFILE_LIST_SCAN_ID s_id;
896  QFILE_TUPLE_RECORD tplrec, p_tplrec;
897  char *p_tplp;
898  SCAN_CODE qp_scan;
899  PR_TYPE *pr_type;
900  OR_BUF buf;
901  int length;
902  bool list_on;
903  int tpl_len;
904  char *ptr;
905 
906  /* assert */
907  if (list_id->type_list.domp == NULL)
908  {
909  return V_ERROR;
910  }
911 
912  PRIM_SET_NULL (&list_val);
913  PRIM_SET_NULL (&list_val2);
914 
915  if (list_id->tuple_cnt == 0)
916  {
917  return V_TRUE; /* empty set */
918  }
919 
920  if (qfile_open_list_scan (list_id, &s_id) != NO_ERROR)
921  {
922  return V_ERROR;
923  }
924 
925  res = V_TRUE;
926  pr_type = list_id->type_list.domp[0]->type;
927 
928  tplrec.size = 0;
929  tplrec.tpl = NULL;
930  p_tplrec.size = DB_PAGESIZE;
931  p_tplrec.tpl = (QFILE_TUPLE) db_private_alloc (thread_p, DB_PAGESIZE);
932  if (p_tplrec.tpl == NULL)
933  {
934  qfile_close_scan (thread_p, &s_id);
935  return V_ERROR;
936  }
937 
938  list_on = false;
939  card1 = 0;
940  while ((qp_scan = qfile_scan_list_next (thread_p, &s_id, &tplrec, PEEK)) == S_SUCCESS)
941  {
942  pr_clear_value (&list_val);
943 
944  if (qfile_locate_tuple_value (tplrec.tpl, 0, &ptr, &length) == V_UNBOUND)
945  {
946  res = V_UNKNOWN;
947  goto end;
948  }
949 
950  OR_BUF_INIT (buf, ptr, length);
951 
952  pr_type->data_readval (&buf, &list_val, list_id->type_list.domp[0], -1, true, NULL, 0);
953 
954  if (list_on == true)
955  {
956  p_tplp = (char *) p_tplrec.tpl + QFILE_TUPLE_LENGTH_SIZE;
957 
959 
960  pr_type->data_readval (&buf, &list_val2, list_id->type_list.domp[0], -1, true, NULL, 0);
961 
962  rc = eval_value_rel_cmp (&list_val, &list_val2, R_EQ, NULL);
963  if (rc == V_ERROR)
964  {
965  res = V_ERROR;
966  goto end;
967  }
968  else if (rc != V_TRUE)
969  {
970  card2 = eval_item_card_set (&list_val2, set, R_EQ);
971  if (card2 == ER_FAILED)
972  {
973  res = V_ERROR;
974  goto end;
975  }
976  else if (card2 == UNKNOWN_CARD)
977  {
978  res = V_UNKNOWN;
979  goto end;
980  }
981 
982  if (card1 > card2)
983  {
984  res = V_FALSE;
985  goto end;
986  }
987  card1 = 0;
988  }
989  pr_clear_value (&list_val2);
990  }
991 
992  tpl_len = QFILE_GET_TUPLE_LENGTH (tplrec.tpl);
993  if (p_tplrec.size < tpl_len)
994  {
995  p_tplrec.size = tpl_len;
996  p_tplrec.tpl = (QFILE_TUPLE) db_private_realloc (thread_p, p_tplrec.tpl, tpl_len);
997  if (p_tplrec.tpl == NULL)
998  {
999  res = V_ERROR;
1000  goto end;
1001  }
1002  }
1003  memcpy (p_tplrec.tpl, tplrec.tpl, tpl_len);
1004  list_on = true;
1005  card1++;
1006  }
1007 
1008  if (qp_scan != S_END)
1009  {
1010  res = V_ERROR;
1011  goto end;
1012  }
1013 
1014  if (list_on == true)
1015  {
1016  p_tplp = (char *) p_tplrec.tpl + QFILE_TUPLE_LENGTH_SIZE; /* no unbound value */
1017 
1019 
1020  pr_type->data_readval (&buf, &list_val2, list_id->type_list.domp[0], -1, true, NULL, 0);
1021 
1022  card2 = eval_item_card_set (&list_val2, set, R_EQ);
1023  if (card2 == ER_FAILED)
1024  {
1025  res = V_ERROR;
1026  goto end;
1027  }
1028  else if (card2 == UNKNOWN_CARD)
1029  {
1030  res = V_UNKNOWN;
1031  goto end;
1032  }
1033  else if (card1 > card2)
1034  {
1035  res = V_FALSE;
1036  goto end;
1037  }
1038  }
1039 
1040 end:
1041  pr_clear_value (&list_val);
1042  pr_clear_value (&list_val2);
1043  qfile_close_scan (thread_p, &s_id);
1044  if (p_tplrec.tpl != NULL)
1045  {
1046  db_private_free_and_init (thread_p, p_tplrec.tpl);
1047  }
1048  return res;
1049 }
1050 
1051 /*
1052  * eval_sub_sort_list_to_sort_list () -
1053  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1054  * list_id1(in): First Sorted LIST FILE identifier
1055  * list_id2(in): Second Sorted LIST FILE identifier
1056  *
1057  * Note: Find if the first list file is a subset of the second list
1058  * file. The list files must be of one column and treated like
1059  * a multi_set. The routine uses the same semantics of finding
1060  * subset relationship between two multi_sets.
1061  *
1062  * Note: in a sorted list file of one column , ALL the NULL values, tuples
1063  * appear at the beginning of the list file.
1064  */
1065 static DB_LOGICAL
1067 {
1068  int card1, card2;
1069  DB_LOGICAL res, rc;
1070  DB_VALUE list_val, list_val2;
1071  QFILE_LIST_SCAN_ID s_id;
1072  QFILE_TUPLE_RECORD tplrec, p_tplrec;
1073  char *p_tplp;
1074  SCAN_CODE qp_scan;
1075  PR_TYPE *pr_type;
1076  OR_BUF buf;
1077  int length;
1078  bool list_on;
1079  int tpl_len;
1080  char *ptr;
1081 
1082  /* assert */
1083  if (list_id1->type_list.domp == NULL)
1084  {
1085  return V_ERROR;
1086  }
1087 
1088  PRIM_SET_NULL (&list_val);
1089  PRIM_SET_NULL (&list_val2);
1090 
1091  if (list_id1->tuple_cnt == 0)
1092  {
1093  return V_TRUE; /* empty set */
1094  }
1095 
1096  if (qfile_open_list_scan (list_id1, &s_id) != NO_ERROR)
1097  {
1098  return V_ERROR;
1099  }
1100 
1101  res = V_TRUE;
1102  pr_type = list_id1->type_list.domp[0]->type;
1103 
1104  tplrec.size = 0;
1105  tplrec.tpl = NULL;
1106  p_tplrec.size = DB_PAGESIZE;
1107  p_tplrec.tpl = (QFILE_TUPLE) db_private_alloc (thread_p, DB_PAGESIZE);
1108  if (p_tplrec.tpl == NULL)
1109  {
1110  qfile_close_scan (thread_p, &s_id);
1111  return V_ERROR;
1112  }
1113 
1114  list_on = false;
1115  card1 = 0;
1116  while ((qp_scan = qfile_scan_list_next (thread_p, &s_id, &tplrec, PEEK)) == S_SUCCESS)
1117  {
1118  pr_clear_value (&list_val);
1119 
1120  if (qfile_locate_tuple_value (tplrec.tpl, 0, &ptr, &length) == V_UNBOUND)
1121  {
1122  res = V_UNKNOWN;
1123  goto end;
1124  }
1125 
1126  OR_BUF_INIT (buf, ptr, length);
1127 
1128  pr_type->data_readval (&buf, &list_val, list_id1->type_list.domp[0], -1, true, NULL, 0);
1129 
1130  if (list_on == true)
1131  {
1132  p_tplp = (char *) p_tplrec.tpl + QFILE_TUPLE_LENGTH_SIZE;
1133 
1135 
1136  pr_type->data_readval (&buf, &list_val2, list_id1->type_list.domp[0], -1, true, NULL, 0);
1137 
1138  rc = eval_value_rel_cmp (&list_val, &list_val2, R_EQ, NULL);
1139 
1140  if (rc == V_ERROR)
1141  {
1142  res = V_ERROR;
1143  goto end;
1144  }
1145  else if (rc != V_TRUE)
1146  {
1147  card2 = eval_item_card_sort_list (thread_p, &list_val2, list_id2);
1148  if (card2 == ER_FAILED)
1149  {
1150  res = V_ERROR;
1151  goto end;
1152  }
1153  else if (card2 == UNKNOWN_CARD)
1154  {
1155  res = V_UNKNOWN;
1156  goto end;
1157  }
1158 
1159  if (card1 > card2)
1160  {
1161  res = V_FALSE;
1162  goto end;
1163  }
1164  card1 = 0;
1165  }
1166  pr_clear_value (&list_val2);
1167  }
1168 
1169  tpl_len = QFILE_GET_TUPLE_LENGTH (tplrec.tpl);
1170  if (p_tplrec.size < tpl_len)
1171  {
1172  p_tplrec.size = tpl_len;
1173  p_tplrec.tpl = (QFILE_TUPLE) db_private_realloc (thread_p, p_tplrec.tpl, tpl_len);
1174  if (p_tplrec.tpl == NULL)
1175  {
1176  res = V_ERROR;
1177  goto end;
1178  }
1179  }
1180  memcpy (p_tplrec.tpl, tplrec.tpl, tpl_len);
1181  list_on = true;
1182  card1++;
1183  }
1184 
1185  if (qp_scan != S_END)
1186  {
1187  res = V_ERROR;
1188  goto end;
1189  }
1190 
1191  if (list_on == true)
1192  {
1193  p_tplp = (char *) p_tplrec.tpl + QFILE_TUPLE_LENGTH_SIZE; /* no unbound value */
1194 
1196 
1197  if (pr_type->data_readval (&buf, &list_val2, list_id1->type_list.domp[0], -1, true, NULL, 0) != NO_ERROR)
1198  {
1199  res = V_ERROR;
1200  goto end;
1201  }
1202 
1203  card2 = eval_item_card_sort_list (thread_p, &list_val2, list_id2);
1204  if (card2 == ER_FAILED)
1205  {
1206  res = V_ERROR;
1207  goto end;
1208  }
1209  else if (card2 == UNKNOWN_CARD)
1210  {
1211  res = V_UNKNOWN;
1212  goto end;
1213  }
1214  else if (card1 > card2)
1215  {
1216  res = V_FALSE;
1217  goto end;
1218  }
1219  }
1220 
1221 end:
1222  pr_clear_value (&list_val);
1223  pr_clear_value (&list_val2);
1224  qfile_close_scan (thread_p, &s_id);
1225  if (p_tplrec.tpl != NULL)
1226  {
1227  db_private_free_and_init (thread_p, p_tplrec.tpl);
1228  }
1229 
1230  return res;
1231 }
1232 
1233 /*
1234  * eval_eq_multi_set_to_sort_list () -
1235  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1236  * set(in): DB_SET representation
1237  * list_id(in): Sorted LIST FILE identifier
1238  *
1239  * Note: Find if given multi_set is equal to the given list file.
1240  * The routine uses the same semantics of finding equality
1241  * relationship between two multi_sets.
1242  */
1243 static DB_LOGICAL
1245 {
1246  DB_LOGICAL res1, res2;
1247 
1248  res1 = eval_sub_multi_set_to_sort_list (thread_p, set, list_id);
1249  res2 = eval_sub_sort_list_to_multi_set (thread_p, list_id, set);
1250 
1251  return eval_logical_result (res1, res2);
1252 }
1253 
1254 /*
1255  * eval_ne_multi_set_to_sort_list () -
1256  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1257  * set(in): DB_SET representation
1258  * list_id(in): Sorted LIST FILE identifier
1259  *
1260  * Note: Find if given multi_set is not equal to the given list file.
1261  */
1262 static DB_LOGICAL
1264 {
1265  DB_LOGICAL res;
1266 
1267  res = eval_eq_multi_set_to_sort_list (thread_p, set, list_id);
1268  /* negate the result */
1269  return eval_negative (res);
1270 }
1271 
1272 /*
1273  * eval_le_multi_set_to_sort_list () -
1274  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1275  * set(in): DB_SET representation
1276  * list_id(in): Sorted LIST FILE identifier
1277  *
1278  * Note: Find if given multi_set is a subset of the given list file.
1279  */
1280 static DB_LOGICAL
1282 {
1283  return eval_sub_multi_set_to_sort_list (thread_p, set, list_id);
1284 }
1285 
1286 /*
1287  * eval_lt_multi_set_to_sort_list () -
1288  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1289  * set(in): DB_SET representation
1290  * list_id(in): Sorted LIST FILE identifier
1291  *
1292  * Note: Find if given multi_set is a proper subset of the given list file.
1293  */
1294 static DB_LOGICAL
1296 {
1297  DB_LOGICAL res1, res2;
1298 
1299  res1 = eval_sub_multi_set_to_sort_list (thread_p, set, list_id);
1300  res2 = eval_ne_multi_set_to_sort_list (thread_p, set, list_id);
1301 
1302  return eval_logical_result (res1, res2);
1303 }
1304 
1305 /*
1306  * eval_le_sort_list_to_multi_set () -
1307  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1308  * list_id(in): Sorted LIST FILE identifier
1309  * set(in): Multi_set disk representation
1310  *
1311  * Note: Find if given list file is a subset of the multi_set.
1312  */
1313 static DB_LOGICAL
1315 {
1316  return eval_sub_sort_list_to_multi_set (thread_p, list_id, set);
1317 }
1318 
1319 /*
1320  * eval_lt_sort_list_to_multi_set () -
1321  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1322  * list_id(in): Sorted LIST FILE identifier
1323  * set(in): DB_SET representation
1324  *
1325  * Note: Find if given list file is a proper subset of the multi_set.
1326  */
1327 static DB_LOGICAL
1329 {
1330  DB_LOGICAL res1, res2;
1331 
1332  res1 = eval_sub_sort_list_to_multi_set (thread_p, list_id, set);
1333  res2 = eval_ne_multi_set_to_sort_list (thread_p, set, list_id);
1334 
1335  return eval_logical_result (res1, res2);
1336 }
1337 
1338 /*
1339  * eval_eq_sort_list_to_sort_list () -
1340  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1341  * list_id1(in): First Sorted LIST FILE identifier
1342  * list_id2(in): Second Sorted LIST FILE identifier
1343  *
1344  * Note: Find if the first list file is equal to the second list file.
1345  * The list files must be of one column and treated like
1346  * multi_sets. The routine uses the same semantics of finding
1347  * equality relationship between two multi_sets.
1348  */
1349 static DB_LOGICAL
1351 {
1352  DB_LOGICAL res1, res2;
1353 
1354  res1 = eval_sub_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1355  res2 = eval_sub_sort_list_to_sort_list (thread_p, list_id2, list_id1);
1356 
1357  return eval_logical_result (res1, res2);
1358 }
1359 
1360 /*
1361  * eval_ne_sort_list_to_sort_list () -
1362  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1363  * list_id1(in): First Sorted LIST FILE identifier
1364  * list_id2(in): Second Sorted LIST FILE identifier
1365  *
1366  * Note: Find if the first list file is not equal to the second one.
1367  */
1368 static DB_LOGICAL
1370 {
1371  DB_LOGICAL res;
1372 
1373  res = eval_eq_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1374  /* negate the result */
1375  return eval_negative (res);
1376 }
1377 
1378 /*
1379  * eval_le_sort_list_to_sort_list () -
1380  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1381  * list_id1(in): First Sorted LIST FILE identifier
1382  * list_id2(in): Second Sorted LIST FILE identifier
1383  *
1384  * Note: Find if the first list file is a subset if the second one.
1385  */
1386 static DB_LOGICAL
1388 {
1389  return eval_sub_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1390 }
1391 
1392 /*
1393  * eval_lt_sort_list_to_sort_list () -
1394  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1395  * list_id1(in): First Sorted LIST FILE identifier
1396  * list_id2(in): Second Sorted LIST FILE identifier
1397  *
1398  * Note: Find if the first list file is a proper subset if the second
1399  * list file.
1400  */
1401 static DB_LOGICAL
1403 {
1404  DB_LOGICAL res1, res2;
1405 
1406  res1 = eval_sub_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1407  res2 = eval_ne_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1408 
1409  return eval_logical_result (res1, res2);
1410 }
1411 
1412 /*
1413  * eval_multi_set_to_sort_list () -
1414  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1415  * set(in): DB_SET representation
1416  * list_id(in): Sorted LIST FILE identifier
1417  * rel_operator(in): Relational Operator
1418  *
1419  * Note: Find if given multi_set and the list file satisfy the
1420  * relationship indicated by the relational operator. The list
1421  * file must be of one column, sorted and is treated like a
1422  * multi_set.
1423  */
1424 static DB_LOGICAL
1426 {
1427  switch (rel_operator)
1428  {
1429  case R_LT:
1430  return eval_lt_multi_set_to_sort_list (thread_p, set, list_id);
1431  case R_LE:
1432  return eval_le_multi_set_to_sort_list (thread_p, set, list_id);
1433  case R_GT:
1434  return eval_lt_sort_list_to_multi_set (thread_p, list_id, set);
1435  case R_GE:
1436  return eval_le_sort_list_to_multi_set (thread_p, list_id, set);
1437  case R_EQ:
1438  return eval_eq_multi_set_to_sort_list (thread_p, set, list_id);
1439  case R_NE:
1440  return eval_ne_multi_set_to_sort_list (thread_p, set, list_id);
1441  default:
1442  return V_ERROR;
1443  }
1444 }
1445 
1446 /*
1447  * eval_sort_list_to_multi_set () -
1448  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1449  * list_id(in): Sorted LIST FILE identifier
1450  * set(in): DB_SET representation
1451  * rel_operator(in): Relational Operator
1452  *
1453  * Note: Find if given list file and the multi_set satisfy the
1454  * relationship indicated by the relational operator. The list
1455  * file must be of one column, sorted and is treated like a
1456  * multi_set.
1457  */
1458 static DB_LOGICAL
1460 {
1461  switch (rel_operator)
1462  {
1463  case R_LT:
1464  return eval_lt_sort_list_to_multi_set (thread_p, list_id, set);
1465  case R_LE:
1466  return eval_le_sort_list_to_multi_set (thread_p, list_id, set);
1467  case R_GT:
1468  return eval_lt_multi_set_to_sort_list (thread_p, set, list_id);
1469  case R_GE:
1470  return eval_le_multi_set_to_sort_list (thread_p, set, list_id);
1471  case R_EQ:
1472  return eval_eq_multi_set_to_sort_list (thread_p, set, list_id);
1473  case R_NE:
1474  return eval_ne_multi_set_to_sort_list (thread_p, set, list_id);
1475  default:
1476  return V_ERROR;
1477  }
1478 }
1479 
1480 /*
1481  * eval_sort_list_to_sort_list () -
1482  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1483  * list_id1(in): First Sorted LIST FILE identifier
1484  * list_id2(in): Second Sorted LIST FILE identifier
1485  * rel_operator(in): Relational Operator
1486  *
1487  * Note: Find if first list file and the second list file satisfy the
1488  * relationship indicated by the relational operator. The list
1489  * files must be of one column, sorted and are treated like
1490  * multi_sets.
1491  */
1492 static DB_LOGICAL
1494  REL_OP rel_operator)
1495 {
1496  switch (rel_operator)
1497  {
1498  case R_LT:
1499  return eval_lt_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1500  case R_LE:
1501  return eval_le_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1502  case R_GT:
1503  return eval_lt_sort_list_to_sort_list (thread_p, list_id2, list_id1);
1504  case R_GE:
1505  return eval_le_sort_list_to_sort_list (thread_p, list_id2, list_id1);
1506  case R_EQ:
1507  return eval_eq_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1508  case R_NE:
1509  return eval_ne_sort_list_to_sort_list (thread_p, list_id1, list_id2);
1510  default:
1511  return V_ERROR;
1512  }
1513 }
1514 
1515 /*
1516  * eval_set_list_cmp () -
1517  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1518  * et_comp(in): compound evaluation term
1519  * vd(in):
1520  * dbval1(in): lhs db_value, if lhs is a set.
1521  * dbval2(in): rhs db_value, if rhs is a set.
1522  *
1523  * Note: Perform set/set, set/list, and list/list comparisons.
1524  */
1525 static DB_LOGICAL
1526 eval_set_list_cmp (THREAD_ENTRY * thread_p, const COMP_EVAL_TERM * et_comp, val_descr * vd, DB_VALUE * dbval1,
1527  DB_VALUE * dbval2)
1528 {
1529  QFILE_LIST_ID *t_list_id;
1530  QFILE_SORTED_LIST_ID *lhs_srlist_id, *rhs_srlist_id;
1531 
1532  if (et_comp->lhs->type == TYPE_LIST_ID)
1533  {
1534  /* execute linked query */
1535  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_comp->lhs, vd);
1536  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_comp->lhs) != XASL_SUCCESS)
1537  {
1538  return V_ERROR;
1539  }
1540 
1541  /*
1542  * lhs value refers to a list file. for efficiency reasons
1543  * first sort the list file
1544  */
1545  lhs_srlist_id = et_comp->lhs->value.srlist_id;
1546  if (lhs_srlist_id->sorted == false)
1547  {
1548  if (lhs_srlist_id->list_id->tuple_cnt > 1)
1549  {
1550  t_list_id = qfile_sort_list (thread_p, lhs_srlist_id->list_id, NULL, Q_ALL, true);
1551  if (t_list_id == NULL)
1552  {
1553  return V_ERROR;
1554  }
1555  }
1556  lhs_srlist_id->sorted = true;
1557  }
1558 
1559  /* rhs value can only be either a set or a list file */
1560  if (et_comp->rhs->type == TYPE_LIST_ID)
1561  {
1562  /* execute linked query */
1563  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_comp->rhs, vd);
1564  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_comp->rhs) != XASL_SUCCESS)
1565  {
1566  return V_ERROR;
1567  }
1568 
1569  /*
1570  * rhs value refers to a list file. for efficiency reasons
1571  * first sort the list file
1572  */
1573  rhs_srlist_id = et_comp->rhs->value.srlist_id;
1574  if (rhs_srlist_id->sorted == false)
1575  {
1576  if (rhs_srlist_id->list_id->tuple_cnt > 1)
1577  {
1578  t_list_id = qfile_sort_list (thread_p, rhs_srlist_id->list_id, NULL, Q_ALL, true);
1579  if (t_list_id == NULL)
1580  {
1581  return V_ERROR;
1582  }
1583  }
1584  rhs_srlist_id->sorted = true;
1585  }
1586 
1587  /* compare two list files */
1588  return eval_sort_list_to_sort_list (thread_p, lhs_srlist_id->list_id, rhs_srlist_id->list_id,
1589  et_comp->rel_op);
1590  }
1591  else
1592  {
1593  /* compare list file and set */
1594  return eval_sort_list_to_multi_set (thread_p, lhs_srlist_id->list_id, db_get_set (dbval2), et_comp->rel_op);
1595  }
1596  }
1597  else if (et_comp->rhs->type == TYPE_LIST_ID)
1598  {
1599  /* execute linked query */
1600  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_comp->rhs, vd);
1601  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_comp->rhs) != XASL_SUCCESS)
1602  {
1603  return V_ERROR;
1604  }
1605 
1606  /*
1607  * rhs value refers to a list file. for efficiency reasons
1608  * first sort the list file
1609  */
1610  rhs_srlist_id = et_comp->rhs->value.srlist_id;
1611  if (rhs_srlist_id->sorted == false)
1612  {
1613  if (rhs_srlist_id->list_id->tuple_cnt > 1)
1614  {
1615  t_list_id = qfile_sort_list (thread_p, rhs_srlist_id->list_id, NULL, Q_ALL, true);
1616  if (t_list_id == NULL)
1617  {
1618  return V_ERROR;
1619  }
1620  }
1621  rhs_srlist_id->sorted = true;
1622  }
1623 
1624  /* lhs must be a set value, compare set and list */
1625  return eval_multi_set_to_sort_list (thread_p, db_get_set (dbval1), rhs_srlist_id->list_id, et_comp->rel_op);
1626  }
1627 
1628  return V_UNKNOWN;
1629 }
1630 
1631 /*
1632  * Main Predicate Evaluation Routines
1633  */
1634 
1635 /*
1636  * eval_pred () -
1637  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
1638  * pr(in): Predicate Expression Tree
1639  * vd(in): Value descriptor for positional values (optional)
1640  * obj_oid(in): Object Identifier
1641  *
1642  * Note: This is the main predicate expression evalution routine. It
1643  * evaluates the given predicate predicate expression on the
1644  * specified evaluation item to see if the evaluation item
1645  * satisfies the indicate predicate. It uses a 3-valued logic
1646  * and returns V_TRUE, V_FALSE or V_UNKNOWN. If an error occurs,
1647  * necessary error code is set and V_ERROR is returned.
1648  */
1649 DB_LOGICAL
1650 eval_pred (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
1651 {
1652  const COMP_EVAL_TERM *et_comp;
1653  const ALSM_EVAL_TERM *et_alsm;
1654  const LIKE_EVAL_TERM *et_like;
1655  DB_VALUE *peek_val1, *peek_val2, *peek_val3;
1656  DB_LOGICAL result = V_UNKNOWN;
1657  int regexp_res;
1658  const PRED_EXPR *t_pr;
1659  QFILE_SORTED_LIST_ID *srlist_id;
1660 
1661  peek_val1 = NULL;
1662  peek_val2 = NULL;
1663  peek_val3 = NULL;
1664 
1666  {
1669 
1670  return V_ERROR;
1671  }
1672 
1673  thread_inc_recursion_depth (thread_p);
1674 
1675  switch (pr->type)
1676  {
1677  case T_PRED:
1678  switch (pr->pe.m_pred.bool_op)
1679  {
1680  case B_AND:
1681  /* 'pt_to_pred_expr()' will generate right-linear tree */
1682  result = V_TRUE;
1683  for (t_pr = pr; result == V_TRUE && t_pr->type == T_PRED && t_pr->pe.m_pred.bool_op == B_AND;
1684  t_pr = t_pr->pe.m_pred.rhs)
1685  {
1686  if (result == V_UNKNOWN)
1687  {
1688  result = eval_pred (thread_p, t_pr->pe.m_pred.lhs, vd, obj_oid);
1689  result = (result == V_TRUE) ? V_UNKNOWN : result;
1690  }
1691  else
1692  {
1693  result = eval_pred (thread_p, t_pr->pe.m_pred.lhs, vd, obj_oid);
1694  }
1695 
1696  if (result == V_FALSE || result == V_ERROR)
1697  {
1698  goto exit;
1699  }
1700  }
1701 
1702  if (result == V_UNKNOWN)
1703  {
1704  result = eval_pred (thread_p, t_pr, vd, obj_oid);
1705  result = (result == V_TRUE) ? V_UNKNOWN : result;
1706  }
1707  else
1708  {
1709  result = eval_pred (thread_p, t_pr, vd, obj_oid);
1710  }
1711  break;
1712 
1713  case B_OR:
1714  /* 'pt_to_pred_expr()' will generate right-linear tree */
1715  result = V_FALSE;
1716  for (t_pr = pr; result == V_FALSE && t_pr->type == T_PRED && t_pr->pe.m_pred.bool_op == B_OR;
1717  t_pr = t_pr->pe.m_pred.rhs)
1718  {
1719  if (result == V_UNKNOWN)
1720  {
1721  result = eval_pred (thread_p, t_pr->pe.m_pred.lhs, vd, obj_oid);
1722  result = (result == V_FALSE) ? V_UNKNOWN : result;
1723  }
1724  else
1725  {
1726  result = eval_pred (thread_p, t_pr->pe.m_pred.lhs, vd, obj_oid);
1727  }
1728 
1729  if (result == V_TRUE || result == V_ERROR)
1730  {
1731  goto exit;
1732  }
1733  }
1734 
1735  if (result == V_UNKNOWN)
1736  {
1737  result = eval_pred (thread_p, t_pr, vd, obj_oid);
1738  result = (result == V_FALSE) ? V_UNKNOWN : result;
1739  }
1740  else
1741  {
1742  result = eval_pred (thread_p, t_pr, vd, obj_oid);
1743  }
1744  break;
1745 
1746  case B_XOR:
1747  {
1748  DB_LOGICAL result_lhs, result_rhs;
1749 
1750  result_lhs = eval_pred (thread_p, pr->pe.m_pred.lhs, vd, obj_oid);
1751  result_rhs = eval_pred (thread_p, pr->pe.m_pred.rhs, vd, obj_oid);
1752 
1753  if (result_lhs == V_ERROR || result_rhs == V_ERROR)
1754  {
1755  result = V_ERROR;
1756  }
1757  else if (result_lhs == V_UNKNOWN || result_rhs == V_UNKNOWN)
1758  {
1759  result = V_UNKNOWN;
1760  }
1761  else if (result_lhs == result_rhs)
1762  {
1763  result = V_FALSE;
1764  }
1765  else
1766  {
1767  result = V_TRUE;
1768  }
1769  }
1770  break;
1771 
1772  case B_IS:
1773  case B_IS_NOT:
1774  {
1775  DB_LOGICAL result_lhs, result_rhs;
1776 
1777  result_lhs = eval_pred (thread_p, pr->pe.m_pred.lhs, vd, obj_oid);
1778  result_rhs = eval_pred (thread_p, pr->pe.m_pred.rhs, vd, obj_oid);
1779 
1780  if (result_lhs == V_ERROR || result_rhs == V_ERROR)
1781  {
1782  result = V_ERROR;
1783  }
1784  else if (result_lhs == result_rhs)
1785  {
1786  result = (pr->pe.m_pred.bool_op == B_IS) ? V_TRUE : V_FALSE;
1787  }
1788  else
1789  {
1790  result = (pr->pe.m_pred.bool_op == B_IS) ? V_FALSE : V_TRUE;
1791  }
1792  }
1793  break;
1794 
1795  default:
1796  result = V_ERROR;
1797  break;
1798  }
1799  break;
1800 
1801  case T_EVAL_TERM:
1802  switch (pr->pe.m_eval_term.et_type)
1803  {
1804  case T_COMP_EVAL_TERM:
1805  /*
1806  * compound evaluation terms are used to test relationships
1807  * such as equality, greater than etc. between two items
1808  * Each datatype defines its own meaning of relationship
1809  * indicated by one of the relational operators.
1810  */
1811  et_comp = &pr->pe.m_eval_term.et.et_comp;
1812 
1813  /* evaluate NULL predicate, if specified */
1814  if (et_comp->rel_op == R_NULL)
1815  {
1816  result = eval_pred_comp1 (thread_p, pr, vd, obj_oid);
1817  if (result == V_ERROR)
1818  {
1819  goto exit;
1820  }
1821  break;
1822  }
1823 
1824  /* evaluate EXISTS predicate, if specified */
1825  if (et_comp->rel_op == R_EXISTS)
1826  {
1827  /* leaf node should refer to either a set or list file */
1828  if (et_comp->lhs->type == TYPE_LIST_ID)
1829  {
1830  /* execute linked query */
1831  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_comp->lhs, vd);
1832  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_comp->lhs) != XASL_SUCCESS)
1833  {
1834  result = V_ERROR;
1835  goto exit;
1836  }
1837 
1838  srlist_id = et_comp->lhs->value.srlist_id;
1839  result = ((srlist_id->list_id->tuple_cnt > 0) ? V_TRUE : V_FALSE);
1840  }
1841  else
1842  {
1843  /* must be a set */
1844  if (fetch_peek_dbval (thread_p, et_comp->lhs, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
1845  {
1846  result = V_ERROR;
1847  goto exit;
1848  }
1849  else if (db_value_is_null (peek_val1))
1850  {
1851  result = V_UNKNOWN;
1852  goto exit;
1853  }
1854  else if (!TP_IS_SET_TYPE (DB_VALUE_DOMAIN_TYPE (peek_val1)))
1855  {
1857  result = V_ERROR;
1858  goto exit;
1859  }
1860 
1861  result = ((db_set_size (db_get_set (peek_val1)) > 0) ? V_TRUE : V_FALSE);
1862  }
1863  break;
1864  }
1865 
1866  /*
1867  * fetch left hand size and right hand size values, if one of
1868  * values are unbound, result = V_UNKNOWN
1869  */
1870  if (et_comp->lhs->type != TYPE_LIST_ID)
1871  {
1872  if (fetch_peek_dbval (thread_p, et_comp->lhs, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
1873  {
1874  result = V_ERROR;
1875  goto exit;
1876  }
1877  else if (db_value_is_null (peek_val1))
1878  {
1879  if (et_comp->rel_op != R_EQ_TORDER && et_comp->rel_op != R_NULLSAFE_EQ)
1880  {
1881  result = V_UNKNOWN;
1882  goto exit;
1883  }
1884  }
1885  }
1886 
1887  if (et_comp->rhs->type != TYPE_LIST_ID)
1888  {
1889  if (fetch_peek_dbval (thread_p, et_comp->rhs, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
1890  {
1891  result = V_ERROR;
1892  goto exit;
1893  }
1894  else if (db_value_is_null (peek_val2))
1895  {
1896  if (et_comp->rel_op != R_EQ_TORDER && et_comp->rel_op != R_NULLSAFE_EQ)
1897  {
1898  result = V_UNKNOWN;
1899  goto exit;
1900  }
1901  }
1902  }
1903 
1904  if (et_comp->lhs->type == TYPE_LIST_ID || et_comp->rhs->type == TYPE_LIST_ID)
1905  {
1906  result = eval_set_list_cmp (thread_p, et_comp, vd, peek_val1, peek_val2);
1907  }
1908  else
1909  {
1910  /*
1911  * general case: compare values, db_value_compare will
1912  * take care of any coercion necessary.
1913  */
1914  result = eval_value_rel_cmp (peek_val1, peek_val2, et_comp->rel_op, et_comp);
1915  }
1916  break;
1917 
1918  case T_ALSM_EVAL_TERM:
1919  {
1920  DB_TYPE rhs_type = DB_TYPE_UNKNOWN;
1921  bool rhs_is_set = false;
1922 
1923  et_alsm = &pr->pe.m_eval_term.et.et_alsm;
1924 
1925  /*
1926  * Note: According to ANSI, if the set or list file is empty,
1927  * the result of comparison is true/false for ALL/SOME,
1928  * regardless of whether lhs value is bound or not.
1929  */
1930  if (et_alsm->elemset->type != TYPE_LIST_ID)
1931  {
1932  /* fetch rhs value */
1933  if (fetch_peek_dbval (thread_p, et_alsm->elemset, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
1934  {
1935  result = V_ERROR;
1936  goto exit;
1937  }
1938  else if (db_value_is_null (peek_val2))
1939  {
1940  result = V_UNKNOWN;
1941  goto exit;
1942  }
1943 
1944  rhs_type = DB_VALUE_TYPE (peek_val2);
1945  rhs_is_set = TP_IS_SET_TYPE (rhs_type);
1946  if (rhs_is_set && set_size (db_get_set (peek_val2)) == 0)
1947  {
1948  /* empty set */
1949  result = (et_alsm->eq_flag == F_ALL) ? V_TRUE : V_FALSE;
1950  goto exit;
1951  }
1952  }
1953  else
1954  {
1955  /* execute linked query */
1956  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_alsm->elemset, vd);
1957  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_alsm->elemset) != XASL_SUCCESS)
1958  {
1959  result = V_ERROR;
1960  goto exit;
1961  }
1962  else
1963  {
1964  /* check of empty list file */
1965  srlist_id = et_alsm->elemset->value.srlist_id;
1966  if (srlist_id->list_id->tuple_cnt == 0)
1967  {
1968  result = (et_alsm->eq_flag == F_ALL) ? V_TRUE : V_FALSE;
1969  goto exit;
1970  }
1971  }
1972  }
1973 
1974  /* fetch lhs value */
1975  if (fetch_peek_dbval (thread_p, et_alsm->elem, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
1976  {
1977  result = V_ERROR;
1978  goto exit;
1979  }
1980  else if (db_value_is_null (peek_val1))
1981  {
1982  result = V_UNKNOWN;
1983  goto exit;
1984  }
1985 
1986  if (et_alsm->elemset->type == TYPE_LIST_ID)
1987  {
1988  /* rhs value is a list, use list evaluation routines */
1989  srlist_id = et_alsm->elemset->value.srlist_id;
1990  if (et_alsm->eq_flag == F_ALL)
1991  {
1992  result = eval_all_list_eval (thread_p, peek_val1, srlist_id->list_id, et_alsm->rel_op);
1993  }
1994  else
1995  {
1996  result = eval_some_list_eval (thread_p, peek_val1, srlist_id->list_id, et_alsm->rel_op);
1997  }
1998  }
1999  else if (rhs_is_set)
2000  {
2001  /* rhs value is a set, use set evaluation routines */
2002  if (et_alsm->eq_flag == F_ALL)
2003  {
2004  result = eval_all_eval (peek_val1, db_get_set (peek_val2), et_alsm->rel_op);
2005  }
2006  else
2007  {
2008  result = eval_some_eval (peek_val1, db_get_set (peek_val2), et_alsm->rel_op);
2009  }
2010  }
2011  else
2012  {
2013  /* other cases, use general evaluation routines */
2014  result = eval_value_rel_cmp (peek_val1, peek_val2, et_alsm->rel_op, NULL);
2015  }
2016  }
2017  break;
2018 
2019  case T_LIKE_EVAL_TERM:
2020  et_like = &pr->pe.m_eval_term.et.et_like;
2021 
2022  /* fetch source text expression */
2023  if (fetch_peek_dbval (thread_p, et_like->src, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2024  {
2025  result = V_ERROR;
2026  goto exit;
2027  }
2028  else if (db_value_is_null (peek_val1))
2029  {
2030  result = V_UNKNOWN;
2031  goto exit;
2032  }
2033 
2034  /* fetch pattern regular expression */
2035  if (fetch_peek_dbval (thread_p, et_like->pattern, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
2036  {
2037  result = V_ERROR;
2038  goto exit;
2039  }
2040  else if (db_value_is_null (peek_val2))
2041  {
2042  result = V_UNKNOWN;
2043  goto exit;
2044  }
2045 
2046  if (et_like->esc_char)
2047  {
2048  /* fetch escape regular expression */
2049  if (fetch_peek_dbval (thread_p, et_like->esc_char, vd, NULL, obj_oid, NULL, &peek_val3) != NO_ERROR)
2050  {
2051  result = V_ERROR;
2052  goto exit;
2053  }
2054  }
2055  /* evaluate regular expression match */
2056  /* Note: Currently only STRING type is supported */
2057  db_string_like (peek_val1, peek_val2, peek_val3, &regexp_res);
2058  result = (DB_LOGICAL) regexp_res;
2059  break;
2060 
2061  case T_RLIKE_EVAL_TERM:
2062  /* evaluate rlike */
2063  result = eval_pred_rlike7 (thread_p, pr, vd, obj_oid);
2064  break;
2065 
2066  default:
2067  result = V_ERROR;
2068  break;
2069  }
2070  break;
2071 
2072  case T_NOT_TERM:
2073  result = eval_pred (thread_p, pr->pe.m_not_term, vd, obj_oid);
2074  /* negate the result */
2075  result = eval_negative (result);
2076  break;
2077 
2078  default:
2079  result = V_ERROR;
2080  }
2081 
2082 exit:
2083 
2084  thread_dec_recursion_depth (thread_p);
2085 
2086  return result;
2087 }
2088 
2089 /*
2090  * eval_pred_comp0 () -
2091  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2092  * pr(in): Predicate Expression Tree
2093  * vd(in): Value descriptor for positional values (optional)
2094  * obj_oid(in): Object Identifier
2095  *
2096  * Note: single node regular comparison predicate
2097  */
2098 DB_LOGICAL
2099 eval_pred_comp0 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2100 {
2101  const COMP_EVAL_TERM *et_comp;
2102  DB_VALUE *peek_val1, *peek_val2;
2103 
2104  peek_val1 = NULL;
2105  peek_val2 = NULL;
2106 
2107  et_comp = &pr->pe.m_eval_term.et.et_comp;
2108 
2109  /*
2110  * fetch left hand size and right hand size values, if one of
2111  * values are unbound, return V_UNKNOWN
2112  */
2113  if (fetch_peek_dbval (thread_p, et_comp->lhs, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2114  {
2115  return V_ERROR;
2116  }
2117  else if (db_value_is_null (peek_val1) && et_comp->rel_op != R_NULLSAFE_EQ)
2118  {
2119  return V_UNKNOWN;
2120  }
2121 
2122  if (fetch_peek_dbval (thread_p, et_comp->rhs, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
2123  {
2124  return V_ERROR;
2125  }
2126  else if (db_value_is_null (peek_val2) && et_comp->rel_op != R_NULLSAFE_EQ)
2127  {
2128  return V_UNKNOWN;
2129  }
2130 
2131  /*
2132  * general case: compare values, db_value_compare will
2133  * take care of any coercion necessary.
2134  */
2135  return eval_value_rel_cmp (peek_val1, peek_val2, et_comp->rel_op, et_comp);
2136 }
2137 
2138 /*
2139  * eval_pred_comp1 () -
2140  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2141  * pr(in): Predicate Expression Tree
2142  * vd(in): Value descriptor for positional values (optional)
2143  * obj_oid(in): Object Identifier
2144  *
2145  * Note: single leaf node NULL predicate
2146  */
2147 DB_LOGICAL
2148 eval_pred_comp1 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2149 {
2150  const COMP_EVAL_TERM *et_comp;
2151  DB_VALUE *peek_val1;
2152 
2153  peek_val1 = NULL;
2154 
2155  et_comp = &pr->pe.m_eval_term.et.et_comp;
2156 
2157  if (fetch_peek_dbval (thread_p, et_comp->lhs, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2158  {
2159  return V_ERROR;
2160  }
2161  else if (db_value_is_null (peek_val1))
2162  {
2163  return V_TRUE;
2164  }
2165 
2166  if (DB_VALUE_DOMAIN_TYPE (peek_val1) == DB_TYPE_OID
2167  && !heap_is_object_not_null (thread_p, (OID *) NULL, db_get_oid (peek_val1)))
2168  {
2169  return V_TRUE;
2170  }
2171  else
2172  {
2173  return V_FALSE;
2174  }
2175 }
2176 
2177 /*
2178  * eval_pred_comp2 () -
2179  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2180  * pr(in): Predicate Expression Tree
2181  * vd(in): Value descriptor for positional values (optional)
2182  * obj_oid(in): Object Identifier
2183  *
2184  * Note: single node EXIST predicate
2185  */
2186 DB_LOGICAL
2187 eval_pred_comp2 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2188 {
2189  const COMP_EVAL_TERM *et_comp;
2190  DB_VALUE *peek_val1;
2191 
2192  peek_val1 = NULL;
2193 
2194  et_comp = &pr->pe.m_eval_term.et.et_comp;
2195 
2196  /* evaluate EXISTS predicate, if specified */
2197  /* leaf node should refer to either a set or list file */
2198  if (et_comp->lhs->type == TYPE_LIST_ID)
2199  {
2200  /* execute linked query */
2201  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_comp->lhs, vd);
2202  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_comp->lhs) != XASL_SUCCESS)
2203  {
2204  return V_ERROR;
2205  }
2206  else
2207  {
2208  QFILE_SORTED_LIST_ID *srlist_id;
2209 
2210  srlist_id = et_comp->lhs->value.srlist_id;
2211  return (srlist_id->list_id->tuple_cnt > 0) ? V_TRUE : V_FALSE;
2212  }
2213  }
2214  else
2215  {
2216  if (fetch_peek_dbval (thread_p, et_comp->lhs, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2217  {
2218  return V_ERROR;
2219  }
2220  else if (db_value_is_null (peek_val1))
2221  {
2222  return V_UNKNOWN;
2223  }
2224  else if (!TP_IS_SET_TYPE (DB_VALUE_DOMAIN_TYPE (peek_val1)))
2225  {
2227  return V_ERROR;
2228  }
2229 
2230  return (set_size (db_get_set (peek_val1)) > 0) ? V_TRUE : V_FALSE;
2231  }
2232 }
2233 
2234 /*
2235  * eval_pred_comp3 () -
2236  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2237  * pr(in): Predicate Expression Tree
2238  * vd(in): Value descriptor for positional values (optional)
2239  * obj_oid(in): Object Identifier
2240  *
2241  * Note: single node lhs or rhs list file predicate
2242  */
2243 DB_LOGICAL
2244 eval_pred_comp3 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2245 {
2246  const COMP_EVAL_TERM *et_comp;
2247  DB_VALUE *peek_val1, *peek_val2;
2248 
2249  peek_val1 = NULL;
2250  peek_val2 = NULL;
2251 
2252  et_comp = &pr->pe.m_eval_term.et.et_comp;
2253 
2254  /*
2255  * fetch left hand size and right hand size values, if one of
2256  * values are unbound, result = V_UNKNOWN
2257  */
2258  if (et_comp->lhs->type != TYPE_LIST_ID)
2259  {
2260  if (fetch_peek_dbval (thread_p, et_comp->lhs, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2261  {
2262  return V_ERROR;
2263  }
2264  else if (db_value_is_null (peek_val1))
2265  {
2266  return V_UNKNOWN;
2267  }
2268  }
2269 
2270  if (et_comp->rhs->type != TYPE_LIST_ID)
2271  {
2272  if (fetch_peek_dbval (thread_p, et_comp->rhs, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
2273  {
2274  return V_ERROR;
2275  }
2276  else if (db_value_is_null (peek_val2))
2277  {
2278  return V_UNKNOWN;
2279  }
2280  }
2281 
2282  if (et_comp->lhs->type == TYPE_LIST_ID || et_comp->rhs->type == TYPE_LIST_ID)
2283  {
2284  return eval_set_list_cmp (thread_p, et_comp, vd, peek_val1, peek_val2);
2285  }
2286  else
2287  {
2288  return V_UNKNOWN;
2289  }
2290 }
2291 
2292 /*
2293  * eval_pred_alsm4 () -
2294  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2295  * pr(in): Predicate Expression Tree
2296  * vd(in): Value descriptor for positional values (optional)
2297  * obj_oid(in): Object Identifier
2298  *
2299  * Note: single node all/some predicate with a set
2300  */
2301 DB_LOGICAL
2302 eval_pred_alsm4 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2303 {
2304  const ALSM_EVAL_TERM *et_alsm;
2305  DB_VALUE *peek_val1, *peek_val2;
2306 
2307  peek_val1 = NULL;
2308  peek_val2 = NULL;
2309 
2310  et_alsm = &pr->pe.m_eval_term.et.et_alsm;
2311 
2312  /*
2313  * Note: According to ANSI, if the set or list file is empty,
2314  * the result of comparison is true/false for ALL/SOME,
2315  * regardles of whether lhs value is bound or not.
2316  */
2317  if (fetch_peek_dbval (thread_p, et_alsm->elemset, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
2318  {
2319  return V_ERROR;
2320  }
2321  else if (db_value_is_null (peek_val2))
2322  {
2323  return V_UNKNOWN;
2324  }
2325  else if (!TP_IS_SET_TYPE (DB_VALUE_DOMAIN_TYPE (peek_val2)))
2326  {
2328  return V_ERROR;
2329  }
2330 
2331  if (set_size (db_get_set (peek_val2)) == 0)
2332  {
2333  /* empty set */
2334  return ((et_alsm->eq_flag == F_ALL) ? V_TRUE : V_FALSE);
2335  }
2336 
2337  /* fetch item value */
2338  if (fetch_peek_dbval (thread_p, et_alsm->elem, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2339  {
2340  return V_ERROR;
2341  }
2342  else if (db_value_is_null (peek_val1))
2343  {
2344  return V_UNKNOWN;
2345  }
2346 
2347  /* rhs value is a set, use set evaluation routines */
2348  if (et_alsm->eq_flag == F_ALL)
2349  {
2350  return eval_all_eval (peek_val1, db_get_set (peek_val2), et_alsm->rel_op);
2351  }
2352  else
2353  {
2354  return eval_some_eval (peek_val1, db_get_set (peek_val2), et_alsm->rel_op);
2355  }
2356 }
2357 
2358 /*
2359  * eval_pred_alsm5 () -
2360  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2361  * pr(in): Predicate Expression Tree
2362  * vd(in): Value descriptor for positional values (optional)
2363  * obj_oid(in): Object Identifier
2364  *
2365  * Note: single node all/some predicate with a list file
2366  */
2367 DB_LOGICAL
2368 eval_pred_alsm5 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2369 {
2370  const ALSM_EVAL_TERM *et_alsm;
2371  DB_VALUE *peek_val1;
2372  QFILE_SORTED_LIST_ID *srlist_id;
2373 
2374  peek_val1 = NULL;
2375 
2376  et_alsm = &pr->pe.m_eval_term.et.et_alsm;
2377 
2378  /* execute linked query */
2379  EXECUTE_REGU_VARIABLE_XASL (thread_p, et_alsm->elemset, vd);
2380  if (CHECK_REGU_VARIABLE_XASL_STATUS (et_alsm->elemset) != XASL_SUCCESS)
2381  {
2382  return V_ERROR;
2383  }
2384 
2385  /*
2386  * Note: According to ANSI, if the set or list file is empty,
2387  * the result of comparison is true/false for ALL/SOME,
2388  * regardless of whether lhs value is bound or not.
2389  */
2390  srlist_id = et_alsm->elemset->value.srlist_id;
2391  if (srlist_id->list_id->tuple_cnt == 0)
2392  {
2393  return (et_alsm->eq_flag == F_ALL) ? V_TRUE : V_FALSE;
2394  }
2395 
2396  /* fetch item value */
2397  if (fetch_peek_dbval (thread_p, et_alsm->elem, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2398  {
2399  return V_ERROR;
2400  }
2401  else if (db_value_is_null (peek_val1))
2402  {
2403  return V_UNKNOWN;
2404  }
2405 
2406  if (et_alsm->eq_flag == F_ALL)
2407  {
2408  return eval_all_list_eval (thread_p, peek_val1, srlist_id->list_id, et_alsm->rel_op);
2409  }
2410  else
2411  {
2412  return eval_some_list_eval (thread_p, peek_val1, srlist_id->list_id, et_alsm->rel_op);
2413  }
2414 }
2415 
2416 /*
2417  * eval_pred_like6 () -
2418  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2419  * pr(in): Predicate Expression Tree
2420  * vd(in): Value descriptor for positional values (optional)
2421  * obj_oid(in): Object Identifier
2422  *
2423  * Note: single node like predicate
2424  */
2425 DB_LOGICAL
2426 eval_pred_like6 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2427 {
2428  const LIKE_EVAL_TERM *et_like;
2429  DB_VALUE *peek_val1, *peek_val2, *peek_val3;
2430  int regexp_res;
2431 
2432  peek_val1 = NULL;
2433  peek_val2 = NULL;
2434  peek_val3 = NULL;
2435 
2436  et_like = &pr->pe.m_eval_term.et.et_like;
2437 
2438  /* fetch source text expression */
2439  if (fetch_peek_dbval (thread_p, et_like->src, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2440  {
2441  return V_ERROR;
2442  }
2443  else if (db_value_is_null (peek_val1))
2444  {
2445  return V_UNKNOWN;
2446  }
2447 
2448  /* fetch pattern regular expression */
2449  if (fetch_peek_dbval (thread_p, et_like->pattern, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
2450  {
2451  return V_ERROR;
2452  }
2453  else if (db_value_is_null (peek_val2))
2454  {
2455  return V_UNKNOWN;
2456  }
2457 
2458  if (et_like->esc_char)
2459  {
2460  /* fetch escape regular expression */
2461  if (fetch_peek_dbval (thread_p, et_like->esc_char, vd, NULL, obj_oid, NULL, &peek_val3) != NO_ERROR)
2462  {
2463  return V_ERROR;
2464  }
2465  }
2466 
2467  /* evaluate regular expression match */
2468  /* Note: Currently only STRING type is supported */
2469  db_string_like (peek_val1, peek_val2, peek_val3, &regexp_res);
2470 
2471  return (DB_LOGICAL) regexp_res;
2472 }
2473 
2474 /*
2475  * eval_pred_rlike7 () -
2476  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2477  * pr(in): Predicate Expression Tree
2478  * vd(in): Value descriptor for positional values (optional)
2479  * obj_oid(in): Object Identifier
2480  *
2481  * Note: single node like predicate
2482  */
2483 DB_LOGICAL
2484 eval_pred_rlike7 (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, val_descr * vd, OID * obj_oid)
2485 {
2486  const RLIKE_EVAL_TERM *et_rlike;
2487  DB_VALUE *peek_val1, *peek_val2, *peek_val3;
2488  int regexp_res;
2489 
2490  peek_val1 = NULL;
2491  peek_val2 = NULL;
2492  peek_val3 = NULL;
2493 
2494  et_rlike = &pr->pe.m_eval_term.et.et_rlike;
2495 
2496  /* fetch source text expression */
2497  if (fetch_peek_dbval (thread_p, et_rlike->src, vd, NULL, obj_oid, NULL, &peek_val1) != NO_ERROR)
2498  {
2499  return V_ERROR;
2500  }
2501  else if (db_value_is_null (peek_val1))
2502  {
2503  return V_UNKNOWN;
2504  }
2505 
2506  /* fetch pattern */
2507  if (fetch_peek_dbval (thread_p, et_rlike->pattern, vd, NULL, obj_oid, NULL, &peek_val2) != NO_ERROR)
2508  {
2509  return V_ERROR;
2510  }
2511  else if (db_value_is_null (peek_val2))
2512  {
2513  return V_UNKNOWN;
2514  }
2515 
2516  /* fetch case sensitiveness */
2517  if (fetch_peek_dbval (thread_p, et_rlike->case_sensitive, vd, NULL, obj_oid, NULL, &peek_val3) != NO_ERROR)
2518  {
2519  return V_ERROR;
2520  }
2521  else if (db_value_is_null (peek_val3))
2522  {
2523  return V_UNKNOWN;
2524  }
2525 
2526  /* evaluate regular expression match */
2527  db_string_rlike (peek_val1, peek_val2, peek_val3, &et_rlike->compiled_regex, &et_rlike->compiled_pattern,
2528  &regexp_res);
2529 
2530  return (DB_LOGICAL) regexp_res;
2531 }
2532 
2533 /*
2534  * eval_fnc () -
2535  * return:
2536  * pr(in): Predicate Expression Tree
2537  * single_node_type(in):
2538  */
2540 eval_fnc (THREAD_ENTRY * thread_p, const PRED_EXPR * pr, DB_TYPE * single_node_type)
2541 {
2542  // todo - thread_p is never used
2543 
2544  const COMP_EVAL_TERM *et_comp;
2545  const ALSM_EVAL_TERM *et_alsm;
2546 
2547  *single_node_type = DB_TYPE_NULL;
2548  if (pr == NULL)
2549  {
2550  return NULL;
2551  }
2552 
2553  if (pr->type == T_EVAL_TERM)
2554  {
2555  switch (pr->pe.m_eval_term.et_type)
2556  {
2557  case T_COMP_EVAL_TERM:
2558  et_comp = &pr->pe.m_eval_term.et.et_comp;
2559 
2560  /*
2561  * et_comp->type can be DB_TYPE_NULL,
2562  * in the case of positional variables
2563  */
2564  *single_node_type = et_comp->type;
2565 
2566  if (et_comp->rel_op == R_NULL)
2567  {
2568  return (PR_EVAL_FNC) eval_pred_comp1;
2569  }
2570  else if (et_comp->rel_op == R_EXISTS)
2571  {
2572  return (PR_EVAL_FNC) eval_pred_comp2;
2573  }
2574 
2575  if (et_comp->lhs->type == TYPE_LIST_ID || et_comp->rhs->type == TYPE_LIST_ID)
2576  {
2577  return (PR_EVAL_FNC) eval_pred_comp3;
2578  }
2579 
2580  return (PR_EVAL_FNC) eval_pred_comp0;
2581 
2582  case T_ALSM_EVAL_TERM:
2583  et_alsm = &pr->pe.m_eval_term.et.et_alsm;
2584 
2585  /*
2586  * et_alsm->item_type can be DB_TYPE_NULL,
2587  * in the case of positional variables
2588  */
2589  *single_node_type = et_alsm->item_type;
2590 
2591  return ((et_alsm->elemset->type != TYPE_LIST_ID)
2593 
2594  case T_LIKE_EVAL_TERM:
2595  return (PR_EVAL_FNC) eval_pred_like6;
2596 
2597  case T_RLIKE_EVAL_TERM:
2598  return (PR_EVAL_FNC) eval_pred_rlike7;
2599 
2600  default:
2601  return NULL;
2602  }
2603  }
2604 
2605  /* general case */
2606  return (PR_EVAL_FNC) eval_pred;
2607 }
2608 
2609 /*
2610  * update_logical_result () - checks DB_LOGICAL value and qualification
2611  * return: new DB_LOGICAL value and qualification (if needed)
2612  * thread_p(in):
2613  * ev_res(in): logical value to be checked
2614  * qualification(in/out): a pointer to the qualification to be used in logical
2615  * value check. This member can be modified.
2616  */
2617 DB_LOGICAL
2618 update_logical_result (THREAD_ENTRY * thread_p, DB_LOGICAL ev_res, int *qualification)
2619 {
2620  int q;
2621 
2622  if (ev_res == V_ERROR)
2623  {
2624  return ev_res;
2625  }
2626 
2627  if (qualification != NULL)
2628  {
2629  q = *qualification;
2630  if (q == QPROC_QUALIFIED)
2631  {
2632  if (ev_res != V_TRUE) /* V_FALSE || V_UNKNOWN */
2633  {
2634  return V_FALSE; /* not qualified, continue to the next tuple */
2635  }
2636  }
2637  else if (q == QPROC_NOT_QUALIFIED)
2638  {
2639  if (ev_res != V_FALSE) /* V_TRUE || V_UNKNOWN */
2640  {
2641  return V_FALSE; /* qualified, continue to the next tuple */
2642  }
2643  }
2644  else if (q == QPROC_QUALIFIED_OR_NOT)
2645  {
2646  if (ev_res == V_TRUE)
2647  {
2648  *qualification = QPROC_QUALIFIED;
2649  }
2650  else if (ev_res == V_FALSE)
2651  {
2652  *qualification = QPROC_NOT_QUALIFIED;
2653  }
2654  else /* V_UNKNOWN */
2655  {
2656  /* nop */
2657  ;
2658  }
2659  }
2660  else
2661  { /* invalid value; the same as QPROC_QUALIFIED */
2662  if (ev_res != V_TRUE) /* V_FALSE || V_UNKNOWN */
2663  {
2664  return V_FALSE; /* not qualified, continue to the next tuple */
2665  }
2666  }
2667  }
2668 
2669  assert (ev_res != V_ERROR);
2670  if (ev_res == V_TRUE)
2671  {
2672  return V_TRUE;
2673  }
2674  else
2675  {
2676  /* V_FALSE || V_UNKNOWN */
2677  return V_FALSE; /* not qualified, continue to the next tuple */
2678  }
2679 }
2680 
2681 /*
2682  * eval_data_filter () -
2683  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2684  * oid(in): pointer to OID
2685  * recdesp(in): pointer to RECDES (record descriptor)
2686  * filterp(in): pointer to FILTER_INFO (filter information)
2687  *
2688  * Note: evaluate data filter(predicates) given as FILTER_INFO.
2689  */
2690 DB_LOGICAL
2691 eval_data_filter (THREAD_ENTRY * thread_p, OID * oid, RECDES * recdesp, HEAP_SCANCACHE * scan_cache,
2692  FILTER_INFO * filterp)
2693 {
2694  SCAN_PRED *scan_predp;
2695  SCAN_ATTRS *scan_attrsp;
2696  DB_LOGICAL ev_res;
2697 
2698  if (!filterp)
2699  {
2700  return V_TRUE;
2701  }
2702 
2703  scan_predp = filterp->scan_pred;
2704  scan_attrsp = filterp->scan_attrs;
2705  if (!scan_predp)
2706  {
2707  return V_ERROR;
2708  }
2709 
2710  if (scan_attrsp != NULL && scan_attrsp->attr_cache != NULL && scan_predp->regu_list != NULL)
2711  {
2712  /* read the predicate values from the heap into the attribute cache */
2713  if (heap_attrinfo_read_dbvalues (thread_p, oid, recdesp, scan_cache, scan_attrsp->attr_cache) != NO_ERROR)
2714  {
2715  return V_ERROR;
2716  }
2717 
2718  if (oid == NULL && recdesp == NULL && filterp->val_list)
2719  {
2720  /*
2721  * In the case of class attribute scan, we should fetch regu_list
2722  * before pred evaluation because eval_pred*() functions do not
2723  * know class OID so that TYPE_CLASSOID regu cannot be handled
2724  * correctly.
2725  */
2726  if (fetch_val_list (thread_p, scan_predp->regu_list, filterp->val_descr, filterp->class_oid, oid, NULL, PEEK)
2727  != NO_ERROR)
2728  {
2729  return V_ERROR;
2730  }
2731  }
2732  }
2733 
2734  /* evaluate the predicates of the data filter */
2735  ev_res = V_TRUE;
2736  if (scan_predp->pr_eval_fnc && scan_predp->pred_expr)
2737  {
2738  ev_res = (*scan_predp->pr_eval_fnc) (thread_p, scan_predp->pred_expr, filterp->val_descr, oid);
2739  }
2740 
2741  if (oid == NULL && recdesp == NULL)
2742  {
2743  /* class attribute scan case; fetch was done before evaluation */
2744  return ev_res;
2745  }
2746 
2747  if (ev_res == V_TRUE && scan_predp->regu_list && filterp->val_list)
2748  {
2749  /*
2750  * fetch the values for the regu variable list of the data filter
2751  * from the cached attribute information
2752  */
2753  if (fetch_val_list (thread_p, scan_predp->regu_list, filterp->val_descr, filterp->class_oid, oid, NULL, PEEK) !=
2754  NO_ERROR)
2755  {
2756  return V_ERROR;
2757  }
2758  }
2759 
2760  return ev_res;
2761 }
2762 
2763 /*
2764  * eval_key_filter () -
2765  * return: DB_LOGICAL (V_TRUE, V_FALSE, V_UNKNOWN or V_ERROR)
2766  * value(in): pointer to DB_VALUE (key value)
2767  * filterp(in): pointer to FILTER_INFO (filter information)
2768  *
2769  * Note: evaluate key filter(predicates) given as FILTER_INFO
2770  */
2771 DB_LOGICAL
2772 eval_key_filter (THREAD_ENTRY * thread_p, DB_VALUE * value, FILTER_INFO * filterp)
2773 {
2774  DB_MIDXKEY *midxkey;
2775  int i, j;
2776  SCAN_PRED *scan_predp;
2777  SCAN_ATTRS *scan_attrsp;
2778  DB_LOGICAL ev_res;
2779  bool found_empty_str;
2780  DB_TYPE type;
2781  HEAP_ATTRVALUE *attrvalue;
2782  DB_VALUE *valp;
2783  int prev_j_index;
2784  char *prev_j_ptr;
2785 
2786  if (value == NULL)
2787  {
2788  return V_ERROR;
2789  }
2790 
2791  if (filterp == NULL)
2792  {
2793  return V_TRUE;
2794  }
2795 
2796  scan_predp = filterp->scan_pred;
2797  scan_attrsp = filterp->scan_attrs;
2798  if (scan_predp == NULL || scan_attrsp == NULL)
2799  {
2800  return V_ERROR;
2801  }
2802 
2803  if (scan_predp->regu_list == NULL)
2804  {
2805  return V_TRUE;
2806  }
2807 
2808  ev_res = V_TRUE;
2809 
2810  if (scan_predp->pr_eval_fnc && scan_predp->pred_expr)
2811  {
2812  if (DB_VALUE_TYPE (value) == DB_TYPE_MIDXKEY)
2813  {
2814  midxkey = db_get_midxkey (value);
2815 
2816  if (filterp->btree_num_attrs <= 0 || !filterp->btree_attr_ids || !midxkey)
2817  {
2818  return V_ERROR;
2819  }
2820 
2821  prev_j_index = 0;
2822  prev_j_ptr = NULL;
2823 
2824  /* for all attributes specified in the filter */
2825  for (i = 0; i < scan_attrsp->num_attrs; i++)
2826  {
2827  /* for the attribute ID array of the index key */
2828  for (j = 0; j < filterp->btree_num_attrs; j++)
2829  {
2830  if (scan_attrsp->attr_ids[i] != filterp->btree_attr_ids[j])
2831  {
2832  continue;
2833  }
2834 
2835  /* now, found the attr */
2836 
2837  attrvalue = heap_attrvalue_locate (scan_attrsp->attr_ids[i], scan_attrsp->attr_cache);
2838  if (attrvalue == NULL)
2839  {
2840  return V_ERROR;
2841  }
2842 
2843  valp = &(attrvalue->dbvalue);
2844  if (pr_clear_value (valp) != NO_ERROR)
2845  {
2846  return V_ERROR;
2847  }
2848 
2849  if (filterp->func_idx_col_id != -1 && j > filterp->func_idx_col_id)
2850  {
2851  j = j + 1;
2852  }
2853 
2854  /* get j-th element value from the midxkey */
2855  if (pr_midxkey_get_element_nocopy (midxkey, j, valp, &prev_j_index, &prev_j_ptr) != NO_ERROR)
2856  {
2857  return V_ERROR;
2858  }
2859 
2860  found_empty_str = false;
2862  {
2863  if (valp->need_clear)
2864  {
2865  type = DB_VALUE_DOMAIN_TYPE (valp);
2866  if (QSTR_IS_ANY_CHAR_OR_BIT (type) && valp->data.ch.medium.buf != NULL)
2867  {
2868  /* convert NULL into Empty-string */
2869  valp->domain.general_info.is_null = 0;
2870  found_empty_str = true;
2871  }
2872  }
2873  }
2874 
2875  if (found_empty_str)
2876  {
2877  /* convert NULL into Empty-string */
2878  valp->domain.general_info.is_null = 0;
2879  }
2880 
2881  attrvalue->state = HEAP_WRITTEN_ATTRVALUE;
2882 
2883  break; /* immediately exit inner-loop */
2884  }
2885 
2886  if (j >= filterp->btree_num_attrs)
2887  {
2888  /*
2889  * the attribute exists in key filter scan cache, but it is
2890  * not a member of attributes consisting index key
2891  */
2892  DB_VALUE null;
2893 
2894  db_make_null (&null);
2895  if (heap_attrinfo_set (NULL, scan_attrsp->attr_ids[i], &null, scan_attrsp->attr_cache) != NO_ERROR)
2896  {
2897  return V_ERROR;
2898  }
2899  }
2900  }
2901  }
2902  else
2903  {
2904  if (scan_attrsp->attr_ids == NULL)
2905  {
2906  /* defense code */
2907  assert_release (false);
2908  return V_ERROR;
2909  }
2910  attrvalue = heap_attrvalue_locate (scan_attrsp->attr_ids[0], scan_attrsp->attr_cache);
2911  if (attrvalue == NULL)
2912  {
2913  return V_ERROR;
2914  }
2915 
2916  valp = &(attrvalue->dbvalue);
2917  if (pr_clear_value (valp) != NO_ERROR)
2918  {
2919  return V_ERROR;
2920  }
2921 
2922  if (pr_clone_value (value, valp) != NO_ERROR)
2923  {
2924  return V_ERROR;
2925  }
2926 
2927  found_empty_str = false;
2929  {
2930  if (valp->need_clear)
2931  {
2932  type = DB_VALUE_DOMAIN_TYPE (valp);
2933  if (QSTR_IS_ANY_CHAR_OR_BIT (type) && valp->data.ch.medium.buf != NULL)
2934  {
2935  /* convert NULL into Empty-string */
2936  found_empty_str = true;
2937  }
2938  }
2939  }
2940 
2941  if (found_empty_str)
2942  {
2943  /* convert NULL into Empty-string */
2944  valp->domain.general_info.is_null = 0;
2945 
2946  /* set single-column key val */
2947  value->domain.general_info.is_null = 0;
2948  }
2949 
2950  attrvalue->state = HEAP_WRITTEN_ATTRVALUE;
2951  }
2952 
2953  /*
2954  * evaluate the predicates of the key filter
2955  * using the given key value
2956  */
2957  ev_res = (*scan_predp->pr_eval_fnc) (thread_p, scan_predp->pred_expr, filterp->val_descr, NULL /* obj_oid */ );
2958  }
2959 
2960  return ev_res;
2961 }
#define QFILE_TUPLE_VALUE_HEADER_SIZE
Definition: query_list.h:229
pred_expr * lhs
DB_LOGICAL eval_pred_rlike7(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
int data_readval(struct or_buf *buf, DB_VALUE *value, const tp_domain *domain, int size, bool copy, char *copy_buf, int copy_buf_len) const
#define TP_IS_DATE_OR_TIME_TYPE(typeid)
TP_DOMAIN_STATUS tp_value_coerce(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain)
static DB_LOGICAL eval_sort_list_to_multi_set(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id, DB_SET *set, REL_OP rel_operator)
#define NO_ERROR
Definition: error_code.h:46
DB_COLLECTION * db_get_set(const DB_VALUE *value)
char buf[DB_SMALL_CHAR_BUF_SIZE]
Definition: dbtype_def.h:991
ATTR_ID * btree_attr_ids
static int eval_item_card_set(DB_VALUE *item, DB_SET *set, REL_OP rel_operator)
DB_MIDXKEY * db_get_midxkey(const DB_VALUE *value)
SCAN_CODE
QFILE_TUPLE_VALUE_TYPE_LIST type_list
Definition: query_list.h:428
REGU_DATATYPE type
Definition: regu_var.hpp:172
ATTR_ID * attr_ids
static DB_LOGICAL eval_sub_sort_list_to_multi_set(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id, DB_SET *set)
#define TP_IS_SET_TYPE(typenum)
SCAN_PRED * scan_pred
int thread_get_recursion_depth(cubthread::entry *thread_p)
int tp_more_general_type(const DB_TYPE type1, const DB_TYPE type2)
DB_TYPE
Definition: dbtype_def.h:670
regu_variable_node * src
#define ER_FAILED
Definition: error_code.h:47
TYPE_EVAL_TERM et_type
#define CHECK_REGU_VARIABLE_XASL_STATUS(r)
Definition: xasl.h:528
SCAN_CODE qfile_scan_list_next(THREAD_ENTRY *thread_p, QFILE_LIST_SCAN_ID *scan_id_p, QFILE_TUPLE_RECORD *tuple_record_p, int peek)
Definition: list_file.c:4724
static DB_LOGICAL eval_le_sort_list_to_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id1, QFILE_LIST_ID *list_id2)
static DB_LOGICAL eval_some_list_eval(THREAD_ENTRY *thread_p, DB_VALUE *item, QFILE_LIST_ID *list_id, REL_OP rel_operator)
#define OR_BUF_INIT(buf, data, size)
DB_VALUE_COMPARE_RESULT tp_value_compare_with_error(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion, int total_order, bool *can_compare)
DB_LOGICAL eval_key_filter(THREAD_ENTRY *thread_p, DB_VALUE *value, FILTER_INFO *filterp)
regu_variable_node * elem
#define assert_release(e)
Definition: error_manager.h:96
union regu_variable_node::regu_data_value value
DB_LOGICAL(* PR_EVAL_FNC)(THREAD_ENTRY *thread_p, const PRED_EXPR *, val_descr *, OID *)
static DB_LOGICAL eval_some_eval(DB_VALUE *item, DB_SET *set, REL_OP rel_operator)
bool REGU_VARIABLE_IS_FLAGED(const regu_variable_node *regu, int flag)
Definition: regu_var.hpp:253
static DB_LOGICAL eval_lt_sort_list_to_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id1, QFILE_LIST_ID *list_id2)
DB_LOGICAL eval_pred_comp2(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
PROC_TYPE type
Definition: xasl.h:953
REL_OP
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
#define ER_MAX_RECURSION_SQL_DEPTH
Definition: error_code.h:1453
cub_regex_object * compiled_regex
regu_variable_node * lhs
const int REGU_VARIABLE_FETCH_NOT_CONST
Definition: regu_var.hpp:164
QFILE_TUPLE_VALUE_FLAG qfile_locate_tuple_value(QFILE_TUPLE tuple, int index, char **tuple_value_p, int *value_size_p)
Definition: list_file.c:905
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
void THREAD_ENTRY
static DB_LOGICAL eval_negative(DB_LOGICAL res)
DB_LOGICAL eval_pred(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
DB_DATA data
Definition: dbtype_def.h:1083
static DB_LOGICAL eval_ne_multi_set_to_sort_list(THREAD_ENTRY *thread_p, DB_SET *set, QFILE_LIST_ID *list_id)
TP_DOMAIN * tp_domain_resolve_default(DB_TYPE type)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
static DB_LOGICAL eval_eq_multi_set_to_sort_list(THREAD_ENTRY *thread_p, DB_SET *set, QFILE_LIST_ID *list_id)
static DB_LOGICAL eval_all_list_eval(THREAD_ENTRY *thread_p, DB_VALUE *item, QFILE_LIST_ID *list_id, REL_OP rel_operator)
Definition: db_set.h:35
#define assert(x)
static DB_LOGICAL eval_value_rel_cmp(DB_VALUE *dbval1, DB_VALUE *dbval2, REL_OP rel_operator, const COMP_EVAL_TERM *et_comp)
QFILE_SORTED_LIST_ID * srlist_id
Definition: regu_var.hpp:188
int prm_get_integer_value(PARAM_ID prm_id)
DB_LOGICAL eval_pred_like6(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
regu_variable_list_node * regu_list
comp_eval_term et_comp
QFILE_LIST_ID * list_id
Definition: xasl.h:955
DB_LOGICAL eval_pred_comp0(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
union cubxasl::pred_expr::@185 pe
int fetch_peek_dbval(THREAD_ENTRY *thread_p, REGU_VARIABLE *regu_var, val_descr *vd, OID *class_oid, OID *obj_oid, QFILE_TUPLE tpl, DB_VALUE **peek_dbval)
Definition: fetch.c:3773
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
PRED_EXPR * pred_expr
#define TP_IS_NUMERIC_TYPE(typeid)
HEAP_ATTRVALUE * heap_attrvalue_locate(ATTR_ID attrid, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:10590
int heap_attrinfo_read_dbvalues(THREAD_ENTRY *thread_p, const OID *inst_oid, RECDES *recdes, HEAP_SCANCACHE *scan_cache, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:10337
#define QFILE_GET_TUPLE_VALUE_LENGTH(ptr)
Definition: query_list.h:253
static DB_LOGICAL eval_all_eval(DB_VALUE *item, DB_SET *set, REL_OP rel_operator)
#define NULL
Definition: freelistheap.h:34
#define QFILE_TUPLE_LENGTH_SIZE
Definition: query_list.h:224
struct pr_type * type
Definition: object_domain.h:76
DB_CHAR ch
Definition: dbtype_def.h:1070
SCAN_ATTRS * scan_attrs
#define QFILE_GET_TUPLE_LENGTH(tpl)
Definition: query_list.h:238
regu_variable_node * rhs
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
void PRIM_SET_NULL(DB_VALUE *value)
DB_LOGICAL eval_pred_comp3(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
void or_init(OR_BUF *buf, char *data, int length)
regu_variable_node * src
static DB_LOGICAL eval_lt_sort_list_to_multi_set(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id, DB_SET *set)
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
int set_get_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2575
int pr_midxkey_get_element_nocopy(const DB_MIDXKEY *midxkey, int index, DB_VALUE *value, int *prev_indexp, char **prev_ptrp)
need_clear_type need_clear
Definition: dbtype_def.h:1084
val_list_node * val_list
int db_set_size(DB_SET *set)
Definition: db_set.c:557
int pr_clear_value(DB_VALUE *value)
int qfile_open_list_scan(QFILE_LIST_ID *list_id_p, QFILE_LIST_SCAN_ID *scan_id_p)
Definition: list_file.c:4658
static DB_LOGICAL eval_sub_multi_set_to_sort_list(THREAD_ENTRY *thread_p, DB_SET *set1, QFILE_LIST_ID *list_id)
DB_LOGICAL eval_pred_alsm5(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
int db_string_rlike(const DB_VALUE *src, const DB_VALUE *pattern, const DB_VALUE *case_sensitive, cub_regex_object **comp_regex, char **comp_pattern, int *result)
DB_LOGICAL update_logical_result(THREAD_ENTRY *thread_p, DB_LOGICAL ev_res, int *qualification)
struct db_domain_info::general_info general_info
#define TP_IS_CHAR_TYPE(typeid)
static DB_LOGICAL eval_ne_sort_list_to_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id1, QFILE_LIST_ID *list_id2)
int fetch_val_list(THREAD_ENTRY *thread_p, regu_variable_list_node *regu_list, val_descr *vd, OID *class_oid, OID *obj_oid, QFILE_TUPLE tpl, int peek)
Definition: fetch.c:4526
DB_LOGICAL eval_pred_comp1(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
static int rc
Definition: serial.c:50
static DB_LOGICAL eval_eq_sort_list_to_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id1, QFILE_LIST_ID *list_id2)
void qfile_close_scan(THREAD_ENTRY *thread_p, QFILE_LIST_SCAN_ID *scan_id_p)
Definition: list_file.c:4774
bool db_value_is_null(const DB_VALUE *value)
#define ARG_FILE_LINE
Definition: error_manager.h:44
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
OID * db_get_oid(const DB_VALUE *value)
PR_EVAL_FNC eval_fnc(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, DB_TYPE *single_node_type)
PR_EVAL_FNC pr_eval_fnc
DB_LOGICAL eval_pred_alsm4(THREAD_ENTRY *thread_p, const PRED_EXPR *pr, val_descr *vd, OID *obj_oid)
regu_variable_node * elemset
void thread_dec_recursion_depth(cubthread::entry *thread_p)
#define UNKNOWN_CARD
static DB_LOGICAL eval_sub_sort_list_to_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id1, QFILE_LIST_ID *list_id2)
static DB_LOGICAL eval_le_sort_list_to_multi_set(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id, DB_SET *set)
static DB_LOGICAL eval_set_list_cmp(THREAD_ENTRY *thread_p, const COMP_EVAL_TERM *et_comp, val_descr *vd, DB_VALUE *dbval1, DB_VALUE *dbval2)
static DB_LOGICAL eval_multi_set_to_sort_list(THREAD_ENTRY *thread_p, DB_SET *set, QFILE_LIST_ID *list_id, REL_OP rel_operator)
#define DB_PAGESIZE
char * QFILE_TUPLE
Definition: query_list.h:281
DB_LOGICAL
Definition: dbtype_def.h:1218
bool prm_get_bool_value(PARAM_ID prm_id)
#define QSTR_IS_ANY_CHAR_OR_BIT(s)
Definition: string_opfunc.h:47
static DB_LOGICAL eval_le_multi_set_to_sort_list(THREAD_ENTRY *thread_p, DB_SET *set, QFILE_LIST_ID *list_id)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int db_string_like(const DB_VALUE *src_string, const DB_VALUE *pattern, const DB_VALUE *esc_char, int *result)
int i
Definition: dynamic_load.c:954
int db_make_null(DB_VALUE *value)
QFILE_LIST_ID * qfile_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id_p, SORT_LIST *sort_list_p, QUERY_OPTIONS option, bool do_close)
Definition: list_file.c:4030
#define DB_IS_NULL(value)
Definition: dbtype.h:63
static DB_LOGICAL eval_sort_list_to_sort_list(THREAD_ENTRY *thread_p, QFILE_LIST_ID *list_id1, QFILE_LIST_ID *list_id2, REL_OP rel_operator)
static DB_LOGICAL eval_lt_multi_set_to_sort_list(THREAD_ENTRY *thread_p, DB_SET *set, QFILE_LIST_ID *list_id)
DB_LOGICAL eval_data_filter(THREAD_ENTRY *thread_p, OID *oid, RECDES *recdesp, HEAP_SCANCACHE *scan_cache, FILTER_INFO *filterp)
heap_cache_attrinfo * attr_cache
#define EXECUTE_REGU_VARIABLE_XASL(thread_p, r, v)
Definition: xasl.h:499
TYPE_PRED_EXPR type
const int REGU_VARIABLE_FETCH_ALL_CONST
Definition: regu_var.hpp:163
alsm_eval_term et_alsm
regu_variable_node * pattern
union cubxasl::eval_term::@184 et
void thread_inc_recursion_depth(cubthread::entry *thread_p)
like_eval_term et_like
#define ER_QPROC_INVALID_DATATYPE
Definition: error_code.h:534
regu_variable_node * pattern
int heap_attrinfo_set(const OID *inst_oid, ATTR_ID attrid, DB_VALUE *attr_val, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:11239
pred_expr * rhs
bool heap_is_object_not_null(THREAD_ENTRY *thread_p, OID *class_oid, const OID *oid)
Definition: heap_file.c:8848
#define db_private_realloc(thrd, ptr, size)
Definition: memory_alloc.h:231
regu_variable_node * esc_char
#define PEEK
Definition: file_io.h:74
rlike_eval_term et_rlike
static DB_LOGICAL eval_logical_result(DB_LOGICAL res1, DB_LOGICAL res2)
DB_VALUE_COMPARE_RESULT tp_set_compare(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion, int total_order)
struct db_char::@54 medium
VAL_DESCR * val_descr
static int eval_item_card_sort_list(THREAD_ENTRY *thread_p, DB_VALUE *item, QFILE_LIST_ID *list_id)
regu_variable_node * case_sensitive
QFILE_LIST_ID * list_id
Definition: query_list.h:533