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