/** * Returns an exception string for the given type of exception, function * and additional formatting parameters. This function will crash the * system or return bogus when the malexception enum is not aligned with * the exceptionNames array. */ str createException(enum malexception type, const char *fcn, const char *format, ...) { va_list ap; str ret; if (GDKerrbuf && (ret = strstr(format, MAL_MALLOC_FAIL)) != NULL && ret[strlen(MAL_MALLOC_FAIL)] != ':' && (strncmp(GDKerrbuf, "GDKmalloc", 9) == 0 || strncmp(GDKerrbuf, "GDKrealloc", 10) == 0 || strncmp(GDKerrbuf, "GDKzalloc", 9) == 0 || strncmp(GDKerrbuf, "GDKstrdup", 9) == 0 || strncmp(GDKerrbuf, "allocating too much virtual address space", 41) == 0)) { /* override errors when the underlying error is memory * exhaustion, but include whatever it is that the GDK level * reported */ ret = createException(type, fcn, SQLSTATE(HY001) MAL_MALLOC_FAIL ": %s", GDKerrbuf); GDKclrerr(); return ret; } if (strcmp(format, GDK_EXCEPTION) == 0 && GDKerrbuf[0]) { /* for GDK errors, report the underlying error */ char *p = GDKerrbuf; if (strncmp(p, GDKERROR, strlen(GDKERROR)) == 0) p += strlen(GDKERROR); if (strlen(p) > 6 && p[5] == '!') ret = createException(type, fcn, "%s", p); else ret = createException(type, fcn, "GDK reported error: %s", p); GDKclrerr(); return ret; } va_start(ap, format); ret = createExceptionInternal(type, fcn, format, ap); va_end(ap); GDKclrerr(); return ret; }
/* in the commit epilogue, the BBP-status of the bats is changed to * reflect their presence in the succeeded checkpoint. Also bats from * the previous checkpoint that were deleted now are physically * destroyed. */ static void epilogue(int cnt, bat *subcommit) { int i = 0; while (++i < cnt) { bat bid = subcommit ? subcommit[i] : i; if (BBP_status(bid) & BBPPERSISTENT) { BBP_status_on(bid, BBPEXISTING, subcommit ? "TMsubcommit" : "TMcommit"); } else if (BBP_status(bid) & BBPDELETED) { /* check mmap modes of bats that are now * transient. this has to be done after the * commit succeeded, because the mmap modes * allowed on transient bats would be * dangerous on persistent bats. If the commit * failed, the already processed bats that * would become transient after the commit, * but didn't due to the failure, would be a * consistency risk. */ BAT *b = BBP_cache(bid); if (b) { /* check mmap modes */ if (BATcheckmodes(b, true) != GDK_SUCCEED) fprintf(stderr, "#epilogue: BATcheckmodes failed\n"); } } if ((BBP_status(bid) & BBPDELETED) && BBP_refs(bid) <= 0 && BBP_lrefs(bid) <= 0) { BAT *b = BBPquickdesc(bid, TRUE); /* the unloaded ones are deleted without * loading deleted disk images */ if (b) { BATdelete(b); if (BBP_cache(bid)) { /* those that quickdesc * decides to load => free * memory */ BATfree(b); } } BBPclear(bid); /* clear with locking */ } BBP_status_off(bid, BBPDELETED | BBPSWAPPED | BBPNEW, subcommit ? "TMsubcommit" : "TMcommit"); } GDKclrerr(); }
static str mythrow(enum malexception type, const char *fcn, const char *msg) { char *errbuf = GDKerrbuf; char *s; if (errbuf && *errbuf) { if (strncmp(errbuf, "!ERROR: ", 8) == 0) errbuf += 8; if (strchr(errbuf, '!') == errbuf + 5) { s = createException(type, fcn, "%s", errbuf); } else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') { s = createException(type, fcn, "%s", s + 2); } else { s = createException(type, fcn, "%s", errbuf); } GDKclrerr(); return s; } return createException(type, fcn, "%s", msg); }