aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pl/plpgsql/src/pl_comp.c2
-rw-r--r--src/pl/plpgsql/src/pl_exec.c111
-rw-r--r--src/pl/plpgsql/src/pl_funcs.c39
-rw-r--r--src/pl/plpgsql/src/pl_gram.y126
-rw-r--r--src/pl/plpgsql/src/plpgsql.h22
5 files changed, 106 insertions, 194 deletions
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index f459c02f7be..1300ea6a525 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -545,7 +545,7 @@ do_compile(FunctionCallInfo fcinfo,
{
if (rettypeid == VOIDOID ||
rettypeid == RECORDOID)
- /* okay */ ;
+ /* okay */ ;
else if (rettypeid == TRIGGEROID || rettypeid == EVTTRIGGEROID)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index ec480cb0ba8..1959d6dc424 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -272,8 +272,7 @@ static ParamListInfo setup_unshared_param_list(PLpgSQL_execstate *estate,
PLpgSQL_expr *expr);
static void plpgsql_param_fetch(ParamListInfo params, int paramid);
static void exec_move_row(PLpgSQL_execstate *estate,
- PLpgSQL_rec *rec,
- PLpgSQL_row *row,
+ PLpgSQL_variable *target,
HeapTuple tup, TupleDesc tupdesc);
static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
PLpgSQL_row *row,
@@ -281,8 +280,7 @@ static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
static HeapTuple get_tuple_from_datum(Datum value);
static TupleDesc get_tupdesc_from_datum(Datum value);
static void exec_move_row_from_datum(PLpgSQL_execstate *estate,
- PLpgSQL_rec *rec,
- PLpgSQL_row *row,
+ PLpgSQL_variable *target,
Datum value);
static char *convert_value_to_string(PLpgSQL_execstate *estate,
Datum value, Oid valtype);
@@ -425,13 +423,15 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
if (!fcinfo->argnull[i])
{
/* Assign row value from composite datum */
- exec_move_row_from_datum(&estate, NULL, row,
+ exec_move_row_from_datum(&estate,
+ (PLpgSQL_variable *) row,
fcinfo->arg[i]);
}
else
{
/* If arg is null, treat it as an empty row */
- exec_move_row(&estate, NULL, row, NULL, NULL);
+ exec_move_row(&estate, (PLpgSQL_variable *) row,
+ NULL, NULL);
}
/* clean up after exec_move_row() */
exec_eval_cleanup(&estate);
@@ -2327,7 +2327,7 @@ exec_stmt_forc(PLpgSQL_execstate *estate, PLpgSQL_stmt_forc *stmt)
set_args.sqlstmt = stmt->argquery;
set_args.into = true;
/* XXX historically this has not been STRICT */
- set_args.row = (PLpgSQL_row *)
+ set_args.target = (PLpgSQL_variable *)
(estate->datums[curvar->cursor_explicit_argrow]);
if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
@@ -3755,8 +3755,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
{
SPITupleTable *tuptab = SPI_tuptable;
uint64 n = SPI_processed;
- PLpgSQL_rec *rec = NULL;
- PLpgSQL_row *row = NULL;
+ PLpgSQL_variable *target;
/* If the statement did not return a tuple table, complain */
if (tuptab == NULL)
@@ -3764,13 +3763,8 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("INTO used with a command that cannot return data")));
- /* Determine if we assign to a record or a row */
- if (stmt->rec != NULL)
- rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
- else if (stmt->row != NULL)
- row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
- else
- elog(ERROR, "unsupported target");
+ /* Fetch target's datum entry */
+ target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
/*
* If SELECT ... INTO specified STRICT, and the query didn't find
@@ -3794,7 +3788,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
}
/* set the target to NULL(s) */
- exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
+ exec_move_row(estate, target, NULL, tuptab->tupdesc);
}
else
{
@@ -3813,7 +3807,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
}
/* Put the first result row into the target */
- exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
+ exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
}
/* Clean up */
@@ -3946,8 +3940,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
{
SPITupleTable *tuptab = SPI_tuptable;
uint64 n = SPI_processed;
- PLpgSQL_rec *rec = NULL;
- PLpgSQL_row *row = NULL;
+ PLpgSQL_variable *target;
/* If the statement did not return a tuple table, complain */
if (tuptab == NULL)
@@ -3955,13 +3948,8 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("INTO used with a command that cannot return data")));
- /* Determine if we assign to a record or a row */
- if (stmt->rec != NULL)
- rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
- else if (stmt->row != NULL)
- row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
- else
- elog(ERROR, "unsupported target");
+ /* Fetch target's datum entry */
+ target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
/*
* If SELECT ... INTO specified STRICT, and the query didn't find
@@ -3985,7 +3973,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
}
/* set the target to NULL(s) */
- exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
+ exec_move_row(estate, target, NULL, tuptab->tupdesc);
}
else
{
@@ -4005,7 +3993,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
}
/* Put the first result row into the target */
- exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
+ exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
}
/* clean up after exec_move_row() */
exec_eval_cleanup(estate);
@@ -4163,7 +4151,7 @@ exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
set_args.sqlstmt = stmt->argquery;
set_args.into = true;
/* XXX historically this has not been STRICT */
- set_args.row = (PLpgSQL_row *)
+ set_args.target = (PLpgSQL_variable *)
(estate->datums[curvar->cursor_explicit_argrow]);
if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
@@ -4221,8 +4209,6 @@ static int
exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
{
PLpgSQL_var *curvar;
- PLpgSQL_rec *rec = NULL;
- PLpgSQL_row *row = NULL;
long how_many = stmt->how_many;
SPITupleTable *tuptab;
Portal portal;
@@ -4269,16 +4255,7 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
if (!stmt->is_move)
{
- /* ----------
- * Determine if we fetch into a record or a row
- * ----------
- */
- if (stmt->rec != NULL)
- rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
- else if (stmt->row != NULL)
- row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
- else
- elog(ERROR, "unsupported target");
+ PLpgSQL_variable *target;
/* ----------
* Fetch 1 tuple from the cursor
@@ -4292,10 +4269,11 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
* Set the target appropriately.
* ----------
*/
+ target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
if (n == 0)
- exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
+ exec_move_row(estate, target, NULL, tuptab->tupdesc);
else
- exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
+ exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
exec_eval_cleanup(estate);
SPI_freetuptable(tuptab);
@@ -4514,7 +4492,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
if (isNull)
{
/* If source is null, just assign nulls to the row */
- exec_move_row(estate, NULL, row, NULL, NULL);
+ exec_move_row(estate, (PLpgSQL_variable *) row,
+ NULL, NULL);
}
else
{
@@ -4523,7 +4502,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot assign non-composite value to a row variable")));
- exec_move_row_from_datum(estate, NULL, row, value);
+ exec_move_row_from_datum(estate, (PLpgSQL_variable *) row,
+ value);
}
break;
}
@@ -4538,7 +4518,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
if (isNull)
{
/* If source is null, just assign nulls to the record */
- exec_move_row(estate, rec, NULL, NULL, NULL);
+ exec_move_row(estate, (PLpgSQL_variable *) rec,
+ NULL, NULL);
}
else
{
@@ -4547,7 +4528,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot assign non-composite value to a record variable")));
- exec_move_row_from_datum(estate, rec, NULL, value);
+ exec_move_row_from_datum(estate, (PLpgSQL_variable *) rec,
+ value);
}
break;
}
@@ -5341,22 +5323,14 @@ static int
exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
Portal portal, bool prefetch_ok)
{
- PLpgSQL_rec *rec = NULL;
- PLpgSQL_row *row = NULL;
+ PLpgSQL_variable *var;
SPITupleTable *tuptab;
bool found = false;
int rc = PLPGSQL_RC_OK;
uint64 n;
- /*
- * Determine if we assign to a record or a row
- */
- if (stmt->rec != NULL)
- rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
- else if (stmt->row != NULL)
- row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
- else
- elog(ERROR, "unsupported target");
+ /* Fetch loop variable's datum entry */
+ var = (PLpgSQL_variable *) estate->datums[stmt->var->dno];
/*
* 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,
*/
if (n == 0)
{
- exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
+ exec_move_row(estate, var, NULL, tuptab->tupdesc);
exec_eval_cleanup(estate);
}
else
@@ -5397,7 +5371,7 @@ exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
/*
* Assign the tuple to the target
*/
- exec_move_row(estate, rec, row, tuptab->vals[i], tuptab->tupdesc);
+ exec_move_row(estate, var, tuptab->vals[i], tuptab->tupdesc);
exec_eval_cleanup(estate);
/*
@@ -5949,16 +5923,17 @@ plpgsql_param_fetch(ParamListInfo params, int paramid)
*/
static void
exec_move_row(PLpgSQL_execstate *estate,
- PLpgSQL_rec *rec,
- PLpgSQL_row *row,
+ PLpgSQL_variable *target,
HeapTuple tup, TupleDesc tupdesc)
{
/*
* Record is simple - just copy the tuple and its descriptor into the
* record variable
*/
- if (rec != NULL)
+ if (target->dtype == PLPGSQL_DTYPE_REC)
{
+ PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
+
/*
* Copy input first, just in case it is pointing at variable's value
*/
@@ -6027,8 +6002,9 @@ exec_move_row(PLpgSQL_execstate *estate,
* If we have no tuple data at all, we'll assign NULL to all columns of
* the row variable.
*/
- if (row != NULL)
+ if (target->dtype == PLPGSQL_DTYPE_ROW)
{
+ PLpgSQL_row *row = (PLpgSQL_row *) target;
int td_natts = tupdesc ? tupdesc->natts : 0;
int t_natts;
int fnum;
@@ -6195,8 +6171,7 @@ get_tupdesc_from_datum(Datum value)
*/
static void
exec_move_row_from_datum(PLpgSQL_execstate *estate,
- PLpgSQL_rec *rec,
- PLpgSQL_row *row,
+ PLpgSQL_variable *target,
Datum value)
{
HeapTupleHeader td = DatumGetHeapTupleHeader(value);
@@ -6217,7 +6192,7 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate,
tmptup.t_data = td;
/* Do the move */
- exec_move_row(estate, rec, row, &tmptup, tupdesc);
+ exec_move_row(estate, target, &tmptup, tupdesc);
/* Release tupdesc usage count */
ReleaseTupleDesc(tupdesc);
diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c
index 23f54e1c21b..be779b6fc4c 100644
--- a/src/pl/plpgsql/src/pl_funcs.c
+++ b/src/pl/plpgsql/src/pl_funcs.c
@@ -1062,7 +1062,7 @@ static void
dump_fors(PLpgSQL_stmt_fors *stmt)
{
dump_ind();
- printf("FORS %s ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
+ printf("FORS %s ", stmt->var->refname);
dump_expr(stmt->query);
printf("\n");
@@ -1076,7 +1076,7 @@ static void
dump_forc(PLpgSQL_stmt_forc *stmt)
{
dump_ind();
- printf("FORC %s ", stmt->rec->refname);
+ printf("FORC %s ", stmt->var->refname);
printf("curvar=%d\n", stmt->curvar);
dump_indent += 2;
@@ -1174,15 +1174,11 @@ dump_fetch(PLpgSQL_stmt_fetch *stmt)
dump_cursor_direction(stmt);
dump_indent += 2;
- if (stmt->rec != NULL)
+ if (stmt->target != NULL)
{
dump_ind();
- printf(" target = %d %s\n", stmt->rec->dno, stmt->rec->refname);
- }
- if (stmt->row != NULL)
- {
- dump_ind();
- printf(" target = %d %s\n", stmt->row->dno, stmt->row->refname);
+ printf(" target = %d %s\n",
+ stmt->target->dno, stmt->target->refname);
}
dump_indent -= 2;
}
@@ -1420,19 +1416,12 @@ dump_execsql(PLpgSQL_stmt_execsql *stmt)
printf("\n");
dump_indent += 2;
- if (stmt->rec != NULL)
+ if (stmt->target != NULL)
{
dump_ind();
printf(" INTO%s target = %d %s\n",
stmt->strict ? " STRICT" : "",
- stmt->rec->dno, stmt->rec->refname);
- }
- if (stmt->row != NULL)
- {
- dump_ind();
- printf(" INTO%s target = %d %s\n",
- stmt->strict ? " STRICT" : "",
- stmt->row->dno, stmt->row->refname);
+ stmt->target->dno, stmt->target->refname);
}
dump_indent -= 2;
}
@@ -1446,19 +1435,12 @@ dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
printf("\n");
dump_indent += 2;
- if (stmt->rec != NULL)
- {
- dump_ind();
- printf(" INTO%s target = %d %s\n",
- stmt->strict ? " STRICT" : "",
- stmt->rec->dno, stmt->rec->refname);
- }
- if (stmt->row != NULL)
+ if (stmt->target != NULL)
{
dump_ind();
printf(" INTO%s target = %d %s\n",
stmt->strict ? " STRICT" : "",
- stmt->row->dno, stmt->row->refname);
+ stmt->target->dno, stmt->target->refname);
}
if (stmt->params != NIL)
{
@@ -1485,8 +1467,7 @@ static void
dump_dynfors(PLpgSQL_stmt_dynfors *stmt)
{
dump_ind();
- printf("FORS %s EXECUTE ",
- (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
+ printf("FORS %s EXECUTE ", stmt->var->refname);
dump_expr(stmt->query);
printf("\n");
if (stmt->params != NIL)
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 94f1f585930..e802440b451 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -90,7 +90,7 @@ static PLpgSQL_stmt *make_case(int location, PLpgSQL_expr *t_expr,
List *case_when_list, List *else_stmts);
static char *NameOfDatum(PLwdatum *wdatum);
static void check_assignable(PLpgSQL_datum *datum, int location);
-static void read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row,
+static void read_into_target(PLpgSQL_variable **target,
bool *strict);
static PLpgSQL_row *read_into_scalar_list(char *initial_name,
PLpgSQL_datum *initial_datum,
@@ -138,8 +138,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
char *name;
int lineno;
PLpgSQL_datum *scalar;
- PLpgSQL_rec *rec;
- PLpgSQL_row *row;
+ PLpgSQL_datum *row;
} forvariable;
struct
{
@@ -1310,22 +1309,18 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
- if ($1.rec)
+ if ($1.row)
{
- new->rec = $1.rec;
- check_assignable((PLpgSQL_datum *) new->rec, @1);
- }
- else if ($1.row)
- {
- new->row = $1.row;
- check_assignable((PLpgSQL_datum *) new->row, @1);
+ new->var = (PLpgSQL_variable *) $1.row;
+ check_assignable($1.row, @1);
}
else if ($1.scalar)
{
/* convert single scalar to list */
- new->row = make_scalar_list1($1.name, $1.scalar,
- $1.lineno, @1);
- /* no need for check_assignable */
+ new->var = (PLpgSQL_variable *)
+ make_scalar_list1($1.name, $1.scalar,
+ $1.lineno, @1);
+ /* make_scalar_list1 did check_assignable */
}
else
{
@@ -1381,9 +1376,10 @@ for_control : for_variable K_IN
"LOOP");
/* create loop's private RECORD variable */
- new->rec = plpgsql_build_record($1.name,
- $1.lineno,
- true);
+ new->var = (PLpgSQL_variable *)
+ plpgsql_build_record($1.name,
+ $1.lineno,
+ true);
$$ = (PLpgSQL_stmt *) new;
}
@@ -1504,22 +1500,18 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_fors));
new->cmd_type = PLPGSQL_STMT_FORS;
- if ($1.rec)
+ if ($1.row)
{
- new->rec = $1.rec;
- check_assignable((PLpgSQL_datum *) new->rec, @1);
- }
- else if ($1.row)
- {
- new->row = $1.row;
- check_assignable((PLpgSQL_datum *) new->row, @1);
+ new->var = (PLpgSQL_variable *) $1.row;
+ check_assignable($1.row, @1);
}
else if ($1.scalar)
{
/* convert single scalar to list */
- new->row = make_scalar_list1($1.name, $1.scalar,
- $1.lineno, @1);
- /* no need for check_assignable */
+ new->var = (PLpgSQL_variable *)
+ make_scalar_list1($1.name, $1.scalar,
+ $1.lineno, @1);
+ /* make_scalar_list1 did check_assignable */
}
else
{
@@ -1558,32 +1550,26 @@ for_variable : T_DATUM
{
$$.name = NameOfDatum(&($1));
$$.lineno = plpgsql_location_to_lineno(@1);
- if ($1.datum->dtype == PLPGSQL_DTYPE_ROW)
+ if ($1.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ $1.datum->dtype == PLPGSQL_DTYPE_REC)
{
$$.scalar = NULL;
- $$.rec = NULL;
- $$.row = (PLpgSQL_row *) $1.datum;
- }
- else if ($1.datum->dtype == PLPGSQL_DTYPE_REC)
- {
- $$.scalar = NULL;
- $$.rec = (PLpgSQL_rec *) $1.datum;
- $$.row = NULL;
+ $$.row = $1.datum;
}
else
{
int tok;
$$.scalar = $1.datum;
- $$.rec = NULL;
$$.row = NULL;
/* check for comma-separated list */
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == ',')
- $$.row = read_into_scalar_list($$.name,
- $$.scalar,
- @1);
+ $$.row = (PLpgSQL_datum *)
+ read_into_scalar_list($$.name,
+ $$.scalar,
+ @1);
}
}
| T_WORD
@@ -1593,7 +1579,6 @@ for_variable : T_DATUM
$$.name = $1.ident;
$$.lineno = plpgsql_location_to_lineno(@1);
$$.scalar = NULL;
- $$.rec = NULL;
$$.row = NULL;
/* check for comma-separated list */
tok = yylex();
@@ -1620,15 +1605,10 @@ stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA
new->expr = $7;
new->body = $8.stmts;
- if ($3.rec)
- {
- new->varno = $3.rec->dno;
- check_assignable((PLpgSQL_datum *) $3.rec, @3);
- }
- else if ($3.row)
+ if ($3.row)
{
new->varno = $3.row->dno;
- check_assignable((PLpgSQL_datum *) $3.row, @3);
+ check_assignable($3.row, @3);
}
else if ($3.scalar)
{
@@ -1981,8 +1961,7 @@ stmt_dynexecute : K_EXECUTE
new->query = expr;
new->into = false;
new->strict = false;
- new->rec = NULL;
- new->row = NULL;
+ new->target = NULL;
new->params = NIL;
/*
@@ -1999,7 +1978,7 @@ stmt_dynexecute : K_EXECUTE
if (new->into) /* multiple INTO */
yyerror("syntax error");
new->into = true;
- read_into_target(&new->rec, &new->row, &new->strict);
+ read_into_target(&new->target, &new->strict);
endtoken = yylex();
}
else if (endtoken == K_USING)
@@ -2107,11 +2086,10 @@ stmt_open : K_OPEN cursor_variable
stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO
{
PLpgSQL_stmt_fetch *fetch = $2;
- PLpgSQL_rec *rec;
- PLpgSQL_row *row;
+ PLpgSQL_variable *target;
/* We have already parsed everything through the INTO keyword */
- read_into_target(&rec, &row, NULL);
+ read_into_target(&target, NULL);
if (yylex() != ';')
yyerror("syntax error");
@@ -2127,8 +2105,7 @@ stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO
parser_errposition(@1)));
fetch->lineno = plpgsql_location_to_lineno(@1);
- fetch->rec = rec;
- fetch->row = row;
+ fetch->target = target;
fetch->curvar = $3->dno;
fetch->is_move = false;
@@ -2842,8 +2819,7 @@ make_execsql_stmt(int firsttoken, int location)
IdentifierLookup save_IdentifierLookup;
PLpgSQL_stmt_execsql *execsql;
PLpgSQL_expr *expr;
- PLpgSQL_row *row = NULL;
- PLpgSQL_rec *rec = NULL;
+ PLpgSQL_variable *target = NULL;
int tok;
int prev_tok;
bool have_into = false;
@@ -2907,7 +2883,7 @@ make_execsql_stmt(int firsttoken, int location)
have_into = true;
into_start_loc = yylloc;
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
- read_into_target(&rec, &row, &have_strict);
+ read_into_target(&target, &have_strict);
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
}
}
@@ -2949,8 +2925,7 @@ make_execsql_stmt(int firsttoken, int location)
execsql->sqlstmt = expr;
execsql->into = have_into;
execsql->strict = have_strict;
- execsql->rec = rec;
- execsql->row = row;
+ execsql->target = target;
return (PLpgSQL_stmt *) execsql;
}
@@ -3341,13 +3316,12 @@ check_assignable(PLpgSQL_datum *datum, int location)
* INTO keyword.
*/
static void
-read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
+read_into_target(PLpgSQL_variable **target, bool *strict)
{
int tok;
/* Set default results */
- *rec = NULL;
- *row = NULL;
+ *target = NULL;
if (strict)
*strict = false;
@@ -3368,22 +3342,11 @@ read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
switch (tok)
{
case T_DATUM:
- if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW)
- {
- check_assignable(yylval.wdatum.datum, yylloc);
- *row = (PLpgSQL_row *) yylval.wdatum.datum;
-
- if ((tok = yylex()) == ',')
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("record or row variable cannot be part of multiple-item INTO list"),
- parser_errposition(yylloc)));
- plpgsql_push_back_token(tok);
- }
- else if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
+ if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
{
check_assignable(yylval.wdatum.datum, yylloc);
- *rec = (PLpgSQL_rec *) yylval.wdatum.datum;
+ *target = (PLpgSQL_variable *) yylval.wdatum.datum;
if ((tok = yylex()) == ',')
ereport(ERROR,
@@ -3394,8 +3357,9 @@ read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
}
else
{
- *row = read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
- yylval.wdatum.datum, yylloc);
+ *target = (PLpgSQL_variable *)
+ read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
+ yylval.wdatum.datum, yylloc);
}
break;
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 2b199485624..84485785370 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -549,8 +549,7 @@ typedef struct PLpgSQL_stmt_forq
PLpgSQL_stmt_type cmd_type;
int lineno;
char *label;
- PLpgSQL_rec *rec;
- PLpgSQL_row *row;
+ PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
} PLpgSQL_stmt_forq;
@@ -562,8 +561,7 @@ typedef struct PLpgSQL_stmt_fors
PLpgSQL_stmt_type cmd_type;
int lineno;
char *label;
- PLpgSQL_rec *rec;
- PLpgSQL_row *row;
+ PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
/* end of fields that must match PLpgSQL_stmt_forq */
PLpgSQL_expr *query;
@@ -577,8 +575,7 @@ typedef struct PLpgSQL_stmt_forc
PLpgSQL_stmt_type cmd_type;
int lineno;
char *label;
- PLpgSQL_rec *rec;
- PLpgSQL_row *row;
+ PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
/* end of fields that must match PLpgSQL_stmt_forq */
int curvar;
@@ -593,8 +590,7 @@ typedef struct PLpgSQL_stmt_dynfors
PLpgSQL_stmt_type cmd_type;
int lineno;
char *label;
- PLpgSQL_rec *rec;
- PLpgSQL_row *row;
+ PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
/* end of fields that must match PLpgSQL_stmt_forq */
PLpgSQL_expr *query;
@@ -624,7 +620,6 @@ typedef struct PLpgSQL_stmt_open
int lineno;
int curvar;
int cursor_options;
- PLpgSQL_row *returntype;
PLpgSQL_expr *argquery;
PLpgSQL_expr *query;
PLpgSQL_expr *dynquery;
@@ -638,8 +633,7 @@ typedef struct PLpgSQL_stmt_fetch
{
PLpgSQL_stmt_type cmd_type;
int lineno;
- PLpgSQL_rec *rec; /* target, as record or row */
- PLpgSQL_row *row;
+ PLpgSQL_variable *target; /* target (record or row) */
int curvar; /* cursor variable to fetch from */
FetchDirection direction; /* fetch direction */
long how_many; /* count, if constant (expr is NULL) */
@@ -750,8 +744,7 @@ typedef struct PLpgSQL_stmt_execsql
* mod_stmt is set when we plan the query */
bool into; /* INTO supplied? */
bool strict; /* INTO STRICT flag */
- PLpgSQL_rec *rec; /* INTO target, if record */
- PLpgSQL_row *row; /* INTO target, if row */
+ PLpgSQL_variable *target; /* INTO target (record or row) */
} PLpgSQL_stmt_execsql;
/*
@@ -764,8 +757,7 @@ typedef struct PLpgSQL_stmt_dynexecute
PLpgSQL_expr *query; /* string expression */
bool into; /* INTO supplied? */
bool strict; /* INTO STRICT flag */
- PLpgSQL_rec *rec; /* INTO target, if record */
- PLpgSQL_row *row; /* INTO target, if row */
+ PLpgSQL_variable *target; /* INTO target (record or row) */
List *params; /* USING expressions */
} PLpgSQL_stmt_dynexecute;