Hello

This patch remove redundant rows from PL/pgSQL executor (-89 lines).
Doesn't change a functionality.

Regards

Pavel Stehule
*** ./src/pl/plpgsql/src/pl_exec.c.orig	2010-12-16 10:25:37.000000000 +0100
--- ./src/pl/plpgsql/src/pl_exec.c	2010-12-17 10:50:31.793623763 +0100
***************
*** 204,209 ****
--- 204,211 ----
  						  PLpgSQL_expr *dynquery, List *params,
  						  const char *portalname, int cursorOptions);
  
+ static bool can_leave_loop(PLpgSQL_execstate *estate,
+ 				    PLpgSQL_any_loop *stmt, int *rc);
  
  /* ----------
   * plpgsql_exec_function	Called by the call handler for
***************
*** 1566,1571 ****
--- 1568,1637 ----
  	return exec_stmts(estate, stmt->else_stmts);
  }
  
+ /*
+  * function returns true, when outer cycle should be leaved
+  */
+ static bool 
+ can_leave_loop(PLpgSQL_execstate *estate, PLpgSQL_any_loop *stmt, int *rc)
+ {
+ 	switch (*rc)
+ 	{
+ 		case PLPGSQL_RC_OK:
+ 			return false;
+ 
+ 		case PLPGSQL_RC_RETURN:
+ 			return true;
+ 
+ 		case PLPGSQL_RC_EXIT:
+ 			if (estate->exitlabel == NULL)
+ 			{
+ 				/* unlabelled exit, finish the current loop */
+ 				*rc = PLPGSQL_RC_OK;
+ 			}
+ 			if (stmt->label != NULL && strcmp(stmt->label, estate->exitlabel) == 0)
+ 			{
+ 				/* labelled exit, matches the current stmt's label */
+ 				estate->exitlabel = NULL;
+ 				*rc = PLPGSQL_RC_OK;
+ 			}
+ 
+ 			/*
+ 			 * otherwise, this is a labelled exit that does not match the
+ 			 * current statement's label, if any: return RC_EXIT so that the
+ 			 * EXIT continues to propagate up the stack.
+ 			 */
+ 			return true;
+ 
+ 		case PLPGSQL_RC_CONTINUE:
+ 			if (estate->exitlabel == NULL)
+ 			{
+ 				/* anonymous continue, so re-run the loop */
+ 				*rc = PLPGSQL_RC_OK;
+ 			}
+ 			else if (stmt->label != NULL &&
+ 					 strcmp(stmt->label, estate->exitlabel) == 0)
+ 			{
+ 				/* label matches named continue, so re-run loop */
+ 				estate->exitlabel = NULL;
+ 				*rc = PLPGSQL_RC_OK;
+ 			}
+ 			else
+ 			{
+ 				/*
+ 				 * otherwise, this is a named continue that does not match the
+ 				 * current statement's label, if any: return RC_CONTINUE so
+ 				 * that the CONTINUE will propagate up the stack.
+ 				 */
+ 				return true;
+ 			}
+ 
+ 			return false;
+ 
+ 		default:
+ 			elog(ERROR, "unrecognized rc: %d", *rc);
+ 			return false;		/* be compiler quiet */
+ 	}
+ }
  
  /* ----------
   * exec_stmt_loop			Loop over statements until
***************
*** 1575,1621 ****
  static int
  exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
  {
  	for (;;)
  	{
! 		int			rc = exec_stmts(estate, stmt->body);
! 
! 		switch (rc)
! 		{
! 			case PLPGSQL_RC_OK:
! 				break;
! 
! 			case PLPGSQL_RC_EXIT:
! 				if (estate->exitlabel == NULL)
! 					return PLPGSQL_RC_OK;
! 				if (stmt->label == NULL)
! 					return PLPGSQL_RC_EXIT;
! 				if (strcmp(stmt->label, estate->exitlabel) != 0)
! 					return PLPGSQL_RC_EXIT;
! 				estate->exitlabel = NULL;
! 				return PLPGSQL_RC_OK;
! 
! 			case PLPGSQL_RC_CONTINUE:
! 				if (estate->exitlabel == NULL)
! 					/* anonymous continue, so re-run the loop */
! 					break;
! 				else if (stmt->label != NULL &&
! 						 strcmp(stmt->label, estate->exitlabel) == 0)
! 					/* label matches named continue, so re-run loop */
! 					estate->exitlabel = NULL;
! 				else
! 					/* label doesn't match named continue, so propagate upward */
! 					return PLPGSQL_RC_CONTINUE;
! 				break;
! 
! 			case PLPGSQL_RC_RETURN:
! 				return rc;
  
! 			default:
! 				elog(ERROR, "unrecognized rc: %d", rc);
! 		}
  	}
  
! 	return PLPGSQL_RC_OK;
  }
  
  
--- 1641,1657 ----
  static int
  exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
  {
+ 	int	rc;
+ 
  	for (;;)
  	{
! 		rc = exec_stmts(estate, stmt->body);
  
! 		if (can_leave_loop(estate, (PLpgSQL_any_loop *) stmt, &rc))
! 			break;
  	}
  
! 	return rc;
  }
  
  
***************
*** 1628,1636 ****
  static int
  exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt)
  {
  	for (;;)
  	{
- 		int			rc;
  		bool		value;
  		bool		isnull;
  
--- 1664,1673 ----
  static int
  exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt)
  {
+ 	int	rc;
+ 
  	for (;;)
  	{
  		bool		value;
  		bool		isnull;
  
***************
*** 1642,1684 ****
  
  		rc = exec_stmts(estate, stmt->body);
  
! 		switch (rc)
! 		{
! 			case PLPGSQL_RC_OK:
! 				break;
! 
! 			case PLPGSQL_RC_EXIT:
! 				if (estate->exitlabel == NULL)
! 					return PLPGSQL_RC_OK;
! 				if (stmt->label == NULL)
! 					return PLPGSQL_RC_EXIT;
! 				if (strcmp(stmt->label, estate->exitlabel) != 0)
! 					return PLPGSQL_RC_EXIT;
! 				estate->exitlabel = NULL;
! 				return PLPGSQL_RC_OK;
! 
! 			case PLPGSQL_RC_CONTINUE:
! 				if (estate->exitlabel == NULL)
! 					/* anonymous continue, so re-run loop */
! 					break;
! 				else if (stmt->label != NULL &&
! 						 strcmp(stmt->label, estate->exitlabel) == 0)
! 					/* label matches named continue, so re-run loop */
! 					estate->exitlabel = NULL;
! 				else
! 					/* label doesn't match named continue, propagate upward */
! 					return PLPGSQL_RC_CONTINUE;
! 				break;
! 
! 			case PLPGSQL_RC_RETURN:
! 				return rc;
! 
! 			default:
! 				elog(ERROR, "unrecognized rc: %d", rc);
! 		}
  	}
  
! 	return PLPGSQL_RC_OK;
  }
  
  
--- 1679,1689 ----
  
  		rc = exec_stmts(estate, stmt->body);
  
! 		if (can_leave_loop(estate, (PLpgSQL_any_loop *) stmt, &rc))
! 			break;
  	}
  
! 	return rc;
  }
  
  
***************
*** 1789,1838 ****
  		 */
  		rc = exec_stmts(estate, stmt->body);
  
! 		if (rc == PLPGSQL_RC_RETURN)
! 			break;				/* break out of the loop */
! 		else if (rc == PLPGSQL_RC_EXIT)
! 		{
! 			if (estate->exitlabel == NULL)
! 				/* unlabelled exit, finish the current loop */
! 				rc = PLPGSQL_RC_OK;
! 			else if (stmt->label != NULL &&
! 					 strcmp(stmt->label, estate->exitlabel) == 0)
! 			{
! 				/* labelled exit, matches the current stmt's label */
! 				estate->exitlabel = NULL;
! 				rc = PLPGSQL_RC_OK;
! 			}
! 
! 			/*
! 			 * otherwise, this is a labelled exit that does not match the
! 			 * current statement's label, if any: return RC_EXIT so that the
! 			 * EXIT continues to propagate up the stack.
! 			 */
  			break;
- 		}
- 		else if (rc == PLPGSQL_RC_CONTINUE)
- 		{
- 			if (estate->exitlabel == NULL)
- 				/* unlabelled continue, so re-run the current loop */
- 				rc = PLPGSQL_RC_OK;
- 			else if (stmt->label != NULL &&
- 					 strcmp(stmt->label, estate->exitlabel) == 0)
- 			{
- 				/* label matches named continue, so re-run loop */
- 				estate->exitlabel = NULL;
- 				rc = PLPGSQL_RC_OK;
- 			}
- 			else
- 			{
- 				/*
- 				 * otherwise, this is a named continue that does not match the
- 				 * current statement's label, if any: return RC_CONTINUE so
- 				 * that the CONTINUE will propagate up the stack.
- 				 */
- 				break;
- 			}
- 		}
  
  		/*
  		 * Increase/decrease loop value, unless it would overflow, in which
--- 1794,1801 ----
  		 */
  		rc = exec_stmts(estate, stmt->body);
  
! 		if (can_leave_loop(estate, (PLpgSQL_any_loop *) stmt, &rc))
  			break;
  
  		/*
  		 * Increase/decrease loop value, unless it would overflow, in which
***************
*** 4410,4469 ****
  			 */
  			rc = exec_stmts(estate, stmt->body);
  
! 			if (rc != PLPGSQL_RC_OK)
! 			{
! 				if (rc == PLPGSQL_RC_EXIT)
! 				{
! 					if (estate->exitlabel == NULL)
! 					{
! 						/* unlabelled exit, so exit the current loop */
! 						rc = PLPGSQL_RC_OK;
! 					}
! 					else if (stmt->label != NULL &&
! 							 strcmp(stmt->label, estate->exitlabel) == 0)
! 					{
! 						/* label matches this loop, so exit loop */
! 						estate->exitlabel = NULL;
! 						rc = PLPGSQL_RC_OK;
! 					}
! 
! 					/*
! 					 * otherwise, we processed a labelled exit that does not
! 					 * match the current statement's label, if any; return
! 					 * RC_EXIT so that the EXIT continues to recurse upward.
! 					 */
! 				}
! 				else if (rc == PLPGSQL_RC_CONTINUE)
! 				{
! 					if (estate->exitlabel == NULL)
! 					{
! 						/* unlabelled continue, so re-run the current loop */
! 						rc = PLPGSQL_RC_OK;
! 						continue;
! 					}
! 					else if (stmt->label != NULL &&
! 							 strcmp(stmt->label, estate->exitlabel) == 0)
! 					{
! 						/* label matches this loop, so re-run loop */
! 						estate->exitlabel = NULL;
! 						rc = PLPGSQL_RC_OK;
! 						continue;
! 					}
! 
! 					/*
! 					 * otherwise, we process a labelled continue that does not
! 					 * match the current statement's label, if any; return
! 					 * RC_CONTINUE so that the CONTINUE will propagate up the
! 					 * stack.
! 					 */
! 				}
! 
! 				/*
! 				 * We're aborting the loop.  Need a goto to get out of two
! 				 * levels of loop...
! 				 */
  				goto loop_exit;
- 			}
  		}
  
  		SPI_freetuptable(tuptab);
--- 4373,4380 ----
  			 */
  			rc = exec_stmts(estate, stmt->body);
  
! 			if (can_leave_loop(estate, (PLpgSQL_any_loop *) stmt, &rc))
  				goto loop_exit;
  		}
  
  		SPI_freetuptable(tuptab);
*** ./src/pl/plpgsql/src/plpgsql.h.orig	2010-12-16 09:14:42.000000000 +0100
--- ./src/pl/plpgsql/src/plpgsql.h	2010-12-17 09:54:39.726801715 +0100
***************
*** 407,412 ****
--- 407,420 ----
  } PLpgSQL_case_when;
  
  
+ typedef struct					/* Ancestor of loops */
+ {
+ 	int			cmd_type;
+ 	int			lineno;
+ 	char	   *label;
+ } PLpgSQL_any_loop;
+ 
+ 
  typedef struct
  {								/* Unconditional LOOP statement		*/
  	int			cmd_type;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to