On Thu, 2004-09-16 at 00:06, Neil Conway wrote: > Attached is a proof of concept patch that implements this.
Woops, the patch is really attached this time. -Neil
Index: src/pl/plpgsql/src/gram.y =================================================================== RCS file: /home/neilc/private-cvsroot/pgsql-server/src/pl/plpgsql/src/gram.y,v retrieving revision 1.62 diff -c -r1.62 gram.y *** src/pl/plpgsql/src/gram.y 14 Sep 2004 23:46:46 -0000 1.62 --- src/pl/plpgsql/src/gram.y 15 Sep 2004 01:13:05 -0000 *************** *** 526,532 **** plpgsql_convert_ident(yytext, &name, 1); /* name should be malloc'd for use as varname */ $$.name = strdup(name); ! $$.lineno = plpgsql_scanner_lineno(); pfree(name); } ; --- 526,532 ---- plpgsql_convert_ident(yytext, &name, 1); /* name should be malloc'd for use as varname */ $$.name = strdup(name); ! $$.lineno = plpgsql_scanner_lineno(); pfree(name); } ; *************** *** 1315,1328 **** stmt_execsql : execsql_start lno { ! PLpgSQL_stmt_execsql *new; ! new = malloc(sizeof(PLpgSQL_stmt_execsql)); ! new->cmd_type = PLPGSQL_STMT_EXECSQL; ! new->lineno = $2; ! new->sqlstmt = read_sql_stmt($1); ! $$ = (PLpgSQL_stmt *)new; } ; --- 1315,1349 ---- stmt_execsql : execsql_start lno { ! int tok = yylex(); ! plpgsql_push_back_token(tok); ! if (tok == '(') ! { ! PLpgSQL_stmt_perform *new; ! char *prefix; ! prefix = malloc(strlen($1) + 7 + 1); ! sprintf(prefix, "SELECT %s", $1); ! ! new = malloc(sizeof(PLpgSQL_stmt_perform)); ! new->cmd_type = PLPGSQL_STMT_PERFORM; ! new->lineno = $2; ! new->expr = read_sql_stmt(prefix); ! ! $$ = (PLpgSQL_stmt *)new; ! free(prefix); ! } ! else ! { ! PLpgSQL_stmt_execsql *new; ! new = malloc(sizeof(PLpgSQL_stmt_execsql)); ! new->cmd_type = PLPGSQL_STMT_EXECSQL; ! new->lineno = $2; ! new->sqlstmt = read_sql_stmt($1); ! ! $$ = (PLpgSQL_stmt *)new; ! } } ; *************** *** 1540,1545 **** --- 1561,1567 ---- execsql_start : T_WORD { $$ = strdup(yytext); } + /* XXX: why do we need this case? */ | T_ERROR { $$ = strdup(yytext); } ; Index: src/pl/plpgsql/src/pl_exec.c =================================================================== RCS file: /home/neilc/private-cvsroot/pgsql-server/src/pl/plpgsql/src/pl_exec.c,v retrieving revision 1.119 diff -c -r1.119 pl_exec.c *** src/pl/plpgsql/src/pl_exec.c 13 Sep 2004 20:09:20 -0000 1.119 --- src/pl/plpgsql/src/pl_exec.c 15 Sep 2004 01:13:06 -0000 *************** *** 1166,1177 **** PLpgSQL_expr *expr = stmt->expr; int rc; - /* - * If not already done create a plan for this expression - */ - if (expr->plan == NULL) - exec_prepare_plan(estate, expr); - rc = exec_run_select(estate, expr, 0, NULL); if (rc != SPI_OK_SELECT) ereport(ERROR, --- 1166,1171 ---- *************** *** 4152,4158 **** expr->expr_simple_expr = NULL; /* ! * 1. We can only evaluate queries that resulted in one single * execution plan */ if (list_length(spi_plan->ptlist) != 1) --- 4146,4152 ---- expr->expr_simple_expr = NULL; /* ! * 1. We can only evaluate queries that resulted in a single * execution plan */ if (list_length(spi_plan->ptlist) != 1) Index: src/test/regress/sql/plpgsql.sql =================================================================== RCS file: /home/neilc/private-cvsroot/pgsql-server/src/test/regress/sql/plpgsql.sql,v retrieving revision 1.15 diff -c -r1.15 plpgsql.sql *** src/test/regress/sql/plpgsql.sql 10 Sep 2004 18:40:09 -0000 1.15 --- src/test/regress/sql/plpgsql.sql 15 Sep 2004 01:13:06 -0000 *************** *** 1750,1752 **** --- 1750,1778 ---- drop function trap_foreign_key(int); drop function trap_foreign_key_2(); + + -- + -- "bare" function calls + -- + + create function called_func() returns int as ' + BEGIN + RAISE NOTICE ''called_func() invoked''; + RETURN 5; + END; + ' language 'plpgsql'; + + create function calling_func(param int) returns int as ' + BEGIN + called_func(); + CALLED_FUNC(); + if param = 100 then + called_func(); + else + called_func(); + end if; + RETURN 10; + END; + ' language 'plpgsql'; + + select calling_func(15);
---------------------------(end of broadcast)--------------------------- TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly