@@ -272,17 +272,15 @@ static ParamListInfo setup_unshared_param_list(PLpgSQL_execstate *estate,
272272PLpgSQL_expr * expr );
273273static void plpgsql_param_fetch (ParamListInfo params ,int paramid );
274274static void exec_move_row (PLpgSQL_execstate * estate ,
275- PLpgSQL_rec * rec ,
276- PLpgSQL_row * row ,
275+ PLpgSQL_variable * target ,
277276HeapTuple tup ,TupleDesc tupdesc );
278277static HeapTuple make_tuple_from_row (PLpgSQL_execstate * estate ,
279278PLpgSQL_row * row ,
280279TupleDesc tupdesc );
281280static HeapTuple get_tuple_from_datum (Datum value );
282281static TupleDesc get_tupdesc_from_datum (Datum value );
283282static void exec_move_row_from_datum (PLpgSQL_execstate * estate ,
284- PLpgSQL_rec * rec ,
285- PLpgSQL_row * row ,
283+ PLpgSQL_variable * target ,
286284Datum value );
287285static char * convert_value_to_string (PLpgSQL_execstate * estate ,
288286Datum value ,Oid valtype );
@@ -425,13 +423,15 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
425423if (!fcinfo -> argnull [i ])
426424{
427425/* Assign row value from composite datum */
428- exec_move_row_from_datum (& estate ,NULL ,row ,
426+ exec_move_row_from_datum (& estate ,
427+ (PLpgSQL_variable * )row ,
429428fcinfo -> arg [i ]);
430429}
431430else
432431{
433432/* If arg is null, treat it as an empty row */
434- exec_move_row (& estate ,NULL ,row ,NULL ,NULL );
433+ exec_move_row (& estate , (PLpgSQL_variable * )row ,
434+ NULL ,NULL );
435435}
436436/* clean up after exec_move_row() */
437437exec_eval_cleanup (& estate );
@@ -2327,7 +2327,7 @@ exec_stmt_forc(PLpgSQL_execstate *estate, PLpgSQL_stmt_forc *stmt)
23272327set_args .sqlstmt = stmt -> argquery ;
23282328set_args .into = true;
23292329/* XXX historically this has not been STRICT */
2330- set_args .row = (PLpgSQL_row * )
2330+ set_args .target = (PLpgSQL_variable * )
23312331(estate -> datums [curvar -> cursor_explicit_argrow ]);
23322332
23332333if (exec_stmt_execsql (estate ,& set_args )!= PLPGSQL_RC_OK )
@@ -3755,22 +3755,16 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
37553755{
37563756SPITupleTable * tuptab = SPI_tuptable ;
37573757uint64 n = SPI_processed ;
3758- PLpgSQL_rec * rec = NULL ;
3759- PLpgSQL_row * row = NULL ;
3758+ PLpgSQL_variable * target ;
37603759
37613760/* If the statement did not return a tuple table, complain */
37623761if (tuptab == NULL )
37633762ereport (ERROR ,
37643763(errcode (ERRCODE_SYNTAX_ERROR ),
37653764errmsg ("INTO used with a command that cannot return data" )));
37663765
3767- /* Determine if we assign to a record or a row */
3768- if (stmt -> rec != NULL )
3769- rec = (PLpgSQL_rec * ) (estate -> datums [stmt -> rec -> dno ]);
3770- else if (stmt -> row != NULL )
3771- row = (PLpgSQL_row * ) (estate -> datums [stmt -> row -> dno ]);
3772- else
3773- elog (ERROR ,"unsupported target" );
3766+ /* Fetch target's datum entry */
3767+ target = (PLpgSQL_variable * )estate -> datums [stmt -> target -> dno ];
37743768
37753769/*
37763770 * If SELECT ... INTO specified STRICT, and the query didn't find
@@ -3794,7 +3788,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
37943788errdetail ?errdetail_internal ("parameters: %s" ,errdetail ) :0 ));
37953789}
37963790/* set the target to NULL(s) */
3797- exec_move_row (estate ,rec , row ,NULL ,tuptab -> tupdesc );
3791+ exec_move_row (estate ,target ,NULL ,tuptab -> tupdesc );
37983792}
37993793else
38003794{
@@ -3813,7 +3807,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
38133807errdetail ?errdetail_internal ("parameters: %s" ,errdetail ) :0 ));
38143808}
38153809/* Put the first result row into the target */
3816- exec_move_row (estate ,rec , row ,tuptab -> vals [0 ],tuptab -> tupdesc );
3810+ exec_move_row (estate ,target ,tuptab -> vals [0 ],tuptab -> tupdesc );
38173811}
38183812
38193813/* Clean up */
@@ -3946,22 +3940,16 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
39463940{
39473941SPITupleTable * tuptab = SPI_tuptable ;
39483942uint64 n = SPI_processed ;
3949- PLpgSQL_rec * rec = NULL ;
3950- PLpgSQL_row * row = NULL ;
3943+ PLpgSQL_variable * target ;
39513944
39523945/* If the statement did not return a tuple table, complain */
39533946if (tuptab == NULL )
39543947ereport (ERROR ,
39553948(errcode (ERRCODE_SYNTAX_ERROR ),
39563949errmsg ("INTO used with a command that cannot return data" )));
39573950
3958- /* Determine if we assign to a record or a row */
3959- if (stmt -> rec != NULL )
3960- rec = (PLpgSQL_rec * ) (estate -> datums [stmt -> rec -> dno ]);
3961- else if (stmt -> row != NULL )
3962- row = (PLpgSQL_row * ) (estate -> datums [stmt -> row -> dno ]);
3963- else
3964- elog (ERROR ,"unsupported target" );
3951+ /* Fetch target's datum entry */
3952+ target = (PLpgSQL_variable * )estate -> datums [stmt -> target -> dno ];
39653953
39663954/*
39673955 * If SELECT ... INTO specified STRICT, and the query didn't find
@@ -3985,7 +3973,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
39853973errdetail ?errdetail_internal ("parameters: %s" ,errdetail ) :0 ));
39863974}
39873975/* set the target to NULL(s) */
3988- exec_move_row (estate ,rec , row ,NULL ,tuptab -> tupdesc );
3976+ exec_move_row (estate ,target ,NULL ,tuptab -> tupdesc );
39893977}
39903978else
39913979{
@@ -4005,7 +3993,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
40053993}
40063994
40073995/* Put the first result row into the target */
4008- exec_move_row (estate ,rec , row ,tuptab -> vals [0 ],tuptab -> tupdesc );
3996+ exec_move_row (estate ,target ,tuptab -> vals [0 ],tuptab -> tupdesc );
40093997}
40103998/* clean up after exec_move_row() */
40113999exec_eval_cleanup (estate );
@@ -4163,7 +4151,7 @@ exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
41634151set_args .sqlstmt = stmt -> argquery ;
41644152set_args .into = true;
41654153/* XXX historically this has not been STRICT */
4166- set_args .row = (PLpgSQL_row * )
4154+ set_args .target = (PLpgSQL_variable * )
41674155(estate -> datums [curvar -> cursor_explicit_argrow ]);
41684156
41694157if (exec_stmt_execsql (estate ,& set_args )!= PLPGSQL_RC_OK )
@@ -4221,8 +4209,6 @@ static int
42214209exec_stmt_fetch (PLpgSQL_execstate * estate ,PLpgSQL_stmt_fetch * stmt )
42224210{
42234211PLpgSQL_var * curvar ;
4224- PLpgSQL_rec * rec = NULL ;
4225- PLpgSQL_row * row = NULL ;
42264212long how_many = stmt -> how_many ;
42274213SPITupleTable * tuptab ;
42284214Portal portal ;
@@ -4269,16 +4255,7 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
42694255
42704256if (!stmt -> is_move )
42714257{
4272- /* ----------
4273- * Determine if we fetch into a record or a row
4274- * ----------
4275- */
4276- if (stmt -> rec != NULL )
4277- rec = (PLpgSQL_rec * ) (estate -> datums [stmt -> rec -> dno ]);
4278- else if (stmt -> row != NULL )
4279- row = (PLpgSQL_row * ) (estate -> datums [stmt -> row -> dno ]);
4280- else
4281- elog (ERROR ,"unsupported target" );
4258+ PLpgSQL_variable * target ;
42824259
42834260/* ----------
42844261 * Fetch 1 tuple from the cursor
@@ -4292,10 +4269,11 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
42924269 * Set the target appropriately.
42934270 * ----------
42944271 */
4272+ target = (PLpgSQL_variable * )estate -> datums [stmt -> target -> dno ];
42954273if (n == 0 )
4296- exec_move_row (estate ,rec , row ,NULL ,tuptab -> tupdesc );
4274+ exec_move_row (estate ,target ,NULL ,tuptab -> tupdesc );
42974275else
4298- exec_move_row (estate ,rec , row ,tuptab -> vals [0 ],tuptab -> tupdesc );
4276+ exec_move_row (estate ,target ,tuptab -> vals [0 ],tuptab -> tupdesc );
42994277
43004278exec_eval_cleanup (estate );
43014279SPI_freetuptable (tuptab );
@@ -4514,7 +4492,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
45144492if (isNull )
45154493{
45164494/* If source is null, just assign nulls to the row */
4517- exec_move_row (estate ,NULL ,row ,NULL ,NULL );
4495+ exec_move_row (estate , (PLpgSQL_variable * )row ,
4496+ NULL ,NULL );
45184497}
45194498else
45204499{
@@ -4523,7 +4502,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
45234502ereport (ERROR ,
45244503(errcode (ERRCODE_DATATYPE_MISMATCH ),
45254504errmsg ("cannot assign non-composite value to a row variable" )));
4526- exec_move_row_from_datum (estate ,NULL ,row ,value );
4505+ exec_move_row_from_datum (estate , (PLpgSQL_variable * )row ,
4506+ value );
45274507}
45284508break ;
45294509}
@@ -4538,7 +4518,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
45384518if (isNull )
45394519{
45404520/* If source is null, just assign nulls to the record */
4541- exec_move_row (estate ,rec ,NULL ,NULL ,NULL );
4521+ exec_move_row (estate , (PLpgSQL_variable * )rec ,
4522+ NULL ,NULL );
45424523}
45434524else
45444525{
@@ -4547,7 +4528,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
45474528ereport (ERROR ,
45484529(errcode (ERRCODE_DATATYPE_MISMATCH ),
45494530errmsg ("cannot assign non-composite value to a record variable" )));
4550- exec_move_row_from_datum (estate ,rec ,NULL ,value );
4531+ exec_move_row_from_datum (estate , (PLpgSQL_variable * )rec ,
4532+ value );
45514533}
45524534break ;
45534535}
@@ -5341,22 +5323,14 @@ static int
53415323exec_for_query (PLpgSQL_execstate * estate ,PLpgSQL_stmt_forq * stmt ,
53425324Portal portal ,bool prefetch_ok )
53435325{
5344- PLpgSQL_rec * rec = NULL ;
5345- PLpgSQL_row * row = NULL ;
5326+ PLpgSQL_variable * var ;
53465327SPITupleTable * tuptab ;
53475328bool found = false;
53485329int rc = PLPGSQL_RC_OK ;
53495330uint64 n ;
53505331
5351- /*
5352- * Determine if we assign to a record or a row
5353- */
5354- if (stmt -> rec != NULL )
5355- rec = (PLpgSQL_rec * ) (estate -> datums [stmt -> rec -> dno ]);
5356- else if (stmt -> row != NULL )
5357- row = (PLpgSQL_row * ) (estate -> datums [stmt -> row -> dno ]);
5358- else
5359- elog (ERROR ,"unsupported target" );
5332+ /* Fetch loop variable's datum entry */
5333+ var = (PLpgSQL_variable * )estate -> datums [stmt -> var -> dno ];
53605334
53615335/*
53625336 * Make sure the portal doesn't get closed by the user statements we
@@ -5379,7 +5353,7 @@ exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
53795353 */
53805354if (n == 0 )
53815355{
5382- exec_move_row (estate ,rec , row ,NULL ,tuptab -> tupdesc );
5356+ exec_move_row (estate ,var ,NULL ,tuptab -> tupdesc );
53835357exec_eval_cleanup (estate );
53845358}
53855359else
@@ -5397,7 +5371,7 @@ exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
53975371/*
53985372 * Assign the tuple to the target
53995373 */
5400- exec_move_row (estate ,rec , row ,tuptab -> vals [i ],tuptab -> tupdesc );
5374+ exec_move_row (estate ,var ,tuptab -> vals [i ],tuptab -> tupdesc );
54015375exec_eval_cleanup (estate );
54025376
54035377/*
@@ -5949,16 +5923,17 @@ plpgsql_param_fetch(ParamListInfo params, int paramid)
59495923 */
59505924static void
59515925exec_move_row (PLpgSQL_execstate * estate ,
5952- PLpgSQL_rec * rec ,
5953- PLpgSQL_row * row ,
5926+ PLpgSQL_variable * target ,
59545927HeapTuple tup ,TupleDesc tupdesc )
59555928{
59565929/*
59575930 * Record is simple - just copy the tuple and its descriptor into the
59585931 * record variable
59595932 */
5960- if (rec != NULL )
5933+ if (target -> dtype == PLPGSQL_DTYPE_REC )
59615934{
5935+ PLpgSQL_rec * rec = (PLpgSQL_rec * )target ;
5936+
59625937/*
59635938 * Copy input first, just in case it is pointing at variable's value
59645939 */
@@ -6027,8 +6002,9 @@ exec_move_row(PLpgSQL_execstate *estate,
60276002 * If we have no tuple data at all, we'll assign NULL to all columns of
60286003 * the row variable.
60296004 */
6030- if (row != NULL )
6005+ if (target -> dtype == PLPGSQL_DTYPE_ROW )
60316006{
6007+ PLpgSQL_row * row = (PLpgSQL_row * )target ;
60326008int td_natts = tupdesc ?tupdesc -> natts :0 ;
60336009int t_natts ;
60346010int fnum ;
@@ -6195,8 +6171,7 @@ get_tupdesc_from_datum(Datum value)
61956171 */
61966172static void
61976173exec_move_row_from_datum (PLpgSQL_execstate * estate ,
6198- PLpgSQL_rec * rec ,
6199- PLpgSQL_row * row ,
6174+ PLpgSQL_variable * target ,
62006175Datum value )
62016176{
62026177HeapTupleHeader td = DatumGetHeapTupleHeader (value );
@@ -6217,7 +6192,7 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate,
62176192tmptup .t_data = td ;
62186193
62196194/* Do the move */
6220- exec_move_row (estate ,rec , row ,& tmptup ,tupdesc );
6195+ exec_move_row (estate ,target ,& tmptup ,tupdesc );
62216196
62226197/* Release tupdesc usage count */
62236198ReleaseTupleDesc (tupdesc );