Обсуждение: varchar() troubles

Поиск
Список
Период
Сортировка

varchar() troubles

От
"Thomas G. Lockhart"
Дата:
I've been seeing trouble with varchar() columns for a little while, and
since it is still there with a fresh install of the development tree
it's time to report it:

postgres=> create table t (v varchar(80),i int);
CREATE
postgres=> insert into t values ('hi',1);
INSERT 18122 1
postgres=> select * from t;
v |i
--+-
hi|0
(1 row)

As you can see, the varchar() column apparently trashes the subsequent
column. I ran across it trying to verify the tutorial examples for the
documentation. If the varchar() is the last column in the table, the
problem does not crop up, at least in the simplest case:

postgres=> create table t2 (i int, v varchar(80));
CREATE
postgres=> insert into t2 values (2,'hi');
INSERT 18133 1
postgres=> select * from t2;
i|v
-+--
2|hi
(1 row)

Also, I believe that if the varchar() field is substantially shorter the
problem does not manifest itself:

postgres=> create table t4 (v varchar(4), i int);
CREATE
postgres=> insert into t4 values ('hi',4);
INSERT 18156 1
postgres=> select * from t4;
v |i
--+-
hi|4
(1 row)

but varchar(10) still shows the problem:

postgres=> create table t3 (v varchar(10), i int);
CREATE
postgres=> insert into t3 values ('hi',3);
INSERT 18145 1
postgres=> select * from t3;
v |i
--+-
hi|0
(1 row)

This is from the development source as of around 1998-01-12 14:30 GMT

                                                                    -
Tom


Re: varchar() troubles

От
Bruce Momjian
Дата:
>
> I've been seeing trouble with varchar() columns for a little while, and
> since it is still there with a fresh install of the development tree
> it's time to report it:
>
> postgres=> create table t (v varchar(80),i int);
> CREATE
> postgres=> insert into t values ('hi',1);
> INSERT 18122 1
> postgres=> select * from t;
> v |i
> --+-
> hi|0
> (1 row)

Did you see this before or only after the varchar() length change I
made?


--
Bruce Momjian
maillist@candle.pha.pa.us

Re: varchar() troubles

От
"Thomas G. Lockhart"
Дата:
Bruce Momjian wrote:

> >
> > I've been seeing trouble with varchar() columns for a little while, and
> > since it is still there with a fresh install of the development tree
> > it's time to report it:
> >
> > postgres=> create table t (v varchar(80),i int);
> > CREATE
> > postgres=> insert into t values ('hi',1);
> > INSERT 18122 1
> > postgres=> select * from t;
> > v |i
> > --+-
> > hi|0
> > (1 row)
>
> Did you see this before or only after the varchar() length change I
> made?

Pretty sure only after but it's hard to tell for sure. My trees for 971204
and 971222 both core dump on inserts to varchar, but I can't remember what
else I was doing with the trees at the time. v6.2.1p5 works OK on this:

postgres=> create table t (v varchar(80),i int);
CREATE
postgres=> insert into t values ('hi',1);
INSERT 142735 1
postgres=> select * from t;
v |i
--+-
hi|1
(1 row)

                                                                        -
Tom


Re: varchar() troubles

От
Bruce Momjian
Дата:
> Pretty sure only after but it's hard to tell for sure. My trees for 971204
> and 971222 both core dump on inserts to varchar, but I can't remember what
> else I was doing with the trees at the time. v6.2.1p5 works OK on this:
>
> postgres=> create table t (v varchar(80),i int);
> CREATE
> postgres=> insert into t values ('hi',1);
> INSERT 142735 1
> postgres=> select * from t;
> v |i
> --+-
> hi|1
> (1 row)

I am working on it.  Look at this:

    test=> create table t15 (x varchar(7),x1 int, x2 int, x3 int)
    test-> ;
    CREATE
    test=> insert into t15 values ('as',1,2,3);
    INSERT 143436 1
    test=> select * from t15;
    x |x1|x2|x3
    --+--+--+--
    as| 2| 3| 0
    (1 row)

Srange, huh?

--
Bruce Momjian
maillist@candle.pha.pa.us

Re: varchar() troubles

От
Bruce Momjian
Дата:
> Pretty sure only after but it's hard to tell for sure. My trees for 971204
> and 971222 both core dump on inserts to varchar, but I can't remember what
> else I was doing with the trees at the time. v6.2.1p5 works OK on this:
>
> postgres=> create table t (v varchar(80),i int);
> CREATE
> postgres=> insert into t values ('hi',1);
> INSERT 142735 1
> postgres=> select * from t;
> v |i
> --+-
> hi|1
> (1 row)

The data on disk is OK, so it must be the retrieve code.

--
Bruce Momjian
maillist@candle.pha.pa.us

Re: [HACKERS] Re: varchar() troubles

От
"Thomas G. Lockhart"
Дата:
> Pretty sure only after but it's hard to tell for sure. My trees for 971204
> and 971222 both core dump on inserts to varchar, but I can't remember what
> else I was doing with the trees at the time.

I now recall that the varchar code was broken during this time (for who knows
how long?), as I discovered when trying to reproduce the tutorial results for
the documentation.

The problem was that some things were copied using VARSIZE rather than
subtracting out VARHDRSZ first (actually, I think it might have use
sizeof(int) and other dangers too). I patched that near the end of the year
and my 980101.d tree and 980106.d tree do not exhibit the symptom:

postgres=> create table t (v varchar(80),i int);
CREATE
postgres=> insert into t values ('hi', 1);
INSERT 643562 1
postgres=> select * from t;
v |i
--+-
hi|1
(1 row)

Hope this helps :/

                                             - Tom


Re: [HACKERS] Re: varchar() troubles

От
Bruce Momjian
Дата:
>
> > Pretty sure only after but it's hard to tell for sure. My trees for 971204
> > and 971222 both core dump on inserts to varchar, but I can't remember what
> > else I was doing with the trees at the time.
>
> I now recall that the varchar code was broken during this time (for who knows
> how long?), as I discovered when trying to reproduce the tutorial results for
> the documentation.
>
> The problem was that some things were copied using VARSIZE rather than
> subtracting out VARHDRSZ first (actually, I think it might have use
> sizeof(int) and other dangers too). I patched that near the end of the year
> and my 980101.d tree and 980106.d tree do not exhibit the symptom:
>
> postgres=> create table t (v varchar(80),i int);
> CREATE
> postgres=> insert into t values ('hi', 1);
> INSERT 643562 1
> postgres=> select * from t;
> v |i
> --+-
> hi|1
> (1 row)

I have found that ExecEvalVar() uses a descriptor that has the attr
length set to the maximum, instead of -1.  The ExecTypeFromTL() comment
says:

/* ----------------------------------------------------------------
 *      ExecTypeFromTL
 *
 *      Currently there are about 4 different places where we create
 *      TupleDescriptors.  They should all be merged, or perhaps
 *      be rewritten to call BuildDesc().
 *

Clearly stating that the tuple descriptors in the system are created in
several places.  Some places have the length set wrong.  I am going to
have to take a look at all those places, and make sure they have
consistent behaviour.

--
Bruce Momjian
maillist@candle.pha.pa.us

Re: varchar() troubles

От
Bruce Momjian
Дата:
>
> Bruce,
>
> The new varchar() stuff looks good, just a minor problem with "select into"
> where the new table does not seem to get a copy of the atttypmod value
> from the source table.
>
> I had a quick look at the code but guess you'll find the problem 10 times
> faster than I could.

OK, I have fixed this.  The real way to fix this it to add restypmod to
Resdom, and pass the value all the way through the engine, so tupDesc
always has the proper atttypmod value, but it is not clear how to do
this in the parser, so I put the code back in to just do a lookup in
execMain/execUtils when doing an SELECT * INTO TABLE.

If we start using atttypmod more, we will have to do this.

--
Bruce Momjian
maillist@candle.pha.pa.us