Skip to content

Commit 218db04

Browse files
committed
Add support of operators to plpgsql_show_dependency_tb()
Operators are especially tricky to find by just searching the code since it is common for many operators to share the same name, so the ability to find all dependencies on custom operators is a useful feature.
1 parent 0512aea commit 218db04

File tree

6 files changed

+68
-5
lines changed

6 files changed

+68
-5
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ You can use pragma `table` and create ephemeral table:
411411

412412
# Dependency list
413413

414-
A function <i>plpgsql_show_dependency_tb</i> can show all functions and relations used
414+
A function <i>plpgsql_show_dependency_tb</i> can show all functions, operators and relations used
415415
inside processed function:
416416

417417
postgres=# select * from plpgsql_show_dependency_tb('testfunc(int,float)');
@@ -420,6 +420,7 @@ inside processed function:
420420
╞══════════╪═══════╪════════╪═════════╪════════════════════════════╡
421421
│ FUNCTION │ 36008 │ public │ myfunc1 │ (integer,double precision) │
422422
│ FUNCTION │ 35999 │ public │ myfunc2 │ (integer,double precision) │
423+
│ OPERATOR │ 36007 │ public │ ** │ (integer,integer) │
423424
│ RELATION │ 36005 │ public │ myview │ │
424425
│ RELATION │ 36002 │ public │ mytable │ │
425426
└──────────┴───────┴────────┴─────────┴────────────────────────────┘

expected/plpgsql_check_active.out

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3290,14 +3290,16 @@ create function myfunc1(a int, b float) returns integer as $$ begin end $$ langu
32903290
create function myfunc2(a int, b float) returns integer as $$ begin end $$ language plpgsql;
32913291
create function myfunc3(a int, b float) returns integer as $$ begin end $$ language plpgsql;
32923292
create function myfunc4(a int, b float) returns integer as $$ begin end $$ language plpgsql;
3293+
create function opfunc1(a int, b float) returns integer as $$ begin end $$ language plpgsql;
3294+
create operator *** (procedure = opfunc1, leftarg = int, rightarg = float);
32933295
create table mytable(a int);
32943296
create table myview as select * from mytable;
32953297
create function testfunc(a int, b float)
32963298
returns void as $$
32973299
declare x integer;
32983300
begin
32993301
raise notice '%', myfunc1(a, b);
3300-
x := myfunc2(a, b);
3302+
x := myfunc2(a, b) operator(public.***) 1;
33013303
perform myfunc3(m.a, b) from myview m;
33023304
insert into mytable select myfunc4(a, b);
33033305
end;
@@ -3315,9 +3317,10 @@ select type, schema, name, params from plpgsql_show_dependency_tb('testfunc(int,
33153317
FUNCTION | public | myfunc2 | (integer,double precision)
33163318
FUNCTION | public | myfunc3 | (integer,double precision)
33173319
FUNCTION | public | myfunc4 | (integer,double precision)
3320+
OPERATOR | public | *** | (integer,double precision)
33183321
RELATION | public | mytable |
33193322
RELATION | public | myview |
3320-
(6 rows)
3323+
(7 rows)
33213324

33223325
drop function testfunc(int, float);
33233326
drop function myfunc1(int, float);

sql/plpgsql_check_active.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,9 @@ create function myfunc2(a int, b float) returns integer as $$ begin end $$ langu
23922392
create function myfunc3(a int, b float) returns integer as $$ begin end $$ language plpgsql;
23932393
create function myfunc4(a int, b float) returns integer as $$ begin end $$ language plpgsql;
23942394

2395+
create function opfunc1(a int, b float) returns integer as $$ begin end $$ language plpgsql;
2396+
create operator *** (procedure = opfunc1, leftarg = int, rightarg = float);
2397+
23952398
create table mytable(a int);
23962399
create table myview as select * from mytable;
23972400

@@ -2400,7 +2403,7 @@ returns void as $$
24002403
declare x integer;
24012404
begin
24022405
raise notice '%', myfunc1(a, b);
2403-
x := myfunc2(a, b);
2406+
x := myfunc2(a, b) operator(public.***) 1;
24042407
perform myfunc3(m.a, b) from myview m;
24052408
insert into mytable select myfunc4(a, b);
24062409
end;

src/catalog.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "catalog/pg_extension.h"
2424
#include "catalog/indexing.h"
2525
#include "catalog/pg_language.h"
26+
#include "catalog/pg_operator.h"
2627
#include "catalog/pg_proc.h"
2728
#include "catalog/pg_type.h"
2829
#include "commands/extension.h"
@@ -341,3 +342,22 @@ plpgsql_check_is_plpgsql_function(Oid foid)
341342
return result;
342343
}
343344

345+
/*
346+
* plpgsql_check_get_op_namespace
347+
* returns the name space of the operator with the given opno
348+
*/
349+
Oid
350+
plpgsql_check_get_op_namespace(Oid opno)
351+
{
352+
HeapTuple tp;
353+
354+
tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
355+
if (HeapTupleIsValid(tp))
356+
{
357+
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
358+
ReleaseSysCache(tp);
359+
return optup->oprnamespace;
360+
}
361+
else
362+
return InvalidOid;
363+
}

src/expr_walk.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static int check_fmt_string(const char *fmt,
4040
bool no_error);
4141

4242
/*
43-
* Send to ouput all not yet displayed relations and functions.
43+
* Send to ouput all not yet displayed relations, operators and functions.
4444
*/
4545
static bool
4646
detect_dependency_walker(Node *node, void *context)
@@ -120,6 +120,41 @@ detect_dependency_walker(Node *node, void *context)
120120
}
121121
}
122122

123+
if (IsA(node, OpExpr))
124+
{
125+
OpExpr *opexpr = (OpExpr *) node;
126+
127+
if (plpgsql_check_get_op_namespace(opexpr->opno) != PG_CATALOG_NAMESPACE)
128+
{
129+
StringInfoData str;
130+
Oid lefttype;
131+
Oid righttype;
132+
133+
op_input_types(opexpr->opno, &lefttype, &righttype);
134+
135+
initStringInfo(&str);
136+
appendStringInfoChar(&str, '(');
137+
if (lefttype != InvalidOid)
138+
appendStringInfoString(&str, format_type_be(lefttype));
139+
else
140+
appendStringInfoChar(&str, '-');
141+
appendStringInfoChar(&str, ',');
142+
if (righttype != InvalidOid)
143+
appendStringInfoString(&str, format_type_be(righttype));
144+
else
145+
appendStringInfoChar(&str, '-');
146+
appendStringInfoChar(&str, ')');
147+
148+
plpgsql_check_put_dependency(ri,
149+
"OPERATOR",
150+
opexpr->opno,
151+
get_namespace_name(plpgsql_check_get_op_namespace(opexpr->opno)),
152+
get_opname(opexpr->opno),
153+
str.data);
154+
pfree(str.data);
155+
}
156+
}
157+
123158
return expression_tree_walker(node, detect_dependency_walker, context);
124159
}
125160

src/plpgsql_check.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ extern void plpgsql_check_precheck_conditions(plpgsql_check_info *cinfo);
203203
extern char *plpgsql_check_get_src(HeapTuple procTuple);
204204
extern Oid plpgsql_check_pragma_func_oid(void);
205205
extern bool plpgsql_check_is_plpgsql_function(Oid foid);
206+
extern Oid plpgsql_check_get_op_namespace(Oid opno);
206207

207208
/*
208209
* functions from tablefunc.c

0 commit comments

Comments
 (0)