Re: [HACKERS] Re: varchar() troubles (fwd)

Bruce Momjian <maillist@candle.pha.pa.us>

From: Bruce Momjian <maillist@candle.pha.pa.us>
To: vadim@sable.krasnoyarsk.su (Vadim B. Mikheev)
Cc: hackers@postgreSQL.org (PostgreSQL-development)
Date: 1998-01-16T05:05:03Z
Lists: pgsql-hackers
Forwarded message:
> > Why attlen should be -1 ?
> > attlen in pg_attribute for v in table t is 84, why run-time attlen
> > should be -1 ? How else maxlen constraint could be checked ?
> > IMHO, you have to change heap_getattr() to check is atttype == VARCHAROID
> > and use vl_len if yes. Also, other places where attlen is used must be 
> > changed too - e.g. ExecEvalVar():
> > 
> >     {
> >         len = tuple_type->attrs[attnum - 1]->attlen;
> >         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >         byval = tuple_type->attrs[attnum - 1]->attbyval ? true : false;
> >     }
> > 
> >     execConstByVal = byval;
> >     execConstLen = len;
> >     ^^^^^^^^^^^^^^^^^^ - used in nodeHash.c
> > 
> 
> The major problem is that TupleDesc comes from several places, and
> attlen means several things.
> 
> There are some cases where TupleDesc (int numatt, Attrs[]) is created
> on-the-fly (tupdesc.c), and the attlen is the length of the type.  In
> other cases, we get attlen from opening the relation, heap_open(), and
> in these cases it is the length as defined for the particular attribute.
> 
> Certainly a bad situation.  I am not sure about a fix.

OK, here is a temporary fix to the problem.  It does the heap_open(),
then replaces the attrs for VARCHAR with attlen of -1.  You can't just
change the field, because the data is in a cache and you are just
returned a pointer.

Can I add an 'attdeflen' for "attributed defined length" field to
pg_attribute, and change the attlen references needed to the new field?
This is the only proper way to fix it.


---------------------------------------------------------------------------

*** ./backend/executor/execAmi.c.orig	Thu Jan 15 22:42:13 1998
--- ./backend/executor/execAmi.c	Thu Jan 15 23:54:37 1998
***************
*** 42,47 ****
--- 42,48 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "catalog/heap.h"
+ #include "catalog/pg_type.h"
  
  static Pointer
  ExecBeginScan(Relation relation, int nkeys, ScanKey skeys,
***************
*** 124,129 ****
--- 125,155 ----
  	if (relation == NULL)
  		elog(DEBUG, "ExecOpenR: relation == NULL, heap_open failed.");
  
+ 	{
+ 		int i;
+ 		Relation trel = palloc(sizeof(RelationData));
+ 		TupleDesc tdesc = palloc(sizeof(struct tupleDesc));
+ 		AttributeTupleForm *tatt =
+ 				palloc(sizeof(AttributeTupleForm*)*relation->rd_att->natts);
+ 
+ 		memcpy(trel, relation, sizeof(RelationData));
+ 		memcpy(tdesc, relation->rd_att, sizeof(struct tupleDesc));
+ 		trel->rd_att = tdesc;
+ 		tdesc->attrs = tatt;
+ 		
+ 		for (i = 0; i < relation->rd_att->natts; i++)
+ 		{
+ 			if (relation->rd_att->attrs[i]->atttypid != VARCHAROID)
+ 				tdesc->attrs[i] = relation->rd_att->attrs[i];
+ 			else
+ 			{
+ 				tdesc->attrs[i] = palloc(sizeof(FormData_pg_attribute));
+ 				memcpy(tdesc->attrs[i], relation->rd_att->attrs[i],
+ 											sizeof(FormData_pg_attribute));
+ 				tdesc->attrs[i]->attlen = -1;
+ 			}
+ 		}
+ 	}
  	return relation;
  }
  


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