aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/plpgsql.sgml51
-rw-r--r--src/pl/plpgsql/src/pl_comp.c134
-rw-r--r--src/pl/plpgsql/src/pl_exec.c211
-rw-r--r--src/pl/plpgsql/src/pl_funcs.c12
-rw-r--r--src/pl/plpgsql/src/plpgsql.h24
-rw-r--r--src/pl/plpgsql/src/scan.l8
-rw-r--r--src/test/regress/expected/plpgsql.out38
-rw-r--r--src/test/regress/sql/plpgsql.sql32
8 files changed, 38 insertions, 472 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index ecbfb49f1f2..f0cbbf2896c 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.93 2006/05/30 12:03:12 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.94 2006/05/30 13:40:55 momjian Exp $ -->
<chapter id="plpgsql">
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
@@ -880,55 +880,6 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ;
</para>
<para>
- To obtain the values of the fields the record is made up of,
- the record variable can be qualified with the column or field
- name. This can be done either by literally using the column name
- or the column name for indexing the record can be taken out of a scalar
- variable. The syntax for this notation is Record_variable.(IndexVariable).
- To get information about the column field names of the record,
- a special expression exists that returns all column names as an array:
- RecordVariable.(*) .
- Thus, the RECORD can be viewed
- as an associative array that allows for introspection of it's contents.
- This feature is especially useful for writing generic triggers that
- operate on records with unknown structure.
- Here is an example procedure that shows column names and values
- of the predefined record NEW in a trigger procedure:
-<programlisting>
-
-CREATE OR REPLACE FUNCTION show_associative_records() RETURNS TRIGGER AS $$
- DECLARE
- colname TEXT;
- colcontent TEXT;
- colnames TEXT[];
- coln INT4;
- coli INT4;
- BEGIN
--- obtain an array with all field names of the record
- colnames := NEW.(*);
- RAISE NOTICE 'All column names of test record: %', colnames;
--- show field names and contents of record
- coli := 1;
- coln := array_upper(colnames,1);
- RAISE NOTICE 'Number of columns in NEW: %', coln;
- FOR coli IN 1 .. coln LOOP
- colname := colnames[coli];
- colcontent := NEW.(colname);
- RAISE NOTICE 'column % of NEW: %', quote_ident(colname), quote_literal(colcontent);
- END LOOP;
--- Do it with a fixed field name:
--- will have to know the column name
- RAISE NOTICE 'column someint of NEW: %', quote_literal(NEW.someint);
- RETURN NULL;
- END;
-$$ LANGUAGE plpgsql;
---CREATE TABLE test_records (someint INT8, somestring TEXT);
---CREATE TRIGGER tr_test_record BEFORE INSERT ON test_records FOR EACH ROW EXECUTE PROCEDURE show_associative_records();
-
-</programlisting>
- </para>
-
- <para>
Note that <literal>RECORD</> is not a true data type, only a placeholder.
One should also realize that when a <application>PL/pgSQL</application>
function is declared to return type <type>record</>, this is not quite the
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index db7bc6bb106..e904a4dfbbe 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.105 2006/05/30 12:03:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.106 2006/05/30 13:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -884,8 +884,7 @@ plpgsql_parse_dblword(char *word)
new = palloc(sizeof(PLpgSQL_recfield));
new->dtype = PLPGSQL_DTYPE_RECFIELD;
- new->fieldindex.fieldname = pstrdup(cp[1]);
- new->fieldindex_flag = RECFIELD_USE_FIELDNAME;
+ new->fieldname = pstrdup(cp[1]);
new->recparentno = ns->itemno;
plpgsql_adddatum((PLpgSQL_datum *) new);
@@ -991,8 +990,7 @@ plpgsql_parse_tripword(char *word)
new = palloc(sizeof(PLpgSQL_recfield));
new->dtype = PLPGSQL_DTYPE_RECFIELD;
- new->fieldindex.fieldname = pstrdup(cp[2]);
- new->fieldindex_flag = RECFIELD_USE_FIELDNAME;
+ new->fieldname = pstrdup(cp[2]);
new->recparentno = ns->itemno;
plpgsql_adddatum((PLpgSQL_datum *) new);
@@ -1440,132 +1438,6 @@ plpgsql_parse_dblwordrowtype(char *word)
return T_DTYPE;
}
-/* ----------
- * plpgsql_parse_recindex
- * lookup associative index into record
- * ----------
- */
-int
-plpgsql_parse_recindex(char *word)
-{
- PLpgSQL_nsitem *ns1, *ns2;
- char *cp[2];
- int ret = T_ERROR;
- char *fieldvar;
- int fl;
-
- /* Do case conversion and word separation */
- plpgsql_convert_ident(word, cp, 2);
- Assert(cp[1] != NULL);
-
- /* cleanup the "(identifier)" string to "identifier" */
- fieldvar = cp[1];
- Assert(*fieldvar == '(');
- ++fieldvar; /* get rid of ( */
-
- fl = strlen(fieldvar);
- Assert(fieldvar[fl-1] == ')');
- fieldvar[fl-1] = 0; /* get rid of ) */
-
- /*
- * Lookup the first word
- */
- ns1 = plpgsql_ns_lookup(cp[0], NULL);
- if ( ns1 == NULL )
- {
- pfree(cp[0]);
- pfree(cp[1]);
- return T_ERROR;
- }
-
- ns2 = plpgsql_ns_lookup(fieldvar, NULL);
- pfree(cp[0]);
- pfree(cp[1]);
- if ( ns2 == NULL ) /* name lookup failed */
- return T_ERROR;
-
- switch (ns1->itemtype)
- {
- case PLPGSQL_NSTYPE_REC:
- {
- /*
- * First word is a record name, so second word must be an
- * variable holding the field name in this record.
- */
- if ( ns2->itemtype == PLPGSQL_NSTYPE_VAR ) {
- PLpgSQL_recfield *new;
-
- new = palloc(sizeof(PLpgSQL_recfield));
- new->dtype = PLPGSQL_DTYPE_RECFIELD;
- new->fieldindex.indexvar_no = ns2->itemno;
- new->fieldindex_flag = RECFIELD_USE_INDEX_VAR;
- new->recparentno = ns1->itemno;
-
- plpgsql_adddatum((PLpgSQL_datum *) new);
-
- plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
- ret = T_SCALAR;
- }
- break;
- }
- default:
- break;
- }
- return ret;
-}
-
-
-/* ----------
- * plpgsql_parse_recfieldnames
- * create fieldnames of a record
- * ----------
- */
-int
-plpgsql_parse_recfieldnames(char *word)
-{
- PLpgSQL_nsitem *ns1;
- char *cp[2];
- int ret = T_ERROR;
-
- /* Do case conversion and word separation */
- plpgsql_convert_ident(word, cp, 2);
-
- /*
- * Lookup the first word
- */
- ns1 = plpgsql_ns_lookup(cp[0], NULL);
- if ( ns1 == NULL )
- {
- pfree(cp[0]);
- pfree(cp[1]);
- return T_ERROR;
- }
-
- pfree(cp[0]);
- pfree(cp[1]);
-
- switch (ns1->itemtype)
- {
- case PLPGSQL_NSTYPE_REC:
- {
- PLpgSQL_recfieldproperties *new;
-
- new = palloc(sizeof(PLpgSQL_recfieldproperties));
- new->dtype = PLPGSQL_DTYPE_RECFIELDNAMES;
- new->recparentno = ns1->itemno;
- new->save_fieldnames = NULL;
- plpgsql_adddatum((PLpgSQL_datum *) new);
- plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
- ret = T_SCALAR; /* ??? */
- break;
- }
- default:
- break;
- }
- return ret;
-}
-
-
/*
* plpgsql_build_variable - build a datum-array entry of a given
* datatype
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 07f1211f4e5..b27849c8913 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.168 2006/05/30 12:03:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.169 2006/05/30 13:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -741,7 +741,7 @@ copy_plpgsql_datum(PLpgSQL_datum *datum)
case PLPGSQL_DTYPE_RECFIELD:
case PLPGSQL_DTYPE_ARRAYELEM:
case PLPGSQL_DTYPE_TRIGARG:
- case PLPGSQL_DTYPE_RECFIELDNAMES:
+
/*
* These datum records are read-only at runtime, so no need to
* copy them
@@ -851,7 +851,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
case PLPGSQL_DTYPE_RECFIELD:
case PLPGSQL_DTYPE_ARRAYELEM:
- case PLPGSQL_DTYPE_RECFIELDNAMES:
break;
default:
@@ -2180,8 +2179,6 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
static void
exec_eval_cleanup(PLpgSQL_execstate *estate)
{
- int i;
- ArrayType *a;
/* Clear result of a full SPI_execute */
if (estate->eval_tuptable != NULL)
SPI_freetuptable(estate->eval_tuptable);
@@ -2190,14 +2187,6 @@ exec_eval_cleanup(PLpgSQL_execstate *estate)
/* Clear result of exec_eval_simple_expr (but keep the econtext) */
if (estate->eval_econtext != NULL)
ResetExprContext(estate->eval_econtext);
- for ( i = 0; i < estate->ndatums; ++i ) {
- if ( estate->datums[i]->dtype == PLPGSQL_DTYPE_RECFIELDNAMES ) {
- a = ((PLpgSQL_recfieldproperties *)(estate->datums[i]))->save_fieldnames;
- if ( a )
- pfree(a);
- ((PLpgSQL_recfieldproperties *)(estate->datums[i]))->save_fieldnames = NULL;
- }
- }
}
@@ -3167,7 +3156,7 @@ exec_assign_value(PLpgSQL_execstate *estate,
*/
PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target;
PLpgSQL_rec *rec;
- int fno = 0;
+ int fno;
HeapTuple newtup;
int natts;
int i;
@@ -3196,35 +3185,12 @@ exec_assign_value(PLpgSQL_execstate *estate,
* Get the number of the records field to change and the
* number of attributes in the tuple.
*/
- if ( recfield->fieldindex_flag == RECFIELD_USE_FIELDNAME ) {
- fno = SPI_fnumber(rec->tupdesc, recfield->fieldindex.fieldname);
- if (fno == SPI_ERROR_NOATTRIBUTE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\" has no field \"%s\"",
- rec->refname, recfield->fieldindex.fieldname)));
- }
- else if ( recfield->fieldindex_flag == RECFIELD_USE_INDEX_VAR ) {
- PLpgSQL_var * idxvar = (PLpgSQL_var *) (estate->datums[recfield->fieldindex.indexvar_no]);
- char * fname = convert_value_to_string(idxvar->value, idxvar->datatype->typoid);
- if ( fname == NULL )
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\": cannot evaluate variable to record index string",
- rec->refname)));
- fno = SPI_fnumber(rec->tupdesc, fname);
- pfree(fname);
- if (fno == SPI_ERROR_NOATTRIBUTE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\" has no field \"%s\"",
- rec->refname, fname)));
- }
- else
+ fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
+ if (fno == SPI_ERROR_NOATTRIBUTE)
ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\": internal error",
- rec->refname)));
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("record \"%s\" has no field \"%s\"",
+ rec->refname, recfield->fieldname)));
fno--;
natts = rec->tupdesc->natts;
@@ -3544,7 +3510,7 @@ exec_eval_datum(PLpgSQL_execstate *estate,
{
PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
PLpgSQL_rec *rec;
- int fno = 0;
+ int fno;
rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
if (!HeapTupleIsValid(rec->tup))
@@ -3553,125 +3519,22 @@ exec_eval_datum(PLpgSQL_execstate *estate,
errmsg("record \"%s\" is not assigned yet",
rec->refname),
errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
- if ( recfield->fieldindex_flag == RECFIELD_USE_FIELDNAME ) {
- fno = SPI_fnumber(rec->tupdesc, recfield->fieldindex.fieldname);
- if (fno == SPI_ERROR_NOATTRIBUTE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\" has no field \"%s\"",
- rec->refname, recfield->fieldindex.fieldname)));
- }
- else if ( recfield->fieldindex_flag == RECFIELD_USE_INDEX_VAR ) {
- PLpgSQL_var * idxvar = (PLpgSQL_var *) (estate->datums[recfield->fieldindex.indexvar_no]);
- char * fname = convert_value_to_string(idxvar->value, idxvar->datatype->typoid);
- if ( fname == NULL )
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\": cannot evaluate variable to record index string",
- rec->refname)));
- fno = SPI_fnumber(rec->tupdesc, fname);
- pfree(fname);
- if (fno == SPI_ERROR_NOATTRIBUTE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\" has no field \"%s\"",
- rec->refname, fname)));
- }
- else
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\": internal error",
- rec->refname)));
-
- /* Do not allow typeids to become "narrowed" by InvalidOids
- causing specialized typeids from the tuple restricting the destination */
- if ( expectedtypeid != InvalidOid && expectedtypeid != SPI_gettypeid(rec->tupdesc, fno) ) {
- Datum cval = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull);
- cval = exec_simple_cast_value(cval,
- SPI_gettypeid(rec->tupdesc, fno),
- expectedtypeid,
- -1,
- *isnull);
-
- *value = cval;
- *typeid = expectedtypeid;
- /* ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("type of \"%s\" does not match that when preparing the plan",
- rec->refname)));
- */
- }
- else { /* expected typeid matches */
- *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull);
- *typeid = SPI_gettypeid(rec->tupdesc, fno);
- }
- break;
- }
-
- case PLPGSQL_DTYPE_RECFIELDNAMES:
- /* Construct array datum from record field names */
- {
- Oid arraytypeid,
- arrayelemtypeid = TEXTOID;
- int16 arraytyplen,
- elemtyplen;
- bool elemtypbyval;
- char elemtypalign;
- ArrayType *arrayval;
- PLpgSQL_recfieldproperties * recfp = (PLpgSQL_recfieldproperties *) datum;
- PLpgSQL_rec *rec = (PLpgSQL_rec *) (estate->datums[recfp->recparentno]);
- int fc, tfc = 0;
- Datum *arrayelems;
- char *fieldname;
-
- if (!HeapTupleIsValid(rec->tup))
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("record \"%s\" is not assigned yet",
- rec->refname),
- errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
- arrayelems = palloc(sizeof(Datum) * rec->tupdesc->natts);
- arraytypeid = get_array_type(arrayelemtypeid);
- arraytyplen = get_typlen(arraytypeid);
- get_typlenbyvalalign(arrayelemtypeid,
- &elemtyplen,
- &elemtypbyval,
- &elemtypalign);
-
- if ( expectedtypeid != InvalidOid && expectedtypeid != arraytypeid )
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("type of \"%s\" does not match array type when preparing the plan",
- rec->refname)));
- for ( fc = 0; fc < rec->tupdesc->natts; ++fc ) {
- fieldname = SPI_fname(rec->tupdesc, fc+1);
- if ( fieldname ) {
- arrayelems[fc] = DirectFunctionCall1(textin, CStringGetDatum(fieldname));
- pfree(fieldname);
- ++tfc;
- }
- }
- arrayval = construct_array(arrayelems, tfc,
- arrayelemtypeid,
- elemtyplen,
- elemtypbyval,
- elemtypalign);
-
-
- /* construct_array copies data; free temp elem array */
- for ( fc = 0; fc < tfc; ++fc )
- pfree(DatumGetPointer(arrayelems[fc]));
- pfree(arrayelems);
- *value = PointerGetDatum(arrayval);
- *typeid = arraytypeid;
- *isnull = false;
- /* need to save the pointer because otherwise it does not get freed */
- if ( recfp->save_fieldnames )
- pfree(recfp->save_fieldnames);
- recfp->save_fieldnames = arrayval;
- break;
- }
-
+ fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
+ if (fno == SPI_ERROR_NOATTRIBUTE)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("record \"%s\" has no field \"%s\"",
+ rec->refname, recfield->fieldname)));
+ *typeid = SPI_gettypeid(rec->tupdesc, fno);
+ *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull);
+ if (expectedtypeid != InvalidOid && expectedtypeid != *typeid)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("type of \"%s.%s\" does not match that when preparing the plan",
+ rec->refname, recfield->fieldname)));
+ break;
+ }
+
case PLPGSQL_DTYPE_TRIGARG:
{
PLpgSQL_trigarg *trigarg = (PLpgSQL_trigarg *) datum;
@@ -3769,29 +3632,7 @@ exec_eval_expr(PLpgSQL_execstate *estate,
*/
if (expr->plan == NULL)
exec_prepare_plan(estate, expr);
- else {
- /*
- * check for any subexpressions with varying type in the expression
- * currently (July 05), this is a record field of a record indexed by a variable
- */
- int i;
- PLpgSQL_datum *d;
- PLpgSQL_recfield *rf;
- for ( i = 0; i < expr->nparams; ++i ) {
- d = estate->datums[expr->params[i]];
- if ( d->dtype == PLPGSQL_DTYPE_RECFIELD ) {
- rf = (PLpgSQL_recfield *)d;
- if ( rf->fieldindex_flag == RECFIELD_USE_INDEX_VAR )
- break;
- }
- }
- if ( i < expr->nparams ) { /* expr may change it's type */
- /* now discard the plan and get new one */
- SPI_freeplan(expr->plan);
- expr->plan = NULL;
- exec_prepare_plan(estate, expr);
- }
- }
+
/*
* If this is a simple expression, bypass SPI and use the executor
* directly
diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c
index c2905055bdf..9420ab15cf3 100644
--- a/src/pl/plpgsql/src/pl_funcs.c
+++ b/src/pl/plpgsql/src/pl_funcs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.51 2006/05/30 12:03:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.52 2006/05/30 13:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1044,13 +1044,9 @@ plpgsql_dumptree(PLpgSQL_function *func)
printf("REC %s\n", ((PLpgSQL_rec *) d)->refname);
break;
case PLPGSQL_DTYPE_RECFIELD:
- if ( ((PLpgSQL_recfield *) d)->fieldindex_flag == RECFIELD_USE_FIELDNAME )
- printf("RECFIELD %-16s of REC %d\n",
- ((PLpgSQL_recfield *) d)->fieldindex.fieldname,
- ((PLpgSQL_recfield *) d)->recparentno);
- else
- printf("RECFIELD Variable of REC %d\n",
- ((PLpgSQL_recfield *) d)->recparentno);
+ printf("RECFIELD %-16s of REC %d\n",
+ ((PLpgSQL_recfield *) d)->fieldname,
+ ((PLpgSQL_recfield *) d)->recparentno);
break;
case PLPGSQL_DTYPE_ARRAYELEM:
printf("ARRAYELEM of VAR %d subscript ",
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 4a46597f095..86fea3ca465 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.73 2006/05/30 12:03:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.74 2006/05/30 13:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -52,8 +52,7 @@ enum
PLPGSQL_DTYPE_RECFIELD,
PLPGSQL_DTYPE_ARRAYELEM,
PLPGSQL_DTYPE_EXPR,
- PLPGSQL_DTYPE_TRIGARG,
- PLPGSQL_DTYPE_RECFIELDNAMES
+ PLPGSQL_DTYPE_TRIGARG
};
/* ----------
@@ -252,25 +251,10 @@ typedef struct
{ /* Field in record */
int dtype;
int rfno;
- union {
- char *fieldname;
- int indexvar_no; /* dno of variable holding index string */
- } fieldindex;
- enum {
- RECFIELD_USE_FIELDNAME,
- RECFIELD_USE_INDEX_VAR,
- } fieldindex_flag;
+ char *fieldname;
int recparentno; /* dno of parent record */
} PLpgSQL_recfield;
-typedef struct
-{ /* Field in record */
- int dtype;
- int rfno;
- int recparentno; /* dno of parent record */
- ArrayType * save_fieldnames;
-} PLpgSQL_recfieldproperties;
-
typedef struct
{ /* Element of array variable */
@@ -677,8 +661,6 @@ extern int plpgsql_parse_dblwordtype(char *word);
extern int plpgsql_parse_tripwordtype(char *word);
extern int plpgsql_parse_wordrowtype(char *word);
extern int plpgsql_parse_dblwordrowtype(char *word);
-extern int plpgsql_parse_recfieldnames(char *word);
-extern int plpgsql_parse_recindex(char *word);
extern PLpgSQL_type *plpgsql_parse_datatype(const char *string);
extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod);
extern PLpgSQL_variable *plpgsql_build_variable(const char *refname, int lineno,
diff --git a/src/pl/plpgsql/src/scan.l b/src/pl/plpgsql/src/scan.l
index 5202058f4c6..dfc2b942ecb 100644
--- a/src/pl/plpgsql/src/scan.l
+++ b/src/pl/plpgsql/src/scan.l
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.48 2006/05/30 12:03:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.49 2006/05/30 13:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -222,12 +222,6 @@ dump { return O_DUMP; }
{param}{space}*\.{space}*{identifier}{space}*%ROWTYPE {
plpgsql_error_lineno = plpgsql_scanner_lineno();
return plpgsql_parse_dblwordrowtype(yytext); }
-{identifier}{space}*\.\(\*\) {
- plpgsql_error_lineno = plpgsql_scanner_lineno();
- return plpgsql_parse_recfieldnames(yytext); }
-{identifier}{space}*\.\({identifier}\) {
- plpgsql_error_lineno = plpgsql_scanner_lineno();
- return plpgsql_parse_recindex(yytext); }
{digit}+ { return T_NUMBER; }
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index e20d76c0aeb..6e6597dadb2 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -2725,44 +2725,6 @@ end;
$$ language plpgsql;
ERROR: end label "outer_label" specified for unlabelled block
CONTEXT: compile of PL/pgSQL function "end_label4" near line 5
--- check introspective records
-create table ritest (i INT4, t TEXT);
-insert into ritest (i, t) VALUES (1, 'sometext');
-create function test_record() returns void as $$
-declare
- cname text;
- tval text;
- ival int4;
- tval2 text;
- ival2 int4;
- columns text[];
- r RECORD;
-begin
- SELECT INTO r * FROM ritest WHERE i = 1;
- ival := r.i;
- tval := r.t;
- RAISE NOTICE 'ival=%, tval=%', ival, tval;
- cname := 'i';
- ival2 := r.(cname);
- cname :='t';
- tval2 := r.(cname);
- RAISE NOTICE 'ival2=%, tval2=%', ival2, tval2;
- columns := r.(*);
- RAISE NOTICE 'fieldnames=%', columns;
- RETURN;
-end;
-$$ language plpgsql;
-select test_record();
-NOTICE: ival=1, tval=sometext
-NOTICE: ival2=1, tval2=sometext
-NOTICE: fieldnames={i,t}
- test_record
--------------
-
- (1 row)
-
-drop table ritest;
-drop function test_record();
-- using list of scalars in fori and fore stmts
create function for_vect() returns void as $proc$
<<lbl>>declare a integer; b varchar; c varchar; r record;
diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql
index 05460629860..19e145be65f 100644
--- a/src/test/regress/sql/plpgsql.sql
+++ b/src/test/regress/sql/plpgsql.sql
@@ -2281,38 +2281,6 @@ begin
end;
$$ language plpgsql;
--- check introspective records
-create table ritest (i INT4, t TEXT);
-insert into ritest (i, t) VALUES (1, 'sometext');
-create function test_record() returns void as $$
-declare
- cname text;
- tval text;
- ival int4;
- tval2 text;
- ival2 int4;
- columns text[];
- r RECORD;
-begin
- SELECT INTO r * FROM ritest WHERE i = 1;
- ival := r.i;
- tval := r.t;
- RAISE NOTICE 'ival=%, tval=%', ival, tval;
- cname := 'i';
- ival2 := r.(cname);
- cname :='t';
- tval2 := r.(cname);
- RAISE NOTICE 'ival2=%, tval2=%', ival2, tval2;
- columns := r.(*);
- RAISE NOTICE 'fieldnames=%', columns;
- RETURN;
-end;
-$$ language plpgsql;
-select test_record();
-drop table ritest;
-drop function test_record();
-
-
-- using list of scalars in fori and fore stmts
create function for_vect() returns void as $proc$
<<lbl>>declare a integer; b varchar; c varchar; r record;