Thread: Refactoring psql for backward-compatibility

Refactoring psql for backward-compatibility

From
David Fetter
Date:
Folks,

I'm trying to come up with a design for \ commands in psql in 8.2.
8.1 broke just about every \ command because they now depend on roles,
which is great for 8.1 or better, but not so good if you're connecting
to DBs <= 8.0.  So, I'm volunteering to code up the next version of
psql, which will be aware of the back-end version, and I'm trying to
figure out what strategy will satisfy the following requirements for \
commands:

1.  Correctness: as in the sense of "works the same way that the
then-current version of psql did."

2.  Maintainability: each new version should be easy to add.

3.  Performance

Neil Conway suggested something like a get_function_list(), which I
presume would be called on connect, and would be version-aware.  Does
this seem like a good idea?  If so, what might an implementation look
like?  I know C isn't all that great for function overloading, so do
we want to keep all the SQL for all previous versions in memory,
or...?

I'd much appeciate tips, specific RTFMs and feedback on this so I can
get cracking on a patch.

Cheers,
D
-- 
David Fetter david@fetter.org http://fetter.org/
phone: +1 415 235 3778

Remember to vote!


Re: Refactoring psql for backward-compatibility

From
Martijn van Oosterhout
Date:
On Wed, Dec 14, 2005 at 01:52:56AM -0800, David Fetter wrote:
> Folks,
>
> I'm trying to come up with a design for \ commands in psql in 8.2.
> 8.1 broke just about every \ command because they now depend on roles,
> which is great for 8.1 or better, but not so good if you're connecting
> to DBs <= 8.0.  So, I'm volunteering to code up the next version of
> psql, which will be aware of the back-end version, and I'm trying to
> figure out what strategy will satisfy the following requirements for \
> commands:

Well, most of the \ commands just end up calling an SQL statement so in
theory it should be possible to seperate those out into seperate files.

sql_7_3.c

char *sql_array[] =
{ [LIST_NAMESPACES] = "SELECT blah";

etc...

And do that for each version. If it's actual code changes required,
perhaps a better approach would be to use function pointers. Create an
array of the possible \ commands and move the functions to a
subdirectory. Then you can do things like:

7.3/table.c

slash_command_func_t func_array_7_3[] =
{ [LIST_NAMESPACES] = list_namespaces_7_3,

If you set current_slashcommands to point to the right array on
startup, then calling the code would be like:

current_slashcommands[cmd]( ... )

The function pointer version may be more flexible and handle more
subtle changes. Including this like "this command does not apply to
this version".

I think your biggest stumbling block will be proving it's not a
maintainence nightmare.

Hope this helps,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

Re: Refactoring psql for backward-compatibility

From
Andrew Dunstan
Date:

David Fetter wrote:

>
>I'd much appeciate tips, specific RTFMs and feedback on this so I can
>get cracking on a patch.
>
>
>  
>

well, before you even start on a patch we should have agreement that 
this is a good idea, and an agreed design.

This is really an m * n problem. That's what does indeed make it a 
maintenance nightmare. A new version of psql implements a new command 
and suddenly we have to provide compatibility versions (if possible) for 
m server versions back. Repeat for n versions of psql.

One way might to have some loadable SPs that correspond to the slash 
commands for a particular psql version, and have psql search for those 
on startup, and use them in preference to its builtin versions. But it 
would be mighty messy.

I am really not sure it's worth the effort. Just testing would be a pain 
(buildfarm could not do it, as it now stands, at least).


cheers

andrew


Re: Refactoring psql for backward-compatibility

From
Alvaro Herrera
Date:
Andrew Dunstan wrote:
> 
> David Fetter wrote:
> 
> >I'd much appeciate tips, specific RTFMs and feedback on this so I can
> >get cracking on a patch.
> 
> well, before you even start on a patch we should have agreement that 
> this is a good idea, and an agreed design.
> 
> This is really an m * n problem. That's what does indeed make it a 
> maintenance nightmare. A new version of psql implements a new command 
> and suddenly we have to provide compatibility versions (if possible) for 
> m server versions back. Repeat for n versions of psql.

You just need to give the user a message saying "this server version
does not implement this command".

Of course, the design needs to support the fact that some server
versions will not implement all backslash commands.  This should not be
too difficult.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: Refactoring psql for backward-compatibility

From
Hannu Krosing
Date:
Ühel kenal päeval, K, 2005-12-14 kell 01:52, kirjutas David Fetter:
> Folks,
> 
> I'm trying to come up with a design for \ commands in psql in 8.2.
> 8.1 broke just about every \ command because they now depend on roles,
> which is great for 8.1 or better, but not so good if you're connecting
> to DBs <= 8.0.  So, I'm volunteering to code up the next version of
> psql, which will be aware of the back-end version, and I'm trying to
> figure out what strategy will satisfy the following requirements for \
> commands:
> 
> 1.  Correctness: as in the sense of "works the same way that the
> then-current version of psql did."
> 
> 2.  Maintainability: each new version should be easy to add.
> 
> 3.  Performance
> 
> Neil Conway suggested something like a get_function_list(), which I
> presume would be called on connect, and would be version-aware.  Does
> this seem like a good idea?  If so, what might an implementation look
> like?  I know C isn't all that great for function overloading, so do
> we want to keep all the SQL for all previous versions in memory,
> or...?

It would be much nicer if we could just add pg_psql schema with a view
for each argumentless command and a C/plpgsql/sql function for each
command taking arguments. 

And one 'main' view, which lists all shlash commands to instrument the
psql at connect or when doing the actual \x

it is a waste of programmer resources, that eachtool doing introspection
has to reimplement them.

and this would also allow sute admins to add new commands to their
specific databases , perhaps "\slony tables" for listing all tables
tohether with their slony status (subscriber, master, not replicated)
and other status info 

------------
Hannu




Re: Refactoring psql for backward-compatibility

From
Christopher Kings-Lynne
Date:
> Neil Conway suggested something like a get_function_list(), which I
> presume would be called on connect, and would be version-aware.  Does
> this seem like a good idea?  If so, what might an implementation look
> like?  I know C isn't all that great for function overloading, so do
> we want to keep all the SQL for all previous versions in memory,
> or...?

If it was me I'd just copy the pg_dump way of doing things...

Chris



Re: Refactoring psql for backward-compatibility

From
David Fetter
Date:
On Thu, Dec 15, 2005 at 09:20:46AM +0800, Christopher Kings-Lynne wrote:
> >Neil Conway suggested something like a get_function_list(), which I
> >presume would be called on connect, and would be version-aware.
> >Does this seem like a good idea?  If so, what might an
> >implementation look like?  I know C isn't all that great for
> >function overloading, so do we want to keep all the SQL for all
> >previous versions in memory, or...?
> 
> If it was me I'd just copy the pg_dump way of doing things...

To the extent possible, I'd like to preserve the exact functionality
(or lack thereof) of previous versions.  Would this be possible that
way?

Cheers,
D
-- 
David Fetter david@fetter.org http://fetter.org/
phone: +1 415 235 3778

Remember to vote!


Re: Refactoring psql for backward-compatibility

From
Christopher Kings-Lynne
Date:
>>If it was me I'd just copy the pg_dump way of doing things...
> 
> To the extent possible, I'd like to preserve the exact functionality
> (or lack thereof) of previous versions.  Would this be possible that
> way?

Don't see it'd be too hard.  All pg_dump basically does is this:

if (version <= 7.3) {  query = "..";
else if (version == 7.4) {  query = "..";
else  query = "..";

Other than that you might need some smarts in the output table display 
logic so that it doesn't "assume" what columns are available from the 
queries.

Or something.

Chris