CUBRID Engine  latest
db_set.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  * db_set.c - API functions for manipulating sets & sequences.
21  */
22 
23 #include "db_set.h"
24 #include "db_set_function.h"
25 
26 #if !defined (SERVER_MODE)
27 #include "authenticate.h"
28 #endif // not SERVER_MODE
29 #if !defined (SERVER_MODE)
30 #include "class_object.h"
31 #endif // SERVER_MODE
32 #include "db.h"
33 #include "dbtype.h"
34 #include "error_manager.h"
35 #include "object_primitive.h"
36 #include "set_object.h"
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stdarg.h>
41 #include <ctype.h>
42 #include <string.h>
43 
44 #define ERROR_SET(error, code) \
45  do { \
46  error = code; \
47  er_set (ER_WARNING_SEVERITY, ARG_FILE_LINE, code, 0); \
48  } while (0)
49 
50 #define ERROR_SET1(error, code, arg1) \
51  do { \
52  error = code; \
53  er_set (ER_WARNING_SEVERITY, ARG_FILE_LINE, code, 1, arg1); \
54  } while (0)
55 
56 /*
57  * SET CREATION FUNCTIONS
58  */
59 
60 /*
61  * db_set_create() - This function creates an empty set for an attribute.
62  * The type of set(set, multiset, or sequence) is determined by examining
63  * the attribute that is specified.
64  * return : set descriptor
65  * classop(in): class or instance pointer
66  * name(in): attribute name
67  *
68  * note : The returned set is not immediately given to the attribute
69  * it must be given to an attribute later using a db_put() call
70  */
71 DB_SET *
72 db_set_create (MOP classop, const char *name)
73 {
74  DB_SET *set;
75 #if !defined(SERVER_MODE)
76  int error = NO_ERROR;
77 #endif
78 
80 
81  set = NULL;
82  if (classop != NULL && name != NULL)
83  {
84 #if !defined(SERVER_MODE)
85  SM_CLASS *class_;
86  SM_ATTRIBUTE *att;
87 
88  if (au_fetch_class (classop, &class_, AU_FETCH_READ, AU_SELECT) == NO_ERROR)
89  {
90  att = classobj_find_attribute (class_, name, 0);
91  if (att == NULL)
92  {
93  ERROR_SET1 (error, ER_OBJ_INVALID_ATTRIBUTE, name);
94  }
95  else
96  {
97  if (att->type->id == DB_TYPE_SET)
98  {
99  set = set_create_basic ();
100  }
101  else if (att->type->id == DB_TYPE_MULTISET)
102  {
103  set = set_create_multi ();
104  }
105  else if (att->type->id == DB_TYPE_SEQUENCE)
106  {
107  set = set_create_sequence (0);
108  }
109  else
110  {
111  ERROR_SET1 (error, ER_OBJ_DOMAIN_CONFLICT, name);
112  }
113  }
114  }
115 #endif
116  }
117 
118  return (set);
119 }
120 
121 /*
122  * db_set_create_basic() - This function creates a basic set for an attribute.
123  * The class and name arguments can be set to NULL. If values are supplied,
124  * a check will be made to make sure that the attribute was defined with the
125  * set domain.
126  * return : set descriptor
127  * classop(in): class or instance
128  * name(in): attribute name
129  *
130  * note : The new set will not be attached to any object, so you must use the
131  * db_put() function to assign it as the value of an attribute.
132  */
133 DB_SET *
134 db_set_create_basic (MOP classop, const char *name)
135 {
136  DB_SET *set;
137 #if !defined(SERVER_MODE)
138  int error = NO_ERROR;
139 #endif
140 
142 
143  set = NULL;
144  if (classop == NULL || name == NULL)
145  {
146  set = set_create_basic ();
147  }
148  else
149  {
150 #if !defined(SERVER_MODE)
151  SM_CLASS *class_;
152  SM_ATTRIBUTE *att;
153 
154  if (au_fetch_class (classop, &class_, AU_FETCH_READ, AU_SELECT) == NO_ERROR)
155  {
156  att = classobj_find_attribute (class_, name, 0);
157  if (att == NULL)
158  {
159  ERROR_SET1 (error, ER_OBJ_INVALID_ATTRIBUTE, name);
160  }
161  else
162  {
163  if (att->type->id == DB_TYPE_SET)
164  {
165  set = set_create_basic ();
166  }
167  else
168  {
169  ERROR_SET1 (error, ER_OBJ_DOMAIN_CONFLICT, name);
170  }
171  }
172  }
173 #endif
174  }
175 
176  return (set);
177 }
178 
179 /*
180  * db_set_create_multi() - This function creates an empty multiset. The class
181  * and name arguments can be set to NULL. If values are supplied, a check
182  * will be made to make sure that the attribute was defined with the
183  * multiset domain.
184  * return : set descriptor
185  * classop(in): class or instance
186  * name(in): attribute name
187  *
188  * note : The new set will not be attached to any object, so you must use the
189  * db_put() function to assign it as the value of an attribute.
190  */
191 DB_SET *
192 db_set_create_multi (MOP classop, const char *name)
193 {
194  DB_SET *set;
195 #if !defined(SERVER_MODE)
196  int error = NO_ERROR;
197 #endif
198 
200 
201  set = NULL;
202  if (classop == NULL || name == NULL)
203  {
204  set = set_create_multi ();
205  }
206  else
207  {
208 #if !defined(SERVER_MODE)
209  SM_CLASS *class_;
210  SM_ATTRIBUTE *att;
211 
212  if (au_fetch_class (classop, &class_, AU_FETCH_READ, AU_SELECT) == NO_ERROR)
213  {
214  att = classobj_find_attribute (class_, name, 0);
215  if (att == NULL)
216  {
217  ERROR_SET1 (error, ER_OBJ_INVALID_ATTRIBUTE, name);
218  }
219  else
220  {
221  if (att->type->id == DB_TYPE_MULTISET)
222  {
223  set = set_create_multi ();
224  }
225  else
226  {
227  ERROR_SET1 (error, ER_OBJ_DOMAIN_CONFLICT, name);
228  }
229  }
230  }
231 #endif
232  }
233 
234  return (set);
235 }
236 
237 /*
238  * db_seq_create() - This function creates an empty sequence. The class and
239  * name arguments can be set to NULL. If values are supplied, a check will
240  * be made to make sure that the attribute was defined with the sequence
241  * domain.
242  * return : a set (sequence) descriptor
243  * classop(in): class or instance
244  * name(in): attribute name
245  * size(in): initial size
246  *
247  * note : The new set will not be attached to any object, so you must use the
248  * db_put( ) function to assign it as the value of an attribute. If the size
249  * is not known, it is permissible to pass zero.
250  */
251 DB_SET *
252 db_seq_create (MOP classop, const char *name, int size)
253 {
254  DB_SET *set;
255 #if !defined(SERVER_MODE)
256  int error = NO_ERROR;
257 #endif
258 
260 
261  set = NULL;
262  if (classop == NULL || name == NULL)
263  {
264  set = set_create_sequence (size);
265  }
266  else
267  {
268 #if !defined(SERVER_MODE)
269  SM_CLASS *class_;
270  SM_ATTRIBUTE *att;
271 
272  if (au_fetch_class (classop, &class_, AU_FETCH_READ, AU_SELECT) == NO_ERROR)
273  {
274  att = classobj_find_attribute (class_, name, 0);
275  if (att == NULL)
276  {
277  ERROR_SET1 (error, ER_OBJ_INVALID_ATTRIBUTE, name);
278  }
279  else
280  {
281  if (att->type->id == DB_TYPE_SEQUENCE)
282  {
283  set = set_create_sequence (size);
284  }
285  else
286  {
287  ERROR_SET1 (error, ER_OBJ_DOMAIN_CONFLICT, name);
288  }
289  }
290  }
291 #endif
292  }
293 
294  return (set);
295 }
296 
297 /*
298  * db_set_free() - This function frees a set handle. If the set is owned by an
299  * object, the contents of the set are not freed, only the set handle is
300  * freed. If the set is not owned by an object, the handle and all of the
301  * elements are freed.
302  * return : error code
303  * set(in): set descriptor
304  */
305 int
307 {
308  /* don't check connection here, we always allow things to be freed */
309  if (set != NULL)
310  {
311  set_free (set);
312  }
313 
314  return (NO_ERROR);
315 }
316 
317 /*
318  * db_seq_free() -
319  * return : error code
320  * seq(in): set descriptor
321  */
322 int
324 {
325  /* don't check connection here, we always allow things to be freed */
326  if (seq != NULL)
327  {
328  set_free (seq);
329  }
330 
331  return (NO_ERROR);
332 }
333 
334 /*
335  * db_set_filter() - This function causes set elements containing references
336  * to deleted objects to be completely removed from the designated set.
337  * The system does not automatically filter sets containing references to
338  * deleted objects; if you do not call this function, make sure that your
339  * application code is prepared to encounter deleted objects.
340  * return : error code
341  * set(in): set to filter
342  */
343 int
345 {
346  int retval;
347 
349  CHECK_1ARG_ERROR (set);
350 
351  /* Check if modifications are disabled only if the set is owned */
352  if (set->owner != NULL)
353  {
355  }
356 
357  retval = (set_filter (set));
358 
359  return (retval);
360 }
361 
362 /*
363  * db_seq_filter() - This function causes set elements containing references
364  * to deleted objects to be completely removed from the designated set.
365  * The system does not automatically filter sets containing references to
366  * deleted objects; if you do not call this function, make sure that your
367  * application code is prepared to encounter deleted objects.
368  * return : error code
369  * set(in): set to filter
370  */
371 int
373 {
374  int retval;
375 
377  CHECK_1ARG_ERROR (set);
378 
379  /* Check if modifications are disabled only if the set is owned */
380  if (set->owner != NULL)
381  {
383  }
384 
385  retval = (set_filter (set));
386 
387  return (retval);
388 }
389 
390 /*
391  * db_set_copy() - This function makes a copy of the given set. The copied set
392  * will be a free set that is not owned by an object and will not be
393  * persistent in the database.
394  * return : a new set
395  * source(in): a set to copy
396  *
397  * note : To make the set persistent, you must assign it as the value of an
398  * object attribute. If you do not assign the set to an attribute, it must be
399  * freed manually with db_set_free function
400  */
401 DB_SET *
402 db_set_copy (DB_SET * source)
403 {
404  DB_SET *new_ = NULL;
405 
407 
408  if (source != NULL)
409  {
410  new_ = set_copy (source);
411  }
412 
413  return (new_);
414 }
415 
416 /*
417  * db_seq_copy() - This function makes a copy of the given source. The copied
418  * sequence will be a free set that is not owned by an object and will not
419  * be persistent in the database.
420  * return : a new sequence
421  * source(in): a sequence to copy
422  *
423  * note : To make the sequence persistent, you must assign it as the value of
424  * an object attribute. If you do not assign the sequence to an attribute,
425  * it must be freed manually with db_seq_free function
426  */
427 DB_SEQ *
428 db_seq_copy (DB_SEQ * source)
429 {
430  DB_SEQ *new_ = NULL;
431 
433 
434  if (source != NULL)
435  {
436  new_ = set_copy (source);
437  }
438 
439  return (new_);
440 }
441 
442 /*
443  * SET/MULTI-SET FUNCTIONS
444  */
445 
446 /*
447  * db_set_add() - This function adds an element to a set or multiset. If the
448  * set is a basic set and the value already exists in the set, a zero is
449  * returned, indicating that no error occurred. If the set is a multiset,
450  * the value will be added even if it already exists. If the set has been
451  * assigned as the value of an attribute, the domain of the value is first
452  * checked against the attribute domain. If they do not match, a zero is
453  * returned, indicating that no error occurred.
454  * return : error code
455  * set(in): set descriptor
456  * value(in): value to add
457  *
458  * note : you may not make any assumptions about the position of the value
459  * within the set; it will be added wherever the system determines is most
460  * convenient. If you need to have sets with ordered elements, you must use
461  * sequences. Sets and multi-sets cannot contain NULL elements, if the value
462  * has a basic type of DB_TYPE_NULL, an error is returned.
463  */
464 int
465 db_set_add (DB_SET * set, DB_VALUE * value)
466 {
467  int error = NO_ERROR;
468 
470  CHECK_1ARG_ERROR (set);
471 
472  /* Check if modifications are disabled only if the set is owned */
473  if (set->owner != NULL)
474  {
476  }
477 
478  if ((value != NULL) && (DB_VALUE_TYPE (value) > DB_TYPE_LAST))
479  {
481  }
482  else
483  {
484  error = set_add_element (set, value);
485  }
486 
487  return (error);
488 }
489 
490 /*
491  * db_set_get() - This function gets the value of an element of a set or
492  * multiset. This is the only set or multiset function that accepts an
493  * index. The first element of the set is accessed with an index of 0
494  * (zero). The index is used to sequentially retrieve elements and assumes
495  * that the set will not be modified for the duration of the set iteration
496  * loop. You cannot assume that the elements of the set remain in any
497  * particular order after a db_set_add statement.
498  * return : error code
499  * set(in): set descriptor
500  * index(in) : element index
501  * value(out): value container to be filled in with element value
502  *
503  * note : The supplied value container is filled in with a copy of the set
504  * element contents and must be freed with db_value_clear or db_value_free
505  * when the value is no longer required.
506  */
507 int
508 db_set_get (DB_SET * set, int index, DB_VALUE * value)
509 {
510  int retval;
511 
513  CHECK_2ARGS_ERROR (set, value);
514 
515  retval = (set_get_element (set, index, value));
516 
517  return (retval);
518 }
519 
520 /*
521  * db_set_drop() - This function removes the first matching element from a set
522  * or multiset. If no element matches the supplied value, a zero is
523  * returned, indicating no error occurred. If more than one element matches,
524  * only the first one is removed.
525  * return : error code
526  * set(in): set descriptor
527  * value(in): value to drop from the set
528  */
529 int
530 db_set_drop (DB_SET * set, DB_VALUE * value)
531 {
532  int retval;
533 
535  CHECK_1ARG_ERROR (set);
536 
537  /* Check if modifications are disabled only if the set is owned */
538  if (set->owner != NULL)
539  {
541  }
542 
543  retval = (set_drop_element (set, value, false));
544 
545  return (retval);
546 }
547 
548 /*
549  * db_set_size() - This function returns the total number of elements in a set,
550  * including elements that may have a NULL value. This function should
551  * always be used prior to using program loops to iterate over the set
552  * elements.
553  * return : total number of elements in the set
554  * set(in): set descriptor
555  */
556 int
558 {
559  int retval;
560 
562  CHECK_1ARG_MINUSONE (set);
563 
564  /* allow all types */
565  retval = (set_size (set));
566 
567  return (retval);
568 }
569 
570 /*
571  * db_set_cardinality() - The cardinality of a set is defined as the number of
572  * non-null elements, and this function returns the number of non-null
573  * elements in the set.
574  * return : number of non-null elements in the set
575  * set(in): set descriptor
576  */
577 int
579 {
580  int retval;
581 
583  CHECK_1ARG_MINUSONE (set);
584 
585  /* allow all types */
586  retval = (set_cardinality (set));
587 
588  return (retval);
589 }
590 
591 /*
592  * db_set_ismember() - This function checks to see if a value is found in a set
593  * return : non-zero if the value is in the set
594  * set(in): set descriptor
595  * value(in): value to test
596  */
597 int
599 {
600  int retval;
601 
603  CHECK_1ARG_FALSE (set);
604 
605  /* allow all types */
606  retval = (set_ismember (set, value)) ? 1 : 0;
607 
608  return (retval);
609 }
610 
611 /*
612  * db_set_isempty() - This function checks to see if a set is empty. The set
613  * (or sequence) must have no elements at all in order for this to be true.
614  * If this is a sequence and there are only NULL elements, this function
615  * will return false since NULL elements are still considered valid elements
616  * for sequences.
617  * return : non-zero if the set has no elements
618  * set(in): set descriptor
619  */
620 int
622 {
623  int retval;
624 
626  CHECK_1ARG_FALSE (set);
627 
628  /* allow all types */
629  retval = (set_isempty (set)) ? 1 : 0;
630 
631  return (retval);
632 }
633 
634 /*
635  * db_set_has_null() - This function checks to see if a set is empty. The set
636  * (or sequence) must have no elements at all in order for this to be true.
637  * If this is a sequence and there are only NULL elements, this function
638  * will return false since NULL elements are still considered valid elements
639  * for sequences.
640  * return : non-zero if the set has no elements
641  * set(in): set descriptor
642  */
643 int
645 {
646  int retval;
647 
649  CHECK_1ARG_FALSE (set);
650 
651  /* allow all types */
652  retval = (set_has_null (set)) ? 1 : 0;
653 
654  return (retval);
655 }
656 
657 /*
658  * db_set_print() - This is a debugging function that prints a simple
659  * description of a set. This should be used for information purposes only.
660  * return : error code
661  * set(in): set descriptor
662  */
663 int
665 {
667  CHECK_1ARG_ERROR (set);
668 
669  /* allow all types */
670  set_print (set);
671 
672  return (NO_ERROR);
673 }
674 
675 /*
676  * db_set_type() - This function returns the type identifier for a set. This
677  * can be used in places where it is not known if a set descriptor is for
678  * a set, multi-set or sequence.
679  * return : set type identifier
680  * set(in): set descriptor
681  */
682 DB_TYPE
684 {
685  DB_TYPE type = DB_TYPE_NULL;
686 
687  if (set != NULL)
688  {
689  type = set_get_type (set);
690  }
691 
692  return (type);
693 }
694 
695 /*
696  * SEQUENCE FUNCTIONS
697  */
698 
699 /*
700  * db_seq_get() - This function retrieves the value of a sequence element.
701  * The first element of the sequence is accessed with an index of 0 (zero).
702  * return : error code
703  * set(in): sequence identifier
704  * index(in): element index
705  * value(out): value to be filled in with element contents
706  *
707  * note : The value will be copied from the sequence, so it must be released
708  * using either function db_value_clear() or db_value_free() when it is
709  * no longer needed.
710  */
711 int
712 db_seq_get (DB_SET * set, int index, DB_VALUE * value)
713 {
714  int retval;
715 
717  CHECK_2ARGS_ERROR (set, value);
718 
719  /* should make sure this is a sequence, probably introduce another set_ level function to do this rather than
720  * checking the type here */
721  retval = (set_get_element (set, index, value));
722 
723  return (retval);
724 }
725 
726 /*
727  * db_seq_put() - This function puts a value in a sequence at a fixed position.
728  * The value will always remain in the specified position so you can use
729  * db_seq_get() with the same index to retrieve it at a later time.
730  * This will overwrite the current value at that position if one exists. The
731  * value can be of type DB_TYPE_NULL, in which case the current element will
732  * be cleared and set to NULL.
733  * return : error code
734  * set(in): sequence descriptor
735  * index(in): element index
736  * value(in): value to put in the sequence
737  *
738  * note : The domain of the value must be compatible with the domain of the set
739  * (if the set has been assigned to an attribute). If the set does not have
740  * an element with the specified index, it will automatically grow to be as
741  * large as the given index. The empty elements (if any) between the former
742  * length of the set and the new index will be set to DB_TYPE_NULL.
743  */
744 int
745 db_seq_put (DB_SET * set, int index, DB_VALUE * value)
746 {
747  int error = NO_ERROR;
748 
750  CHECK_1ARG_ERROR (set);
751 
752  /* Check if modifications are disabled only if the set is owned */
753  if (set->owner != NULL)
754  {
756  }
757 
758  if ((value != NULL) && (DB_VALUE_TYPE (value) > DB_TYPE_LAST))
759  {
761  }
762  else
763  {
764  error = set_put_element (set, index, value);
765  }
766 
767  return (error);
768 }
769 
770 /*
771  * db_seq_insert() - This function inserts a value into a sequence at the
772  * specified position. All elements starting from that position will be
773  * shifted down to make room for the new element. As with other sequence
774  * building functions, the domain of the value must be compatible with the
775  * domain of the sequence. The sequence will automatically grow to make room
776  * for the new value. Any existing slots that contain NULL will not be
777  * reused because NULL is a valid sequence element. If the index is beyond
778  * the length of the sequence, the sequence will grow and the value is
779  * appended.
780  * return : error code
781  * set(in): sequence descriptor
782  * index(in): element index
783  * value(in): value to insert
784  */
785 int
786 db_seq_insert (DB_SET * set, int index, DB_VALUE * value)
787 {
788  int error = NO_ERROR;
789 
791  CHECK_1ARG_ERROR (set);
792 
793  /* Check if modifications are disabled only if the set is owned */
794  if (set->owner != NULL)
795  {
797  }
798 
799  if ((value != NULL) && (DB_VALUE_TYPE (value) > DB_TYPE_LAST))
800  {
802  }
803  else
804  {
805  error = set_insert_element (set, index, value);
806  }
807 
808  return (error);
809 }
810 
811 /*
812  * db_seq_drop() - This function removes an element from a sequence. Any
813  * elements following the indexed element will be shifted up to take up
814  * the space. The length of the set will be decreased by one.
815  * return : error code
816  * set(in): sequence descriptor
817  * index(in): element index
818  *
819  * note : If you want to clear an element without shifting subsequent elements
820  * up, use db_seq_put() with a value of DB_TYPE_NULL.
821  */
822 int
824 {
825  int retval;
826 
828  CHECK_1ARG_ERROR (set);
829 
830  /* Check if modifications are disabled only if the set is owned */
831  if (set->owner != NULL)
832  {
834  }
835 
836  retval = (set_drop_seq_element (set, index));
837 
838  return (retval);
839 }
840 
841 /*
842  * db_seq_size() - This function returns the total number of slots allocated
843  * for a sequence.
844  * return : total number of elements in the sequence
845  * set(in): sequence descriptor
846  */
847 int
849 {
850  int retval;
851 
853  CHECK_1ARG_MINUSONE (set);
854 
855  retval = (set_size (set));
856 
857  return (retval);
858 }
859 
860 /*
861  * db_seq_cardinality() - This function returns only the number of non-null
862  * elements in the sequence.
863  * return : number of non-null elements in the sequence
864  * set(in): sequence descriptor
865  */
866 int
868 {
869  int retval;
870 
872  CHECK_1ARG_MINUSONE (set);
873 
874  retval = (set_cardinality (set));
875 
876  return (retval);
877 }
878 
879 /*
880  * db_seq_print() - This is debug function to print out a simple description of
881  * a sequence.
882  * return : error code
883  * set(in): sequence descriptor
884  */
885 int
887 {
889  CHECK_1ARG_ERROR (set);
890 
891  set_print (set);
892 
893  return (NO_ERROR);
894 }
895 
896 /*
897  * db_seq_find() - This function can be used to sequentially search for
898  * elements in a sequence that match a particular value. To search
899  * for duplicate elements in a sequence, you can call this function multiple
900  * times and set the index parameter to one greater than the number returned
901  * by the previous call to this function.
902  * return: the index of the element or error code if not found
903  * set(in): sequence descriptor
904  * value(in): value to search for
905  * index(in): starting index (zero if starting from the beginning)
906  */
907 int
908 db_seq_find (DB_SET * set, DB_VALUE * value, int index)
909 {
910  int retval;
911 
913  CHECK_2ARGS_ERROR (set, value);
914 
915  retval = (set_find_seq_element (set, value, index));
916 
917  return (retval);
918 }
919 
920 /*
921  * GENERIC COLLECTION FUNCTIONS
922  */
923 
924 /*
925  * The new DB_COLLECTION style of collection maintenance is preferred over
926  * the old SET/MULTISET/SEQUENCE distinction. Its easier to code against
927  * and makes switching between collection types easier.
928  *
929  */
930 
931 /*
932  * db_col_create() - This is the primary function for constructing a new
933  * collection. Type should be DB_TYPE_SET, DB_TYPE_MULTISET, or
934  * DB_TYPE_SEQUENCE. Size should always be specified if known before
935  * hand as it will significantly improve performance when incrementally
936  * building collections. Domain is optional. If NULL, it is assumed that
937  * this is a "wildcard" collection and can contain elements of any domain.
938  * The elements already existing in the collection should be within the
939  * supplied domain.If a domain is supplied, the type argument is ignored.
940  * return : collection (NULL if error)
941  * type(in): one of the DB_TYPE_ collection types
942  * size(in): initial size to preallocate (zero if unknown)
943  * domain(in): fully specified domain (optional)
944  *
945  * note : The collection handle returned must be freed using the db_col_free()
946  * function when the collection handle is no longer necessary.
947  */
949 db_col_create (DB_TYPE type, int size, DB_DOMAIN * domain)
950 {
951  DB_COLLECTION *col;
952 
954 
955  if (domain != NULL)
956  {
957  col = set_create_with_domain (domain, size);
958  }
959  else
960  {
961  col = set_create (type, size);
962  }
963 
964  return col;
965 }
966 
967 /*
968  * db_col_copy() - This function returns a copy of the given collection. The
969  * new collection has the identical domain and element values as the source
970  * collection.
971  * return : new collection (NULL if error)
972  * col(in): collection to copy
973  */
976 {
977  DB_COLLECTION *new_ = NULL;
978 
980 
981  if (col != NULL)
982  {
983  new_ = set_copy (col);
984  }
985 
986  return new_;
987 }
988 
989 /*
990  * db_col_free() - This function frees storage for the collection. This
991  * function must be called for any collection created by the
992  * db_col_create() function as well as for any collection handle
993  * returned by any other API function.
994  * return : error status
995  * col(in): collection to free
996  */
997 int
999 {
1000  /* don't check connection here, we always allow things to be freed */
1001 
1002  if (col != NULL)
1003  {
1004  set_free (col);
1005  }
1006 
1007  return NO_ERROR;
1008 }
1009 
1010 /*
1011  * db_col_filter() - This function examines each element in the collection for
1012  * references to objects that have been deleted. If any such elements are
1013  * found, they are removed. If the collection type is DB_TYPE_SEQUENCE, then
1014  * the elements containing deleted object references will be changed to have
1015  * a DB_TYPE_NULL value. DB_TYPE_MULTISET or DB_TYPE_SET, elements containing
1016  * deleted object references are first converted to elements containing a
1017  * DB_TYPE_NULL value. After all deleted object references have been
1018  * converted to null values, all but one of the null values are then removed
1019  * from the collection.
1020  * return : error status
1021  * col(in): collection to filter
1022  */
1023 int
1025 {
1026  int error;
1027 
1029  CHECK_1ARG_ERROR (col);
1030 
1031  /* Check if modifications are disabled only if the set is owned */
1032  if (col->owner != NULL)
1033  {
1035  }
1036 
1037  error = set_filter (col);
1038 
1039  return error;
1040 }
1041 
1042 /*
1043  * db_col_add() - This is used to add new elements to a collection.
1044  *
1045  * return : error status
1046  * col(in): collection to extend
1047  * value(in): value to add
1048  *
1049  * note : db_col_add is normally used only with collections of type DB_TYPE_SET
1050  * and DB_TYPE_MULTISET. It can be used with collections of type
1051  * DB_TYPE_SEQUENCE but the new elements will always be appended to the end
1052  * of the sequence. If you need more control over the positioning of
1053  * elements in a sequence, you may use the db_col_put or db_col_insert
1054  * functions.
1055  */
1056 int
1058 {
1059  int error = NO_ERROR;
1060 
1062  CHECK_1ARG_ERROR (col);
1063 
1064  /* Check if modifications are disabled only if the set is owned */
1065  if (col->owner != NULL)
1066  {
1068  }
1069 
1070  error = set_add_element (col, value);
1071 
1072  return error;
1073 }
1074 
1075 /*
1076  * db_col_drop() - This function is used to remove a value from a collection.
1077  * return : error code
1078  * col(in): collection
1079  * value(in): value to drop
1080  * all(in): non-zero to drop all occurrences of the value
1081  *
1082  */
1083 int
1084 db_col_drop (DB_COLLECTION * col, DB_VALUE * value, int all)
1085 {
1086  int error;
1087 
1089  CHECK_1ARG_ERROR (col);
1090 
1091  /* Check if modifications are disabled only if the set is owned */
1092  if (col->owner != NULL)
1093  {
1095  }
1096 
1097  error = set_drop_element (col, value, false);
1098 
1099  return error;
1100 }
1101 
1102 /*
1103  * db_col_drop_element() - The element with the given index will be removed
1104  * from the collection and all subsequent elements in the collection will
1105  * be moved up. The sequence size will be reduced by one. If the sequence
1106  * has no elements at the given index, an error is returned.
1107  * return : error code
1108  * col(in): collection
1109  * element_index(in): index of element to drop
1110  */
1111 int
1112 db_col_drop_element (DB_COLLECTION * col, int element_index)
1113 {
1114  int error;
1115 
1117  CHECK_1ARG_ERROR (col);
1118 
1119  /* Check if modifications are disabled only if the set is owned */
1120  if (col->owner != NULL)
1121  {
1123  }
1124 
1125  /* kludge, not preventing SET or MULTISET operations, might want to define some behavior here, even thouth the
1126  * resulting set order after the drop is undefined. */
1127  error = set_drop_seq_element (col, element_index);
1128 
1129  return error;
1130 }
1131 
1132 /*
1133  * db_col_drop_nulls() - This function is used to remove all NULL db_values
1134  * from a collection.
1135  * return : error code
1136  * col(in): collection
1137  */
1138 int
1140 {
1141  int error;
1142  DB_VALUE value;
1143 
1145  CHECK_1ARG_ERROR (col);
1146 
1147  /* Check if modifications are disabled only if the set is owned */
1148  if (col->owner != NULL)
1149  {
1151  }
1152 
1153  db_make_null (&value);
1154 
1155  error = set_drop_element (col, &value, true);
1156 
1157  return error;
1158 }
1159 
1160 /*
1161  * db_col_size() - This function is used to obtain the number of elements found
1162  * within the collection.
1163  * return : number of elements in the collection
1164  * col(in): collection
1165  */
1166 int
1168 {
1169  int size;
1170 
1172  CHECK_1ARG_MINUSONE (col);
1173 
1174  size = set_size (col);
1175 
1176  return size;
1177 }
1178 
1179 /*
1180  * db_col_cardinality() - This function returns the number of elements in the
1181  * collection that have non-NULL values.
1182  * return: the cardinality of the collection
1183  * col(in): collection
1184  *
1185  * note : This is different than db_col_size which returns the total
1186  * number of elements in the collection, including those with NULL
1187  * values. Use of db_col_cardinality is discouraged since it is
1188  * almost always the case that the API programmer really should be
1189  * using db_col_size.
1190  */
1191 int
1193 {
1194  int card;
1195 
1197  CHECK_1ARG_MINUSONE (col);
1198 
1199  card = set_cardinality (col);
1200 
1201  return card;
1202 }
1203 
1204 /*
1205  * db_col_get() - This function is the primary function for retrieving values
1206  * out of a collection. It can be used for collections of all types.
1207  * return : error status
1208  * col(in): collection
1209  * element_index(in): index of element to access
1210  * value(in): container in which to store value
1211  *
1212  * note : The insertion order of elements in a collection of type DB_TYPE_SET
1213  * or DB_TYPE_MULTISET is undefined, but the collection is guaranteed to
1214  * retain its current order as long as no modifications are made to the
1215  * collection. This makes it possible to iterate over the elements of a
1216  * collection using an index. Iterations over a collection are normally
1217  * performed by first obtaining the size of the collection with the
1218  * db_col_size() function and then entering a loop whose index begins at 0
1219  * and ends at the value of db_col_size() minus one.
1220  */
1221 int
1222 db_col_get (DB_COLLECTION * col, int element_index, DB_VALUE * value)
1223 {
1224  int error;
1225 
1227  CHECK_2ARGS_ERROR (col, value);
1228 
1229  error = set_get_element (col, element_index, value);
1230 
1231  return error;
1232 }
1233 
1234 /*
1235  * db_col_put() - This function assigns the given value to the element of the
1236  * collection with the given index. The previous contents of the element are
1237  * freed. This function is normally used with collections of type
1238  * DB_TYPE_SEQUENCE. This function is normally used to populate
1239  * DB_TYPE_SEQUENCE collections since it allows more control over the
1240  * positioning of the values within the collection. If the given collection
1241  * is of type DB_TYPE_SET or DB_TYPE_MULTISET, the index argument is ignored
1242  * and the function behaves identically to the db_col_add() function.
1243  * return : error code
1244  * col(in): collection
1245  * element_index(in): index of element to modify
1246  * value(in): value to assign
1247  */
1248 int
1249 db_col_put (DB_COLLECTION * col, int element_index, DB_VALUE * value)
1250 {
1251  int error = NO_ERROR;
1252  DB_TYPE coltype;
1253 
1255  CHECK_1ARG_ERROR (col);
1256 
1257  /* Check if modifications are disabled only if the set is owned */
1258  if (col->owner != NULL)
1259  {
1261  }
1262 
1263  coltype = set_get_type (col);
1264  if (coltype == DB_TYPE_SEQUENCE)
1265  {
1266  error = set_put_element (col, element_index, value);
1267  }
1268  else
1269  {
1270  error = set_add_element (col, value);
1271  }
1272 
1273  return error;
1274 }
1275 
1276 /*
1277  * db_col_insert() - This function inserts a new element into the sequence at a
1278  * position immediately before the indexed element. This function is
1279  * normally used with collections of type DB_TYPE_SEQUENCE. If the index is
1280  * 0, the new element is added to the beginning of the sequence. All
1281  * elements in the sequence are moved down to make room for the new element.
1282  * The sequence increases in size by one element.
1283  * return : error status
1284  * col(in): collection
1285  * element_index(in): index of new element
1286  * value(in): value to insert
1287  */
1288 int
1289 db_col_insert (DB_COLLECTION * col, int element_index, DB_VALUE * value)
1290 {
1291  int error = NO_ERROR;
1292  DB_TYPE coltype;
1293 
1295  CHECK_1ARG_ERROR (col);
1296 
1297  /* Check if modifications are disabled only if the set is owned */
1298  if (col->owner != NULL)
1299  {
1301  }
1302 
1303  coltype = set_get_type (col);
1304  if (coltype == DB_TYPE_SEQUENCE)
1305  {
1306  error = set_insert_element (col, element_index, value);
1307  }
1308  else
1309  {
1310  error = set_add_element (col, value);
1311  }
1312 
1313  return error;
1314 }
1315 
1316 /*
1317  * db_col_ismember() - This function can be used to determine if a particular
1318  * value is found within a collection.
1319  * return :
1320  * 0 = the value was not found within the collection
1321  * >0 = the value was found within the collection
1322  * <0 = an error was detected.
1323  * col(in): collection
1324  * value(in): value to search for
1325  */
1326 int
1328 {
1329  int member;
1330 
1332  CHECK_1ARG_MINUSONE (col);
1333 
1334  member = set_ismember (col, value) ? 1 : 0;
1335 
1336  return member;
1337 }
1338 
1339 /*
1340  * db_col_find() - This function can be used to scan a collection looking for
1341  * elements that whose values are equal to the given value. It is normally
1342  * used with collections of DB_TYPE_SEQUENCE but can be used with other
1343  * collection types.
1344  * return : index of the desired element
1345  * col(in): collection
1346  * value(in): value to search for
1347  * starting_index(in): starting index
1348  * found_index(out): returned index of element
1349  *
1350  * note : since this function uses element indexes, it can only be used
1351  * reliably with collections of type DB_TYPE_SET and DB_TYPE_MULTISET when
1352  * there are no modifications being made to the collection. The index
1353  * returned by this function has the following properties. If the value is
1354  * greater than or equal to 0, the number represents a valid element index.
1355  * This index can be used with the db_col_get() or db_col_put()functions for
1356  * example to directly access the element. If the index returned is -1, it
1357  * indicates that the value as not found in the collection. When the element
1358  * is not found, the error ER_SEQ_ELEMENT_NOT_FOUND is also set and returned.
1359  * The index will also be -1 if any other error is detected.
1360  * The starting_index parameter can be used to search for more than one
1361  * occurrence of the value. To search for the first occurrence of the value,
1362  * the starting_index should be 0. If an occurrence is found, to find the
1363  * next occurrence, set the starting_index to the index value returned by
1364  * the last db_col_find() call plus one.
1365  */
1366 int
1367 db_col_find (DB_COLLECTION * col, DB_VALUE * value, int starting_index, int *found_index)
1368 {
1369  int error = NO_ERROR;
1370  int psn;
1371 
1373  CHECK_2ARGS_ERROR (col, value);
1374 
1375  psn = set_find_seq_element (col, value, starting_index);
1376 
1377  if (psn < 0)
1378  {
1379  if (found_index != NULL)
1380  {
1381  *found_index = -1;
1382  }
1383  error = (int) psn;
1384  }
1385  else
1386  {
1387  if (found_index != NULL)
1388  {
1389  *found_index = psn;
1390  }
1391  }
1392 
1393  return error;
1394 }
1395 
1396 /*
1397  * db_col_type() - This function returns the base type for this collection.
1398  * return : one of DB_TYPE_SET, DB_TYPE_MULTISET, or DB_TYPE_SEQUENCE.
1399  * col(in): collection
1400  */
1401 DB_TYPE
1403 {
1404  DB_TYPE type = DB_TYPE_NULL;
1405 
1408 
1409  type = set_get_type (col);
1410 
1411  return type;
1412 }
1413 
1414 /*
1415  * db_col_domain() - This function returns the fully specified domain
1416  * for the collection.
1417  * return : domain of the collection
1418  * col(in): collection
1419  */
1420 DB_DOMAIN *
1422 {
1423  DB_DOMAIN *domain = NULL;
1424 
1425  CHECK_CONNECT_NULL ();
1426  CHECK_1ARG_NULL (col);
1427 
1428  domain = set_get_domain (col);
1429 
1430  return domain;
1431 }
1432 
1433 /*
1434  * db_col_fprint() - This is a debugging function that will emit a printed
1435  * representation of the collection to the file.
1436  * It is not intended to be used to emit a "readable" representation of
1437  * the collection, in particular, it may truncate the output if the
1438  * collection is very long.
1439  * return : error code
1440  * fp(in): file handle
1441  * col(in): collection
1442  */
1443 int
1444 db_col_fprint (FILE * fp, DB_COLLECTION * col)
1445 {
1447  CHECK_1ARG_ERROR (col);
1448 
1449  /* hack, so we don't have to know how the compiler does this */
1450  if (fp == NULL)
1451  {
1452  fp = stdout;
1453  }
1454 
1455  set_fprint (fp, col);
1456 
1457  return NO_ERROR;
1458 }
1459 
1460 /*
1461  * db_col_print() - Please refer to the db_col_fprintf() function
1462  * return: error code
1463  * col(in): collection
1464  */
1465 int
1467 {
1468  return db_col_fprint (stdout, col);
1469 }
1470 
1471 /*
1472  * db_col_optimize() - This function makes the set is in its optimal order
1473  * for performance(sort overhead) reason.
1474  * return : error status
1475  * col(in): collection
1476  */
1477 int
1479 {
1480  int error = NO_ERROR;
1481 
1483  CHECK_1ARG_ERROR (col);
1484 
1485  error = set_optimize (col);
1486 
1487  return error;
1488 }
#define CHECK_1ARG_MINUSONE(obj)
Definition: db.h:192
DB_COLLECTION * set_create(DB_TYPE type, int initial_size)
Definition: set_object.c:2373
int db_col_put(DB_COLLECTION *col, int element_index, DB_VALUE *value)
Definition: db_set.c:1249
DB_COLLECTION * set_create_multi(void)
Definition: set_object.c:2419
#define CHECK_MODIFICATION_ERROR()
Definition: db.h:121
#define NO_ERROR
Definition: error_code.h:46
int set_drop_seq_element(DB_COLLECTION *set, int index)
Definition: set_object.c:2902
#define CHECK_CONNECT_FALSE()
Definition: db.h:103
int db_seq_find(DB_SET *set, DB_VALUE *value, int index)
Definition: db_set.c:908
DB_DOMAIN * db_col_domain(DB_COLLECTION *col)
Definition: db_set.c:1421
#define CHECK_2ARGS_ERROR(obj1, obj2)
Definition: db.h:195
DB_SET * db_seq_create(MOP classop, const char *name, int size)
Definition: db_set.c:252
void set_free(DB_COLLECTION *set)
Definition: set_object.c:2560
int db_seq_get(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:712
DB_TYPE
Definition: dbtype_def.h:670
int db_seq_filter(DB_SET *set)
Definition: db_set.c:372
int db_seq_put(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:745
DB_COLLECTION * set_copy(DB_COLLECTION *set)
Definition: set_object.c:2473
int db_col_get(DB_COLLECTION *col, int element_index, DB_VALUE *value)
Definition: db_set.c:1222
int db_col_filter(DB_COLLECTION *col)
Definition: db_set.c:1024
DB_COLLECTION * set_create_sequence(int size)
Definition: set_object.c:2432
DB_SET * db_set_copy(DB_SET *source)
Definition: db_set.c:402
#define ERROR_SET(error, code)
Definition: db_set.c:44
int db_col_drop_element(DB_COLLECTION *col, int element_index)
Definition: db_set.c:1112
DB_COLLECTION * db_col_copy(DB_COLLECTION *col)
Definition: db_set.c:975
int db_col_find(DB_COLLECTION *col, DB_VALUE *value, int starting_index, int *found_index)
Definition: db_set.c:1367
SM_ATTRIBUTE * classobj_find_attribute(SM_CLASS *class_, const char *name, int class_attribute)
#define CHECK_1ARG_FALSE(obj)
Definition: db.h:180
int db_col_optimize(DB_COLLECTION *col)
Definition: db_set.c:1478
DB_SET * db_set_create_multi(MOP classop, const char *name)
Definition: db_set.c:192
DB_COLLECTION * set_create_with_domain(TP_DOMAIN *domain, int initial_size)
Definition: set_object.c:2438
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
int db_set_print(DB_SET *set)
Definition: db_set.c:664
int db_seq_cardinality(DB_SET *set)
Definition: db_set.c:867
int db_set_filter(DB_SET *set)
Definition: db_set.c:344
int db_col_add(DB_COLLECTION *col, DB_VALUE *value)
Definition: db_set.c:1057
struct db_object * owner
Definition: db_set.h:41
bool set_ismember(DB_COLLECTION *set, DB_VALUE *value)
Definition: set_object.c:3199
Definition: db_set.h:35
int db_set_get(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:508
int set_add_element(DB_COLLECTION *set, DB_VALUE *value)
Definition: set_object.c:2641
int db_col_ismember(DB_COLLECTION *col, DB_VALUE *value)
Definition: db_set.c:1327
int db_col_insert(DB_COLLECTION *col, int element_index, DB_VALUE *value)
Definition: db_set.c:1289
int set_filter(DB_COLLECTION *set)
Definition: set_object.c:3744
int au_fetch_class(MOP op, SM_CLASS **class_ptr, AU_FETCHMODE fetchmode, DB_AUTH type)
int db_set_isempty(DB_SET *set)
Definition: db_set.c:621
int db_seq_size(DB_SET *set)
Definition: db_set.c:848
#define CHECK_1ARG_ERROR(obj)
Definition: db.h:186
DB_SEQ * db_seq_copy(DB_SEQ *source)
Definition: db_set.c:428
DB_TYPE db_col_type(DB_COLLECTION *col)
Definition: db_set.c:1402
int db_col_free(DB_COLLECTION *col)
Definition: db_set.c:998
#define CHECK_1ARG_NULL(obj)
Definition: db.h:171
int db_col_drop(DB_COLLECTION *col, DB_VALUE *value, int all)
Definition: db_set.c:1084
#define NULL
Definition: freelistheap.h:34
int db_set_has_null(DB_COLLECTION *set)
Definition: db_set.c:644
struct pr_type * type
Definition: class_object.h:443
int db_set_add(DB_SET *set, DB_VALUE *value)
Definition: db_set.c:465
int db_seq_free(DB_SEQ *seq)
Definition: db_set.c:323
#define ER_OBJ_INVALID_ATTRIBUTE
Definition: error_code.h:273
DB_SET * db_set_create_basic(MOP classop, const char *name)
Definition: db_set.c:134
int db_set_free(DB_SET *set)
Definition: db_set.c:306
int set_get_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2575
int db_set_size(DB_SET *set)
Definition: db_set.c:557
int db_col_size(DB_COLLECTION *col)
Definition: db_set.c:1167
void set_fprint(FILE *fp, DB_COLLECTION *set)
Definition: set_object.c:3696
int db_col_drop_nulls(DB_COLLECTION *col)
Definition: db_set.c:1139
int set_cardinality(DB_COLLECTION *set)
Definition: set_object.c:2999
int set_put_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2719
static void error(const char *msg)
Definition: gencat.c:331
TP_DOMAIN * set_get_domain(DB_COLLECTION *set)
Definition: set_object.c:3319
#define AU_SELECT
Definition: authenticate.h:69
#define CHECK_CONNECT_NULL()
Definition: db.h:91
int db_set_ismember(DB_SET *set, DB_VALUE *value)
Definition: db_set.c:598
bool set_isempty(DB_COLLECTION *set)
Definition: set_object.c:3074
DB_COLLECTION * db_col_create(DB_TYPE type, int size, DB_DOMAIN *domain)
Definition: db_set.c:949
#define ER_OBJ_INVALID_ARGUMENTS
Definition: error_code.h:275
int db_seq_print(DB_SET *set)
Definition: db_set.c:886
void set_print(DB_COLLECTION *set)
Definition: set_object.c:3731
#define CHECK_1ARG_ERROR_WITH_TYPE(obj, TYPE)
Definition: db.h:189
bool set_has_null(DB_COLLECTION *set)
Definition: set_object.c:3160
int set_optimize(DB_COLLECTION *ref)
Definition: set_object.c:4049
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int db_make_null(DB_VALUE *value)
#define ERROR_SET1(error, code, arg1)
Definition: db_set.c:50
DB_TYPE id
#define ER_OBJ_DOMAIN_CONFLICT
Definition: error_code.h:285
int set_find_seq_element(DB_COLLECTION *set, DB_VALUE *value, int index)
Definition: set_object.c:2962
DB_TYPE set_get_type(DB_COLLECTION *set)
Definition: set_object.c:3566
DB_TYPE db_set_type(DB_SET *set)
Definition: db_set.c:683
int set_insert_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2781
int db_col_print(DB_COLLECTION *col)
Definition: db_set.c:1466
int db_set_drop(DB_SET *set, DB_VALUE *value)
Definition: db_set.c:530
int db_seq_insert(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:786
int db_set_cardinality(DB_SET *set)
Definition: db_set.c:578
int db_col_cardinality(DB_COLLECTION *col)
Definition: db_set.c:1192
int db_seq_drop(DB_SET *set, int index)
Definition: db_set.c:823
DB_SET * db_set_create(MOP classop, const char *name)
Definition: db_set.c:72
#define CHECK_CONNECT_MINUSONE()
Definition: db.h:100
int set_drop_element(DB_COLLECTION *set, DB_VALUE *value, bool match_nulls)
Definition: set_object.c:2842
#define CHECK_CONNECT_ERROR()
Definition: db.h:88
int db_col_fprint(FILE *fp, DB_COLLECTION *col)
Definition: db_set.c:1444
DB_COLLECTION * set_create_basic(void)
Definition: set_object.c:2407