将函数调用识别为前端和后端之间的代理

Recognize function calls as proxy between frontend and backend

基于 问题,我发现我无法期望使用 'F' 标识符找到作为代理的函数调用。

我研究了更多,现在我认为 postgreSQL 使用 extended query protocol 发送函数等参数语句。 (如果我错了请纠正我)

我知道执行 prepared-statements 也会使用扩展查询协议(我认为应该有更多使用此协议的语句)

所以我认为这不应该是将函数调用识别为代理的方式。还有别的办法吗?有可能吗?还是我完全迷失了一切并误解了一切?

顺便说一下,通过识别函数调用我的意思是我需要识别函数调用并调查作为前端-后端连接(客户端和服务器之间)的第三方传递的参数和函数名称

PostgreSQL 对带参数的语句使用 扩展查询协议,但这些参数不一定与函数参数相同。

要使用 the C API 的示例,如果您发送这样的函数调用:

res = PQexec(conn, "SELECT myfun(42)");

它将在带有 'Q'查询)标识符的数据包中发送。

如果你这样发送:

const Oid types[1] = { INT4OID };
const char * const vals[1] = { "42" };

res = PQexecParams(conn, "SELECT myfun()", 1, types, vals, NULL, NULL, 0);

查询将在带有 'P' (Parse) 标识符的数据包中发送,参数将在以下 'B' (绑定)包.

但这与函数调用无关,对于这样的查询也会发生同样的情况:

SELECT val FROM mytab WHERE id = ;

你说你的目标是监听前后端协议并过滤掉所有函数调用和传递给它们的参数。

这是一项非常艰巨的任务;本质上它意味着你必须解析发送到服务器的 SQL 语句,这意味着你必须至少复制 PostgreSQL 的解析器的一部分。您必须记住一些已解析的语句并从绑定数据包中注入参数。

除此之外,我想到了两个问题:

  1. 这样您将无法捕获函数内部发出的函数调用是否重要?

  2. 在这种情况下如何确定传递的参数:

    SELECT myfun((SELECT val FROM tab WHERE id = 42));
    

    或者这个:

    SELECT myfun(CAST(otherfun(42) || '0' AS integer));
    

也许有更好的方法来实现你想要的,比如破解 PostgreSQL 服务器并在实际调用函数的地方提取你的信息。