PostgreSQL利用错误上下文传递数据

原创
2020/08/19 06:31
阅读数 237

当我们需要在不同模块间传递数据时,怎样尽量不修改原有代码而达到目的,本文介绍一种方法。

 

1、错误上下文堆栈

先来看定义(src/include/utils/elog.h):

typedef struct ErrorContextCallback
{
  struct ErrorContextCallback *previous;
  void		(*callback) (void *arg);
  void	   *arg;
} ErrorContextCallback;

包含三个成员:上一层堆栈、回调函数、参数。

 

2、回调函数

在 errfinish 中逐层调用:

for (econtext = error_context_stack;
     econtext != NULL;
     econtext = econtext->previous)
  econtext->callback(econtext->arg);

这也就做了一个限制,每层错误栈的callback函数必须设置,不能为空。或者缩短生命周期,确保这段过程不抛出错误。

 

3、在pg_hint_plan中的例子

	/*
	 * Support for nested plpgsql functions. This is quite ugly but this is the
	 * only point I could find where I can get the query string.
	 */
	if (plpgsql_recurse_level > 0 &&
		error_context_stack && error_context_stack->arg)
	{
		MemoryContext oldcontext;

		oldcontext = MemoryContextSwitchTo(TopMemoryContext);
		current_hint_str =
			get_hints_from_comment((char *)error_context_stack->arg);
		MemoryContextSwitchTo(oldcontext);
	}

虽然非常ugly,但确实worked。

 

4、问题

从pg_hint_plan代码可以看到,它利用PLpgSQL_plugin来确认是否是在PL/pgSQL运行上下文中。如果利用错误上下文在两个不同contrib间传递信息,首先要保证的是某个错误上下文确实是它们为对方准备的,而目前是无法获知的。也许可以给结构体增加一个成员,用于标识错误上下文的来源。

总之这不是什么好方法,总算是能实现而已,简单一写就不再继续了,仅供参考,下篇介绍一种更合适的。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部