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

Reply via email to