基于这个问题,我发现我不能指望使用'F'
标识符找到函数调用作为代理。
我进行了更多研究,现在我认为postgreSQL使用扩展查询协议来发送参数语句,例如函数。 (如果我错了纠正我)
我知道执行准备语句也会使用扩展查询协议(我认为应该有更多使用该协议的语句)
因此,我认为这不应该是将函数调用识别为代理的方法。 还有其他办法吗? 有可能吗? 还是我完全迷失并误解了一切?
顺便说一句,通过识别函数调用,我的意思是我需要识别一个函数调用,并在前端与后端连接(客户端与服务器之间)中作为第三方调查传递的参数和函数名称
PostgreSQL对带有参数的语句使用扩展的查询协议 ,但是这些参数不一定与函数参数相同。
要使用使用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)", 1, types, vals, NULL, NULL, 0);
查询将以带有'P'
( Parse )标识符的数据包发送,参数将以随后的'B'
( Bind )数据包发送。
但这与函数调用无关,对于这样的查询也会发生同样的情况:
SELECT val FROM mytab WHERE id = $1;
您说您的目标是听前端到后端协议,并过滤掉所有函数调用和传递给它们的参数。
这是一项非常艰巨的任务。 本质上,这意味着您必须解析发送到服务器的SQL语句,并且这意味着您必须至少复制PostgreSQL的解析器的一部分。 您将必须记住一些已解析的语句,并从绑定数据包中注入参数。
除此之外,我想到两个问题:
这样一来,您将无法捕获在函数内部发出的函数调用是否重要?
在这种情况下,如何确定传递的参数:
SELECT myfun((SELECT val FROM tab WHERE id = 42));
或这个:
SELECT myfun(CAST(otherfun(42) || '0' AS integer));
也许有更好的方法来实现您想要的功能,例如入侵PostgreSQL服务器并在实际调用该函数的位置提取信息。