⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elog.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */		case ENOTEMPTY: /* Directory not empty */#endif			edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;			break;			/* Insufficient resources */		case ENOSPC:			/* No space left on device */			edata->sqlerrcode = ERRCODE_DISK_FULL;			break;		case ENFILE:			/* File table overflow */		case EMFILE:			/* Too many open files */			edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;			break;			/* Hardware failure */		case EIO:				/* I/O error */			edata->sqlerrcode = ERRCODE_IO_ERROR;			break;			/* All else is classified as internal errors */		default:			edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;			break;	}	return 0;					/* return value does not matter */}/* * errcode_for_socket_access --- add SQLSTATE error code to the current error * * The SQLSTATE code is chosen based on the saved errno value.	We assume * that the failing operation was some type of socket access. * * NOTE: the primary error message string should generally include %m * when this is used. */interrcode_for_socket_access(void){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	switch (edata->saved_errno)	{			/* Loss of connection */		case EPIPE:#ifdef ECONNRESET		case ECONNRESET:#endif			edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;			break;			/* All else is classified as internal errors */		default:			edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;			break;	}	return 0;					/* return value does not matter */}/* * This macro handles expansion of a format string and associated parameters; * it's common code for errmsg(), errdetail(), etc.  Must be called inside * a routine that is declared like "const char *fmt, ..." and has an edata * pointer set up.	The message is assigned to edata->targetfield, or * appended to it if appendval is true. * * Note: we pstrdup the buffer rather than just transferring its storage * to the edata field because the buffer might be considerably larger than * really necessary. */#define EVALUATE_MESSAGE(targetfield, appendval)  \	{ \		char		   *fmtbuf; \		StringInfoData	buf; \		/* Internationalize the error format string */ \		fmt = _(fmt); \		/* Expand %m in format string */ \		fmtbuf = expand_fmt_string(fmt, edata); \		initStringInfo(&buf); \		if ((appendval) && edata->targetfield) \			appendStringInfo(&buf, "%s\n", edata->targetfield); \		/* Generate actual output --- have to use appendStringInfoVA */ \		for (;;) \		{ \			va_list		args; \			bool		success; \			va_start(args, fmt); \			success = appendStringInfoVA(&buf, fmtbuf, args); \			va_end(args); \			if (success) \				break; \			enlargeStringInfo(&buf, buf.maxlen); \		} \		/* Done with expanded fmt */ \		pfree(fmtbuf); \		/* Save the completed message into the stack item */ \		if (edata->targetfield) \			pfree(edata->targetfield); \		edata->targetfield = pstrdup(buf.data); \		pfree(buf.data); \	}/* * errmsg --- add a primary error message text to the current error * * In addition to the usual %-escapes recognized by printf, "%m" in * fmt is replaced by the error message for the caller's value of errno. * * Note: no newline is needed at the end of the fmt string, since * ereport will provide one for the output methods that need it. */interrmsg(const char *fmt,...){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	recursion_depth++;	CHECK_STACK_DEPTH();	oldcontext = MemoryContextSwitchTo(ErrorContext);	EVALUATE_MESSAGE(message, false);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;	return 0;					/* return value does not matter */}/* * errmsg_internal --- add a primary error message text to the current error * * This is exactly like errmsg() except that strings passed to errmsg_internal * are customarily left out of the internationalization message dictionary. * This should be used for "can't happen" cases that are probably not worth * spending translation effort on. */interrmsg_internal(const char *fmt,...){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	recursion_depth++;	CHECK_STACK_DEPTH();	oldcontext = MemoryContextSwitchTo(ErrorContext);	EVALUATE_MESSAGE(message, false);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;	return 0;					/* return value does not matter */}/* * errdetail --- add a detail error message text to the current error */interrdetail(const char *fmt,...){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	recursion_depth++;	CHECK_STACK_DEPTH();	oldcontext = MemoryContextSwitchTo(ErrorContext);	EVALUATE_MESSAGE(detail, false);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;	return 0;					/* return value does not matter */}/* * errhint --- add a hint error message text to the current error */interrhint(const char *fmt,...){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	recursion_depth++;	CHECK_STACK_DEPTH();	oldcontext = MemoryContextSwitchTo(ErrorContext);	EVALUATE_MESSAGE(hint, false);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;	return 0;					/* return value does not matter */}/* * errcontext --- add a context error message text to the current error * * Unlike other cases, multiple calls are allowed to build up a stack of * context information.  We assume earlier calls represent more-closely-nested * states. */interrcontext(const char *fmt,...){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	recursion_depth++;	CHECK_STACK_DEPTH();	oldcontext = MemoryContextSwitchTo(ErrorContext);	EVALUATE_MESSAGE(context, true);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;	return 0;					/* return value does not matter */}/* * errfunction --- add reporting function name to the current error * * This is used when backwards compatibility demands that the function * name appear in messages sent to old-protocol clients.  Note that the * passed string is expected to be a non-freeable constant string. */interrfunction(const char *funcname){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	edata->funcname = funcname;	edata->show_funcname = true;	return 0;					/* return value does not matter */}/* * errposition --- add cursor position to the current error */interrposition(int cursorpos){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	edata->cursorpos = cursorpos;	return 0;					/* return value does not matter */}/* * internalerrposition --- add internal cursor position to the current error */intinternalerrposition(int cursorpos){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	edata->internalpos = cursorpos;	return 0;					/* return value does not matter */}/* * internalerrquery --- add internal query text to the current error * * Can also pass NULL to drop the internal query text entry.  This case * is intended for use in error callback subroutines that are editorializing * on the layout of the error report. */intinternalerrquery(const char *query){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	if (edata->internalquery)	{		pfree(edata->internalquery);		edata->internalquery = NULL;	}	if (query)		edata->internalquery = MemoryContextStrdup(ErrorContext, query);	return 0;					/* return value does not matter */}/* * geterrposition --- return the currently set error position (0 if none) * * This is only intended for use in error callback subroutines, since there * is no other place outside elog.c where the concept is meaningful. */intgeterrposition(void){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	return edata->cursorpos;}/* * getinternalerrposition --- same for internal error position * * This is only intended for use in error callback subroutines, since there * is no other place outside elog.c where the concept is meaningful. */intgetinternalerrposition(void){	ErrorData  *edata = &errordata[errordata_stack_depth];	/* we don't bother incrementing recursion_depth */	CHECK_STACK_DEPTH();	return edata->internalpos;}/* * elog_start --- startup for old-style API * * All that we do here is stash the hidden filename/lineno/funcname * arguments into a stack entry. * * We need this to be separate from elog_finish because there's no other * portable way to deal with inserting extra arguments into the elog call. * (If macros with variable numbers of arguments were portable, it'd be * easy, but they aren't.) */voidelog_start(const char *filename, int lineno, const char *funcname){	ErrorData  *edata;	if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)	{		/*		 * Wups, stack not big enough.	We treat this as a PANIC condition		 * because it suggests an infinite loop of errors during error		 * recovery.		 */		errordata_stack_depth = -1;		/* make room on stack */		ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));	}	edata = &errordata[errordata_stack_depth];	edata->filename = filename;	edata->lineno = lineno;	edata->funcname = funcname;	/* errno is saved now so that error parameter eval can't change it */	edata->saved_errno = errno;}/* * elog_finish --- finish up for old-style API */voidelog_finish(int elevel, const char *fmt,...){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	CHECK_STACK_DEPTH();	/*	 * Do errstart() to see if we actually want to report the message.	 */	errordata_stack_depth--;	errno = edata->saved_errno;	if (!errstart(elevel, edata->filename, edata->lineno, edata->funcname))		return;					/* nothing to do */	/*	 * Format error message just like errmsg().	 */	recursion_depth++;	oldcontext = MemoryContextSwitchTo(ErrorContext);	EVALUATE_MESSAGE(message, false);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;	/*	 * And let errfinish() finish up.	 */	errfinish(0);}/* * Actual output of the top-of-stack error message * * In the ereport(ERROR) case this is called from PostgresMain (or not at all, * if the error is caught by somebody).  For all other severity levels this * is called by errfinish. */voidEmitErrorReport(void){	ErrorData  *edata = &errordata[errordata_stack_depth];	MemoryContext oldcontext;	recursion_depth++;	CHECK_STACK_DEPTH();	oldcontext = MemoryContextSwitchTo(ErrorContext);	/* Send to server log, if enabled */	if (edata->output_to_server)		send_message_to_server_log(edata);	/* Send to client, if enabled */	if (edata->output_to_client)		send_message_to_frontend(edata);	MemoryContextSwitchTo(oldcontext);	recursion_depth--;}/* * CopyErrorData --- obtain a copy of the topmost error stack entry * * This is only for use in error handler code.	The data is copied into the * current memory context, so callers should always switch away from * ErrorContext first; otherwise it will be lost when FlushErrorState is done. */ErrorData *CopyErrorData(void){	ErrorData  *edata = &errordata[errordata_stack_depth];	ErrorData  *newedata;	/*	 * we don't increment recursion_depth because out-of-memory here does not	 * indicate a problem within the error subsystem.	 */	CHECK_STACK_DEPTH();	Assert(CurrentMemoryContext != ErrorContext);	/* Copy the struct itself */	newedata = (ErrorData *) palloc(sizeof(ErrorData));	memcpy(newedata, edata, sizeof(ErrorData));	/* Make copies of separately-allocated fields */	if (newedata->message)		newedata->message = pstrdup(newedata->message);	if (newedata->detail)		newedata->detail = pstrdup(newedata->detail);	if (newedata->hint)		newedata->hint = pstrdup(newedata->hint);	if (newedata->context)		newedata->context = pstrdup(newedata->context);	if (newedata->internalquery)		newedata->internalquery = pstrdup(newedata->internalquery);	return newedata;}/* * FreeErrorData --- free the structure returned by CopyErrorData. * * Error handlers should use this in preference to assuming they know all * the separately-allocated fields. */voidFreeErrorData(ErrorData *edata){	if (edata->message)		pfree(edata->message);	if (edata->detail)		pfree(edata->detail);	if (edata->hint)		pfree(edata->hint);	if (edata->context)		pfree(edata->context);	if (edata->internalquery)		pfree(edata->internalquery);	pfree(edata);}/* * FlushErrorState --- flush the error state after error recovery * * This should be called by an error handler after it's done processing * the error; or as soon as it's done CopyErrorData, if it intends to * do stuff that is likely to provoke another error.  You are not "out" of * the error subsystem until you have done this. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -