1 /**********************************************************************
2 * pl_comp.c - Compiler part of the PL/pgSQL
6 * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.50 2002/09/01 16:28:06 tgl Exp $
8 * This software is copyrighted by Jan Wieck - Hamburg.
10 * The author hereby grants permission to use, copy, modify,
11 * distribute, and license this software and its documentation
12 * for any purpose, provided that existing copyright notices are
13 * retained in all copies and that this notice is included
14 * verbatim in any distributions. No written agreement, license,
15 * or royalty fee is required for any of the authorized uses.
16 * Modifications to this software may be copyrighted by their
17 * author and need not follow the licensing terms described
18 * here, provided that the new terms are clearly indicated on
19 * the first page of each file where they apply.
21 * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
22 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
23 * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
24 * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
25 * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
28 * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
31 * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
32 * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
33 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
34 * ENHANCEMENTS, OR MODIFICATIONS.
36 **********************************************************************/
45 #include "access/heapam.h"
46 #include "catalog/catname.h"
47 #include "catalog/namespace.h"
48 #include "catalog/pg_attribute.h"
49 #include "catalog/pg_attrdef.h"
50 #include "catalog/pg_class.h"
51 #include "catalog/pg_proc.h"
52 #include "catalog/pg_type.h"
53 #include "nodes/makefuncs.h"
54 #include "parser/gramparse.h"
55 #include "parser/parse_type.h"
56 #include "tcop/tcopprot.h"
57 #include "utils/builtins.h"
58 #include "utils/syscache.h"
62 * Variables in the parser that shouldn't go into plpgsql.h
65 extern PLPGSQL_YYSTYPE plpgsql_yylval;
68 * Our own local and global variables
71 static int datums_alloc;
73 PLpgSQL_datum **plpgsql_Datums;
74 static int datums_last = 0;
76 int plpgsql_error_lineno;
77 char *plpgsql_error_funcname;
78 int plpgsql_DumpExecTree = 0;
80 PLpgSQL_function *plpgsql_curr_compile;
83 static PLpgSQL_row *build_rowtype(Oid classOid);
87 * This routine is a crock, and so is everyplace that calls it. The problem
88 * is that the compiled form of a plpgsql function is allocated permanently
89 * (mostly via malloc()) and never released until backend exit. Subsidiary
90 * data structures such as fmgr info records therefore must live forever
91 * as well. A better implementation would store all this stuff in a per-
92 * function memory context that could be reclaimed at need. In the meantime,
93 * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
94 * it might allocate, and whatever the eventual function might allocate using
95 * fn_mcxt, will live forever too.
98 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
100 fmgr_info_cxt(functionId, finfo, TopMemoryContext);
105 * plpgsql_compile Given a pg_proc's oid, make
106 * an execution tree for it.
110 plpgsql_compile(Oid fn_oid, int functype)
114 Form_pg_proc procStruct;
116 Form_pg_type typeStruct;
118 PLpgSQL_function *function;
123 int arg_varnos[FUNC_MAX_ARGS];
124 sigjmp_buf save_restart;
127 * Lookup the pg_proc tuple by Oid
129 procTup = SearchSysCache(PROCOID,
130 ObjectIdGetDatum(fn_oid),
132 if (!HeapTupleIsValid(procTup))
133 elog(ERROR, "plpgsql: cache lookup for proc %u failed", fn_oid);
136 * Setup the scanner input and error info
138 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
139 proc_source = DatumGetCString(DirectFunctionCall1(textout,
140 PointerGetDatum(&procStruct->prosrc)));
141 plpgsql_setinput(proc_source, functype);
142 plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
143 plpgsql_error_lineno = 0;
146 * Catch elog() so we can provide notice about where the error is
148 memcpy(&save_restart, &Warn_restart, sizeof(save_restart));
149 if (sigsetjmp(Warn_restart, 1) != 0)
151 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
154 * If we are the first of cascaded error catchings, print where
157 if (plpgsql_error_funcname != NULL)
159 elog(WARNING, "plpgsql: ERROR during compile of %s near line %d",
160 plpgsql_error_funcname, plpgsql_error_lineno);
162 plpgsql_error_funcname = NULL;
165 siglongjmp(Warn_restart, 1);
169 * Initialize the compiler
172 plpgsql_ns_push(NULL);
173 plpgsql_DumpExecTree = 0;
177 plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
181 * Create the new function node
183 function = malloc(sizeof(PLpgSQL_function));
184 memset(function, 0, sizeof(PLpgSQL_function));
185 plpgsql_curr_compile = function;
187 function->fn_name = strdup(NameStr(procStruct->proname));
188 function->fn_oid = fn_oid;
189 function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
190 function->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
191 function->fn_functype = functype;
198 * Normal function has a defined returntype
200 function->fn_rettype = procStruct->prorettype;
201 function->fn_retset = procStruct->proretset;
204 * Lookup the functions return type
206 typeTup = SearchSysCache(TYPEOID,
207 ObjectIdGetDatum(procStruct->prorettype),
209 if (!HeapTupleIsValid(typeTup))
210 elog(ERROR, "cache lookup for return type %u failed",
211 procStruct->prorettype);
212 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
214 /* Disallow pseudotype result, except VOID or RECORD */
215 if (typeStruct->typtype == 'p')
217 if (procStruct->prorettype == VOIDOID ||
218 procStruct->prorettype == RECORDOID)
220 else if (procStruct->prorettype == TRIGGEROID ||
221 procStruct->prorettype == OPAQUEOID)
222 elog(ERROR, "plpgsql functions cannot return type %s"
223 "\n\texcept when used as triggers",
224 format_type_be(procStruct->prorettype));
226 elog(ERROR, "plpgsql functions cannot return type %s",
227 format_type_be(procStruct->prorettype));
230 if (typeStruct->typrelid != InvalidOid ||
231 procStruct->prorettype == RECORDOID)
232 function->fn_retistuple = true;
235 function->fn_retbyval = typeStruct->typbyval;
236 function->fn_rettyplen = typeStruct->typlen;
237 function->fn_rettypelem = typeStruct->typelem;
238 perm_fmgr_info(typeStruct->typinput, &(function->fn_retinput));
240 ReleaseSysCache(typeTup);
243 * Create the variables for the procedures parameters
245 for (i = 0; i < procStruct->pronargs; i++)
249 snprintf(buf, sizeof(buf), "$%d", i + 1); /* name for variable */
252 * Get the parameters type
254 typeTup = SearchSysCache(TYPEOID,
255 ObjectIdGetDatum(procStruct->proargtypes[i]),
257 if (!HeapTupleIsValid(typeTup))
258 elog(ERROR, "cache lookup for argument type %u failed",
259 procStruct->proargtypes[i]);
260 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
262 /* Disallow pseudotype argument */
263 if (typeStruct->typtype == 'p')
264 elog(ERROR, "plpgsql functions cannot take type %s",
265 format_type_be(procStruct->proargtypes[i]));
267 if (typeStruct->typrelid != InvalidOid)
270 * For tuple type parameters, we set up a record of
273 row = build_rowtype(typeStruct->typrelid);
275 row->refname = strdup(buf);
277 plpgsql_adddatum((PLpgSQL_datum *) row);
278 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, row->rowno,
281 arg_varnos[i] = row->rowno;
286 * Normal parameters get a var node
288 var = malloc(sizeof(PLpgSQL_var));
289 memset(var, 0, sizeof(PLpgSQL_var));
290 var->datatype = malloc(sizeof(PLpgSQL_type));
291 memset(var->datatype, 0, sizeof(PLpgSQL_type));
293 var->dtype = PLPGSQL_DTYPE_VAR;
294 var->refname = strdup(buf);
296 var->datatype->typname = strdup(NameStr(typeStruct->typname));
297 var->datatype->typoid = procStruct->proargtypes[i];
298 perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
299 var->datatype->typelem = typeStruct->typelem;
300 var->datatype->typbyval = typeStruct->typbyval;
301 var->datatype->typlen = typeStruct->typlen;
302 var->datatype->atttypmod = -1;
304 var->notnull = false;
305 var->default_val = NULL;
307 plpgsql_adddatum((PLpgSQL_datum *) var);
308 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno,
311 arg_varnos[i] = var->varno;
313 ReleaseSysCache(typeTup);
320 * Trigger procedures return type is unknown yet
322 function->fn_rettype = InvalidOid;
323 function->fn_retbyval = false;
324 function->fn_retistuple = true;
325 function->fn_retset = false;
328 * Add the record for referencing NEW
330 rec = malloc(sizeof(PLpgSQL_rec));
331 memset(rec, 0, sizeof(PLpgSQL_rec));
332 rec->dtype = PLPGSQL_DTYPE_REC;
333 rec->refname = strdup("new");
336 rec->freetup = false;
337 plpgsql_adddatum((PLpgSQL_datum *) rec);
338 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
339 function->new_varno = rec->recno;
342 * Add the record for referencing OLD
344 rec = malloc(sizeof(PLpgSQL_rec));
345 memset(rec, 0, sizeof(PLpgSQL_rec));
346 rec->dtype = PLPGSQL_DTYPE_REC;
347 rec->refname = strdup("old");
350 rec->freetup = false;
351 plpgsql_adddatum((PLpgSQL_datum *) rec);
352 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
353 function->old_varno = rec->recno;
356 * Add the variable tg_name
358 var = malloc(sizeof(PLpgSQL_var));
359 memset(var, 0, sizeof(PLpgSQL_var));
361 var->dtype = PLPGSQL_DTYPE_VAR;
362 var->refname = strdup("tg_name");
364 var->datatype = plpgsql_parse_datatype("name");
365 var->isconst = false;
366 var->notnull = false;
367 var->default_val = NULL;
369 plpgsql_adddatum((PLpgSQL_datum *) var);
370 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
371 function->tg_name_varno = var->varno;
374 * Add the variable tg_when
376 var = malloc(sizeof(PLpgSQL_var));
377 memset(var, 0, sizeof(PLpgSQL_var));
379 var->dtype = PLPGSQL_DTYPE_VAR;
380 var->refname = strdup("tg_when");
382 var->datatype = plpgsql_parse_datatype("text");
383 var->isconst = false;
384 var->notnull = false;
385 var->default_val = NULL;
387 plpgsql_adddatum((PLpgSQL_datum *) var);
388 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
389 function->tg_when_varno = var->varno;
392 * Add the variable tg_level
394 var = malloc(sizeof(PLpgSQL_var));
395 memset(var, 0, sizeof(PLpgSQL_var));
397 var->dtype = PLPGSQL_DTYPE_VAR;
398 var->refname = strdup("tg_level");
400 var->datatype = plpgsql_parse_datatype("text");
401 var->isconst = false;
402 var->notnull = false;
403 var->default_val = NULL;
405 plpgsql_adddatum((PLpgSQL_datum *) var);
406 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
407 function->tg_level_varno = var->varno;
410 * Add the variable tg_op
412 var = malloc(sizeof(PLpgSQL_var));
413 memset(var, 0, sizeof(PLpgSQL_var));
415 var->dtype = PLPGSQL_DTYPE_VAR;
416 var->refname = strdup("tg_op");
418 var->datatype = plpgsql_parse_datatype("text");
419 var->isconst = false;
420 var->notnull = false;
421 var->default_val = NULL;
423 plpgsql_adddatum((PLpgSQL_datum *) var);
424 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
425 function->tg_op_varno = var->varno;
428 * Add the variable tg_relid
430 var = malloc(sizeof(PLpgSQL_var));
431 memset(var, 0, sizeof(PLpgSQL_var));
433 var->dtype = PLPGSQL_DTYPE_VAR;
434 var->refname = strdup("tg_relid");
436 var->datatype = plpgsql_parse_datatype("oid");
437 var->isconst = false;
438 var->notnull = false;
439 var->default_val = NULL;
441 plpgsql_adddatum((PLpgSQL_datum *) var);
442 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
443 function->tg_relid_varno = var->varno;
446 * Add the variable tg_relname
448 var = malloc(sizeof(PLpgSQL_var));
449 memset(var, 0, sizeof(PLpgSQL_var));
451 var->dtype = PLPGSQL_DTYPE_VAR;
452 var->refname = strdup("tg_relname");
454 var->datatype = plpgsql_parse_datatype("name");
455 var->isconst = false;
456 var->notnull = false;
457 var->default_val = NULL;
459 plpgsql_adddatum((PLpgSQL_datum *) var);
460 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
461 function->tg_relname_varno = var->varno;
464 * Add the variable tg_nargs
466 var = malloc(sizeof(PLpgSQL_var));
467 memset(var, 0, sizeof(PLpgSQL_var));
469 var->dtype = PLPGSQL_DTYPE_VAR;
470 var->refname = strdup("tg_nargs");
472 var->datatype = plpgsql_parse_datatype("int4");
473 var->isconst = false;
474 var->notnull = false;
475 var->default_val = NULL;
477 plpgsql_adddatum((PLpgSQL_datum *) var);
478 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
479 function->tg_nargs_varno = var->varno;
484 elog(ERROR, "unknown function type %u in plpgsql_compile()",
490 * Create the magic FOUND variable.
492 var = malloc(sizeof(PLpgSQL_var));
493 memset(var, 0, sizeof(PLpgSQL_var));
495 var->dtype = PLPGSQL_DTYPE_VAR;
496 var->refname = strdup("found");
498 var->datatype = plpgsql_parse_datatype("bool");
499 var->isconst = false;
500 var->notnull = false;
501 var->default_val = NULL;
503 plpgsql_adddatum((PLpgSQL_datum *) var);
504 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
505 function->found_varno = var->varno;
508 * Forget about the above created variables
510 plpgsql_add_initdatums(NULL);
513 * Now parse the functions text
515 parse_rc = plpgsql_yyparse();
517 elog(ERROR, "plpgsql: parser returned %d ???", parse_rc);
520 * If that was successful, complete the functions info.
522 function->fn_nargs = procStruct->pronargs;
523 for (i = 0; i < function->fn_nargs; i++)
524 function->fn_argvarnos[i] = arg_varnos[i];
525 function->ndatums = plpgsql_nDatums;
526 function->datums = malloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
527 for (i = 0; i < plpgsql_nDatums; i++)
528 function->datums[i] = plpgsql_Datums[i];
529 function->action = plpgsql_yylval.program;
531 ReleaseSysCache(procTup);
534 * Restore the previous elog() jump target
536 plpgsql_error_funcname = NULL;
537 plpgsql_error_lineno = 0;
538 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
541 * Finally return the compiled function
543 if (plpgsql_DumpExecTree)
544 plpgsql_dumptree(function);
550 * plpgsql_parse_word The scanner calls this to postparse
551 * any single word not found by a
556 plpgsql_parse_word(char *word)
561 /* Do case conversion and word separation */
562 plpgsql_convert_ident(word, cp, 1);
565 * Recognize tg_argv when compiling triggers
567 if (plpgsql_curr_compile->fn_functype == T_TRIGGER)
569 if (strcmp(cp[0], "tg_argv") == 0)
571 int save_spacescanned = plpgsql_SpaceScanned;
572 PLpgSQL_trigarg *trigarg;
574 trigarg = malloc(sizeof(PLpgSQL_trigarg));
575 memset(trigarg, 0, sizeof(PLpgSQL_trigarg));
576 trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
578 if (plpgsql_yylex() != '[')
579 plpgsql_yyerror("expected [");
581 trigarg->argnum = plpgsql_read_expression(']', "]");
583 plpgsql_adddatum((PLpgSQL_datum *) trigarg);
584 plpgsql_yylval.variable = (PLpgSQL_datum *) trigarg;
586 plpgsql_SpaceScanned = save_spacescanned;
593 * Do a lookup on the compilers namestack
595 nse = plpgsql_ns_lookup(cp[0], NULL);
599 switch (nse->itemtype)
601 case PLPGSQL_NSTYPE_LABEL:
604 case PLPGSQL_NSTYPE_VAR:
605 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[nse->itemno]);
608 case PLPGSQL_NSTYPE_REC:
609 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
612 case PLPGSQL_NSTYPE_ROW:
613 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
622 * Nothing found - up to now it's a word without any special meaning
631 * plpgsql_parse_dblword Same lookup for two words
632 * separated by a dot.
636 plpgsql_parse_dblword(char *word)
641 /* Do case conversion and word separation */
642 plpgsql_convert_ident(word, cp, 2);
645 * Lookup the first word
647 ns = plpgsql_ns_lookup(cp[0], NULL);
655 switch (ns->itemtype)
657 case PLPGSQL_NSTYPE_LABEL:
660 * First word is a label, so second word could be a variable,
661 * record or row in that bodies namestack. Anything else could
662 * only be something in a query given to the SPI manager and
663 * T_ERROR will get eaten up by the collector routines.
665 ns = plpgsql_ns_lookup(cp[1], cp[0]);
670 switch (ns->itemtype)
672 case PLPGSQL_NSTYPE_VAR:
673 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[ns->itemno]);
676 case PLPGSQL_NSTYPE_REC:
677 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
680 case PLPGSQL_NSTYPE_ROW:
681 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
689 case PLPGSQL_NSTYPE_REC:
692 * First word is a record name, so second word must be a
693 * field in this record.
695 PLpgSQL_recfield *new;
697 new = malloc(sizeof(PLpgSQL_recfield));
698 new->dtype = PLPGSQL_DTYPE_RECFIELD;
699 new->fieldname = strdup(cp[1]);
700 new->recno = ns->itemno;
702 plpgsql_adddatum((PLpgSQL_datum *) new);
704 plpgsql_yylval.variable = (PLpgSQL_datum *) new;
711 case PLPGSQL_NSTYPE_ROW:
714 * First word is a row name, so second word must be a
720 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
721 for (i = 0; i < row->nfields; i++)
723 if (strcmp(row->fieldnames[i], cp[1]) == 0)
725 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[row->varnos[i]]);
731 elog(ERROR, "row %s doesn't have a field %s",
746 * plpgsql_parse_tripword Same lookup for three words
751 plpgsql_parse_tripword(char *word)
756 /* Do case conversion and word separation */
757 plpgsql_convert_ident(word, cp, 3);
760 * Lookup the first word - it must be a label
762 ns = plpgsql_ns_lookup(cp[0], NULL);
770 if (ns->itemtype != PLPGSQL_NSTYPE_LABEL)
779 * First word is a label, so second word could be a record or row
781 ns = plpgsql_ns_lookup(cp[1], cp[0]);
790 switch (ns->itemtype)
792 case PLPGSQL_NSTYPE_REC:
795 * This word is a record name, so third word must be a
796 * field in this record.
798 PLpgSQL_recfield *new;
800 new = malloc(sizeof(PLpgSQL_recfield));
801 new->dtype = PLPGSQL_DTYPE_RECFIELD;
802 new->fieldname = strdup(cp[2]);
803 new->recno = ns->itemno;
805 plpgsql_adddatum((PLpgSQL_datum *) new);
807 plpgsql_yylval.variable = (PLpgSQL_datum *) new;
815 case PLPGSQL_NSTYPE_ROW:
818 * This word is a row name, so third word must be a field
824 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
825 for (i = 0; i < row->nfields; i++)
827 if (strcmp(row->fieldnames[i], cp[2]) == 0)
829 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[row->varnos[i]]);
836 elog(ERROR, "row %s.%s doesn't have a field %s",
837 cp[0], cp[1], cp[2]);
852 * plpgsql_parse_wordtype The scanner found word%TYPE. word can be
853 * a variable name or a basetype.
857 plpgsql_parse_wordtype(char *word)
865 /* Do case conversion and word separation */
866 /* We convert %type to .type momentarily to keep converter happy */
867 i = strlen(word) - 5;
868 Assert(word[i] == '%');
870 plpgsql_convert_ident(word, cp, 2);
875 * Do a lookup on the compilers namestack. But ensure it moves up to
878 old_nsstate = plpgsql_ns_setlocal(false);
879 nse = plpgsql_ns_lookup(cp[0], NULL);
880 plpgsql_ns_setlocal(old_nsstate);
885 switch (nse->itemtype)
887 case PLPGSQL_NSTYPE_VAR:
888 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
897 * Word wasn't found on the namestack. Try to find a data type with
898 * that name, but ignore pg_type entries that are in fact class types.
900 typeOid = LookupTypeName(makeTypeName(cp[0]));
901 if (OidIsValid(typeOid))
905 typeTup = SearchSysCache(TYPEOID,
906 ObjectIdGetDatum(typeOid),
908 if (HeapTupleIsValid(typeTup))
910 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
913 if (!typeStruct->typisdefined ||
914 typeStruct->typrelid != InvalidOid)
916 ReleaseSysCache(typeTup);
921 typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
923 typ->typname = strdup(NameStr(typeStruct->typname));
924 typ->typoid = typeOid;
925 perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
926 typ->typelem = typeStruct->typelem;
927 typ->typbyval = typeStruct->typbyval;
928 typ->typlen = typeStruct->typlen;
931 plpgsql_yylval.dtype = typ;
933 ReleaseSysCache(typeTup);
940 * Nothing found - up to now it's a word without any special meaning
949 * plpgsql_parse_dblwordtype Same lookup for word.word%TYPE
953 plpgsql_parse_dblwordtype(char *word)
959 Form_pg_class classStruct;
961 Form_pg_attribute attrStruct;
963 Form_pg_type typeStruct;
968 /* Do case conversion and word separation */
969 /* We convert %type to .type momentarily to keep converter happy */
970 i = strlen(word) - 5;
971 Assert(word[i] == '%');
973 plpgsql_convert_ident(word, cp, 3);
978 * Lookup the first word
980 nse = plpgsql_ns_lookup(cp[0], NULL);
983 * If this is a label lookup the second word in that labels namestack
988 if (nse->itemtype == PLPGSQL_NSTYPE_LABEL)
990 old_nsstate = plpgsql_ns_setlocal(false);
991 nse = plpgsql_ns_lookup(cp[1], cp[0]);
992 plpgsql_ns_setlocal(old_nsstate);
999 switch (nse->itemtype)
1001 case PLPGSQL_NSTYPE_VAR:
1002 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1017 * First word could also be a table name
1019 classOid = RelnameGetRelid(cp[0]);
1020 if (!OidIsValid(classOid))
1026 classtup = SearchSysCache(RELOID,
1027 ObjectIdGetDatum(classOid),
1029 if (!HeapTupleIsValid(classtup))
1037 * It must be a relation, sequence, view, or type
1039 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1040 if (classStruct->relkind != RELKIND_RELATION &&
1041 classStruct->relkind != RELKIND_SEQUENCE &&
1042 classStruct->relkind != RELKIND_VIEW &&
1043 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1045 ReleaseSysCache(classtup);
1052 * Fetch the named table field and it's type
1054 attrtup = SearchSysCacheAttName(classOid, cp[1]);
1055 if (!HeapTupleIsValid(attrtup))
1057 ReleaseSysCache(classtup);
1062 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1064 typetup = SearchSysCache(TYPEOID,
1065 ObjectIdGetDatum(attrStruct->atttypid),
1067 if (!HeapTupleIsValid(typetup))
1068 elog(ERROR, "cache lookup for type %u of %s.%s failed",
1069 attrStruct->atttypid, cp[0], cp[1]);
1070 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
1073 * Found that - build a compiler type struct and return it
1075 typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
1077 typ->typname = strdup(NameStr(typeStruct->typname));
1078 typ->typoid = attrStruct->atttypid;
1079 perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
1080 typ->typelem = typeStruct->typelem;
1081 typ->typbyval = typeStruct->typbyval;
1082 typ->typlen = typeStruct->typlen;
1083 typ->atttypmod = attrStruct->atttypmod;
1085 plpgsql_yylval.dtype = typ;
1087 ReleaseSysCache(classtup);
1088 ReleaseSysCache(attrtup);
1089 ReleaseSysCache(typetup);
1097 * plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
1098 * So word must be a table name.
1102 plpgsql_parse_wordrowtype(char *word)
1108 /* Do case conversion and word separation */
1109 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1110 i = strlen(word) - 8;
1111 Assert(word[i] == '%');
1113 plpgsql_convert_ident(word, cp, 2);
1116 /* Lookup the relation */
1117 classOid = RelnameGetRelid(cp[0]);
1118 if (!OidIsValid(classOid))
1119 elog(ERROR, "%s: no such class", cp[0]);
1122 * Build and return the complete row definition
1124 plpgsql_yylval.row = build_rowtype(classOid);
1133 * Build a rowtype data structure given the pg_class OID.
1135 static PLpgSQL_row *
1136 build_rowtype(Oid classOid)
1140 Form_pg_class classStruct;
1141 const char *relname;
1145 * Fetch the pg_class tuple.
1147 classtup = SearchSysCache(RELOID,
1148 ObjectIdGetDatum(classOid),
1150 if (!HeapTupleIsValid(classtup))
1151 elog(ERROR, "cache lookup failed for relation %u", classOid);
1152 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1153 relname = NameStr(classStruct->relname);
1155 /* accept relation, sequence, view, or type pg_class entries */
1156 if (classStruct->relkind != RELKIND_RELATION &&
1157 classStruct->relkind != RELKIND_SEQUENCE &&
1158 classStruct->relkind != RELKIND_VIEW &&
1159 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1160 elog(ERROR, "%s isn't a table", relname);
1163 * Create a row datum entry and all the required variables that it
1166 row = malloc(sizeof(PLpgSQL_row));
1167 memset(row, 0, sizeof(PLpgSQL_row));
1169 row->dtype = PLPGSQL_DTYPE_ROW;
1170 row->nfields = classStruct->relnatts;
1171 row->rowtypeclass = classStruct->reltype;
1172 row->fieldnames = malloc(sizeof(char *) * row->nfields);
1173 row->varnos = malloc(sizeof(int) * row->nfields);
1175 for (i = 0; i < row->nfields; i++)
1178 Form_pg_attribute attrStruct;
1180 Form_pg_type typeStruct;
1181 const char *attname;
1185 * Get the attribute and it's type
1187 attrtup = SearchSysCache(ATTNUM,
1188 ObjectIdGetDatum(classOid),
1189 Int16GetDatum(i + 1),
1191 if (!HeapTupleIsValid(attrtup))
1192 elog(ERROR, "cache lookup for attribute %d of class %s failed",
1194 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1196 attname = NameStr(attrStruct->attname);
1198 typetup = SearchSysCache(TYPEOID,
1199 ObjectIdGetDatum(attrStruct->atttypid),
1201 if (!HeapTupleIsValid(typetup))
1202 elog(ERROR, "cache lookup for type %u of %s.%s failed",
1203 attrStruct->atttypid, relname, attname);
1204 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
1207 * Create the internal variable
1209 * We know if the table definitions contain a default value or if the
1210 * field is declared in the table as NOT NULL. But it's possible
1211 * to create a table field as NOT NULL without a default value and
1212 * that would lead to problems later when initializing the
1213 * variables due to entering a block at execution time. Thus we
1214 * ignore this information for now.
1216 var = malloc(sizeof(PLpgSQL_var));
1217 memset(var, 0, sizeof(PLpgSQL_var));
1218 var->dtype = PLPGSQL_DTYPE_VAR;
1219 var->refname = malloc(strlen(relname) + strlen(attname) + 2);
1220 strcpy(var->refname, relname);
1221 strcat(var->refname, ".");
1222 strcat(var->refname, attname);
1223 var->datatype = malloc(sizeof(PLpgSQL_type));
1224 var->datatype->typname = strdup(NameStr(typeStruct->typname));
1225 var->datatype->typoid = attrStruct->atttypid;
1226 perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
1227 var->datatype->typelem = typeStruct->typelem;
1228 var->datatype->typbyval = typeStruct->typbyval;
1229 var->datatype->typlen = typeStruct->typlen;
1230 var->datatype->atttypmod = attrStruct->atttypmod;
1231 var->isconst = false;
1232 var->notnull = false;
1233 var->default_val = NULL;
1234 var->value = (Datum) 0;
1236 var->freeval = false;
1238 plpgsql_adddatum((PLpgSQL_datum *) var);
1241 * Add the variable to the row.
1243 row->fieldnames[i] = strdup(attname);
1244 row->varnos[i] = var->varno;
1246 ReleaseSysCache(typetup);
1247 ReleaseSysCache(attrtup);
1250 ReleaseSysCache(classtup);
1257 * plpgsql_parse_datatype Scanner found something that should
1258 * be a datatype name.
1262 plpgsql_parse_datatype(char *string)
1267 Form_pg_type typeStruct;
1270 /* Let the main parser try to parse it under standard SQL rules */
1271 parseTypeString(string, &type_id, &typmod);
1273 /* Okay, build a PLpgSQL_type data structure for it */
1274 typeTup = SearchSysCache(TYPEOID,
1275 ObjectIdGetDatum(type_id),
1277 if (!HeapTupleIsValid(typeTup))
1278 elog(ERROR, "cache lookup failed for type %u", type_id);
1279 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1281 typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
1283 typ->typname = strdup(NameStr(typeStruct->typname));
1284 typ->typoid = type_id;
1285 perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
1286 typ->typelem = typeStruct->typelem;
1287 typ->typbyval = typeStruct->typbyval;
1288 typ->typlen = typeStruct->typlen;
1289 typ->atttypmod = typmod;
1291 ReleaseSysCache(typeTup);
1298 * plpgsql_adddatum Add a variable, record or row
1299 * to the compilers datum list.
1303 plpgsql_adddatum(PLpgSQL_datum * new)
1305 if (plpgsql_nDatums == datums_alloc)
1308 plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
1311 new->dno = plpgsql_nDatums;
1312 plpgsql_Datums[plpgsql_nDatums++] = new;
1317 * plpgsql_add_initdatums Put all datum entries created
1318 * since the last call into the
1319 * finishing code block so the
1320 * block knows which variables to
1321 * reinitialize when entered.
1325 plpgsql_add_initdatums(int **varnos)
1330 for (i = datums_last; i < plpgsql_nDatums; i++)
1332 switch (plpgsql_Datums[i]->dtype)
1334 case PLPGSQL_DTYPE_VAR:
1345 *varnos = (int *) malloc(sizeof(int) * n);
1348 for (i = datums_last; i < plpgsql_nDatums; i++)
1350 switch (plpgsql_Datums[i]->dtype)
1352 case PLPGSQL_DTYPE_VAR:
1353 (*varnos)[n++] = plpgsql_Datums[i]->dno;
1361 datums_last = plpgsql_nDatums;
1367 * plpgsql_yyerror Handle parser error
1372 plpgsql_yyerror(const char *s)
1374 plpgsql_error_lineno = plpgsql_yylineno;
1375 elog(ERROR, "%s at or near \"%s\"", s, plpgsql_yytext);