Exemplo n.º 1
0
void
elog(int elevel, const char *fmt, ...)
{
	va_list			args;
	bool			ok;
	size_t			len;
	pgutErrorData  *edata;

	if (elevel < pgut_abort_level && !log_required(elevel, pgut_log_level))
		return;

	edata = pgut_errinit(elevel);

	do
	{
		va_start(args, fmt);
		ok = appendStringInfoVA(&edata->msg, fmt, args);
		va_end(args);
	} while (!ok);
	len = strlen(fmt);
	if (len > 2 && strcmp(fmt + len - 2, ": ") == 0)
		appendStringInfoString(&edata->msg, strerror(edata->save_errno));
	trimStringBuffer(&edata->msg);

	pgut_errfinish(true);
}
Exemplo n.º 2
0
/* appendStringInfoVA + automatic buffer extension */
static void
appendStringInfoVA_s(StringInfo str, const char *fmt, va_list args)
{
#if PG_VERSION_NUM >= 90400
	int needed;
	while ((needed = appendStringInfoVA(str, fmt, args)) > 0)
	{
		/* Double the buffer size and try again. */
		enlargeStringInfo(str, needed);
	}
#else
	while (!appendStringInfoVA(str, fmt, args))
	{
		/* Double the buffer size and try again. */
		enlargeStringInfo(str, str->maxlen);
	}
#endif
}
Exemplo n.º 3
0
int errdetail_impl(const char* fmt, ...)
{
    StringInfoData	buf;
    initStringInfo(&buf);
    va_list		args;
    va_start(args, fmt);

	appendStringInfoVA(&buf, fmt, args);
	strncpy(lastErrorMsg, buf.data, sizeof(lastErrorMsg) / sizeof(lastErrorMsg[0]));

	pfree(buf.data);
	return 0;
}
Exemplo n.º 4
0
int
errdetail(const char *fmt,...)
{
	pgutErrorData  *edata = getErrorData();
	va_list			args;
	bool			ok;

	do
	{
		va_start(args, fmt);
		ok = appendStringInfoVA(&edata->detail, fmt, args);
		va_end(args);
	} while (!ok);
	trimStringBuffer(&edata->detail);

	return 0;	/* return value does not matter */
}
Exemplo n.º 5
0
/*
 * appendStringInfo
 *
 * Format text data under the control of fmt (an sprintf-style format string)
 * and append it to whatever is already in str.  More space is allocated
 * to str if necessary.  This is sort of like a combination of sprintf and
 * strcat.
 */
void
appendStringInfo(StringInfo str, const char *fmt,...)
{
    for (;;)
    {
        va_list		args;
        bool		success;

        /* Try to format the data. */
        va_start(args, fmt);
        success = appendStringInfoVA(str, fmt, args);
        va_end(args);

        if (success)
            break;

        /* Double the buffer size and try again. */
        enlargeStringInfo(str, str->maxlen);
    }
}
Exemplo n.º 6
0
/*
 * appendStringInfo
 *
 * Format text data under the control of fmt (an sprintf-style format string)
 * and append it to whatever is already in str.  More space is allocated
 * to str if necessary.  This is sort of like a combination of sprintf and
 * strcat.
 */
void
appendStringInfo(StringInfo str, const char *fmt,...)
{
	for (;;)
	{
		va_list		args;
		int			needed;

		/* Try to format the data. */
		va_start(args, fmt);
		needed = appendStringInfoVA(str, fmt, args);
		va_end(args);

		if (needed == 0)
			break;				/* success */

		/* Increase the buffer size and try again. */
		enlargeStringInfo(str, needed);
	}
}
Exemplo n.º 7
0
/*
 * Error handler for libxml error messages
 */
static void
xml_error_handler(void *ctxt, const char *msg,...)
{
	/* Append the formatted text to xml_err_buf */
	for (;;)
	{
		va_list		args;
		bool		success;

		/* Try to format the data. */
		va_start(args, msg);
		success = appendStringInfoVA(xml_error_buf, msg, args);
		va_end(args);

		if (success)
			break;

		/* Double the buffer size and try again. */
		enlargeStringInfo(xml_error_buf, xml_error_buf->maxlen);
	}
}
Exemplo n.º 8
0
int
errmsg(const char *fmt,...)
{
	pgutErrorData  *edata = getErrorData();
	va_list			args;
	size_t			len;
	bool			ok;

	do
	{
		va_start(args, fmt);
		ok = appendStringInfoVA(&edata->msg, fmt, args);
		va_end(args);
	} while (!ok);
	len = strlen(fmt);
	if (len > 2 && strcmp(fmt + len - 2, ": ") == 0)
		appendStringInfoString(&edata->msg, strerror(edata->save_errno));
	trimStringBuffer(&edata->msg);

	return 0;	/* return value does not matter */
}
Exemplo n.º 9
0
/*
 * Emit a PG error or notice, together with any available info about
 * the current Python error, previously set by PLy_exception_set().
 * This should be used to propagate Python errors into PG.  If fmt is
 * NULL, the Python error becomes the primary error message, otherwise
 * it becomes the detail.  If there is a Python traceback, it is put
 * in the context.
 */
void
PLy_elog(int elevel, const char *fmt,...)
{
	char	   *xmsg;
	char	   *tbmsg;
	int			tb_depth;
	StringInfoData emsg;
	PyObject   *exc,
			   *val,
			   *tb;
	const char *primary = NULL;
	int			sqlerrcode = 0;
	char	   *detail = NULL;
	char	   *hint = NULL;
	char	   *query = NULL;
	int			position = 0;
	char	   *schema_name = NULL;
	char	   *table_name = NULL;
	char	   *column_name = NULL;
	char	   *datatype_name = NULL;
	char	   *constraint_name = NULL;

	PyErr_Fetch(&exc, &val, &tb);

	if (exc != NULL)
	{
		PyErr_NormalizeException(&exc, &val, &tb);

		if (PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
			PLy_get_spi_error_data(val, &sqlerrcode,
								   &detail, &hint, &query, &position,
								   &schema_name, &table_name, &column_name,
								   &datatype_name, &constraint_name);
		else if (PyErr_GivenExceptionMatches(val, PLy_exc_error))
			PLy_get_error_data(val, &sqlerrcode, &detail, &hint,
							   &schema_name, &table_name, &column_name,
							   &datatype_name, &constraint_name);
		else if (PyErr_GivenExceptionMatches(val, PLy_exc_fatal))
			elevel = FATAL;
	}

	/* this releases our refcount on tb! */
	PLy_traceback(exc, val, tb,
				  &xmsg, &tbmsg, &tb_depth);

	if (fmt)
	{
		initStringInfo(&emsg);
		for (;;)
		{
			va_list		ap;
			int			needed;

			va_start(ap, fmt);
			needed = appendStringInfoVA(&emsg, dgettext(TEXTDOMAIN, fmt), ap);
			va_end(ap);
			if (needed == 0)
				break;
			enlargeStringInfo(&emsg, needed);
		}
		primary = emsg.data;

		/* Since we have a format string, we cannot have a SPI detail. */
		Assert(detail == NULL);

		/* If there's an exception message, it goes in the detail. */
		if (xmsg)
			detail = xmsg;
	}
	else
	{
		if (xmsg)
			primary = xmsg;
	}

	PG_TRY();
	{
		ereport(elevel,
				(errcode(sqlerrcode ? sqlerrcode : ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
			  errmsg_internal("%s", primary ? primary : "no exception data"),
				 (detail) ? errdetail_internal("%s", detail) : 0,
				 (tb_depth > 0 && tbmsg) ? errcontext("%s", tbmsg) : 0,
				 (hint) ? errhint("%s", hint) : 0,
				 (query) ? internalerrquery(query) : 0,
				 (position) ? internalerrposition(position) : 0,
				 (schema_name) ? err_generic_string(PG_DIAG_SCHEMA_NAME,
													schema_name) : 0,
				 (table_name) ? err_generic_string(PG_DIAG_TABLE_NAME,
												   table_name) : 0,
				 (column_name) ? err_generic_string(PG_DIAG_COLUMN_NAME,
													column_name) : 0,
				 (datatype_name) ? err_generic_string(PG_DIAG_DATATYPE_NAME,
													  datatype_name) : 0,
			  (constraint_name) ? err_generic_string(PG_DIAG_CONSTRAINT_NAME,
													 constraint_name) : 0));
	}
	PG_CATCH();
	{
		if (fmt)
			pfree(emsg.data);
		if (xmsg)
			pfree(xmsg);
		if (tbmsg)
			pfree(tbmsg);
		Py_XDECREF(exc);
		Py_XDECREF(val);

		PG_RE_THROW();
	}
	PG_END_TRY();

	if (fmt)
		pfree(emsg.data);
	if (xmsg)
		pfree(xmsg);
	if (tbmsg)
		pfree(tbmsg);
	Py_XDECREF(exc);
	Py_XDECREF(val);
}
Exemplo n.º 10
0
/*
 * Emit a PG error or notice, together with any available info about
 * the current Python error, previously set by PLy_exception_set().
 * This should be used to propagate Python errors into PG.	If fmt is
 * NULL, the Python error becomes the primary error message, otherwise
 * it becomes the detail.  If there is a Python traceback, it is put
 * in the context.
 */
void
PLy_elog(int elevel, const char *fmt,...)
{
	char	   *xmsg;
	char	   *tbmsg;
	int			tb_depth;
	StringInfoData emsg;
	PyObject   *exc,
			   *val,
			   *tb;
	const char *primary = NULL;
	int		   sqlerrcode = 0;
	char	   *detail = NULL;
	char	   *hint = NULL;
	char	   *query = NULL;
	int			position = 0;

	PyErr_Fetch(&exc, &val, &tb);
	if (exc != NULL)
	{
		if (PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
			PLy_get_spi_error_data(val, &sqlerrcode, &detail, &hint, &query, &position);
		else if (PyErr_GivenExceptionMatches(val, PLy_exc_fatal))
			elevel = FATAL;
	}
	PyErr_Restore(exc, val, tb);

	PLy_traceback(&xmsg, &tbmsg, &tb_depth);

	if (fmt)
	{
		initStringInfo(&emsg);
		for (;;)
		{
			va_list		ap;
			bool		success;

			va_start(ap, fmt);
			success = appendStringInfoVA(&emsg, dgettext(TEXTDOMAIN, fmt), ap);
			va_end(ap);
			if (success)
				break;
			enlargeStringInfo(&emsg, emsg.maxlen);
		}
		primary = emsg.data;

		/* Since we have a format string, we cannot have a SPI detail. */
		Assert(detail == NULL);

		/* If there's an exception message, it goes in the detail. */
		if (xmsg)
			detail = xmsg;
	}
	else
	{
		if (xmsg)
			primary = xmsg;
	}

	PG_TRY();
	{
		ereport(elevel,
				(errcode(sqlerrcode ? sqlerrcode : ERRCODE_INTERNAL_ERROR),
				 errmsg_internal("%s", primary ? primary : "no exception data"),
				 (detail) ? errdetail_internal("%s", detail) : 0,
				 (tb_depth > 0 && tbmsg) ? errcontext("%s", tbmsg) : 0,
				 (hint) ? errhint("%s", hint) : 0,
				 (query) ? internalerrquery(query) : 0,
				 (position) ? internalerrposition(position) : 0));
	}
	PG_CATCH();
	{
		if (fmt)
			pfree(emsg.data);
		if (xmsg)
			pfree(xmsg);
		if (tbmsg)
			pfree(tbmsg);
		PG_RE_THROW();
	}
	PG_END_TRY();

	if (fmt)
		pfree(emsg.data);
	if (xmsg)
		pfree(xmsg);
	if (tbmsg)
		pfree(tbmsg);
}