Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 976246c

Browse files
committed
The cstring datatype can now be copied, passed around, etc. The typlen
value '-2' is used to indicate a variable-width type whose width is computed as strlen(datum)+1. Everything that looks at typlen is updated except for array support, which Joe Conway is working on; at the moment it wouldn't work to try to create an array of cstring.
1 parent cf4d885 commit 976246c

File tree

23 files changed

+260
-198
lines changed

23 files changed

+260
-198
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--
22
Documentation of the system catalogs, directed toward PostgreSQL developers
3-
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.53 2002/08/13 17:22:08 petere Exp $
3+
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.54 2002/08/24 15:00:45 tgl Exp $
44
-->
55

66
<chapter id="catalogs">
@@ -3173,7 +3173,13 @@
31733173
<entry>typlen</entry>
31743174
<entry><type>int2</type></entry>
31753175
<entry></entry>
3176-
<entry>Length of the storage representation of the type, -1 if variable length</entry>
3176+
<entry>
3177+
For a fixed-size type, <structfield>typlen</structfield> is the number
3178+
of bytes in the internal representation of the type. But for a
3179+
variable-length type, <structfield>typlen</structfield> is negative.
3180+
-1 indicates a <quote>varlena</> type (one that has a length word),
3181+
-2 indicates a null-terminated C string.
3182+
</entry>
31773183
</row>
31783184

31793185
<row>
@@ -3325,7 +3331,7 @@
33253331
<entry><type>char</type></entry>
33263332
<entry></entry>
33273333
<entry><para>
3328-
<structfield>typstorage</structfield> tells for variable-length
3334+
<structfield>typstorage</structfield> tells for varlena
33293335
types (those with <structfield>typlen</structfield> = -1) if
33303336
the type is prepared for toasting and what the default strategy
33313337
for attributes of this type should be.

src/backend/access/common/heaptuple.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.78 2002/07/20 05:16:56 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.79 2002/08/24 15:00:45 tgl Exp $
1313
*
1414
* NOTES
1515
* The old interface functions have been converted to macros
@@ -48,7 +48,7 @@ ComputeDataSize(TupleDesc tupleDesc,
4848
if (nulls[i] != ' ')
4949
continue;
5050

51-
data_length = att_align(data_length, att[i]->attlen, att[i]->attalign);
51+
data_length = att_align(data_length, att[i]->attalign);
5252
data_length = att_addlength(data_length, att[i]->attlen, value[i]);
5353
}
5454

@@ -69,7 +69,7 @@ DataFill(char *data,
6969
{
7070
bits8 *bitP = 0;
7171
int bitmask = 0;
72-
uint32 data_length;
72+
Size data_length;
7373
int i;
7474
int numberOfAttributes = tupleDesc->natts;
7575
Form_pg_attribute *att = tupleDesc->attrs;
@@ -105,12 +105,13 @@ DataFill(char *data,
105105
}
106106

107107
/* XXX we are aligning the pointer itself, not the offset */
108-
data = (char *) att_align((long) data, att[i]->attlen, att[i]->attalign);
108+
data = (char *) att_align((long) data, att[i]->attalign);
109109

110110
if (att[i]->attbyval)
111111
{
112112
/* pass-by-value */
113113
store_att_byval(data, value[i], att[i]->attlen);
114+
data_length = att[i]->attlen;
114115
}
115116
else if (att[i]->attlen == -1)
116117
{
@@ -123,15 +124,22 @@ DataFill(char *data,
123124
data_length = VARATT_SIZE(DatumGetPointer(value[i]));
124125
memcpy(data, DatumGetPointer(value[i]), data_length);
125126
}
127+
else if (att[i]->attlen == -2)
128+
{
129+
/* cstring */
130+
*infomask |= HEAP_HASVARLENA;
131+
data_length = strlen(DatumGetCString(value[i])) + 1;
132+
memcpy(data, DatumGetPointer(value[i]), data_length);
133+
}
126134
else
127135
{
128136
/* fixed-length pass-by-reference */
129-
Assert(att[i]->attlen >= 0);
130-
memcpy(data, DatumGetPointer(value[i]),
131-
(size_t) (att[i]->attlen));
137+
Assert(att[i]->attlen > 0);
138+
data_length = att[i]->attlen;
139+
memcpy(data, DatumGetPointer(value[i]), data_length);
132140
}
133141

134-
data = (char *) att_addlength((long) data, att[i]->attlen, value[i]);
142+
data += data_length;
135143
}
136144
}
137145

@@ -235,17 +243,16 @@ nocachegetattr(HeapTuple tuple,
235243
if (att[attnum]->attcacheoff != -1)
236244
{
237245
return fetchatt(att[attnum],
238-
(char *) tup + tup->t_hoff + att[attnum]->attcacheoff);
246+
(char *) tup + tup->t_hoff +
247+
att[attnum]->attcacheoff);
239248
}
240249
#endif
241250
}
242251
else
243252
{
244253
/*
245254
* there's a null somewhere in the tuple
246-
*/
247-
248-
/*
255+
*
249256
* check to see if desired att is null
250257
*/
251258

@@ -346,11 +353,7 @@ nocachegetattr(HeapTuple tuple,
346353
(HeapTupleNoNulls(tuple) || !att_isnull(j, bp)) &&
347354
(HeapTupleAllFixed(tuple) || att[j]->attlen > 0)); j++)
348355
{
349-
/*
350-
* Fix me when going to a machine with more than a four-byte
351-
* word!
352-
*/
353-
off = att_align(off, att[j]->attlen, att[j]->attalign);
356+
off = att_align(off, att[j]->attalign);
354357

355358
att[j]->attcacheoff = off;
356359

@@ -391,19 +394,19 @@ nocachegetattr(HeapTuple tuple,
391394
off = att[i]->attcacheoff;
392395
else
393396
{
394-
off = att_align(off, att[i]->attlen, att[i]->attalign);
397+
off = att_align(off, att[i]->attalign);
395398

396399
if (usecache)
397400
att[i]->attcacheoff = off;
398401
}
399402

400403
off = att_addlength(off, att[i]->attlen, tp + off);
401404

402-
if (usecache && att[i]->attlen == -1)
405+
if (usecache && att[i]->attlen <= 0)
403406
usecache = false;
404407
}
405408

406-
off = att_align(off, att[attnum]->attlen, att[attnum]->attalign);
409+
off = att_align(off, att[attnum]->attalign);
407410

408411
return fetchatt(att[attnum], tp + off);
409412
}

src/backend/access/common/indextuple.c

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.57 2002/06/20 20:29:24 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.58 2002/08/24 15:00:45 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -64,7 +64,7 @@ index_formtuple(TupleDesc tupleDescriptor,
6464
untoasted_free[i] = false;
6565

6666
/* Do nothing if value is NULL or not of varlena type */
67-
if (null[i] != ' ' || att->attlen >= 0)
67+
if (null[i] != ' ' || att->attlen != -1)
6868
continue;
6969

7070
/*
@@ -243,9 +243,10 @@ nocache_index_getattr(IndexTuple tup,
243243
#endif
244244
}
245245
else
246-
{ /* there's a null somewhere in the tuple */
247-
246+
{
248247
/*
248+
* there's a null somewhere in the tuple
249+
*
249250
* check to see if desired att is null
250251
*/
251252

@@ -291,8 +292,9 @@ nocache_index_getattr(IndexTuple tup,
291292

292293
tp = (char *) tup + data_off;
293294

294-
/* now check for any non-fixed length attrs before our attribute */
295-
295+
/*
296+
* now check for any non-fixed length attrs before our attribute
297+
*/
296298
if (!slow)
297299
{
298300
if (att[attnum]->attcacheoff != -1)
@@ -305,11 +307,13 @@ nocache_index_getattr(IndexTuple tup,
305307
int j;
306308

307309
for (j = 0; j < attnum; j++)
310+
{
308311
if (att[j]->attlen <= 0)
309312
{
310313
slow = true;
311314
break;
312315
}
316+
}
313317
}
314318
}
315319

@@ -337,12 +341,7 @@ nocache_index_getattr(IndexTuple tup,
337341

338342
for (; j <= attnum; j++)
339343
{
340-
/*
341-
* Fix me when going to a machine with more than a four-byte
342-
* word!
343-
*/
344-
345-
off = att_align(off, att[j]->attlen, att[j]->attalign);
344+
off = att_align(off, att[j]->attalign);
346345

347346
att[j]->attcacheoff = off;
348347

@@ -377,22 +376,19 @@ nocache_index_getattr(IndexTuple tup,
377376
off = att[i]->attcacheoff;
378377
else
379378
{
380-
off = att_align(off, att[i]->attlen, att[i]->attalign);
379+
off = att_align(off, att[i]->attalign);
381380

382381
if (usecache)
383382
att[i]->attcacheoff = off;
384383
}
385384

386-
if (att[i]->attlen == -1)
387-
{
388-
off += VARSIZE(tp + off);
385+
off = att_addlength(off, att[i]->attlen, tp + off);
386+
387+
if (usecache && att[i]->attlen <= 0)
389388
usecache = false;
390-
}
391-
else
392-
off += att[i]->attlen;
393389
}
394390

395-
off = att_align(off, att[attnum]->attlen, att[attnum]->attalign);
391+
off = att_align(off, att[attnum]->attalign);
396392

397393
return fetchatt(att[attnum], tp + off);
398394
}

src/backend/access/common/printtup.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.63 2002/08/22 00:01:41 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.64 2002/08/24 15:00:46 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -457,9 +457,15 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
457457
}
458458
else
459459
{
460-
/* fixed size */
460+
/* fixed size or cstring */
461461
attr = origattr;
462462
len = typeinfo->attrs[i]->attlen;
463+
if (len <= 0)
464+
{
465+
/* it's a cstring */
466+
Assert(len == -2 && !typeinfo->attrs[i]->attbyval);
467+
len = strlen(DatumGetCString(attr)) + 1;
468+
}
463469
pq_sendint(&buf, len, sizeof(int32));
464470
if (typeinfo->attrs[i]->attbyval)
465471
{

src/backend/catalog/pg_type.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.78 2002/08/15 16:36:01 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.79 2002/08/24 15:00:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -157,14 +157,25 @@ TypeCreate(const char *typeName,
157157
int i;
158158

159159
/*
160-
* validate size specifications: either positive (fixed-length) or -1
161-
* (variable-length).
160+
* We assume that the caller validated the arguments individually,
161+
* but did not check for bad combinations.
162+
*
163+
* Validate size specifications: either positive (fixed-length) or -1
164+
* (varlena) or -2 (cstring). Pass-by-value types must have a fixed
165+
* length not more than sizeof(Datum).
162166
*/
163-
if (!(internalSize > 0 || internalSize == -1))
167+
if (!(internalSize > 0 ||
168+
internalSize == -1 ||
169+
internalSize == -2))
170+
elog(ERROR, "TypeCreate: invalid type internal size %d",
171+
internalSize);
172+
if (passedByValue &&
173+
(internalSize <= 0 || internalSize > (int16) sizeof(Datum)))
164174
elog(ERROR, "TypeCreate: invalid type internal size %d",
165175
internalSize);
166176

167-
if (internalSize != -1 && storage != 'p')
177+
/* Only varlena types can be toasted */
178+
if (storage != 'p' && internalSize != -1)
168179
elog(ERROR, "TypeCreate: fixed size types must have storage PLAIN");
169180

170181
/*

0 commit comments

Comments
 (0)