OSDN Git Service

Back out patch, wrong previous commit message.
authorBruce Momjian <bruce@momjian.us>
Tue, 30 May 2006 11:58:05 +0000 (11:58 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 30 May 2006 11:58:05 +0000 (11:58 +0000)
doc/src/sgml/plpgsql.sgml
src/pl/plpgsql/src/pl_comp.c
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/pl_funcs.c
src/pl/plpgsql/src/plpgsql.h
src/pl/plpgsql/src/scan.l
src/test/regress/expected/plpgsql.out
src/test/regress/sql/plpgsql.sql

index ef5e9e3..aa67345 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.91 2006/05/30 11:54:51 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.92 2006/05/30 11:58:05 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
index 566379d..a9279ce 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.103 2006/05/30 11:54:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.104 2006/05/30 11:58:05 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
index 63ed3f8..afeb49f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.166 2006/05/30 11:54:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.167 2006/05/30 11:58:05 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
index 8eafb3e..3081884 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.49 2006/05/30 11:54:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.50 2006/05/30 11:58:05 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 ",
index 652f7b7..2c1f7fc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.71 2006/05/30 11:54:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.72 2006/05/30 11:58:05 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,
index c537fba..aee2c60 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.46 2006/05/30 11:54:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.47 2006/05/30 11:58:05 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;                      }
 
index e20d76c..6e6597d 100644 (file)
@@ -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;
index 0546062..19e145b 100644 (file)
@@ -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;