aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pl/plpgsql/src/gram.y70
-rw-r--r--src/pl/plpgsql/src/pl_comp.c99
-rw-r--r--src/pl/plpgsql/src/plpgsql.h16
3 files changed, 87 insertions, 98 deletions
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index 23dc8940290..dd15cf80a2f 100644
--- a/src/pl/plpgsql/src/gram.y
+++ b/src/pl/plpgsql/src/gram.y
@@ -4,7 +4,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.41 2003/03/25 03:16:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.42 2003/04/27 22:21:22 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -307,36 +307,64 @@ decl_stmt : '<' '<' opt_lblname '>' '>'
decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
{
- PLpgSQL_var *new;
+ if (!OidIsValid($3->typrelid))
+ {
+ /* Ordinary scalar datatype */
+ PLpgSQL_var *var;
- new = malloc(sizeof(PLpgSQL_var));
- memset(new, 0, sizeof(PLpgSQL_var));
+ var = malloc(sizeof(PLpgSQL_var));
+ memset(var, 0, sizeof(PLpgSQL_var));
- new->dtype = PLPGSQL_DTYPE_VAR;
- new->refname = $1.name;
- new->lineno = $1.lineno;
+ var->dtype = PLPGSQL_DTYPE_VAR;
+ var->refname = $1.name;
+ var->lineno = $1.lineno;
- new->datatype = $3;
- new->isconst = $2;
- new->notnull = $4;
- new->default_val = $5;
+ var->datatype = $3;
+ var->isconst = $2;
+ var->notnull = $4;
+ var->default_val = $5;
- plpgsql_adddatum((PLpgSQL_datum *)new);
- plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
- $1.name);
+ plpgsql_adddatum((PLpgSQL_datum *)var);
+ plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
+ var->varno,
+ $1.name);
+ }
+ else
+ {
+ /* Composite type --- treat as rowtype */
+ PLpgSQL_row *row;
+
+ row = build_rowtype($3->typrelid);
+ row->dtype = PLPGSQL_DTYPE_ROW;
+ row->refname = $1.name;
+ row->lineno = $1.lineno;
+
+ if ($2)
+ elog(ERROR, "Rowtype variable cannot be CONSTANT");
+ if ($4)
+ elog(ERROR, "Rowtype variable cannot be NOT NULL");
+ if ($5 != NULL)
+ elog(ERROR, "Default value for rowtype variable is not supported");
+
+ plpgsql_adddatum((PLpgSQL_datum *)row);
+ plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
+ row->rowno,
+ $1.name);
+
+ }
}
| decl_varname K_RECORD ';'
{
- PLpgSQL_rec *new;
+ PLpgSQL_rec *var;
- new = malloc(sizeof(PLpgSQL_rec));
+ var = malloc(sizeof(PLpgSQL_rec));
- new->dtype = PLPGSQL_DTYPE_REC;
- new->refname = $1.name;
- new->lineno = $1.lineno;
+ var->dtype = PLPGSQL_DTYPE_REC;
+ var->refname = $1.name;
+ var->lineno = $1.lineno;
- plpgsql_adddatum((PLpgSQL_datum *)new);
- plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, new->recno,
+ plpgsql_adddatum((PLpgSQL_datum *)var);
+ plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, var->recno,
$1.name);
}
| decl_varname decl_rowtype ';'
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index feb80f94ae7..5c88761e05d 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.56 2003/04/24 21:16:44 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.57 2003/04/27 22:21:22 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -81,7 +81,7 @@ PLpgSQL_function *plpgsql_curr_compile;
static void plpgsql_compile_error_callback(void *arg);
-static PLpgSQL_row *build_rowtype(Oid classOid);
+static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
/*
@@ -275,19 +275,11 @@ plpgsql_compile(Oid fn_oid, int functype)
*/
var = malloc(sizeof(PLpgSQL_var));
memset(var, 0, sizeof(PLpgSQL_var));
- var->datatype = malloc(sizeof(PLpgSQL_type));
- memset(var->datatype, 0, sizeof(PLpgSQL_type));
var->dtype = PLPGSQL_DTYPE_VAR;
var->refname = strdup(buf);
var->lineno = 0;
- var->datatype->typname = strdup(NameStr(typeStruct->typname));
- var->datatype->typoid = procStruct->proargtypes[i];
- perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
- var->datatype->typelem = typeStruct->typelem;
- var->datatype->typbyval = typeStruct->typbyval;
- var->datatype->typlen = typeStruct->typlen;
- var->datatype->atttypmod = -1;
+ var->datatype = build_datatype(typeTup, -1);
var->isconst = true;
var->notnull = false;
var->default_val = NULL;
@@ -908,7 +900,6 @@ plpgsql_parse_wordtype(char *word)
if (HeapTupleIsValid(typeTup))
{
Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
- PLpgSQL_type *typ;
if (!typeStruct->typisdefined ||
typeStruct->typrelid != InvalidOid)
@@ -918,17 +909,7 @@ plpgsql_parse_wordtype(char *word)
return T_ERROR;
}
- typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
-
- typ->typname = strdup(NameStr(typeStruct->typname));
- typ->typoid = typeOid;
- perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
- typ->typelem = typeStruct->typelem;
- typ->typbyval = typeStruct->typbyval;
- typ->typlen = typeStruct->typlen;
- typ->atttypmod = -1;
-
- plpgsql_yylval.dtype = typ;
+ plpgsql_yylval.dtype = build_datatype(typeTup, -1);
ReleaseSysCache(typeTup);
pfree(cp[0]);
@@ -960,8 +941,6 @@ plpgsql_parse_dblwordtype(char *word)
HeapTuple attrtup;
Form_pg_attribute attrStruct;
HeapTuple typetup;
- Form_pg_type typeStruct;
- PLpgSQL_type *typ;
char *cp[3];
int i;
@@ -1067,22 +1046,11 @@ plpgsql_parse_dblwordtype(char *word)
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u of %s.%s failed",
attrStruct->atttypid, cp[0], cp[1]);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
/*
* Found that - build a compiler type struct and return it
*/
- typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
-
- typ->typname = strdup(NameStr(typeStruct->typname));
- typ->typoid = attrStruct->atttypid;
- perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
- typ->typelem = typeStruct->typelem;
- typ->typbyval = typeStruct->typbyval;
- typ->typlen = typeStruct->typlen;
- typ->atttypmod = attrStruct->atttypmod;
-
- plpgsql_yylval.dtype = typ;
+ plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
ReleaseSysCache(classtup);
ReleaseSysCache(attrtup);
@@ -1107,8 +1075,6 @@ plpgsql_parse_tripwordtype(char *word)
HeapTuple attrtup;
Form_pg_attribute attrStruct;
HeapTuple typetup;
- Form_pg_type typeStruct;
- PLpgSQL_type *typ;
char *cp[2];
char *colname[1];
int qualified_att_len;
@@ -1192,22 +1158,11 @@ plpgsql_parse_tripwordtype(char *word)
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u of %s.%s failed",
attrStruct->atttypid, cp[0], cp[1]);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
/*
* Found that - build a compiler type struct and return it
*/
- typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
-
- typ->typname = strdup(NameStr(typeStruct->typname));
- typ->typoid = attrStruct->atttypid;
- perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
- typ->typelem = typeStruct->typelem;
- typ->typbyval = typeStruct->typbyval;
- typ->typlen = typeStruct->typlen;
- typ->atttypmod = attrStruct->atttypmod;
-
- plpgsql_yylval.dtype = typ;
+ plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
ReleaseSysCache(classtup);
ReleaseSysCache(attrtup);
@@ -1296,7 +1251,7 @@ plpgsql_parse_dblwordrowtype(char *word)
/*
* Build a rowtype data structure given the pg_class OID.
*/
-static PLpgSQL_row *
+PLpgSQL_row *
build_rowtype(Oid classOid)
{
PLpgSQL_row *row;
@@ -1341,7 +1296,6 @@ build_rowtype(Oid classOid)
HeapTuple attrtup;
Form_pg_attribute attrStruct;
HeapTuple typetup;
- Form_pg_type typeStruct;
const char *attname;
PLpgSQL_var *var;
@@ -1365,7 +1319,6 @@ build_rowtype(Oid classOid)
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u of %s.%s failed",
attrStruct->atttypid, relname, attname);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
/*
* Create the internal variable
@@ -1384,14 +1337,7 @@ build_rowtype(Oid classOid)
strcpy(var->refname, relname);
strcat(var->refname, ".");
strcat(var->refname, attname);
- var->datatype = malloc(sizeof(PLpgSQL_type));
- var->datatype->typname = strdup(NameStr(typeStruct->typname));
- var->datatype->typoid = attrStruct->atttypid;
- perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
- var->datatype->typelem = typeStruct->typelem;
- var->datatype->typbyval = typeStruct->typbyval;
- var->datatype->typlen = typeStruct->typlen;
- var->datatype->atttypmod = attrStruct->atttypmod;
+ var->datatype = build_datatype(typetup, attrStruct->atttypmod);
var->isconst = false;
var->notnull = false;
var->default_val = NULL;
@@ -1428,7 +1374,6 @@ plpgsql_parse_datatype(char *string)
Oid type_id;
int32 typmod;
HeapTuple typeTup;
- Form_pg_type typeStruct;
PLpgSQL_type *typ;
/* Let the main parser try to parse it under standard SQL rules */
@@ -1440,20 +1385,34 @@ plpgsql_parse_datatype(char *string)
0, 0, 0);
if (!HeapTupleIsValid(typeTup))
elog(ERROR, "cache lookup failed for type %u", type_id);
- typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
+
+ typ = build_datatype(typeTup, typmod);
+
+ ReleaseSysCache(typeTup);
+
+ return typ;
+}
+
+/*
+ * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
+ */
+static PLpgSQL_type *
+build_datatype(HeapTuple typeTup, int32 typmod)
+{
+ Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
+ PLpgSQL_type *typ;
typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
typ->typname = strdup(NameStr(typeStruct->typname));
- typ->typoid = type_id;
- perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
- typ->typelem = typeStruct->typelem;
- typ->typbyval = typeStruct->typbyval;
+ typ->typoid = HeapTupleGetOid(typeTup);
typ->typlen = typeStruct->typlen;
+ typ->typbyval = typeStruct->typbyval;
+ typ->typrelid = typeStruct->typrelid;
+ typ->typelem = typeStruct->typelem;
+ perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
typ->atttypmod = typmod;
- ReleaseSysCache(typeTup);
-
return typ;
}
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 3756d94c911..1140cebddcc 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.34 2003/04/24 21:16:44 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.35 2003/04/27 22:21:22 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -142,14 +142,15 @@ typedef struct
typedef struct
-{ /* Postgres base data type */
+{ /* Postgres data type */
char *typname;
- Oid typoid;
- FmgrInfo typinput;
- Oid typelem;
- int16 typlen;
+ Oid typoid; /* OID of the data type */
+ int16 typlen; /* stuff copied from its pg_type entry */
bool typbyval;
- int32 atttypmod;
+ Oid typrelid;
+ Oid typelem;
+ FmgrInfo typinput; /* lookup info for typinput function */
+ int32 atttypmod; /* typmod (taken from someplace else) */
} PLpgSQL_type;
@@ -600,6 +601,7 @@ extern int plpgsql_parse_tripwordtype(char *word);
extern int plpgsql_parse_wordrowtype(char *word);
extern int plpgsql_parse_dblwordrowtype(char *word);
extern PLpgSQL_type *plpgsql_parse_datatype(char *string);
+extern PLpgSQL_row *build_rowtype(Oid classOid);
extern void plpgsql_adddatum(PLpgSQL_datum * new);
extern int plpgsql_add_initdatums(int **varnos);
extern void plpgsql_yyerror(const char *s);