1 /*-------------------------------------------------------------------------
3 * pl_funcs.c - Misc functions for the PL/pgSQL
6 * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.61 2007/07/16 17:01:11 tgl Exp $
13 *-------------------------------------------------------------------------
21 #include "parser/scansup.h"
25 * Local variables for the namestack handling
28 static PLpgSQL_ns *ns_current = NULL;
29 static bool ns_localmode = false;
33 * plpgsql_dstring_init Dynamic string initialization
37 plpgsql_dstring_init(PLpgSQL_dstring *ds)
39 ds->value = palloc(ds->alloc = 512);
46 * plpgsql_dstring_free Dynamic string destruction
50 plpgsql_dstring_free(PLpgSQL_dstring *ds)
56 plpgsql_dstring_expand(PLpgSQL_dstring *ds, int needed)
58 /* Don't allow truncating the string */
59 Assert(needed > ds->alloc);
60 Assert(ds->used <= ds->alloc);
62 /* Might have to double more than once, if needed is large */
66 } while (needed > ds->alloc);
67 ds->value = repalloc(ds->value, ds->alloc);
71 * plpgsql_dstring_append Dynamic string extending
75 plpgsql_dstring_append(PLpgSQL_dstring *ds, const char *str)
77 int len = strlen(str);
78 int needed = ds->used + len;
80 if (needed > ds->alloc)
81 plpgsql_dstring_expand(ds, needed);
83 memcpy(&(ds->value[ds->used - 1]), str, len);
85 ds->value[ds->used - 1] = '\0';
89 * plpgsql_dstring_append_char Append a single character
94 plpgsql_dstring_append_char(PLpgSQL_dstring *ds, char c)
96 if (ds->used == ds->alloc)
97 plpgsql_dstring_expand(ds, ds->used + 1);
99 ds->value[ds->used - 1] = c;
100 ds->value[ds->used] = '\0';
106 * plpgsql_dstring_get Dynamic string get value
110 plpgsql_dstring_get(PLpgSQL_dstring *ds)
117 * plpgsql_ns_init Initialize the namestack
121 plpgsql_ns_init(void)
124 ns_localmode = false;
129 * plpgsql_ns_setlocal Tell plpgsql_ns_lookup to or to
130 * not look into the current level
135 plpgsql_ns_setlocal(bool flag)
139 oldstate = ns_localmode;
146 * plpgsql_ns_push Enter a new namestack level
150 plpgsql_ns_push(const char *label)
157 new = palloc0(sizeof(PLpgSQL_ns));
158 new->upper = ns_current;
161 plpgsql_ns_additem(PLPGSQL_NSTYPE_LABEL, 0, label);
166 * plpgsql_ns_pop Return to the previous level
176 ns_current = old->upper;
178 for (i = 0; i < old->items_used; i++)
179 pfree(old->items[i]);
186 * plpgsql_ns_additem Add an item to the current
191 plpgsql_ns_additem(int itemtype, int itemno, const char *name)
193 PLpgSQL_ns *ns = ns_current;
196 Assert(name != NULL);
198 if (ns->items_used == ns->items_alloc)
200 if (ns->items_alloc == 0)
202 ns->items_alloc = 32;
203 ns->items = palloc(sizeof(PLpgSQL_nsitem *) * ns->items_alloc);
207 ns->items_alloc *= 2;
208 ns->items = repalloc(ns->items,
209 sizeof(PLpgSQL_nsitem *) * ns->items_alloc);
213 nse = palloc(sizeof(PLpgSQL_nsitem) + strlen(name));
214 nse->itemtype = itemtype;
215 nse->itemno = itemno;
216 strcpy(nse->name, name);
217 ns->items[ns->items_used++] = nse;
222 * plpgsql_ns_lookup Lookup for a word in the namestack
226 plpgsql_ns_lookup(const char *name, const char *label)
232 * If a label is specified, lookup only in that
236 for (ns = ns_current; ns != NULL; ns = ns->upper)
238 if (strcmp(ns->items[0]->name, label) == 0)
240 for (i = 1; i < ns->items_used; i++)
242 if (strcmp(ns->items[i]->name, name) == 0)
245 return NULL; /* name not found in specified label */
248 return NULL; /* label not found */
252 * No label given, lookup for visible labels ignoring localmode
254 for (ns = ns_current; ns != NULL; ns = ns->upper)
256 if (strcmp(ns->items[0]->name, name) == 0)
261 * Finally lookup name in the namestack
263 for (ns = ns_current; ns != NULL; ns = ns->upper)
265 for (i = 1; i < ns->items_used; i++)
267 if (strcmp(ns->items[i]->name, name) == 0)
271 return NULL; /* name not found in current namespace */
279 * plpgsql_ns_rename Rename a namespace entry
283 plpgsql_ns_rename(char *oldname, char *newname)
286 PLpgSQL_nsitem *newitem;
290 * Lookup name in the namestack
292 for (ns = ns_current; ns != NULL; ns = ns->upper)
294 for (i = 1; i < ns->items_used; i++)
296 if (strcmp(ns->items[i]->name, oldname) == 0)
298 newitem = palloc(sizeof(PLpgSQL_nsitem) + strlen(newname));
299 newitem->itemtype = ns->items[i]->itemtype;
300 newitem->itemno = ns->items[i]->itemno;
301 strcpy(newitem->name, newname);
307 ns->items[i] = newitem;
314 (errcode(ERRCODE_UNDEFINED_OBJECT),
315 errmsg("there is no variable \"%s\" in the current block",
321 * plpgsql_convert_ident
323 * Convert a possibly-qualified identifier to internal form: handle
324 * double quotes, translate to lower case where not inside quotes,
325 * truncate to NAMEDATALEN.
327 * There may be several identifiers separated by dots and optional
328 * whitespace. Each one is converted to a separate palloc'd string.
329 * The caller passes the expected number of identifiers, as well as
330 * a char* array to hold them. It is an error if we find the wrong
331 * number of identifiers (cf grammar processing of fori_varname).
333 * NOTE: the input string has already been accepted by the flex lexer,
334 * so we don't need a heckuva lot of error checking here.
338 plpgsql_convert_ident(const char *s, char **output, int numidents)
340 const char *sstart = s;
343 /* Outer loop over identifiers */
349 /* Process current identifier */
353 /* Quoted identifier: copy, collapsing out doubled quotes */
355 curident = palloc(strlen(s) + 1); /* surely enough room */
368 if (*s != '"') /* should not happen if lexer checked */
370 (errcode(ERRCODE_SYNTAX_ERROR),
371 errmsg("unterminated \" in name: %s", sstart)));
374 /* Truncate to NAMEDATALEN */
375 truncate_identifier(curident, cp - curident, false);
379 /* Normal identifier: extends till dot or whitespace */
380 const char *thisstart = s;
382 while (*s && *s != '.' && !scanner_isspace(*s))
384 /* Downcase and truncate to NAMEDATALEN */
385 curident = downcase_truncate_identifier(thisstart, s - thisstart,
389 /* Pass ident to caller */
390 if (identctr < numidents)
391 output[identctr++] = curident;
394 (errcode(ERRCODE_SYNTAX_ERROR),
395 errmsg("qualified identifier cannot be used here: %s",
398 /* If not done, skip whitespace, dot, whitespace */
401 while (*s && scanner_isspace(*s))
404 elog(ERROR, "expected dot between identifiers: %s", sstart);
405 while (*s && scanner_isspace(*s))
408 elog(ERROR, "expected another identifier: %s", sstart);
412 if (identctr != numidents)
413 elog(ERROR, "improperly qualified identifier: %s",
419 * Statement type as a string, for use in error messages etc.
422 plpgsql_stmt_typename(PLpgSQL_stmt *stmt)
424 switch (stmt->cmd_type)
426 case PLPGSQL_STMT_BLOCK:
427 return _("statement block");
428 case PLPGSQL_STMT_ASSIGN:
429 return _("assignment");
430 case PLPGSQL_STMT_IF:
432 case PLPGSQL_STMT_LOOP:
434 case PLPGSQL_STMT_WHILE:
436 case PLPGSQL_STMT_FORI:
437 return _("for with integer loop variable");
438 case PLPGSQL_STMT_FORS:
439 return _("for over select rows");
440 case PLPGSQL_STMT_EXIT:
442 case PLPGSQL_STMT_RETURN:
444 case PLPGSQL_STMT_RETURN_NEXT:
445 return _("return next");
446 case PLPGSQL_STMT_RAISE:
448 case PLPGSQL_STMT_EXECSQL:
449 return _("SQL statement");
450 case PLPGSQL_STMT_DYNEXECUTE:
451 return _("execute statement");
452 case PLPGSQL_STMT_DYNFORS:
453 return _("for over execute statement");
454 case PLPGSQL_STMT_GETDIAG:
455 return _("get diagnostics");
456 case PLPGSQL_STMT_OPEN:
458 case PLPGSQL_STMT_FETCH:
460 case PLPGSQL_STMT_CLOSE:
462 case PLPGSQL_STMT_PERFORM:
470 /**********************************************************************
471 * Debug functions for analyzing the compiled code
472 **********************************************************************/
473 static int dump_indent;
475 static void dump_ind(void);
476 static void dump_stmt(PLpgSQL_stmt *stmt);
477 static void dump_block(PLpgSQL_stmt_block *block);
478 static void dump_assign(PLpgSQL_stmt_assign *stmt);
479 static void dump_if(PLpgSQL_stmt_if *stmt);
480 static void dump_loop(PLpgSQL_stmt_loop *stmt);
481 static void dump_while(PLpgSQL_stmt_while *stmt);
482 static void dump_fori(PLpgSQL_stmt_fori *stmt);
483 static void dump_fors(PLpgSQL_stmt_fors *stmt);
484 static void dump_exit(PLpgSQL_stmt_exit *stmt);
485 static void dump_return(PLpgSQL_stmt_return *stmt);
486 static void dump_return_next(PLpgSQL_stmt_return_next *stmt);
487 static void dump_raise(PLpgSQL_stmt_raise *stmt);
488 static void dump_execsql(PLpgSQL_stmt_execsql *stmt);
489 static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
490 static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt);
491 static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt);
492 static void dump_open(PLpgSQL_stmt_open *stmt);
493 static void dump_fetch(PLpgSQL_stmt_fetch *stmt);
494 static void dump_cursor_direction(PLpgSQL_stmt_fetch *stmt);
495 static void dump_close(PLpgSQL_stmt_close *stmt);
496 static void dump_perform(PLpgSQL_stmt_perform *stmt);
497 static void dump_expr(PLpgSQL_expr *expr);
505 for (i = 0; i < dump_indent; i++)
510 dump_stmt(PLpgSQL_stmt *stmt)
512 printf("%3d:", stmt->lineno);
513 switch (stmt->cmd_type)
515 case PLPGSQL_STMT_BLOCK:
516 dump_block((PLpgSQL_stmt_block *) stmt);
518 case PLPGSQL_STMT_ASSIGN:
519 dump_assign((PLpgSQL_stmt_assign *) stmt);
521 case PLPGSQL_STMT_IF:
522 dump_if((PLpgSQL_stmt_if *) stmt);
524 case PLPGSQL_STMT_LOOP:
525 dump_loop((PLpgSQL_stmt_loop *) stmt);
527 case PLPGSQL_STMT_WHILE:
528 dump_while((PLpgSQL_stmt_while *) stmt);
530 case PLPGSQL_STMT_FORI:
531 dump_fori((PLpgSQL_stmt_fori *) stmt);
533 case PLPGSQL_STMT_FORS:
534 dump_fors((PLpgSQL_stmt_fors *) stmt);
536 case PLPGSQL_STMT_EXIT:
537 dump_exit((PLpgSQL_stmt_exit *) stmt);
539 case PLPGSQL_STMT_RETURN:
540 dump_return((PLpgSQL_stmt_return *) stmt);
542 case PLPGSQL_STMT_RETURN_NEXT:
543 dump_return_next((PLpgSQL_stmt_return_next *) stmt);
545 case PLPGSQL_STMT_RAISE:
546 dump_raise((PLpgSQL_stmt_raise *) stmt);
548 case PLPGSQL_STMT_EXECSQL:
549 dump_execsql((PLpgSQL_stmt_execsql *) stmt);
551 case PLPGSQL_STMT_DYNEXECUTE:
552 dump_dynexecute((PLpgSQL_stmt_dynexecute *) stmt);
554 case PLPGSQL_STMT_DYNFORS:
555 dump_dynfors((PLpgSQL_stmt_dynfors *) stmt);
557 case PLPGSQL_STMT_GETDIAG:
558 dump_getdiag((PLpgSQL_stmt_getdiag *) stmt);
560 case PLPGSQL_STMT_OPEN:
561 dump_open((PLpgSQL_stmt_open *) stmt);
563 case PLPGSQL_STMT_FETCH:
564 dump_fetch((PLpgSQL_stmt_fetch *) stmt);
566 case PLPGSQL_STMT_CLOSE:
567 dump_close((PLpgSQL_stmt_close *) stmt);
569 case PLPGSQL_STMT_PERFORM:
570 dump_perform((PLpgSQL_stmt_perform *) stmt);
573 elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
579 dump_stmts(List *stmts)
585 dump_stmt((PLpgSQL_stmt *) lfirst(s));
590 dump_block(PLpgSQL_stmt_block *block)
594 if (block->label == NULL)
600 printf("BLOCK <<%s>>\n", name);
602 dump_stmts(block->body);
604 if (block->exceptions)
608 foreach(e, block->exceptions->exc_list)
610 PLpgSQL_exception *exc = (PLpgSQL_exception *) lfirst(e);
611 PLpgSQL_condition *cond;
614 printf(" EXCEPTION WHEN ");
615 for (cond = exc->conditions; cond; cond = cond->next)
617 if (cond != exc->conditions)
619 printf("%s", cond->condname);
622 dump_stmts(exc->action);
627 printf(" END -- %s\n", name);
631 dump_assign(PLpgSQL_stmt_assign *stmt)
634 printf("ASSIGN var %d := ", stmt->varno);
635 dump_expr(stmt->expr);
640 dump_if(PLpgSQL_stmt_if *stmt)
644 dump_expr(stmt->cond);
647 dump_stmts(stmt->true_body);
649 if (stmt->false_body != NIL)
653 dump_stmts(stmt->false_body);
661 dump_loop(PLpgSQL_stmt_loop *stmt)
666 dump_stmts(stmt->body);
669 printf(" ENDLOOP\n");
673 dump_while(PLpgSQL_stmt_while *stmt)
677 dump_expr(stmt->cond);
680 dump_stmts(stmt->body);
683 printf(" ENDWHILE\n");
687 dump_fori(PLpgSQL_stmt_fori *stmt)
690 printf("FORI %s %s\n", stmt->var->refname, (stmt->reverse) ? "REVERSE" : "NORMAL");
695 dump_expr(stmt->lower);
699 dump_expr(stmt->upper);
703 dump_expr(stmt->step);
707 dump_stmts(stmt->body);
710 printf(" ENDFORI\n");
714 dump_fors(PLpgSQL_stmt_fors *stmt)
717 printf("FORS %s ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
718 dump_expr(stmt->query);
721 dump_stmts(stmt->body);
724 printf(" ENDFORS\n");
728 dump_open(PLpgSQL_stmt_open *stmt)
731 printf("OPEN curvar=%d\n", stmt->curvar);
734 if (stmt->argquery != NULL)
737 printf(" arguments = '");
738 dump_expr(stmt->argquery);
741 if (stmt->query != NULL)
744 printf(" query = '");
745 dump_expr(stmt->query);
748 if (stmt->dynquery != NULL)
751 printf(" execute = '");
752 dump_expr(stmt->dynquery);
760 dump_fetch(PLpgSQL_stmt_fetch *stmt)
766 printf("FETCH curvar=%d\n", stmt->curvar);
767 dump_cursor_direction(stmt);
770 if (stmt->rec != NULL)
773 printf(" target = %d %s\n", stmt->rec->recno, stmt->rec->refname);
775 if (stmt->row != NULL)
778 printf(" target = %d %s\n", stmt->row->rowno, stmt->row->refname);
784 printf("MOVE curvar=%d\n", stmt->curvar);
785 dump_cursor_direction(stmt);
790 dump_cursor_direction(PLpgSQL_stmt_fetch *stmt)
794 switch (stmt->direction)
800 printf(" BACKWARD ");
803 printf(" ABSOLUTE ");
806 printf(" RELATIVE ");
809 printf("??? unknown cursor direction %d", stmt->direction);
814 dump_expr(stmt->expr);
818 printf("%d\n", stmt->how_many);
824 dump_close(PLpgSQL_stmt_close *stmt)
827 printf("CLOSE curvar=%d\n", stmt->curvar);
831 dump_perform(PLpgSQL_stmt_perform *stmt)
834 printf("PERFORM expr = ");
835 dump_expr(stmt->expr);
840 dump_exit(PLpgSQL_stmt_exit *stmt)
843 printf("%s label='%s'",
844 stmt->is_exit ? "EXIT" : "CONTINUE", stmt->label);
845 if (stmt->cond != NULL)
848 dump_expr(stmt->cond);
854 dump_return(PLpgSQL_stmt_return *stmt)
858 if (stmt->retvarno >= 0)
859 printf("variable %d", stmt->retvarno);
860 else if (stmt->expr != NULL)
861 dump_expr(stmt->expr);
868 dump_return_next(PLpgSQL_stmt_return_next *stmt)
871 printf("RETURN NEXT ");
872 if (stmt->retvarno >= 0)
873 printf("variable %d", stmt->retvarno);
874 else if (stmt->expr != NULL)
875 dump_expr(stmt->expr);
882 dump_raise(PLpgSQL_stmt_raise *stmt)
888 printf("RAISE '%s'\n", stmt->message);
890 foreach(lc, stmt->params)
893 printf(" parameter %d: ", i++);
894 dump_expr((PLpgSQL_expr *) lfirst(lc));
901 dump_execsql(PLpgSQL_stmt_execsql *stmt)
905 dump_expr(stmt->sqlstmt);
909 if (stmt->rec != NULL)
912 printf(" INTO%s target = %d %s\n",
913 stmt->strict ? " STRICT" : "",
914 stmt->rec->recno, stmt->rec->refname);
916 if (stmt->row != NULL)
919 printf(" INTO%s target = %d %s\n",
920 stmt->strict ? " STRICT" : "",
921 stmt->row->rowno, stmt->row->refname);
927 dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
931 dump_expr(stmt->query);
935 if (stmt->rec != NULL)
938 printf(" INTO%s target = %d %s\n",
939 stmt->strict ? " STRICT" : "",
940 stmt->rec->recno, stmt->rec->refname);
942 if (stmt->row != NULL)
945 printf(" INTO%s target = %d %s\n",
946 stmt->strict ? " STRICT" : "",
947 stmt->row->rowno, stmt->row->refname);
953 dump_dynfors(PLpgSQL_stmt_dynfors *stmt)
956 printf("FORS %s EXECUTE ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
957 dump_expr(stmt->query);
960 dump_stmts(stmt->body);
963 printf(" ENDFORS\n");
967 dump_getdiag(PLpgSQL_stmt_getdiag *stmt)
972 printf("GET DIAGNOSTICS ");
973 foreach(lc, stmt->diag_items)
975 PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
977 if (lc != list_head(stmt->diag_items))
980 printf("{var %d} = ", diag_item->target);
982 switch (diag_item->kind)
984 case PLPGSQL_GETDIAG_ROW_COUNT:
988 case PLPGSQL_GETDIAG_RESULT_OID:
989 printf("RESULT_OID");
1001 dump_expr(PLpgSQL_expr *expr)
1005 printf("'%s", expr->query);
1006 if (expr->nparams > 0)
1009 for (i = 0; i < expr->nparams; i++)
1013 printf("$%d=%d", i + 1, expr->params[i]);
1021 plpgsql_dumptree(PLpgSQL_function *func)
1026 printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1029 printf("\nFunction's data area:\n");
1030 for (i = 0; i < func->ndatums; i++)
1032 d = func->datums[i];
1034 printf(" entry %d: ", i);
1037 case PLPGSQL_DTYPE_VAR:
1039 PLpgSQL_var *var = (PLpgSQL_var *) d;
1041 printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1042 var->refname, var->datatype->typname,
1043 var->datatype->typoid,
1044 var->datatype->atttypmod);
1046 printf(" CONSTANT\n");
1048 printf(" NOT NULL\n");
1049 if (var->default_val != NULL)
1051 printf(" DEFAULT ");
1052 dump_expr(var->default_val);
1055 if (var->cursor_explicit_expr != NULL)
1057 if (var->cursor_explicit_argrow >= 0)
1058 printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1060 printf(" CURSOR IS ");
1061 dump_expr(var->cursor_explicit_expr);
1066 case PLPGSQL_DTYPE_ROW:
1068 PLpgSQL_row *row = (PLpgSQL_row *) d;
1071 printf("ROW %-16s fields", row->refname);
1072 for (i = 0; i < row->nfields; i++)
1074 if (row->fieldnames[i])
1075 printf(" %s=var %d", row->fieldnames[i],
1081 case PLPGSQL_DTYPE_REC:
1082 printf("REC %s\n", ((PLpgSQL_rec *) d)->refname);
1084 case PLPGSQL_DTYPE_RECFIELD:
1085 printf("RECFIELD %-16s of REC %d\n",
1086 ((PLpgSQL_recfield *) d)->fieldname,
1087 ((PLpgSQL_recfield *) d)->recparentno);
1089 case PLPGSQL_DTYPE_ARRAYELEM:
1090 printf("ARRAYELEM of VAR %d subscript ",
1091 ((PLpgSQL_arrayelem *) d)->arrayparentno);
1092 dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1095 case PLPGSQL_DTYPE_TRIGARG:
1097 dump_expr(((PLpgSQL_trigarg *) d)->argnum);
1101 printf("??? unknown data type %d\n", d->dtype);
1104 printf("\nFunction's statements:\n");
1107 printf("%3d:", func->action->lineno);
1108 dump_block(func->action);
1109 printf("\nEnd of execution tree of function %s\n\n", func->fn_name);