/* * smgrcreate() -- Create a new relation. * * Given an already-created (but presumably unused) SMgrRelation, * cause the underlying disk file or other storage for the fork * to be created. * * If isRedo is true, it is okay for the underlying file to exist * already because we are in a WAL replay sequence. */ void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) { /* * Exit quickly in WAL replay mode if we've already opened the file. If * it's open, it surely must exist. */ if (isRedo && reln->md_fd[forknum] != NULL) return; /* * We may be using the target table space for the first time in this * database, so create a per-database subdirectory if needed. * * XXX this is a fairly ugly violation of module layering, but this seems * to be the best place to put the check. Maybe TablespaceCreateDbspace * should be here and not in commands/tablespace.c? But that would imply * importing a lot of stuff that smgr.c oughtn't know, either. */ TablespaceCreateDbspace(reln->smgr_rnode.node.spcNode, reln->smgr_rnode.node.dbNode, isRedo); (*(smgrsw[reln->smgr_which].smgr_create)) (reln, forknum, isRedo); }
/* * smgrcreate() -- Create a new relation. * * Given an already-created (but presumably unused) SMgrRelation, * cause the underlying disk file or other storage to be created. * * If isRedo is true, it is okay for the underlying file to exist * already because we are in a WAL replay sequence. In this case * we should make no PendingRelDelete entry; the WAL sequence will * tell whether to drop the file. */ void smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo) { XLogRecPtr lsn; XLogRecData rdata; xl_smgr_create xlrec; PendingRelDelete *pending; /* * We may be using the target table space for the first time in this * database, so create a per-database subdirectory if needed. * * XXX this is a fairly ugly violation of module layering, but this seems * to be the best place to put the check. Maybe TablespaceCreateDbspace * should be here and not in commands/tablespace.c? But that would imply * importing a lot of stuff that smgr.c oughtn't know, either. */ TablespaceCreateDbspace(reln->smgr_rnode.spcNode, reln->smgr_rnode.dbNode, isRedo); if (!(*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create relation %u/%u/%u: %m", reln->smgr_rnode.spcNode, reln->smgr_rnode.dbNode, reln->smgr_rnode.relNode))); if (isRedo) return; /* * Make a non-transactional XLOG entry showing the file creation. It's * non-transactional because we should replay it whether the transaction * commits or not; if not, the file will be dropped at abort time. */ xlrec.rnode = reln->smgr_rnode; rdata.data = (char *) &xlrec; rdata.len = sizeof(xlrec); rdata.buffer = InvalidBuffer; rdata.next = NULL; lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_CREATE | XLOG_NO_TRAN, &rdata); /* Add the relation to the list of stuff to delete at abort */ pending = (PendingRelDelete *) MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete)); pending->relnode = reln->smgr_rnode; pending->which = reln->smgr_which; pending->isTemp = isTemp; pending->atCommit = false; /* delete if abort */ pending->nestLevel = GetCurrentTransactionNestLevel(); pending->next = pendingDeletes; pendingDeletes = pending; }