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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers