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