proposal: extensible plpgsql executor - related to assertions

From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Cc: Marko Tiikkaja <pgmail(at)joh(dot)to>, Josh Berkus <josh(at)agliodbs(dot)com>, Peter Eisentraut <peter_e(at)gmx(dot)net>
Subject: proposal: extensible plpgsql executor - related to assertions
Date: 2014-01-04 16:01:37
Message-ID: CAFj8pRA7G_YpnR3cRe+89v3qgefZvunqrd_cJXzjmXRQW7cM=A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello

I am thinking how to implement a assertions and tracking to plpgsql. This
area is not strict and clear - everybody would little bit different
functionality - and implementation can be different if someone use a psql
as main client or some GUI. So I am sceptical to implement assertion
directly to plpgsql. Now I finished plpgsql_check_function as extension
and I had to use a plpgsql plugin API again.

This API is good enough to enable extensible plpgsql executor. It can be
implemened via stmt_beg call, although a special hook can be better.

typedef struct
{
/* Function pointers set up by the plugin */
void (*func_setup) (PLpgSQL_execstate *estate,
PLpgSQL_function *func);
void (*func_beg) (PLpgSQL_execstate *estate,
PLpgSQL_function *func);
void (*func_end) (PLpgSQL_execstate *estate,
PLpgSQL_function *func);
void (*stmt_beg) (PLpgSQL_execstate *estate,
PLpgSQL_stmt *stmt);
void (*stmt_end) (PLpgSQL_execstate *estate,
PLpgSQL_stmt *stmt);

/* Function pointers set by PL/pgSQL itself */
void (*error_callback) (void *arg);
void (*assign_expr) (PLpgSQL_execstate *estate,
PLpgSQL_datum *target,

PLpgSQL_expr *expr);
} PLpgSQL_plugin;

What is missing is a possibility to invoke some custom functionality
(implemented in plugin-extension) from plpgsql code. What example, I can
try to print function parameters, local variables at some point,
assertions, tracking, ... Usually we would to ignore any action, when
plugin is not active. This ensure a minimal slowdown on production when we
don´t would to enable assertions, but we don´t would to modify source code.

I propose a enhance the PLpgSQL_plugin struct by a new hook

void (*pragma)(PLpgSQL_execstate *estate, PLpgSQL_pragma
*pragma_stmt)

typedef struct
{
int cmd_type;
int lineno;
char *refname;
List *exprs;
} pragma_stmt;

PLpgSQL executor should to execute this statement only when pragma hook is
defined.

Syntax of PL/pgSQL should be enhanced about statement pragma

Syntax:

pragma pragmaname [ [ ( ] expr, [expr .. ] [ ) ] ]

This syntax should be checked by plpgsql compiler, but and it is important
- it is not executed by plpgsql executor ever (minimally in this proposal).
So if you don´t would active assertions, then you don´t load a plugin with
assertion implementation.

Expressions are executed by plugin, and it is on plugin responsibility.

So with this functionality we can implement tracking, variable dumping,
assertions

pragma dump_local_variables;
pragma dump_parameters;
pragma assert(a = 10, ´variable a is not 10´);
pragma warning(a > 100, ´a > 100´);
pragma notice a > 100, format('a = "%s"', a);
...

This proposal should not break any current plpgsql code and it is generic -
require only minimal changes in plpgsql runtime. Any current plpgsql
plugins should be workable after compilation (but recompilation is required
for any new version).

Pragma can be used for other plpgsql plugin as other way how to push a some
complex (or simple) parameters to plpgsql related extensions

pragma disable_plpgsql_check;

Opinions, ideas?

Regards

Pavel

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Fabrizio Mello 2014-01-04 16:07:08 Re: [PATCH] Store Extension Options
Previous Message Martijn van Oosterhout 2014-01-04 15:39:22 Re: RFC: Async query processing