Thread: Refactoring psql for backward-compatibility
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!
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.
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
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.
Ü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
> 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
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!
>>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