CUBRID Engine  latest
serial.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  * serial.c - Serial number handling routine
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <assert.h>
28 #include <errno.h>
29 
30 #include "serial.h"
31 #include "memory_hash.h"
32 #include "storage_common.h"
33 #include "heap_file.h"
34 #include "log_append.hpp"
35 #include "numeric_opfunc.h"
36 #include "object_primitive.h"
37 #include "record_descriptor.hpp"
38 #include "server_interface.h"
39 #include "xserver_interface.h"
40 #include "slotted_page.h"
41 #include "dbtype.h"
42 #include "xasl_cache.h"
43 
44 #if !defined(SERVER_MODE)
45 #define pthread_mutex_init(a, b)
46 #define pthread_mutex_destroy(a)
47 #define pthread_mutex_lock(a) 0
48 #define pthread_mutex_unlock(a)
49 static int rv;
50 static int rc;
51 #endif /* !SERVER_MODE */
52 
53 /* attribute of db_serial class */
54 typedef enum
55 {
69 
70 
71 #define NCACHE_OBJECTS 100
72 
73 #define NOT_FOUND -1
74 
77 {
78  OID oid; /* serial object identifier */
79 
80  /* serial object values */
88 
89  /* last cached value */
91 
92  /* free list */
93  struct serial_entry *next;
94 };
95 
98 {
101 };
102 
105 {
106  MHT_TABLE *ht; /* hash table of serial cache pool */
107 
109 
111 
113  pthread_mutex_t cache_pool_mutex;
114 };
115 
117  {NULL_PAGEID, NULL_SLOTID, NULL_VOLID}, PTHREAD_MUTEX_INITIALIZER
118 };
119 
120 #if defined (SERVER_MODE)
121 BTID serial_Cached_btid = BTID_INITIALIZER;
122 #endif /* SERVER_MODE */
123 
126 
127 static int xserial_get_current_value_internal (THREAD_ENTRY * thread_p, DB_VALUE * result_num, const OID * serial_oidp);
128 static int xserial_get_next_value_internal (THREAD_ENTRY * thread_p, DB_VALUE * result_num, const OID * serial_oidp,
129  int num_alloc);
130 static int serial_get_next_cached_value (THREAD_ENTRY * thread_p, SERIAL_CACHE_ENTRY * entry, int num_alloc);
131 static int serial_update_cur_val_of_serial (THREAD_ENTRY * thread_p, SERIAL_CACHE_ENTRY * entry);
132 static int serial_update_serial_object (THREAD_ENTRY * thread_p, PAGE_PTR pgptr, RECDES * recdesc,
133  HEAP_CACHE_ATTRINFO * attr_info, const OID * serial_class_oidp,
134  const OID * serial_oidp, DB_VALUE * key_val);
136  DB_VALUE * cyclic, int nth, DB_VALUE * result_val);
139  DB_VALUE * last_val, int cached_num);
140 static void serial_clear_value (SERIAL_CACHE_ENTRY * entry);
144 // *INDENT-OFF*
145 static int serial_get_attrid (THREAD_ENTRY * thread_p, int attr_index, ATTR_ID &attrid);
146 // *INDENT-ON*
147 
148 /*
149  * xserial_get_current_value () -
150  * return: NO_ERROR, or ER_code
151  * result_num(out) :
152  * oid_p(in) :
153  * cached_num(in) :
154  */
155 int
156 xserial_get_current_value (THREAD_ENTRY * thread_p, DB_VALUE * result_num, const OID * oid_p, int cached_num)
157 {
158  int ret = NO_ERROR;
159  SERIAL_CACHE_ENTRY *entry;
160 #if defined(SERVER_MODE)
161  int rc;
162 #endif /* SERVER_MODE */
163 
164  assert (oid_p != NULL);
165  assert (result_num != NULL);
166 
167  if (cached_num <= 1)
168  {
169  /* not used serial cache */
170  ret = xserial_get_current_value_internal (thread_p, result_num, oid_p);
171  }
172  else
173  {
174  /* used serial cache */
175  rc = pthread_mutex_lock (&serial_Cache_pool.cache_pool_mutex);
176  entry = (SERIAL_CACHE_ENTRY *) mht_get (serial_Cache_pool.ht, oid_p);
177  if (entry != NULL)
178  {
179  pr_clone_value (&entry->cur_val, result_num);
180  }
181  else
182  {
183  ret = xserial_get_current_value_internal (thread_p, result_num, oid_p);
184  }
185  pthread_mutex_unlock (&serial_Cache_pool.cache_pool_mutex);
186  }
187 
188  return ret;
189 }
190 
191 /*
192  * xserial_get_current_value_internal () -
193  * return: NO_ERROR, or ER_code
194  * result_num(out) :
195  * serial_oidp(in) :
196  */
197 static int
198 xserial_get_current_value_internal (THREAD_ENTRY * thread_p, DB_VALUE * result_num, const OID * serial_oidp)
199 {
200  int ret = NO_ERROR;
201  HEAP_SCANCACHE scan_cache;
202  SCAN_CODE scan;
203  RECDES recdesc = RECDES_INITIALIZER;
204  HEAP_CACHE_ATTRINFO attr_info, *attr_info_p = NULL;
205  ATTR_ID attrid;
206  DB_VALUE *cur_val;
207  OID serial_class_oid;
208 
209  oid_get_serial_oid (&serial_class_oid);
210  heap_scancache_quick_start_with_class_oid (thread_p, &scan_cache, &serial_class_oid);
211 
212  /* get record into record desc */
213  scan = heap_get_visible_version (thread_p, serial_oidp, &serial_class_oid, &recdesc, &scan_cache, PEEK, NULL_CHN);
214  if (scan != S_SUCCESS)
215  {
216  if (er_errid () == ER_PB_BAD_PAGEID)
217  {
218  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HEAP_UNKNOWN_OBJECT, 3, serial_oidp->volid, serial_oidp->pageid,
219  serial_oidp->slotid);
220  }
221  else
222  {
224  }
225  goto exit_on_error;
226  }
227 
228  /* retrieve attribute */
229  if (serial_get_attrid (thread_p, SERIAL_ATTR_CURRENT_VAL_INDEX, attrid) != NO_ERROR)
230  {
231  goto exit_on_error;
232  }
233  assert (attrid != NOT_FOUND);
234  ret = heap_attrinfo_start (thread_p, oid_Serial_class_oid, 1, &attrid, &attr_info);
235  if (ret != NO_ERROR)
236  {
237  goto exit_on_error;
238  }
239 
240  attr_info_p = &attr_info;
241 
242  ret = heap_attrinfo_read_dbvalues (thread_p, serial_oidp, &recdesc, NULL, attr_info_p);
243  if (ret != NO_ERROR)
244  {
245  goto exit_on_error;
246  }
247 
248  cur_val = heap_attrinfo_access (attrid, attr_info_p);
249 
250  pr_share_value (cur_val, result_num);
251 
252  heap_attrinfo_end (thread_p, attr_info_p);
253 
254  heap_scancache_end (thread_p, &scan_cache);
255 
256  return NO_ERROR;
257 
258 exit_on_error:
259 
260  if (attr_info_p != NULL)
261  {
262  heap_attrinfo_end (thread_p, attr_info_p);
263  }
264 
265  heap_scancache_end (thread_p, &scan_cache);
266 
267  ret = (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
268  return ret;
269 }
270 
271 /*
272  * xserial_get_next_value () -
273  * return: NO_ERROR, or ER_status
274  * result_num(out) :
275  * oid_p(in) :
276  * cached_num(in) :
277  * num_alloc(in) :
278  * is_auto_increment(in) :
279  * force_set_last_insert_id(in):
280  */
281 int
282 xserial_get_next_value (THREAD_ENTRY * thread_p, DB_VALUE * result_num, const OID * oid_p, int cached_num,
283  int num_alloc, int is_auto_increment, bool force_set_last_insert_id)
284 {
285  int ret = NO_ERROR, granted;
286  SERIAL_CACHE_ENTRY *entry;
287  bool is_cache_mutex_locked = false;
288  bool is_oid_locked = false;
289 #if defined (SERVER_MODE)
290  int rc;
291 #endif /* SERVER_MODE */
292 
293  assert (oid_p != NULL);
294  assert (result_num != NULL);
295 
296  CHECK_MODIFICATION_NO_RETURN (thread_p, ret);
297  if (ret != NO_ERROR)
298  {
299  return ret;
300  }
301 
302  if (num_alloc < 1)
303  {
305  return ER_FAILED;
306  }
307 
308  if (cached_num <= 1)
309  {
310  /* not used serial cache */
311  ret = xserial_get_next_value_internal (thread_p, result_num, oid_p, num_alloc);
312  }
313  else
314  {
315  /* used serial cache */
316  granted = LK_NOTGRANTED;
317 
318  try_again:
319  rc = pthread_mutex_lock (&serial_Cache_pool.cache_pool_mutex);
320  is_cache_mutex_locked = true;
321 
322  entry = (SERIAL_CACHE_ENTRY *) mht_get (serial_Cache_pool.ht, oid_p);
323  if (entry != NULL)
324  {
325  ret = serial_get_next_cached_value (thread_p, entry, num_alloc);
326  if (ret != NO_ERROR)
327  {
328  goto exit;
329  }
330  pr_clone_value (&entry->cur_val, result_num);
331  }
332  else
333  {
334  if (OID_ISNULL (&serial_Cache_pool.db_serial_class_oid))
335  {
337  }
338 
339  if (ret == NO_ERROR)
340  {
341  if (is_oid_locked == false)
342  {
343  granted = lock_object (thread_p, oid_p, &serial_Cache_pool.db_serial_class_oid, X_LOCK, LK_COND_LOCK);
344 
345  if (granted != LK_GRANTED)
346  {
347  /* release mutex, get OID lock, and restart */
348  pthread_mutex_unlock (&serial_Cache_pool.cache_pool_mutex);
349  is_cache_mutex_locked = false;
350  granted =
351  lock_object (thread_p, oid_p, &serial_Cache_pool.db_serial_class_oid, X_LOCK, LK_UNCOND_LOCK);
352  if (granted == LK_GRANTED)
353  {
354  is_oid_locked = true;
355  goto try_again;
356  }
357  }
358  else
359  {
360  is_oid_locked = true;
361  }
362  }
363 
364  if (granted != LK_GRANTED)
365  {
366  assert (er_errid () != NO_ERROR);
367  ret = er_errid ();
368  }
369  else
370  {
371  ret = xserial_get_next_value_internal (thread_p, result_num, oid_p, num_alloc);
372  assert (is_oid_locked == true);
373  (void) lock_unlock_object (thread_p, oid_p, &serial_Cache_pool.db_serial_class_oid, X_LOCK, true);
374  is_oid_locked = false;
375  }
376  }
377  }
378 
379  if (is_cache_mutex_locked == true)
380  {
381  pthread_mutex_unlock (&serial_Cache_pool.cache_pool_mutex);
382  is_cache_mutex_locked = false;
383  }
384  }
385 
386  if (ret == NO_ERROR && is_auto_increment == GENERATE_AUTO_INCREMENT)
387  {
388  /* we update current insert id for this session here */
389  /* Note that we ignore an error during updating current insert id. */
390  (void) xsession_set_cur_insert_id (thread_p, result_num, force_set_last_insert_id);
391  }
392 
393 exit:
394  if (is_cache_mutex_locked)
395  {
396  pthread_mutex_unlock (&serial_Cache_pool.cache_pool_mutex);
397  is_cache_mutex_locked = false;
398  }
399 
400  if (is_oid_locked)
401  {
402  (void) lock_unlock_object (thread_p, oid_p, &serial_Cache_pool.db_serial_class_oid, X_LOCK, true);
403  is_oid_locked = false;
404  }
405 
406  return ret;
407 }
408 
409 /*
410  * serial_get_next_cached_value () -
411  * return: NO_ERROR, or ER_status
412  * entry(in/out) :
413  * num_alloc(in) :
414  */
415 static int
417 {
418  DB_VALUE cmp_result;
419  DB_VALUE next_val;
420  int error, nturns;
421  bool exhausted = false;
422 
423  assert (1 <= num_alloc);
424 
425  /* check if cached numbers were already exhausted */
426  if (num_alloc == 1)
427  {
428  error = numeric_db_value_compare (&entry->cur_val, &entry->last_cached_val, &cmp_result);
429  if (error != NO_ERROR)
430  {
431  return error;
432  }
433  if (db_get_int (&cmp_result) == 0)
434  {
435  /* entry is cached to number of cached_num */
436  exhausted = true;
437  }
438  }
439  else
440  {
441  error =
442  serial_get_nth_value (&entry->inc_val, &entry->cur_val, &entry->min_val, &entry->max_val, &entry->cyclic,
443  num_alloc, &next_val);
444 
445  error = numeric_db_value_compare (&next_val, &entry->last_cached_val, &cmp_result);
446  if (error != NO_ERROR)
447  {
448  return error;
449  }
450 
451  if (db_get_int (&cmp_result) >= 0)
452  {
453  exhausted = true;
454  }
455 
456  }
457 
458  /* consumed all cached value */
459  if (exhausted == true)
460  {
461  nturns = CEIL_PTVDIV (num_alloc, entry->cached_num);
462 
463  error =
464  serial_get_nth_value (&entry->inc_val, &entry->last_cached_val, &entry->min_val, &entry->max_val,
465  &entry->cyclic, (nturns * entry->cached_num), &entry->last_cached_val);
466 
467  if (error != NO_ERROR)
468  {
469  return error;
470  }
471 
472  /* cur_val of db_serial is updated to last_cached_val of entry */
473  error = serial_update_cur_val_of_serial (thread_p, entry);
474  if (error != NO_ERROR)
475  {
476  return error;
477  }
478  }
479 
480  /* get next value */
481  if (num_alloc == 1)
482  {
483  error =
484  serial_get_nth_value (&entry->inc_val, &entry->cur_val, &entry->min_val, &entry->max_val, &entry->cyclic,
485  num_alloc, &next_val);
486  if (error != NO_ERROR)
487  {
488  return error;
489  }
490  }
491 
492  pr_clone_value (&next_val, &entry->cur_val);
493 
494  return NO_ERROR;
495 }
496 
497 /*
498  * serial_update_cur_val_of_serial () -
499  * cur_val of db_serial is updated to last_cached_val of entry
500  * return: NO_ERROR, or ER_status
501  * entry(in) :
502  */
503 static int
505 {
506  int ret = NO_ERROR;
507  HEAP_SCANCACHE scan_cache;
508  SCAN_CODE scan;
509  RECDES recdesc = RECDES_INITIALIZER;
510  HEAP_CACHE_ATTRINFO attr_info, *attr_info_p = NULL;
511  DB_VALUE *val;
512  DB_VALUE key_val;
513  ATTR_ID attrid;
514  OID serial_class_oid;
515 
516  db_make_null (&key_val);
517 
518  CHECK_MODIFICATION_NO_RETURN (thread_p, ret);
519  if (ret != NO_ERROR)
520  {
521  return ret;
522  }
523 
524  oid_get_serial_oid (&serial_class_oid);
525  heap_scancache_quick_start_modify_with_class_oid (thread_p, &scan_cache, &serial_class_oid);
526 
527  scan = heap_get_visible_version (thread_p, &entry->oid, &serial_class_oid, &recdesc, &scan_cache, PEEK, NULL_CHN);
528  if (scan != S_SUCCESS)
529  {
530  if (er_errid () == ER_PB_BAD_PAGEID)
531  {
533  entry->oid.slotid);
534  }
535  else
536  {
538  }
539  goto exit_on_error;
540  }
541 
542  /* retrieve attribute */
543  ret = heap_attrinfo_start (thread_p, oid_Serial_class_oid, -1, NULL, &attr_info);
544  if (ret != NO_ERROR)
545  {
546  goto exit_on_error;
547  }
548 
549  ret = heap_attrinfo_read_dbvalues (thread_p, &entry->oid, &recdesc, NULL, &attr_info);
550  if (ret != NO_ERROR)
551  {
552  heap_attrinfo_end (thread_p, &attr_info);
553  goto exit_on_error;
554  }
555 
556  attr_info_p = &attr_info;
557 
558  if (serial_get_attrid (thread_p, SERIAL_ATTR_NAME_INDEX, attrid) != NO_ERROR)
559  {
560  goto exit_on_error;
561  }
562  assert (attrid != NOT_FOUND);
563  val = heap_attrinfo_access (attrid, attr_info_p);
564  pr_clone_value (val, &key_val);
565 
566  if (serial_get_attrid (thread_p, SERIAL_ATTR_CURRENT_VAL_INDEX, attrid) != NO_ERROR)
567  {
568  goto exit_on_error;
569  }
570  assert (attrid != NOT_FOUND);
571  ret = heap_attrinfo_set (&entry->oid, attrid, &entry->last_cached_val, attr_info_p);
572  if (ret != NO_ERROR)
573  {
574  goto exit_on_error;
575  }
576 
577  ret =
578  serial_update_serial_object (thread_p, scan_cache.page_watcher.pgptr, &recdesc, attr_info_p, oid_Serial_class_oid,
579  &entry->oid, &key_val);
580  if (ret != NO_ERROR)
581  {
582  goto exit_on_error;
583  }
584 
585  pr_clear_value (&key_val);
586 
587  heap_attrinfo_end (thread_p, attr_info_p);
588 
589  heap_scancache_end (thread_p, &scan_cache);
590 
591  return NO_ERROR;
592 
593 exit_on_error:
594 
595  pr_clear_value (&key_val);
596 
597  if (attr_info_p != NULL)
598  {
599  heap_attrinfo_end (thread_p, attr_info_p);
600  }
601 
602  heap_scancache_end (thread_p, &scan_cache);
603 
604  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
605 }
606 
607 /*
608  * xserial_get_next_value_internal () -
609  * return: NO_ERROR, or ER_status
610  * result_num(out) :
611  * serial_oidp(in) :
612  */
613 static int
614 xserial_get_next_value_internal (THREAD_ENTRY * thread_p, DB_VALUE * result_num, const OID * serial_oidp, int num_alloc)
615 {
616  int ret = NO_ERROR;
617  HEAP_SCANCACHE scan_cache;
618  SCAN_CODE scan;
619  RECDES recdesc = RECDES_INITIALIZER;
620  HEAP_CACHE_ATTRINFO attr_info, *attr_info_p = NULL;
621  DB_VALUE *val = NULL;
628  DB_VALUE next_val;
629  DB_VALUE key_val;
630  DB_VALUE last_val;
631  int cached_num, nturns;
632  SERIAL_CACHE_ENTRY *entry = NULL;
633  ATTR_ID attrid;
634  OID serial_class_oid;
635 
636  db_make_null (&key_val);
637 
638  oid_get_serial_oid (&serial_class_oid);
639  heap_scancache_quick_start_modify_with_class_oid (thread_p, &scan_cache, &serial_class_oid);
640 
641  scan = heap_get_visible_version (thread_p, serial_oidp, &serial_class_oid, &recdesc, &scan_cache, PEEK, NULL_CHN);
642  if (scan != S_SUCCESS)
643  {
644  if (er_errid () == ER_PB_BAD_PAGEID)
645  {
646  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HEAP_UNKNOWN_OBJECT, 3, serial_oidp->volid, serial_oidp->pageid,
647  serial_oidp->slotid);
648  }
649  else
650  {
652  }
653  goto exit_on_error;
654  }
655 
656  /* retrieve attribute */
657  ret = heap_attrinfo_start (thread_p, oid_Serial_class_oid, -1, NULL, &attr_info);
658  if (ret != NO_ERROR)
659  {
660  goto exit_on_error;
661  }
662 
663  ret = heap_attrinfo_read_dbvalues (thread_p, serial_oidp, &recdesc, NULL, &attr_info);
664 
665  attr_info_p = &attr_info;
666 
667  if (serial_get_attrid (thread_p, SERIAL_ATTR_CACHED_NUM_INDEX, attrid) != NO_ERROR)
668  {
669  goto exit_on_error;
670  }
671  if (attrid == NOT_FOUND)
672  {
673  cached_num = 0;
674  }
675  else
676  {
677  val = heap_attrinfo_access (attrid, attr_info_p);
678  cached_num = db_get_int (val);
679  }
680 
681  if (serial_get_attrid (thread_p, SERIAL_ATTR_NAME_INDEX, attrid) != NO_ERROR)
682  {
683  goto exit_on_error;
684  }
685  assert (attrid != NOT_FOUND);
686  val = heap_attrinfo_access (attrid, attr_info_p);
687  pr_clone_value (val, &key_val);
688 
689  if (serial_get_attrid (thread_p, SERIAL_ATTR_CURRENT_VAL_INDEX, attrid) != NO_ERROR)
690  {
691  goto exit_on_error;
692  }
693  assert (attrid != NOT_FOUND);
694  val = heap_attrinfo_access (attrid, attr_info_p);
695  pr_share_value (val, &cur_val);
696 
698  {
699  goto exit_on_error;
700  }
701  assert (attrid != NOT_FOUND);
702  val = heap_attrinfo_access (attrid, attr_info_p);
703  pr_share_value (val, &inc_val);
704 
705  if (serial_get_attrid (thread_p, SERIAL_ATTR_MAX_VAL_INDEX, attrid) != NO_ERROR)
706  {
707  goto exit_on_error;
708  }
709  assert (attrid != NOT_FOUND);
710  val = heap_attrinfo_access (attrid, attr_info_p);
711  pr_share_value (val, &max_val);
712 
713  if (serial_get_attrid (thread_p, SERIAL_ATTR_MIN_VAL_INDEX, attrid) != NO_ERROR)
714  {
715  goto exit_on_error;
716  }
717  assert (attrid != NOT_FOUND);
718  val = heap_attrinfo_access (attrid, attr_info_p);
719  pr_share_value (val, &min_val);
720 
721  if (serial_get_attrid (thread_p, SERIAL_ATTR_CYCLIC_INDEX, attrid) != NO_ERROR)
722  {
723  goto exit_on_error;
724  }
725  assert (attrid != NOT_FOUND);
726  val = heap_attrinfo_access (attrid, attr_info_p);
727  pr_share_value (val, &cyclic);
728 
729  if (serial_get_attrid (thread_p, SERIAL_ATTR_STARTED_INDEX, attrid) != NO_ERROR)
730  {
731  goto exit_on_error;
732  }
733  assert (attrid != NOT_FOUND);
734  val = heap_attrinfo_access (attrid, attr_info_p);
735  pr_share_value (val, &started);
736 
737  db_make_null (&last_val);
738 
739  if (db_get_int (&started) == 0)
740  {
741  /* This is the first time to generate the serial value. */
742  db_make_int (&started, 1);
743  if (serial_get_attrid (thread_p, SERIAL_ATTR_STARTED_INDEX, attrid) != NO_ERROR)
744  {
745  goto exit_on_error;
746  }
747  assert (attrid != NOT_FOUND);
748  ret = heap_attrinfo_set (serial_oidp, attrid, &started, attr_info_p);
749  if (ret == NO_ERROR)
750  {
751  pr_share_value (&cur_val, &next_val);
752  if (cached_num > 1)
753  {
754  assert (1 <= num_alloc);
755  nturns = CEIL_PTVDIV (num_alloc, cached_num);
756 
757  ret =
758  serial_get_nth_value (&inc_val, &cur_val, &min_val, &max_val, &cyclic, (nturns * (cached_num - 1)),
759  &last_val);
760  }
761 
762  num_alloc--;
763  }
764  }
765 
766  if (num_alloc > 0)
767  {
768  if (cached_num > 1)
769  {
770  nturns = CEIL_PTVDIV (num_alloc, cached_num);
771 
772  ret =
773  serial_get_nth_value (&inc_val, &cur_val, &min_val, &max_val, &cyclic, (nturns * cached_num), &last_val);
774  }
775 
776  if (ret == NO_ERROR)
777  {
778  ret = serial_get_nth_value (&inc_val, &cur_val, &min_val, &max_val, &cyclic, num_alloc, &next_val);
779  }
780  }
781 
782  if (ret != NO_ERROR)
783  {
784  goto exit_on_error;
785  }
786 
787  /* Now update record */
788  if (serial_get_attrid (thread_p, SERIAL_ATTR_CURRENT_VAL_INDEX, attrid) != NO_ERROR)
789  {
790  goto exit_on_error;
791  }
792  assert (attrid != NOT_FOUND);
793  if (cached_num > 1 && !DB_IS_NULL (&last_val))
794  {
795  ret = heap_attrinfo_set (serial_oidp, attrid, &last_val, attr_info_p);
796  }
797  else
798  {
799  ret = heap_attrinfo_set (serial_oidp, attrid, &next_val, attr_info_p);
800  }
801  if (ret != NO_ERROR)
802  {
803  goto exit_on_error;
804  }
805 
806  ret =
807  serial_update_serial_object (thread_p, scan_cache.page_watcher.pgptr, &recdesc, attr_info_p, oid_Serial_class_oid,
808  serial_oidp, &key_val);
809  if (ret != NO_ERROR)
810  {
811  goto exit_on_error;
812  }
813 
814  /* copy result value */
815  pr_share_value (&next_val, result_num);
816 
817  pr_clear_value (&key_val);
818 
819  heap_attrinfo_end (thread_p, attr_info_p);
820 
821  heap_scancache_end (thread_p, &scan_cache);
822 
823  if (cached_num > 1)
824  {
825  entry = serial_alloc_cache_entry ();
826  if (entry != NULL)
827  {
828  COPY_OID (&entry->oid, serial_oidp);
829  assert (mht_get (serial_Cache_pool.ht, &entry->oid) == NULL);
830  if (mht_put (serial_Cache_pool.ht, &entry->oid, entry) == NULL)
831  {
832  OID_SET_NULL (&entry->oid);
833  entry->next = serial_Cache_pool.free_list;
834  serial_Cache_pool.free_list = entry;
835  entry = NULL;
836  }
837  else
838  {
839  pr_share_value (&next_val, &cur_val);
840  serial_set_cache_entry (entry, &inc_val, &cur_val, &min_val, &max_val, &started, &cyclic, &last_val,
841  cached_num);
842  }
843  }
844  }
845 
846  return NO_ERROR;
847 
848 exit_on_error:
849 
850  pr_clear_value (&key_val);
851 
852  if (attr_info_p != NULL)
853  {
854  heap_attrinfo_end (thread_p, attr_info_p);
855  }
856 
857  heap_scancache_end (thread_p, &scan_cache);
858 
859  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
860 }
861 
862 /*
863  * serial_update_serial_object () -
864  * return: NO_ERROR or error status
865  * pgptr(in) :
866  * recdesc(in) :
867  * attr_info(in) :
868  * serial_class_oidp(in) :
869  * serial_oidp(in) :
870  * key_val(in) :
871  */
872 static int
874  const OID * serial_class_oidp, const OID * serial_oidp, DB_VALUE * key_val)
875 {
876  // *INDENT-OFF*
878  // *INDENT-ON*
879  record_descriptor new_recdesc;
880  SCAN_CODE scan;
881  LOG_DATA_ADDR addr;
882  int ret;
883  int sp_success;
884  int tran_index;
885  LOCK lock_mode = NULL_LOCK;
886 
887  assert_release (serial_class_oidp != NULL && !OID_ISNULL (serial_class_oidp));
888 
889  tran_index = LOG_FIND_THREAD_TRAN_INDEX (thread_p);
890  lock_mode = lock_get_object_lock (serial_oidp, serial_class_oidp);
891 
892  /* need to start topop for replication Replication will recognize and realize a special type of update for serial by
893  * this top operation log record. If lock_mode is X_LOCK means we created or altered the serial obj in an
894  * uncommitted trans For this case, topop and flush mark are not used, since these may cause problem with replication
895  * log. */
896  if (lock_mode != X_LOCK)
897  {
898  log_sysop_start (thread_p);
899  }
900 
901  if (lock_mode != X_LOCK && !LOG_CHECK_LOG_APPLIER (thread_p) && log_does_allow_replication () == true)
902  {
903  repl_start_flush_mark (thread_p);
904  }
905 
906  new_recdesc.set_external_buffer (copyarea);
907 
908  scan = heap_attrinfo_transform_to_disk (thread_p, attr_info, recdesc, &new_recdesc);
909  if (scan != S_SUCCESS)
910  {
911  assert (false);
912  goto exit_on_error;
913  }
914 
915  /* Log the changes */
916  new_recdesc.set_type (recdesc->type);
917  addr.offset = serial_oidp->slotid;
918  addr.pgptr = pgptr;
919 
920  assert (spage_is_updatable (thread_p, addr.pgptr, serial_oidp->slotid, (int) new_recdesc.get_size ()));
921 
922  log_append_redo_recdes (thread_p, RVHF_UPDATE, &addr, &new_recdesc.get_recdes ());
923 
924  /* Now really update */
925  sp_success = spage_update (thread_p, addr.pgptr, serial_oidp->slotid, &new_recdesc.get_recdes ());
926  if (sp_success != SP_SUCCESS)
927  {
929  goto exit_on_error;
930  }
931 
932  /* make replication log for the special type of update for serial */
933  if (!LOG_CHECK_LOG_APPLIER (thread_p) && log_does_allow_replication () == true)
934  {
935  repl_log_insert (thread_p, serial_class_oidp, serial_oidp, LOG_REPLICATION_DATA, RVREPL_DATA_UPDATE, key_val,
937  repl_add_update_lsa (thread_p, serial_oidp);
938 
939  if (lock_mode != X_LOCK)
940  {
941  repl_end_flush_mark (thread_p, false);
942  }
943  }
944 
945  if (lock_mode != X_LOCK)
946  {
947  log_sysop_commit (thread_p);
948  }
949 
950  return NO_ERROR;
951 
952 exit_on_error:
953 
954  if (lock_mode != X_LOCK)
955  {
956  log_sysop_abort (thread_p);
957  }
958 
959  ASSERT_ERROR_AND_SET (ret);
960  return ret;
961 }
962 
963 /*
964  * serial_get_nth_value () - get Nth next_value
965  * return: NO_ERROR, or ER_status
966  * inc_val(in) :
967  * cur_val(in) :
968  * min_val(in) :
969  * max_val(in) :
970  * cyclic(in) :
971  * nth(in) :
972  * result_val(out) :
973  */
974 static int
976  int nth, DB_VALUE * result_val)
977 {
978  DB_VALUE tmp_val, cmp_result, add_val;
979  unsigned char num[DB_NUMERIC_BUF_SIZE];
980  int inc_val_flag;
981  int ret;
982 
983  inc_val_flag = numeric_db_value_is_positive (inc_val);
984  if (inc_val_flag < 0)
985  {
986  return ER_FAILED;
987  }
988 
989  /* Now calculate next value */
990  if (nth > 1)
991  {
992  numeric_coerce_int_to_num (nth, num);
993  db_make_numeric (&tmp_val, num, DB_MAX_NUMERIC_PRECISION, 0);
994  numeric_db_value_mul (inc_val, &tmp_val, &add_val);
995  }
996  else
997  {
998  pr_share_value (inc_val, &add_val);
999  }
1000 
1001  /* inc_val_flag (1 or 0) */
1002  if (inc_val_flag > 0)
1003  {
1004  ret = numeric_db_value_sub (max_val, &add_val, &tmp_val);
1005  if (ret != NO_ERROR)
1006  {
1007  return ret;
1008  }
1009  ret = numeric_db_value_compare (cur_val, &tmp_val, &cmp_result);
1010  if (ret != NO_ERROR)
1011  {
1012  return ret;
1013  }
1014 
1015  /* cur_val + inc_val * cached_num > max_val */
1016  if (db_get_int (&cmp_result) > 0)
1017  {
1018  if (db_get_int (cyclic))
1019  {
1020  pr_share_value (min_val, result_val);
1021  }
1022  else
1023  {
1026  }
1027  }
1028  else
1029  {
1030  (void) numeric_db_value_add (cur_val, &add_val, result_val);
1031  }
1032  }
1033  else
1034  {
1035  ret = numeric_db_value_sub (min_val, &add_val, &tmp_val);
1036  if (ret != NO_ERROR)
1037  {
1038  return ret;
1039  }
1040  ret = numeric_db_value_compare (cur_val, &tmp_val, &cmp_result);
1041  if (ret != NO_ERROR)
1042  {
1043  return ret;
1044  }
1045 
1046  /* cur_val + inc_val * cached_num < min_val */
1047  if (db_get_int (&cmp_result) < 0)
1048  {
1049  if (db_get_int (cyclic))
1050  {
1051  pr_share_value (max_val, result_val);
1052  }
1053  else
1054  {
1057  }
1058  }
1059  else
1060  {
1061  (void) numeric_db_value_add (cur_val, &add_val, result_val);
1062  }
1063  }
1064 
1065  return NO_ERROR;
1066 }
1067 
1068 /*
1069  * serial_initialize_cache_pool () -
1070  * return: NO_ERROR, or ER_status
1071  */
1072 int
1074 {
1075  unsigned int i;
1076 
1077  if (serial_Cache_pool.ht != NULL)
1078  {
1080  }
1081 
1082  serial_Cache_pool.area = serial_alloc_cache_area (NCACHE_OBJECTS);
1083  if (serial_Cache_pool.area == NULL)
1084  {
1085  return ER_OUT_OF_VIRTUAL_MEMORY;
1086  }
1087  serial_Cache_pool.free_list = serial_Cache_pool.area->obj_area;
1088 
1089  pthread_mutex_init (&serial_Cache_pool.cache_pool_mutex, NULL);
1090 
1091  serial_Cache_pool.ht = mht_create ("Serial cache pool hash table", NCACHE_OBJECTS * 8, oid_hash, oid_compare_equals);
1092  if (serial_Cache_pool.ht == NULL)
1093  {
1095  return ER_FAILED;
1096  }
1097 
1098  for (i = 0; i < sizeof (serial_Attrs_id) / sizeof (ATTR_ID); i++)
1099  {
1100  serial_Attrs_id[i] = -1;
1101  }
1102 
1103  return NO_ERROR;
1104 }
1105 
1106 /*
1107  * serial_finalize_cache_pool () -
1108  * return:
1109  */
1110 void
1112 {
1113  SERIAL_CACHE_AREA *tmp_area;
1114 
1115  serial_Cache_pool.free_list = NULL;
1116 
1117  if (serial_Cache_pool.ht != NULL)
1118  {
1119  mht_destroy (serial_Cache_pool.ht);
1120  serial_Cache_pool.ht = NULL;
1121  }
1122 
1123  while (serial_Cache_pool.area)
1124  {
1125  tmp_area = serial_Cache_pool.area;
1126  serial_Cache_pool.area = serial_Cache_pool.area->next;
1127 
1128  free_and_init (tmp_area->obj_area);
1129  free_and_init (tmp_area);
1130  }
1131 
1132  pthread_mutex_destroy (&serial_Cache_pool.cache_pool_mutex);
1133 
1134  serial_Num_attrs = -1;
1135 }
1136 
1137 /*
1138  * serial_get_attrid () -
1139  * return: attribute id or NOT_FOUND
1140  *
1141  * attr_index(in) :
1142  */
1143 // *INDENT-OFF*
1144 static int
1145 serial_get_attrid (THREAD_ENTRY * thread_p, int attr_index, ATTR_ID &attrid)
1146 {
1147  attrid = NOT_FOUND;
1148 
1149  if (serial_Num_attrs < 0)
1150  {
1152  if (error != NO_ERROR)
1153  {
1154  ASSERT_ERROR ();
1155  return error;
1156  }
1157  }
1158 
1159  if (attr_index >= 0 && attr_index <= serial_Num_attrs)
1160  {
1161  attrid = serial_Attrs_id[attr_index];
1162  }
1163  return NO_ERROR;
1164 }
1165 // *INDENT-ON*
1166 
1167 /*
1168  * serial_load_attribute_info_of_db_serial () -
1169  * return: NO_ERROR, or ER_status
1170  */
1171 static int
1173 {
1174  HEAP_SCANCACHE scan;
1175  RECDES class_record;
1176  HEAP_CACHE_ATTRINFO attr_info;
1177  int i, error = NO_ERROR;
1178  char *attr_name_p, *string = NULL;
1179  int alloced_string = 0;
1180 
1181  serial_Num_attrs = -1;
1182 
1183  oid_get_serial_oid (&serial_Cache_pool.db_serial_class_oid);
1184 
1185  if (heap_scancache_quick_start_with_class_oid (thread_p, &scan, &serial_Cache_pool.db_serial_class_oid) != NO_ERROR)
1186  {
1187  return ER_FAILED;
1188  }
1189  if (heap_get_class_record (thread_p, &serial_Cache_pool.db_serial_class_oid, &class_record, &scan, PEEK) != S_SUCCESS)
1190  {
1191  heap_scancache_end (thread_p, &scan);
1192  return ER_FAILED;
1193  }
1194 
1195  error = heap_attrinfo_start (thread_p, &serial_Cache_pool.db_serial_class_oid, -1, NULL, &attr_info);
1196  if (error != NO_ERROR)
1197  {
1198  (void) heap_scancache_end (thread_p, &scan);
1199  return error;
1200  }
1201 
1202  for (i = 0; i < attr_info.num_values; i++)
1203  {
1204  string = NULL;
1205  alloced_string = 0;
1206 
1207  error = or_get_attrname (&class_record, i, &string, &alloced_string);
1208  if (error != NO_ERROR)
1209  {
1210  ASSERT_ERROR ();
1211  goto exit_on_error;
1212  }
1213 
1214  attr_name_p = string;
1215  if (attr_name_p == NULL)
1216  {
1217  error = ER_FAILED;
1218  goto exit_on_error;
1219  }
1220 
1221  if (strcmp (attr_name_p, SERIAL_ATTR_NAME) == 0)
1222  {
1224  }
1225  else if (strcmp (attr_name_p, SERIAL_ATTR_OWNER) == 0)
1226  {
1228  }
1229  else if (strcmp (attr_name_p, SERIAL_ATTR_CURRENT_VAL) == 0)
1230  {
1232  }
1233  else if (strcmp (attr_name_p, SERIAL_ATTR_INCREMENT_VAL) == 0)
1234  {
1236  }
1237  else if (strcmp (attr_name_p, SERIAL_ATTR_MAX_VAL) == 0)
1238  {
1240  }
1241  else if (strcmp (attr_name_p, SERIAL_ATTR_MIN_VAL) == 0)
1242  {
1244  }
1245  else if (strcmp (attr_name_p, SERIAL_ATTR_CYCLIC) == 0)
1246  {
1248  }
1249  else if (strcmp (attr_name_p, SERIAL_ATTR_STARTED) == 0)
1250  {
1252  }
1253  else if (strcmp (attr_name_p, SERIAL_ATTR_CLASS_NAME) == 0)
1254  {
1256  }
1257  else if (strcmp (attr_name_p, SERIAL_ATTR_ATT_NAME) == 0)
1258  {
1260  }
1261  else if (strcmp (attr_name_p, SERIAL_ATTR_CACHED_NUM) == 0)
1262  {
1264  }
1265 
1266  if (string != NULL && alloced_string)
1267  {
1268  db_private_free_and_init (NULL, string);
1269  }
1270  }
1271 
1272  serial_Num_attrs = attr_info.num_values;
1273 
1274  heap_attrinfo_end (thread_p, &attr_info);
1275  error = heap_scancache_end (thread_p, &scan);
1276 
1277  return error;
1278 
1279 exit_on_error:
1280 
1281  heap_attrinfo_end (thread_p, &attr_info);
1282  (void) heap_scancache_end (thread_p, &scan);
1283 
1284  return error;
1285 }
1286 
1287 /*
1288  * serial_set_cache_entry () -
1289  * return:
1290  * entry(out) :
1291  * inc_val(in) :
1292  * cur_val(in) :
1293  * min_val(in) :
1294  * max_val(in) :
1295  * started(in) :
1296  * cyclic(in) :
1297  * last_val(in):
1298  * cached_num(in):
1299  */
1300 static void
1303 {
1304  pr_clone_value (cur_val, &entry->cur_val);
1305  pr_clone_value (inc_val, &entry->inc_val);
1306  pr_clone_value (max_val, &entry->max_val);
1307  pr_clone_value (min_val, &entry->min_val);
1308  pr_clone_value (cyclic, &entry->cyclic);
1309  pr_clone_value (last_val, &entry->last_cached_val);
1310  pr_clone_value (started, &entry->started);
1311  entry->cached_num = cached_num;
1312 }
1313 
1314 /*
1315  * serial_clear_value () - clear all value of cache entry
1316  * return:
1317  * entry(in/out) :
1318  */
1319 static void
1321 {
1322  pr_clear_value (&entry->cur_val);
1323  pr_clear_value (&entry->inc_val);
1324  pr_clear_value (&entry->max_val);
1325  pr_clear_value (&entry->min_val);
1326  pr_clear_value (&entry->cyclic);
1327  pr_clear_value (&entry->started);
1328  entry->cached_num = 0;
1329 }
1330 
1331 /*
1332  * serial_alloc_cache_entry () -
1333  * return:
1334  */
1335 static SERIAL_CACHE_ENTRY *
1337 {
1338  SERIAL_CACHE_ENTRY *entry;
1339  SERIAL_CACHE_AREA *tmp_area;
1340 
1341  if (serial_Cache_pool.free_list == NULL)
1342  {
1344  if (tmp_area == NULL)
1345  {
1346  return NULL;
1347  }
1348 
1349  tmp_area->next = serial_Cache_pool.area;
1350  serial_Cache_pool.area = tmp_area;
1351  serial_Cache_pool.free_list = tmp_area->obj_area;
1352  }
1353 
1354  entry = serial_Cache_pool.free_list;
1355  serial_Cache_pool.free_list = serial_Cache_pool.free_list->next;
1356 
1357  return entry;
1358 }
1359 
1360 /*
1361  * xserial_decache () - decache cache entry of cache pool
1362  * return:
1363  * oidp(in) :
1364  */
1365 void
1366 xserial_decache (THREAD_ENTRY * thread_p, OID * oidp)
1367 {
1368  SERIAL_CACHE_ENTRY *entry;
1369 #if defined (SERVER_MODE)
1370  int rc;
1371 #endif /* SERVER_MODE */
1372 
1373  xcache_remove_by_oid (thread_p, oidp);
1374 
1375  rc = pthread_mutex_lock (&serial_Cache_pool.cache_pool_mutex);
1376  entry = (SERIAL_CACHE_ENTRY *) mht_get (serial_Cache_pool.ht, oidp);
1377  if (entry != NULL)
1378  {
1379  mht_rem (serial_Cache_pool.ht, oidp, NULL, NULL);
1380 
1381  OID_SET_NULL (&entry->oid);
1382  serial_clear_value (entry);
1383  entry->next = serial_Cache_pool.free_list;
1384  serial_Cache_pool.free_list = entry;
1385  }
1386  pthread_mutex_unlock (&serial_Cache_pool.cache_pool_mutex);
1387 }
1388 
1389 /*
1390  * serial_alloc_cache_area () -
1391  * return:
1392  * num(in) :
1393  */
1394 static SERIAL_CACHE_AREA *
1396 {
1397  SERIAL_CACHE_AREA *tmp_area;
1398  int i;
1399 
1400  tmp_area = (SERIAL_CACHE_AREA *) malloc (sizeof (SERIAL_CACHE_AREA));
1401  if (tmp_area == NULL)
1402  {
1404  return NULL;
1405  }
1406  tmp_area->next = NULL;
1407 
1408  tmp_area->obj_area = ((SERIAL_CACHE_ENTRY *) malloc (sizeof (SERIAL_CACHE_ENTRY) * num));
1409  if (tmp_area->obj_area == NULL)
1410  {
1412  free_and_init (tmp_area);
1413  return NULL;
1414  }
1415 
1416  /* make free list */
1417  for (i = 0; i < num - 1; i++)
1418  {
1419  tmp_area->obj_area[i].next = &tmp_area->obj_area[i + 1];
1420  }
1421  tmp_area->obj_area[i].next = NULL;
1422 
1423  return tmp_area;
1424 }
1425 
1426 #if defined (SERVER_MODE)
1427 /*
1428  * serial_cache_index_btid () - Cache serial index BTID.
1429  *
1430  * return : Error Code.
1431  * thread_p (in) : Thread entry.
1432  *
1433  * NOTE that workspace manager is unavailable when restarting from backup.
1434  * It is possible to allow SA_MODE executables except restoredb to use the function,
1435  * however, it is better not to use it in SA_MODE for clarity.
1436  */
1437 int
1438 serial_cache_index_btid (THREAD_ENTRY * thread_p)
1439 {
1440  int error_code = NO_ERROR;
1441  OID serial_oid = OID_INITIALIZER;
1442 
1443  /* Get serial class OID. */
1444  oid_get_serial_oid (&serial_oid);
1445  assert (!OID_ISNULL (&serial_oid));
1446 
1447  /* Now try to get index BTID. Serial index name is "pk_db_serial_name". */
1448  error_code = heap_get_btid_from_index_name (thread_p, &serial_oid, "pk_db_serial_name", &serial_Cached_btid);
1449  if (error_code != NO_ERROR)
1450  {
1451  ASSERT_ERROR ();
1452  return error_code;
1453  }
1454  /* Safe guard: successfully read a non-NULL BTID. */
1455  assert (!BTID_IS_NULL (&serial_Cached_btid));
1456  return NO_ERROR;
1457 }
1458 
1459 /*
1460  * serial_get_index_btid () - Get serial index BTID.
1461  *
1462  * return : Void.
1463  * output (in) : Serial index btid.
1464  *
1465  * NOTE that workspace manager is unavailable when restarting from backup.
1466  * It is possible to allow SA_MODE executables except restoredb to use the function,
1467  * however, it is better not to use it in SA_MODE for clarity.
1468  */
1469 void
1470 serial_get_index_btid (BTID * output)
1471 {
1472  /* Safe guard: a non-NULL serial index BTID is cached. */
1473  assert (!BTID_IS_NULL (&serial_Cached_btid));
1474  /* Safe guard: output parameter for index BTID is not NULL. */
1475  assert (output != NULL);
1476 
1477  BTID_COPY (output, &serial_Cached_btid);
1478 }
1479 #endif /* SERVER_MODE */
char * PAGE_PTR
#define OID_INITIALIZER
Definition: oid.h:36
#define SERIAL_ATTR_CLASS_NAME
DB_VALUE * heap_attrinfo_access(ATTR_ID attrid, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:10665
static int serial_load_attribute_info_of_db_serial(THREAD_ENTRY *thread_p)
Definition: serial.c:1172
#define NO_ERROR
Definition: error_code.h:46
#define SERIAL_ATTR_OWNER
pthread_mutex_t cache_pool_mutex
Definition: serial.c:113
#define ASSERT_ERROR()
SCAN_CODE
#define pthread_mutex_lock(a)
Definition: serial.c:47
void set_external_buffer(char *buf, std::size_t buf_size)
int heap_scancache_quick_start_modify_with_class_oid(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache, OID *class_oid)
Definition: heap_file.c:19331
SCAN_CODE heap_get_visible_version(THREAD_ENTRY *thread_p, const OID *oid, OID *class_oid, RECDES *recdes, HEAP_SCANCACHE *scan_cache, int ispeeking, int old_chn)
Definition: heap_file.c:24272
Definition: serial.c:76
DB_VALUE last_cached_val
Definition: serial.c:90
int db_get_int(const DB_VALUE *value)
OID db_serial_class_oid
Definition: serial.c:112
#define ER_FAILED
Definition: error_code.h:47
static void serial_clear_value(SERIAL_CACHE_ENTRY *entry)
Definition: serial.c:1320
int mht_rem(MHT_TABLE *ht, const void *key, int(*rem_func)(const void *key, void *data, void *args), void *func_args)
Definition: memory_hash.c:1952
int cached_num
Definition: serial.c:87
int xserial_get_current_value(THREAD_ENTRY *thread_p, DB_VALUE *result_num, const OID *oid_p, int cached_num)
Definition: serial.c:156
const void * mht_put(MHT_TABLE *ht, const void *key, void *data)
Definition: memory_hash.c:1778
int db_make_numeric(DB_VALUE *value, const DB_C_NUMERIC num, const int precision, const int scale)
#define ASSERT_ERROR_AND_SET(error_code)
static int rv
Definition: serial.c:49
#define SERIAL_ATTR_CACHED_NUM
#define assert_release(e)
Definition: error_manager.h:96
#define LOG_CHECK_LOG_APPLIER(thread_p)
Definition: log_impl.h:240
DB_VALUE cur_val
Definition: serial.c:81
DB_VALUE min_val
Definition: serial.c:84
int numeric_db_value_compare(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
int lock_object(THREAD_ENTRY *thread_p, const OID *oid, const OID *class_oid, LOCK lock, int cond_flag)
void log_sysop_start(THREAD_ENTRY *thread_p)
Definition: log_manager.c:3578
#define OID_SET_NULL(oidp)
Definition: oid.h:85
#define NULL_SLOTID
MHT_TABLE * ht
Definition: serial.c:106
int er_errid(void)
#define SP_SUCCESS
Definition: slotted_page.h:50
int numeric_db_value_sub(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
SR_ATTRIBUTES
Definition: serial.c:54
void xcache_remove_by_oid(THREAD_ENTRY *thread_p, const OID *oid)
Definition: xasl_cache.c:1869
void xserial_decache(THREAD_ENTRY *thread_p, OID *oidp)
Definition: serial.c:1366
ATTR_ID serial_Attrs_id[SERIAL_ATTR_MAX_INDEX]
Definition: serial.c:124
#define SERIAL_ATTR_NAME
int heap_scancache_end(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache)
Definition: heap_file.c:7195
SERIAL_CACHE_ENTRY * free_list
Definition: serial.c:108
struct serial_cache_area * next
Definition: serial.c:100
#define COPY_OID(dest_oid_ptr, src_oid_ptr)
Definition: oid.h:63
LOCK lock_get_object_lock(const OID *oid, const OID *class_oid)
bool spage_is_updatable(THREAD_ENTRY *thread_p, PAGE_PTR page_p, PGSLOTID slot_id, int record_descriptor_length)
void THREAD_ENTRY
#define NULL_PAGEID
std::size_t get_size(void) const
int ATTR_ID
int spage_update(THREAD_ENTRY *thread_p, PAGE_PTR page_p, PGSLOTID slot_id, const RECDES *record_descriptor_p)
LOCK
SERIAL_CACHE_ENTRY * obj_area
Definition: serial.c:99
void mht_destroy(MHT_TABLE *ht)
Definition: memory_hash.c:1140
int heap_attrinfo_start(THREAD_ENTRY *thread_p, const OID *class_oid, int requested_num_attrs, const ATTR_ID *attrids, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:9427
static SERIAL_CACHE_AREA * serial_alloc_cache_area(int num)
Definition: serial.c:1395
#define RECDES_INITIALIZER
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
DB_VALUE inc_val
Definition: serial.c:82
#define ER_QPROC_INVALID_PARAMETER
Definition: error_code.h:963
#define DB_MAX_NUMERIC_PRECISION
Definition: dbtype_def.h:522
#define SERIAL_ATTR_MAX_VAL
#define assert(x)
static SERIAL_CACHE_ENTRY * serial_alloc_cache_entry(void)
Definition: serial.c:1336
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define SERIAL_ATTR_CYCLIC
static int xserial_get_next_value_internal(THREAD_ENTRY *thread_p, DB_VALUE *result_num, const OID *serial_oidp, int num_alloc)
Definition: serial.c:614
#define BTID_INITIALIZER
SCAN_CODE heap_attrinfo_transform_to_disk(THREAD_ENTRY *thread_p, HEAP_CACHE_ATTRINFO *attr_info, RECDES *old_recdes, record_descriptor *new_recdes)
Definition: heap_file.c:11527
static int serial_get_next_cached_value(THREAD_ENTRY *thread_p, SERIAL_CACHE_ENTRY *entry, int num_alloc)
Definition: serial.c:416
#define ER_QPROC_SERIAL_RANGE_OVERFLOW
Definition: error_code.h:967
#define ER_QPROC_CANNOT_FETCH_SERIAL
Definition: error_code.h:968
static int serial_update_serial_object(THREAD_ENTRY *thread_p, PAGE_PTR pgptr, RECDES *recdesc, HEAP_CACHE_ATTRINFO *attr_info, const OID *serial_class_oidp, const OID *serial_oidp, DB_VALUE *key_val)
Definition: serial.c:873
void lock_unlock_object(THREAD_ENTRY *thread_p, const OID *oid, const OID *class_oid, LOCK lock, bool force)
#define NOT_FOUND
Definition: serial.c:73
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
OID * oid_Serial_class_oid
Definition: oid.c:76
void * mht_get(MHT_TABLE *ht, const void *key)
Definition: memory_hash.c:1419
#define NULL
Definition: freelistheap.h:34
void numeric_coerce_int_to_num(int arg, DB_C_NUMERIC answer)
DB_VALUE max_val
Definition: serial.c:83
int heap_scancache_quick_start_with_class_oid(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache, OID *class_oid)
Definition: heap_file.c:19282
static int xserial_get_current_value_internal(THREAD_ENTRY *thread_p, DB_VALUE *result_num, const OID *serial_oidp)
Definition: serial.c:198
static int serial_get_attrid(THREAD_ENTRY *thread_p, int attr_index, ATTR_ID &attrid)
Definition: serial.c:1145
PAGE_PTR pgptr
Definition: log_append.hpp:57
#define ER_PB_BAD_PAGEID
Definition: error_code.h:67
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int xserial_get_next_value(THREAD_ENTRY *thread_p, DB_VALUE *result_num, const OID *oid_p, int cached_num, int num_alloc, int is_auto_increment, bool force_set_last_insert_id)
Definition: serial.c:282
SERIAL_CACHE_POOL serial_Cache_pool
Definition: serial.c:116
int numeric_db_value_is_positive(const DB_VALUE *dbvalue)
MHT_TABLE * mht_create(const char *name, int est_size, unsigned int(*hash_func)(const void *key, unsigned int ht_size), int(*cmp_func)(const void *key1, const void *key2))
Definition: memory_hash.c:894
struct serial_entry * next
Definition: serial.c:93
int xsession_set_cur_insert_id(THREAD_ENTRY *thread_p, const DB_VALUE *value, bool force)
Definition: session_sr.c:106
unsigned int oid_hash(const void *key_oid, unsigned int htsize)
Definition: oid.c:294
PGBUF_WATCHER page_watcher
Definition: heap_file.h:149
int numeric_db_value_mul(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
SERIAL_CACHE_AREA * area
Definition: serial.c:110
#define CEIL_PTVDIV(dividend, divisor)
Definition: memory_alloc.h:50
int pr_clear_value(DB_VALUE *value)
offset_type offset
Definition: log_append.hpp:58
#define SERIAL_ATTR_CURRENT_VAL
void serial_finalize_cache_pool(void)
Definition: serial.c:1111
void log_sysop_abort(THREAD_ENTRY *thread_p)
Definition: log_manager.c:4017
#define pthread_mutex_destroy(a)
Definition: serial.c:46
int oid_compare_equals(const void *key_oid1, const void *key_oid2)
Definition: oid.c:310
#define SERIAL_ATTR_INCREMENT_VAL
DB_VALUE cyclic
Definition: serial.c:85
static void error(const char *msg)
Definition: gencat.c:331
const recdes & get_recdes(void) const
static int rc
Definition: serial.c:50
int heap_get_btid_from_index_name(THREAD_ENTRY *thread_p, const OID *p_class_oid, const char *index_name, BTID *p_found_btid)
Definition: heap_file.c:16938
int serial_Num_attrs
Definition: serial.c:125
#define LOG_FIND_THREAD_TRAN_INDEX(thrd)
Definition: perf_monitor.h:158
#define ARG_FILE_LINE
Definition: error_manager.h:44
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
#define pthread_mutex_init(a, b)
Definition: serial.c:45
int serial_initialize_cache_pool(THREAD_ENTRY *thread_p)
Definition: serial.c:1073
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define BTID_COPY(btid_ptr1, btid_ptr2)
int or_get_attrname(RECDES *record, int attrid, char **string, int *alloced_string)
#define ER_HEAP_UNKNOWN_OBJECT
Definition: error_code.h:102
void log_sysop_commit(THREAD_ENTRY *thread_p)
Definition: log_manager.c:3895
#define pthread_mutex_unlock(a)
Definition: serial.c:48
static void serial_set_cache_entry(SERIAL_CACHE_ENTRY *entry, DB_VALUE *inc_val, DB_VALUE *cur_val, DB_VALUE *min_val, DB_VALUE *max_val, DB_VALUE *started, DB_VALUE *cyclic, DB_VALUE *last_val, int cached_num)
Definition: serial.c:1301
#define NCACHE_OBJECTS
Definition: serial.c:71
#define CHECK_MODIFICATION_NO_RETURN(error)
Definition: db.h:135
int i
Definition: dynamic_load.c:954
int db_make_null(DB_VALUE *value)
#define DB_IS_NULL(value)
Definition: dbtype.h:63
#define SERIAL_ATTR_STARTED
INT16 type
#define NULL_VOLID
#define DB_NUMERIC_BUF_SIZE
Definition: dbtype_def.h:573
#define BTID_IS_NULL(btid)
int db_make_int(DB_VALUE *value, const int num)
void heap_attrinfo_end(THREAD_ENTRY *thread_p, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:9979
static int serial_update_cur_val_of_serial(THREAD_ENTRY *thread_p, SERIAL_CACHE_ENTRY *entry)
Definition: serial.c:504
#define OID_ISNULL(oidp)
Definition: oid.h:81
OID oid
Definition: serial.c:78
int numeric_db_value_add(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
void set_type(std::int16_t type)
bool log_does_allow_replication(void)
Definition: log_comm.c:270
DB_VALUE started
Definition: serial.c:86
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
PAGE_PTR pgptr
Definition: page_buffer.h:222
#define SERIAL_ATTR_ATT_NAME
#define PEEK
Definition: file_io.h:74
#define SERIAL_ATTR_MIN_VAL
void oid_get_serial_oid(OID *oid)
Definition: oid.c:171
void log_append_redo_recdes(THREAD_ENTRY *thread_p, LOG_RCVINDEX rcvindex, LOG_DATA_ADDR *addr, const RECDES *recdes)
Definition: log_manager.c:2573
static int serial_get_nth_value(DB_VALUE *inc_val, DB_VALUE *cur_val, DB_VALUE *min_val, DB_VALUE *max_val, DB_VALUE *cyclic, int nth, DB_VALUE *result_val)
Definition: serial.c:975
#define ER_QPROC_CANNOT_UPDATE_SERIAL
Definition: error_code.h:969
SCAN_CODE heap_get_class_record(THREAD_ENTRY *thread_p, const OID *class_oid, RECDES *recdes_p, HEAP_SCANCACHE *scan_cache, int ispeeking)
Definition: heap_file.c:24780