/* * InsertIntoErrorTable * * Insert the information in cdbsreh into the error table we are using. * The destination is a regular heap table in a writer gang, and tuplestore * if it's a reader gang. The tuplestore data will be redirected to * the writer gang in the same session later. * By design the error table rows are inserted in a frozen fashion. */ void InsertIntoErrorTable(CdbSreh *cdbsreh) { HeapTuple tuple; tuple = FormErrorTuple(cdbsreh); /* store and freeze the tuple */ frozen_heap_insert(cdbsreh->errtbl, tuple); heap_freetuple(tuple); }
/* * Write into the error log file. This opens the file every time, * so that we can keep it simple to deal with concurrent write. */ static void ErrorLogWrite(CdbSreh *cdbsreh) { HeapTuple tuple; char filename[MAXPGPATH]; FILE *fp; pg_crc32 crc; Assert(OidIsValid(cdbsreh->relid)); ErrorLogFileName(filename, MyDatabaseId, cdbsreh->relid); tuple = FormErrorTuple(cdbsreh); INIT_CRC32C(crc); COMP_CRC32C(crc, tuple->t_data, tuple->t_len); FIN_CRC32C(crc); LWLockAcquire(ErrorLogLock, LW_EXCLUSIVE); fp = AllocateFile(filename, "a"); if (!fp) { mkdir(ErrorLogDir, S_IRWXU); fp = AllocateFile(filename, "a"); } if (!fp) ereport(ERROR, (errmsg("could not open \"%s\": %m", filename))); /* * format: * 0-4: length * 5-8: crc * 9-n: tuple data */ if (fwrite(&tuple->t_len, 1, sizeof(tuple->t_len), fp) != sizeof(tuple->t_len)) elog(ERROR, "could not write tuple length: %m"); if (fwrite(&crc, 1, sizeof(pg_crc32), fp) != sizeof(pg_crc32)) elog(ERROR, "could not write checksum: %m"); if (fwrite(tuple->t_data, 1, tuple->t_len, fp) != tuple->t_len) elog(ERROR, "could not write tuple data: %m"); FreeFile(fp); LWLockRelease(ErrorLogLock); heap_freetuple(tuple); }