Thread: char(xx) problem
Hi we have two servers with installed Linux and PostGreSQL. They are quite same. One is for development (Linux 2.2.9; 128 MB RAM; very overloaded with processes), another for real HTTP serving in Internet (Linux 2.2.9; 64 MB RAM; only http and pgsql) In one of projects we had two tables: create table a( x char(2) ); create table b( y char(3) ); When we try to execute SQL like this: select * from a, b where a.x = b.y; one of servers selects 5-6 records (e.g. all mached records) another selects empty table. The database is one and same. Why happen this? PgSQL version 6.4, do i need to reinstall PgSQL, reinstall `db space' , or how to fix it??? (I fix them with making chars with one and same length, and this is right solution, but i want to have an idea why this difference exists) -------------------------------------------------------------- The reboots are for hardware upgrades! "http://www.nmmm.nu; <nmmm@nmmm.nu>
> Hi > we have two servers with installed Linux and PostGreSQL. They are quite > same. One is for development (Linux 2.2.9; 128 MB RAM; very overloaded with > processes), another for real HTTP serving in Internet (Linux 2.2.9; 64 MB > RAM; only http and pgsql) > > In one of projects we had two tables: > > create table a( > x char(2) > ); > > create table b( > y char(3) > ); > > When we try to execute SQL like this: > > select * from a, b > where a.x = b.y; > > one of servers selects 5-6 records (e.g. all mached records) > another selects empty table. > > The database is one and same. What are the versions of pg? I have similar experience. I used to routinely join on char() and text, or on char() attributes of different length. Can't do that anymore. Not sure when the change occurred -- some time between 6.3 and 6.5. The problem is I beleive related to blank padding: it formerly showed through only in selects, now it affects comparison as well. I'm just wondering: are there any alternatives to blank padding? Why is it done in the first place? --Gene
Sorry PG is 6.4.2 -------------------------------------------------------------- The reboots are for hardware upgrades! "http://www.nmmm.nu; <nmmm@nmmm.nu> ----- Original Message ----- From: Gene Selkov, Jr. <selkovjr@mcs.anl.gov> To: Nikolay Mijaylov <nmmm@nmmm.nu> Cc: pgsql-general <pgsql-general@postgreSQL.org> Sent: петък, Декември 17, 1999 04:02 Subject: Re: [GENERAL] char(xx) problem > > Hi > > we have two servers with installed Linux and PostGreSQL. They are quite > > same. One is for development (Linux 2.2.9; 128 MB RAM; very overloaded with > > processes), another for real HTTP serving in Internet (Linux 2.2.9; 64 MB > > RAM; only http and pgsql) > > > > In one of projects we had two tables: > > > > create table a( > > x char(2) > > ); > > > > create table b( > > y char(3) > > ); > > > > When we try to execute SQL like this: > > > > select * from a, b > > where a.x = b.y; > > > > one of servers selects 5-6 records (e.g. all mached records) > > another selects empty table. > > > > The database is one and same. > > What are the versions of pg? > > I have similar experience. I used to routinely join on char() and > text, or on char() attributes of different length. Can't do that > anymore. Not sure when the change occurred -- some time between 6.3 > and 6.5. The problem is I beleive related to blank padding: it formerly > showed through only in selects, now it affects comparison as well. > > I'm just wondering: are there any alternatives to blank padding? Why > is it done in the first place? > > --Gene > > ************
At 4:02 +0200 on 17/12/1999, Gene Selkov, Jr. wrote: > I'm just wondering: are there any alternatives to blank padding? Why > is it done in the first place? That's how fixed-length char type works, since the early days of SQL. You come to expect it, which means that if you use legacy code that has a fixed-width char type, or you decided to use it for its time-saving possibilities, it should behave according to some way which has been established long ago. What I don't get is why, given two bpchar argument, Postgres doesn't just pad the shorter one to the length of the other and then compares, selects and whatnot. Herouth -- Herouth Maoz, Internet developer. Open University of Israel - Telem project http://telem.openu.ac.il/~herouth/personal/
> > I'm just wondering: are there any alternatives to blank padding? Why > > is it done in the first place? > > That's how fixed-length char type works, since the early days of SQL. You > come to expect it, which means that if you use legacy code that has a > fixed-width char type, or you decided to use it for its time-saving > possibilities, it should behave according to some way which has been > established long ago. I thik I understand why a fixed-size type should be aligned to the multiples of its size in storage -- that's what accounts for some speed improvement. I am still not getting the point when it comes to padding. Because it looks like it draws on speed -- both when you do the padding and when you trim the results. The question is whether a null-terminated string would do as well. My suspicion is that somebody simply didn't like to see the garbage in the database files, and then it stuck. > What I don't get is why, given two bpchar argument, Postgres doesn't just > pad the shorter one to the length of the other and then compares, selects > and whatnot. As the original post by Nikolay Mijaylov indicated, there is (was?) a mechanism for correct comparison between various char(*) and text types, but whether it works or not depends on the weather outside. I can witness its existence in the past, as I still have some code that relies on cross-type comparisons which do not seem to work anymore. Unfortunately, I did not check since a few versions back, but if I understood Nikolay Mijaylov right, he claims to have two installations of the same version that behave differently. Now these code snippets clearly shows how it was intended to work: /***************************************************************************** * Comparison Functions used for bpchar *****************************************************************************/ static int bcTruelen(char *arg) { char *s = VARDATA(arg); int i; int len; len = VARSIZE(arg) - VARHDRSZ; for (i = len - 1; i >= 0; i--) { if (s[i] != ' ') break; } return i + 1; } . . . . bool bpchareq(char *arg1, char *arg2) { int len1, len2; if (arg1 == NULL || arg2 == NULL) return (bool) 0; len1 = bcTruelen(arg1); len2 = bcTruelen(arg2); if (len1 != len2) return 0; return strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0; } What's up with bcTruelen() then? Where does the noise come from? --Gene
Hello: I have two questions that might be FAQs (apologies in advance): (1) Why does the parser choke on backslashed single-quote characters? Or, in other words, why doesn't this work: testing=> \d bubba Table = bubba +--------------------------+----------------------------------+-------+ | Field | Type | Length| +--------------------------+----------------------------------+-------+ | litbub | varchar() | 60 | +--------------------------+----------------------------------+-------+ testing=> insert '\'' into bubba; ERROR: parser: parse error at or near "'" (2) How does one rename a database? Other than dump/destroydb/restore, obviously. TIA -- Nathan L. Cutler < livingston @ iol.cz > telephone: +420-2-51611648 Livingston Professional Translations fax: +420-2-6514377 ** When "pretty good" is not enough ** Prague, Czech Republic
Yes, u understood me right, I plane to install new version in january, and if the problem still exist, I;ll report it again -------------------------------------------------------------- The reboots are for hardware upgrades! "http://www.nmmm.nu; <nmmm@nmmm.nu> ----- Original Message ----- From: Gene Selkov <selkovjr@mcs.anl.gov> To: Herouth Maoz <herouth@oumail.openu.ac.il> Cc: pgsql-general <pgsql-general@postgresql.org> Sent: сряда, Декември 22, 1999 10:00 Subject: Re: [GENERAL] char(xx) problem > > > > I'm just wondering: are there any alternatives to blank padding? Why > > > is it done in the first place? > > > > That's how fixed-length char type works, since the early days of SQL. You > > come to expect it, which means that if you use legacy code that has a > > fixed-width char type, or you decided to use it for its time-saving > > possibilities, it should behave according to some way which has been > > established long ago. > > I thik I understand why a fixed-size type should be aligned to the > multiples of its size in storage -- that's what accounts for some > speed improvement. I am still not getting the point when it comes to > padding. Because it looks like it draws on speed -- both when you do > the padding and when you trim the results. The question is > whether a null-terminated string would do as well. > > My suspicion is that somebody simply didn't like to see the garbage in the > database files, and then it stuck. > > > What I don't get is why, given two bpchar argument, Postgres doesn't just > > pad the shorter one to the length of the other and then compares, selects > > and whatnot. > > As the original post by Nikolay Mijaylov indicated, there is (was?) a > mechanism for correct comparison between various char(*) and text > types, but whether it works or not depends on the weather outside. I > can witness its existence in the past, as I still have some code that > relies on cross-type comparisons which do not seem to work > anymore. Unfortunately, I did not check since a few versions back, but > if I understood Nikolay Mijaylov right, he claims to have two > installations of the same version that behave differently. > > Now these code snippets clearly shows how it was intended to work: > > > /* **************************************************************************** > * Comparison Functions used for bpchar > * **** ************************************************************************/ > > static int > bcTruelen(char *arg) > { > char *s = VARDATA(arg); > int i; > int len; > > len = VARSIZE(arg) - VARHDRSZ; > for (i = len - 1; i >= 0; i--) > { > if (s[i] != ' ') > break; > } > return i + 1; > } > > > . . . . > > > bool > bpchareq(char *arg1, char *arg2) > { > int len1, > len2; > > if (arg1 == NULL || arg2 == NULL) > return (bool) 0; > len1 = bcTruelen(arg1); > len2 = bcTruelen(arg2); > > if (len1 != len2) > return 0; > > return strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0; > } > > What's up with bcTruelen() then? Where does the noise come from? > > > --Gene > > ************
> Hello: > > I have two questions that might be FAQs (apologies in advance): > > (1) Why does the parser choke on backslashed single-quote characters? Or, > in other words, why doesn't this work: > > testing=> \d bubba > Table = bubba > +--------------------------+----------------------------------+-------+ > | Field | Type | Length| > +--------------------------+----------------------------------+-------+ > | litbub | varchar() | 60 | > +--------------------------+----------------------------------+-------+ > testing=> insert '\'' into bubba; > ERROR: parser: parse error at or near "'" INSERT INTO bubba VALUES ('\''); > > (2) How does one rename a database? Other than dump/destroydb/restore, > obviously. I think you can modify pg_database with new name, stop postmaster, rename database directory, and restart. Not sure, but that may work. -- Bruce Momjian | http://www.op.net/~candle maillist@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026