plpgsql: remove useless distinctions between record and row cases - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | plpgsql: remove useless distinctions between record and row cases |
Date | |
Msg-id | 11787.1512713374@sss.pgh.pa.us Whole thread Raw |
List | pgsql-hackers |
I've been fooling around with rewriting plpgsql's composite-variable handling, along the way to getting it to handle domains over composite. I noticed that there's some really unnecessary complication in places where it insists on separating "row" variables from "record" variables. More usually, we'd handle that by using a generically-typed pointer and then doing a node-type check where it's actually necessary to distinguish; which it turns out is exactly one place, exec_move_row(). So attached is a simple patch that eliminates the duplicative coding. Barring objection, I'd like to push this shortly. regards, tom lane diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index ec480cb..1959d6d 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 23f54e1..be779b6 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 94f1f58..e802440 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 2b19948..8448578 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;
pgsql-hackers by date: