Skip to content

Commit 5cc3864

Browse files
committed
record_out and friends need to cope with dropped columns in the row
datatype. Per example from Gaetano Mendola, 2004-07-25.
1 parent 8515efa commit 5cc3864

File tree

1 file changed

+69
-30
lines changed

1 file changed

+69
-30
lines changed

src/backend/utils/adt/rowtypes.c

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.3 2004/06/06 18:06:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.4 2004/08/04 19:31:15 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -58,6 +58,7 @@ record_in(PG_FUNCTION_ARGS)
5858
TupleDesc tupdesc;
5959
HeapTuple tuple;
6060
RecordIOData *my_extra;
61+
bool needComma = false;
6162
int ncolumns;
6263
int i;
6364
char *ptr;
@@ -131,6 +132,26 @@ record_in(PG_FUNCTION_ARGS)
131132
ColumnIOData *column_info = &my_extra->columns[i];
132133
Oid column_type = tupdesc->attrs[i]->atttypid;
133134

135+
/* Ignore dropped columns in datatype, but fill with nulls */
136+
if (tupdesc->attrs[i]->attisdropped)
137+
{
138+
values[i] = (Datum) 0;
139+
nulls[i] = 'n';
140+
continue;
141+
}
142+
143+
if (needComma)
144+
{
145+
/* Skip comma that separates prior field from this one */
146+
if (*ptr == ',')
147+
ptr++;
148+
else /* *ptr must be ')' */
149+
ereport(ERROR,
150+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
151+
errmsg("malformed record literal: \"%s\"", string),
152+
errdetail("Too few columns.")));
153+
}
154+
134155
/* Check for null: completely empty input means null */
135156
if (*ptr == ',' || *ptr == ')')
136157
{
@@ -203,27 +224,9 @@ record_in(PG_FUNCTION_ARGS)
203224
/*
204225
* Prep for next column
205226
*/
206-
if (*ptr == ',')
207-
{
208-
if (i == ncolumns-1)
209-
ereport(ERROR,
210-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
211-
errmsg("malformed record literal: \"%s\"", string),
212-
errdetail("Too many columns.")));
213-
ptr++;
214-
}
215-
else
216-
{
217-
/* *ptr must be ')' */
218-
if (i < ncolumns-1)
219-
ereport(ERROR,
220-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
221-
errmsg("malformed record literal: \"%s\"", string),
222-
errdetail("Too few columns.")));
223-
}
227+
needComma = true;
224228
}
225229

226-
/* The check for ')' here is redundant except when ncolumns == 0 */
227230
if (*ptr++ != ')')
228231
ereport(ERROR,
229232
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
@@ -259,6 +262,7 @@ record_out(PG_FUNCTION_ARGS)
259262
TupleDesc tupdesc;
260263
HeapTupleData tuple;
261264
RecordIOData *my_extra;
265+
bool needComma = false;
262266
int ncolumns;
263267
int i;
264268
Datum *values;
@@ -333,8 +337,13 @@ record_out(PG_FUNCTION_ARGS)
333337
char *tmp;
334338
bool nq;
335339

336-
if (i > 0)
340+
/* Ignore dropped columns in datatype */
341+
if (tupdesc->attrs[i]->attisdropped)
342+
continue;
343+
344+
if (needComma)
337345
appendStringInfoChar(&buf, ',');
346+
needComma = true;
338347

339348
if (nulls[i] == 'n')
340349
{
@@ -414,6 +423,8 @@ record_recv(PG_FUNCTION_ARGS)
414423
HeapTuple tuple;
415424
RecordIOData *my_extra;
416425
int ncolumns;
426+
int usercols;
427+
int validcols;
417428
int i;
418429
Datum *values;
419430
char *nulls;
@@ -463,13 +474,21 @@ record_recv(PG_FUNCTION_ARGS)
463474
values = (Datum *) palloc(ncolumns * sizeof(Datum));
464475
nulls = (char *) palloc(ncolumns * sizeof(char));
465476

466-
/* Verify number of columns */
467-
i = pq_getmsgint(buf, 4);
468-
if (i != ncolumns)
477+
/* Fetch number of columns user thinks it has */
478+
usercols = pq_getmsgint(buf, 4);
479+
480+
/* Need to scan to count nondeleted columns */
481+
validcols = 0;
482+
for (i = 0; i < ncolumns; i++)
483+
{
484+
if (!tupdesc->attrs[i]->attisdropped)
485+
validcols++;
486+
}
487+
if (usercols != validcols)
469488
ereport(ERROR,
470489
(errcode(ERRCODE_DATATYPE_MISMATCH),
471490
errmsg("wrong number of columns: %d, expected %d",
472-
i, ncolumns)));
491+
usercols, validcols)));
473492

474493
/* Process each column */
475494
for (i = 0; i < ncolumns; i++)
@@ -479,13 +498,21 @@ record_recv(PG_FUNCTION_ARGS)
479498
Oid coltypoid;
480499
int itemlen;
481500

501+
/* Ignore dropped columns in datatype, but fill with nulls */
502+
if (tupdesc->attrs[i]->attisdropped)
503+
{
504+
values[i] = (Datum) 0;
505+
nulls[i] = 'n';
506+
continue;
507+
}
508+
482509
/* Verify column datatype */
483510
coltypoid = pq_getmsgint(buf, sizeof(Oid));
484511
if (coltypoid != column_type)
485-
ereport(ERROR,
486-
(errcode(ERRCODE_DATATYPE_MISMATCH),
487-
errmsg("wrong data type: %u, expected %u",
488-
coltypoid, column_type)));
512+
ereport(ERROR,
513+
(errcode(ERRCODE_DATATYPE_MISMATCH),
514+
errmsg("wrong data type: %u, expected %u",
515+
coltypoid, column_type)));
489516

490517
/* Get and check the item length */
491518
itemlen = pq_getmsgint(buf, 4);
@@ -570,6 +597,7 @@ record_send(PG_FUNCTION_ARGS)
570597
HeapTupleData tuple;
571598
RecordIOData *my_extra;
572599
int ncolumns;
600+
int validcols;
573601
int i;
574602
Datum *values;
575603
char *nulls;
@@ -633,14 +661,25 @@ record_send(PG_FUNCTION_ARGS)
633661
/* And build the result string */
634662
pq_begintypsend(&buf);
635663

636-
pq_sendint(&buf, ncolumns, 4);
664+
/* Need to scan to count nondeleted columns */
665+
validcols = 0;
666+
for (i = 0; i < ncolumns; i++)
667+
{
668+
if (!tupdesc->attrs[i]->attisdropped)
669+
validcols++;
670+
}
671+
pq_sendint(&buf, validcols, 4);
637672

638673
for (i = 0; i < ncolumns; i++)
639674
{
640675
ColumnIOData *column_info = &my_extra->columns[i];
641676
Oid column_type = tupdesc->attrs[i]->atttypid;
642677
bytea *outputbytes;
643678

679+
/* Ignore dropped columns in datatype */
680+
if (tupdesc->attrs[i]->attisdropped)
681+
continue;
682+
644683
pq_sendint(&buf, column_type, sizeof(Oid));
645684

646685
if (nulls[i] == 'n')

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy