review: Deparsing DDL command strings
Hello Dimitri
* patching (success)
pavel ~/src/postgresql $ patch -p1 < binBUNnKQVPBP
patching file src/backend/catalog/heap.c
patching file src/backend/commands/event_trigger.c
patching file src/backend/commands/extension.c
patching file src/backend/commands/sequence.c
patching file src/backend/commands/view.c
patching file src/backend/tcop/utility.c
patching file src/backend/utils/adt/Makefile
patching file src/backend/utils/adt/ddl_rewrite.c
patching file src/backend/utils/adt/ruleutils.c
patching file src/backend/utils/cache/evtcache.c
patching file src/bin/psql/describe.c
patching file src/include/catalog/heap.h
patching file src/include/catalog/pg_event_trigger.h
patching file src/include/commands/event_trigger.h
patching file src/include/commands/extension.h
patching file src/include/commands/sequence.h
patching file src/include/commands/view.h
patching file src/include/utils/builtins.h
patching file src/include/utils/evtcache.h
patching file src/pl/plpgsql/src/pl_comp.c
patching file src/pl/plpgsql/src/pl_exec.c
patching file src/pl/plpgsql/src/plpgsql.h
patching file src/test/regress/expected/event_trigger.out
patching file src/test/regress/sql/event_trigger.sql
* compilation (success)
All of PostgreSQL successfully made. Ready to install.
* regress tests (success)
All 133 tests passed.
* issues
** missing doc
** statements are not deparsd for ddl_command_start event
postgres=# create table fooa(a int, b int);
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: CREATE
TABLE, operation: CREATE, type: TABLE, schema: <NULL>, name: <NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: CREATE
TABLE, operation: CREATE, type: TABLE, schema: <NULL>, name: <NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_end, context: TOPLEVEL, tag: CREATE TABLE,
operation: CREATE, type: TABLE, schema: public, name: fooa
NOTICE: command: CREATE TABLE public.fooa (a pg_catalog.int4, b
pg_catalog.int4);
** CREATE FUNCTION is not supported
postgres=# create or replace function bubu(a int) returns int as
$$select $1$$ language sql;
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: CREATE
FUNCTION, operation: CREATE, type: FUNCTION, schema: <NULL>, name:
<NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: CREATE
FUNCTION, operation: CREATE, type: FUNCTION, schema: <NULL>, name:
<NULL>
NOTICE: command: <NULL>
CREATE FUNCTION
* some wrong in deparsing - doesn't support constraints
postgres=# alter table a add column bbbsss int check (bbbsss > 0);
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: ALTER
TABLE, operation: ALTER, type: TABLE, schema: <NULL>, name: <NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_end, context: TOPLEVEL, tag: ALTER TABLE,
operation: ALTER, type: TABLE, schema: public, name: a
NOTICE: command: ALTER TABLE public.a ADD COLUMN bbbsss pg_catalog.int4, ;
ALTER TABLE
Regards
Pavel
Hi,
Thank you Pavel for reviewing my patch! :)
Pavel Stehule <pavel.stehule@gmail.com> writes:
* issues
** missing doc
Yes. I wanted to reach an agreement on why we need the de parsing for.
You can read the Last comment we made about it at the following link, I
didn't have any answer to my proposal.
http://archives.postgresql.org/message-id/m2391fu79m.fsf@2ndQuadrant.fr
In that email, I said:
Also, I'm thinking that publishing the normalized command string is
something that must be maintained in the core code, whereas the external
stable format might be done as a contrib extension, coded in C, working
with the Node *parsetree. Because it needs to ouput a compatible format
when applied to different major versions of PostgreSQL, I think it suits
quite well the model of C coded extensions.
I'd like to hear what people think about that position. I could be
working on the docs meanwhile I guess, but a non trivial amount of what
I'm going to document is to be thrown away if we end up deciding that we
don't want the normalized command string…
** statements are not deparsd for ddl_command_start event
Yes, that's by design, and that's why we have the ddl_command_trace
event alias too. Tom is right in saying that until the catalogs are
fully populated we can not rewrite most of the command string if we want
normalized output (types, constraints, namespaces, all the jazz).
** CREATE FUNCTION is not supported
Not yet. The goal of this patch in this CF is to get a green light on
providing a full implementation of what information to add to event
triggers and in particular about rewriting command strings.
That said, if you think it would help you as a reviewer, I may attack
the CREATE FUNCTION support right now.
* some wrong in deparsing - doesn't support constraints
postgres=# alter table a add column bbbsss int check (bbbsss > 0);
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: ALTER
TABLE, operation: ALTER, type: TABLE, schema: <NULL>, name: <NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_end, context: TOPLEVEL, tag: ALTER TABLE,
operation: ALTER, type: TABLE, schema: public, name: a
NOTICE: command: ALTER TABLE public.a ADD COLUMN bbbsss pg_catalog.int4, ;
ALTER TABLE
Took me some time to figure out how the constraint processing works in
CREATE TABLE, and apparently I didn't finish ALTER TABLE support yet.
Working on that, thanks.
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
Hello
2012/11/22 Dimitri Fontaine <dimitri@2ndquadrant.fr>:
Hi,
Thank you Pavel for reviewing my patch! :)
Pavel Stehule <pavel.stehule@gmail.com> writes:
* issues
** missing doc
Yes. I wanted to reach an agreement on why we need the de parsing for.
You can read the Last comment we made about it at the following link, I
didn't have any answer to my proposal.http://archives.postgresql.org/message-id/m2391fu79m.fsf@2ndQuadrant.fr
In that email, I said:
Also, I'm thinking that publishing the normalized command string is
something that must be maintained in the core code, whereas the external
stable format might be done as a contrib extension, coded in C, working
with the Node *parsetree. Because it needs to ouput a compatible format
when applied to different major versions of PostgreSQL, I think it suits
quite well the model of C coded extensions.I'd like to hear what people think about that position. I could be
working on the docs meanwhile I guess, but a non trivial amount of what
I'm going to document is to be thrown away if we end up deciding that we
don't want the normalized command string…
I agree with you, so for PL languages just plain text is best format -
it is enough for all tasks that, I can imagine, can be solved by all
supported PL. And for complex tasks - exported parsetree is perfect.
My starting point is strategy, so everything should by possible from
PL/pgSQL, that is our most used PL - and there any complex format is
bad - the most work is doable via plan text and regular expressions.
There is precedent - EXPLAIN - we support more formats, but in PL, we
use usually just plain format.
** statements are not deparsd for ddl_command_start event
Yes, that's by design, and that's why we have the ddl_command_trace
event alias too. Tom is right in saying that until the catalogs are
fully populated we can not rewrite most of the command string if we want
normalized output (types, constraints, namespaces, all the jazz).
ok
** CREATE FUNCTION is not supported
Not yet. The goal of this patch in this CF is to get a green light on
providing a full implementation of what information to add to event
triggers and in particular about rewriting command strings.
I don't have a objection. Any other ???
Regards
Pavel
Show quoted text
That said, if you think it would help you as a reviewer, I may attack
the CREATE FUNCTION support right now.* some wrong in deparsing - doesn't support constraints
postgres=# alter table a add column bbbsss int check (bbbsss > 0);
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: ALTER
TABLE, operation: ALTER, type: TABLE, schema: <NULL>, name: <NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_end, context: TOPLEVEL, tag: ALTER TABLE,
operation: ALTER, type: TABLE, schema: public, name: a
NOTICE: command: ALTER TABLE public.a ADD COLUMN bbbsss pg_catalog.int4, ;
ALTER TABLETook me some time to figure out how the constraint processing works in
CREATE TABLE, and apparently I didn't finish ALTER TABLE support yet.
Working on that, thanks.
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
Pavel Stehule <pavel.stehule@gmail.com> writes:
* some wrong in deparsing - doesn't support constraints
postgres=# alter table a add column bbbsss int check (bbbsss > 0);
NOTICE: event: ddl_command_start, context: TOPLEVEL, tag: ALTER
TABLE, operation: ALTER, type: TABLE, schema: <NULL>, name: <NULL>
NOTICE: command: <NULL>
NOTICE: event: ddl_command_end, context: TOPLEVEL, tag: ALTER TABLE,
operation: ALTER, type: TABLE, schema: public, name: a
NOTICE: command: ALTER TABLE public.a ADD COLUMN bbbsss pg_catalog.int4, ;
ALTER TABLE
So apparently to be able to decipher what ALTER TABLE did actually do
you need more than just hook yourself after transformAlterTableStmt()
have been done, because the interesting stuff is happening in the alter
table "work queue", see ATController in src/backend/commands/tablecmds.c
for details.
Exporting that data, I'm now able to implement constraint rewriting this
way:
alter table a add column bbbsss int check (bbbsss > 0);
NOTICE: AT_AddConstraint: a_bbbsss_check
NOTICE: event: ddl_command_end, context: TOPLEVEL, tag: ALTER TABLE, operation: ALTER, type: TABLE, schema: public, name: a
NOTICE: command: ALTER TABLE public.a ADD COLUMN bbbsss pg_catalog.int4, ADD CONSTRAINT a_bbbsss_check CHECK ((bbbsss > 0));
ALTER TABLE
I did publish that work on the github repository (that I rebase every
time I'm pulling from master, beware):
https://github.com/dimitri/postgres/compare/evt_add_info
This implementation also shows to me that it's not possible to get the
command string from the parsetree directly nor after the DDL transform
step if you want such things as the constraint name that's been produced
automatically by the backend. And I don't see any way to implement that
from an extension, without first patching the backend.
As that's the kind of code we want to be able to break at will in
between releases (or to fix an important bug in a minor update), I think
we need to have the facility to provide users with the normalized
command string in core.
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
Hi,
Pavel Stehule <pavel.stehule@gmail.com> writes:
** missing doc
I still would prefer to have an ack about the premises of this patch
before spending time on writing docs for it, namely:
- we want a normalized command string (schema, auto naming of some
objects such as constraints and indexes, exporting default values,
etc);
- this normalisation can not happen as an extension given the current
source code organisation and the new ddl_rewrite module is a good fit
to solve that problem;
- we offer a new event alias "ddl_command_trace" that will get
activated start of a DROP and end of an ALTER or a CREATE command so
that it's easy to hook at the right place when you want to trace
things;
- it's now possible and easy to process GENERATED commands if you wish
to do so (explicit sequence and index operations for a create table
containing a serial primary key column).
I think no complaints is encouraging though, so I will probably begin
the docs effort soonish.
** CREATE FUNCTION is not supported
I've added support for create and drop function in the attached patch.
Not all commands are rewritten yet though, and not all of them even have
support for the TG_OBJECTID, TG_OBJECTNAME and TG_SCHEMANAME variables.
I think we could still apply that patch + docs and a limited set of
commands, and continue filling the gaps till the end of this cycle. Once
we agree on how to attack the problem at hand, do we really need support
for ALTER OPERATOR FAMILY for an intermediate commit? You tell me.
* some wrong in deparsing - doesn't support constraints
I've been fixing that and reviewing ALTER TABLE rewriting, should be ok
now. Note that we have to analyze the alter table work queue, not the
parsetree, if we want to normalize automatic constraints names and such
like.
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
Attachments:
Hello
2012/11/27 Dimitri Fontaine <dimitri@2ndquadrant.fr>:
Hi,
Pavel Stehule <pavel.stehule@gmail.com> writes:
** missing doc
I still would prefer to have an ack about the premises of this patch
before spending time on writing docs for it, namely:- we want a normalized command string (schema, auto naming of some
objects such as constraints and indexes, exporting default values,
etc);- this normalisation can not happen as an extension given the current
source code organisation and the new ddl_rewrite module is a good fit
to solve that problem;- we offer a new event alias "ddl_command_trace" that will get
activated start of a DROP and end of an ALTER or a CREATE command so
that it's easy to hook at the right place when you want to trace
things;- it's now possible and easy to process GENERATED commands if you wish
to do so (explicit sequence and index operations for a create table
containing a serial primary key column).
I agree with these premisses. I am sure so normalised commands strings
are very nice feature, that can be helpful for generation clean audit
logs and messages. I see a one issue - testing a consistency between
commands and their deparsed forms.
Do you have some idea, how to do these tests - Maybe we can write
extension, that will try repeated parsing and deparsing - normalised
string should be same. I am not sure, if this test should be part of
regressions test, but we have to thinking about some tool for
checking.
we can take commands via hooks and we can check.... ORIGINAL CMD ==>
tree1 ==> DEPARSED STRING ==> tree2 .... tree1 <=> tree2
Please, can others to write an agreement or any rejection now?
Does somebody know why this concept is not acceptable? Speak now, please.
I think no complaints is encouraging though, so I will probably begin
the docs effort soonish.** CREATE FUNCTION is not supported
I've added support for create and drop function in the attached patch.
Not all commands are rewritten yet though, and not all of them even have
support for the TG_OBJECTID, TG_OBJECTNAME and TG_SCHEMANAME variables.
I have no problem with "defined" list of fully unsupported statements.
I think we could still apply that patch + docs and a limited set of
commands, and continue filling the gaps till the end of this cycle. Once
we agree on how to attack the problem at hand, do we really need support
for ALTER OPERATOR FAMILY for an intermediate commit? You tell me.* some wrong in deparsing - doesn't support constraints
I've been fixing that and reviewing ALTER TABLE rewriting, should be ok
now. Note that we have to analyze the alter table work queue, not the
parsetree, if we want to normalize automatic constraints names and such
like.Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
I had a small problem with patching and compilation produce warnings too
pavel ~/src/postgresql/src $ cat log | grep warning
scan.c:16247:23: warning: unused variable ‘yyg’ [-Wunused-variable]
../../../src/include/utils/ddl_rewrite.h:24:8: warning: extra tokens
at end of #endif directive [enabled by default]
../../../../src/include/utils/ddl_rewrite.h:24:8: warning: extra
tokens at end of #endif directive [enabled by default]
ddl_rewrite.c:1719:9: warning: variable ‘def’ set but not used
[-Wunused-but-set-variable]
ddl_rewrite.c:1777:21: warning: ‘languageOid’ is used uninitialized in
this function [-Wuninitialized]
All 133 tests passed.
when I tested
postgres=# create table bubuaa(a int unique not null check (a > 20));
NOTICE: snitch: ddl_command_end CREATE TABLE CREATE TABLE
public.bubuaa (a pg_catalog.int4 UNIQUE NOT NULL CHECK ((a > 20)),
CHECK ((a > 20)));
NOTICE: snitch: ddl_command_end CREATE INDEX CREATE UNIQUE INDEX ON
public.bubuaa USING btree (a);
CREATE TABLE
constraint is twice time there - it is probably same, but it is confusing
drop table generate command string
postgres=# drop table bubuaa;
NOTICE: snitch: ddl_command_end DROP TABLE <NULL>
DROP TABLE
functions are supported :)
backslash statement \dy doesn't work
postgres=# \dy
ERROR: column "evtctxs" does not exist
LINE 1: ... array_to_string(array(select x from unnest(evtctxs) a...
I was little bit surprised so general event trigger without tag
predicate was not triggered for CREATE FUNCTION statement. Is it
documented somewhere?
Regards
Pavel
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Pavel Stehule <pavel.stehule@gmail.com> writes:
I agree with these premisses. I am sure so normalised commands strings
are very nice feature, that can be helpful for generation clean audit
logs and messages. I see a one issue - testing a consistency between
commands and their deparsed forms.
Thanks.
Do you have some idea, how to do these tests - Maybe we can write
extension, that will try repeated parsing and deparsing - normalised
string should be same. I am not sure, if this test should be part of
regressions test, but we have to thinking about some tool for
checking.we can take commands via hooks and we can check.... ORIGINAL CMD ==>
tree1 ==> DEPARSED STRING ==> tree2 .... tree1 <=> tree2
We could have an event trigger that stores the statements in a table,
does some object description like \d or \df+, then drops them all and
replay all the statements from the table and describe the objects again.
I'm not sure how to check that the descriptions are the same from the
regression tests themselves, but once that's manually/externally sorted
out the current facilities will sure provide guards against any
regression.
Please, can others to write an agreement or any rejection now?
Does somebody know why this concept is not acceptable? Speak now, please.
+1 :)
I've added support for create and drop function in the attached patch.
Not all commands are rewritten yet though, and not all of them even have
support for the TG_OBJECTID, TG_OBJECTNAME and TG_SCHEMANAME variables.I have no problem with "defined" list of fully unsupported statements.
Cool. The goal still is to support all functions, but I need aproval
first. It's too much work to be wasted 2 months from now.
I had a small problem with patching and compilation produce warnings too
I will look into that. I know I had to switch in between -O0 and -O2 to
be able to debug some really strange things that happened to have been
due to our build infrastructure not being able to cope with some header
changes. Days like that I really hate the C developper tooling.
postgres=# create table bubuaa(a int unique not null check (a > 20));
NOTICE: snitch: ddl_command_end CREATE TABLE CREATE TABLE
public.bubuaa (a pg_catalog.int4 UNIQUE NOT NULL CHECK ((a > 20)),
CHECK ((a > 20)));
NOTICE: snitch: ddl_command_end CREATE INDEX CREATE UNIQUE INDEX ON
public.bubuaa USING btree (a);
CREATE TABLEconstraint is twice time there - it is probably same, but it is confusing
That might be due to some refactoring I just did for the ALTER TABLE.
Sharing code means "action at a distance" sometimes. I need to begin
adding regression tests, but they will look a lot like the ones Robert
did insist on removing last time…
postgres=# \dy
ERROR: column "evtctxs" does not exist
LINE 1: ... array_to_string(array(select x from unnest(evtctxs) a...
My guess is that you didn't initdb the version you tested. As usual I
didn't include the catalog bump in my patch, but initdb still is needed.
I was little bit surprised so general event trigger without tag
predicate was not triggered for CREATE FUNCTION statement. Is it
documented somewhere?
Works for me (from memory). Sequels of the initdb problem?
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
2012/12/4 Dimitri Fontaine <dimitri@2ndquadrant.fr>:
Pavel Stehule <pavel.stehule@gmail.com> writes:
I agree with these premisses. I am sure so normalised commands strings
are very nice feature, that can be helpful for generation clean audit
logs and messages. I see a one issue - testing a consistency between
commands and their deparsed forms.Thanks.
Do you have some idea, how to do these tests - Maybe we can write
extension, that will try repeated parsing and deparsing - normalised
string should be same. I am not sure, if this test should be part of
regressions test, but we have to thinking about some tool for
checking.we can take commands via hooks and we can check.... ORIGINAL CMD ==>
tree1 ==> DEPARSED STRING ==> tree2 .... tree1 <=> tree2We could have an event trigger that stores the statements in a table,
does some object description like \d or \df+, then drops them all and
replay all the statements from the table and describe the objects again.I'm not sure how to check that the descriptions are the same from the
regression tests themselves, but once that's manually/externally sorted
out the current facilities will sure provide guards against any
regression.Please, can others to write an agreement or any rejection now?
Does somebody know why this concept is not acceptable? Speak now, please.+1 :)
I've added support for create and drop function in the attached patch.
Not all commands are rewritten yet though, and not all of them even have
support for the TG_OBJECTID, TG_OBJECTNAME and TG_SCHEMANAME variables.I have no problem with "defined" list of fully unsupported statements.
Cool. The goal still is to support all functions, but I need aproval
first. It's too much work to be wasted 2 months from now.I had a small problem with patching and compilation produce warnings too
I will look into that. I know I had to switch in between -O0 and -O2 to
be able to debug some really strange things that happened to have been
due to our build infrastructure not being able to cope with some header
changes. Days like that I really hate the C developper tooling.postgres=# create table bubuaa(a int unique not null check (a > 20));
NOTICE: snitch: ddl_command_end CREATE TABLE CREATE TABLE
public.bubuaa (a pg_catalog.int4 UNIQUE NOT NULL CHECK ((a > 20)),
CHECK ((a > 20)));
NOTICE: snitch: ddl_command_end CREATE INDEX CREATE UNIQUE INDEX ON
public.bubuaa USING btree (a);
CREATE TABLEconstraint is twice time there - it is probably same, but it is confusing
That might be due to some refactoring I just did for the ALTER TABLE.
Sharing code means "action at a distance" sometimes. I need to begin
adding regression tests, but they will look a lot like the ones Robert
did insist on removing last time…postgres=# \dy
ERROR: column "evtctxs" does not exist
LINE 1: ... array_to_string(array(select x from unnest(evtctxs) a...My guess is that you didn't initdb the version you tested. As usual I
didn't include the catalog bump in my patch, but initdb still is needed.I was little bit surprised so general event trigger without tag
predicate was not triggered for CREATE FUNCTION statement. Is it
documented somewhere?Works for me (from memory). Sequels of the initdb problem?
yes, last two issue are related to missing initdb
Regards
Pavel
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers