Thread: Make psql version aware; hide tablespace from older versions
Index: describe.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/describe.c,v retrieving revision 1.103 diff -c -r1.103 describe.c *** describe.c 15 Jul 2004 03:56:06 -0000 1.103 --- describe.c 7 Aug 2004 22:15:03 -0000 *************** *** 112,117 **** --- 112,123 ---- PGresult *res; printQueryOpt myopt = pset.popt; + if (pset.version < 700500000) { + fprintf(stderr, _("This server version (%d) does not support tablespaces.\n"), + pset.version); + return true; + } + initPQExpBuffer(&buf); printfPQExpBuffer(&buf, *************** *** 706,713 **** /* Get general table info */ printfPQExpBuffer(&buf, "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules, \n" ! "relhasoids, reltablespace \n" "FROM pg_catalog.pg_class WHERE oid = '%s'", oid); res = PSQLexec(buf.data, false); if (!res) --- 712,720 ---- /* Get general table info */ printfPQExpBuffer(&buf, "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules, \n" ! "relhasoids%s \n" "FROM pg_catalog.pg_class WHERE oid = '%s'", + pset.version >= 700500000 ? ", reltablespace" : "", oid); res = PSQLexec(buf.data, false); if (!res) *************** *** 729,735 **** tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 0), "t") == 0; tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 4), "t") == 0; tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 5), "t") == 0; ! tableinfo.tablespace = atooid(PQgetvalue(res, 0, 6)); PQclear(res); headers[0] = _("Column"); --- 736,743 ---- tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 0), "t") == 0; tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 4), "t") == 0; tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 5), "t") == 0; ! tableinfo.tablespace = (pset.version >= 700500000) ? ! atooid(PQgetvalue(res, 0, 6)) : 0; PQclear(res); headers[0] = _("Column"); Index: settings.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/settings.h,v retrieving revision 1.18 diff -c -r1.18 settings.h *** settings.h 12 May 2004 13:38:45 -0000 1.18 --- settings.h 7 Aug 2004 22:15:03 -0000 *************** *** 41,47 **** FILE *cur_cmd_source; /* describe the status of the current main * loop */ bool cur_cmd_interactive; ! const char *progname; /* in case you renamed psql */ char *inputfile; /* for error reporting */ unsigned lineno; /* also for error reporting */ --- 41,47 ---- FILE *cur_cmd_source; /* describe the status of the current main * loop */ bool cur_cmd_interactive; ! int version; const char *progname; /* in case you renamed psql */ char *inputfile; /* for error reporting */ unsigned lineno; /* also for error reporting */ Index: startup.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/startup.c,v retrieving revision 1.95 diff -c -r1.95 startup.c *** startup.c 3 Jun 2004 00:07:37 -0000 1.95 --- startup.c 7 Aug 2004 22:15:03 -0000 *************** *** 217,222 **** --- 217,248 ---- SyncVariables(); + /* Grab the server version */ + PGresult *result; + result = PQexec(pset.db, "SELECT version()"); + pset.version = 0; + if (result && PGRES_TUPLES_OK == PQresultStatus(result) && PQntuples(result)>=1) + { + const char *versionstring; + int x, y; + versionstring = PQgetvalue(result,0,0); + if (strlen(versionstring)>25) { + versionstring+=11; + for (y=1000000; y; y/=1000) { + x = atoi(versionstring); + if (x>0) { + if (x<10) { x*=(y*100); versionstring+=2; } + else if (x<100) { x*=(y*10); versionstring+=3; } + else if (x < 1000) { x*=y; versionstring+=4; } + else { break; } /* should never get here */ + pset.version += x; + } + } + } + } + result = NULL; + PQclear(result); + if (options.action == ACT_LIST_DB) { int success = listAllDbs(false);
It's nice, but currently there are a lot of ways in which psql is broken regarding older server versions. We should be caring about all of them (ideal), or about none (the current situation). There have been proposals in the past about making that happen. You could investigate that (please do -- I'd love to have a cross-version psql, in the same way we have a cross-version compatible pg_dump). The way of your patch is certain to lead into a mantainance nightmare :-( On Sat, Aug 07, 2004 at 10:20:19PM -0000, Greg Sabino Mullane wrote: > + if (pset.version < 700500000) { > + fprintf(stderr, _("This server version (%d) does not support tablespaces.\n"), -- Alvaro Herrera (<alvherre[a]dcc.uchile.cl>) <Schwern> It does it in a really, really complicated way <crab> why does it need to be complicated? <Schwern> Because it's MakeMaker.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 > It's nice, but currently there are a lot of ways in which psql is > broken regarding older server versions. We should be caring about > all of them (ideal), or about none (the current situation). > > There have been proposals in the past about making that happen. You > could investigate that (please do -- I'd love to have a cross-version > psql, in the same way we have a cross-version compatible pg_dump). The ultimate goal, of course, is to get to a more cross-version psql: this is simply the first (but important) step in that direction. I was a part of the previous discussions and remember them well. The basic problem behind making psql able to handle previous versions was that it would take some work and nobody felt like tackling it. Well, I finally got irked enough when testing 7.5^H^H8.0 and psql'ing to my 7.4 database (and getting reltablespace errors) that I decided to finally bite the bullet. The 7.4 -> 7.5 jump is fairly easy, the 7.3 compatibility will be a lot tougher. This will at least allow it to be used against the previous version (7.4), which is a good start. > The way of your patch is certain to lead into a mantainance nightmare :-( Can you elaborate on that? There is no real simple way to do it, but storing the version as a simple 9-digit int[1] and using ifs seems the easiest. If there are too many ifs cluttering a section we can certainly consider making separate functions, but right now nothing warrants that. My patch to ignore tablespace in pre-7.5 has three additional checks inside of describe.c, which I don't think is too bad. [1] If we can guarantee that we will never reach a "hundred" in any version portion of PostgreSQL, the number could be smaller and easier to handle, of course, but better safe than sorry. - -- Greg Sabino Mullane greg@turnstep.com PGP Key: 0x14964AC8 200408072054 -----BEGIN PGP SIGNATURE----- iD8DBQFBFXrbvJuQZxSWSsgRAhoFAKCAafstQcBMIuDR15tRk/a8Hih29gCgxl0g yul9nXVtFxC+Db2DwL3YqUo= =eVfA -----END PGP SIGNATURE-----
Alvaro Herrera <alvherre@dcc.uchile.cl> writes: > It's nice, but currently there are a lot of ways in which psql is broken > regarding older server versions. We should be caring about all of them > (ideal), or about none (the current situation). > There have been proposals in the past about making that happen. You > could investigate that (please do -- I'd love to have a cross-version > psql, in the same way we have a cross-version compatible pg_dump). The > way of your patch is certain to lead into a mantainance nightmare :-( Also, I see no need to write your own code to get the server version. libpq already does this. It doesn't currently export an API to find it out, but I'd rather add that than have psql duplicate the effort. regards, tom lane
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 > Also, I see no need to write your own code to get the server version. > libpq already does this. It doesn't currently export an API to find it > out, but I'd rather add that than have psql duplicate the effort. Good point. I looked around, and not only is the code in libpq cleaner, but it is duplicated in other applications (e.g. pg_dump). In the name of not reinventing the wheel, I played around with making it available. Would something like this be acceptable?: (int) PQversionNumber as a simple interface to the sversion variable? - -- Greg Sabino Mullane greg@turnstep.com PGP Key: 0x14964AC8 200408091920 -----BEGIN PGP SIGNATURE----- iD8DBQFBGAbcvJuQZxSWSsgRAuuWAKDsWC2M2MqzXZV6Kx8ZQ+MnuosbUwCgukUt NsXS8qGfUHNujPz8J2XsDqU= =PsJs -----END PGP SIGNATURE-----
"Greg Sabino Mullane" <greg@turnstep.com> writes: > Would something like this be acceptable?: > (int) PQversionNumber > as a simple interface to the sversion variable? I think "version" is a little too nonspecific. We already have extern int PQprotocolVersion(const PGconn *conn); so consistency would suggest extern int PQserverVersion(const PGconn *conn); regards, tom lane