diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c
index d8adec6cf091e9d238478437a5bb4584226905e8..60a03a417ee593e1f35ac810662194187e705963 100644
--- a/src/backend/regex/regexec.c
+++ b/src/backend/regex/regexec.c
@@ -27,7 +27,7 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/src/backend/regex/regexec.c,v 1.27 2005/10/15 02:49:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/regex/regexec.c,v 1.28 2010/02/01 02:45:29 tgl Exp $
  *
  */
 
@@ -141,6 +141,7 @@ static int	dissect(struct vars *, struct subre *, chr *, chr *);
 static int	condissect(struct vars *, struct subre *, chr *, chr *);
 static int	altdissect(struct vars *, struct subre *, chr *, chr *);
 static int	cdissect(struct vars *, struct subre *, chr *, chr *);
+static int	ccaptdissect(struct vars *, struct subre *, chr *, chr *);
 static int	ccondissect(struct vars *, struct subre *, chr *, chr *);
 static int	crevdissect(struct vars *, struct subre *, chr *, chr *);
 static int	cbrdissect(struct vars *, struct subre *, chr *, chr *);
@@ -560,27 +561,21 @@ dissect(struct vars * v,
 		case '=':				/* terminal node */
 			assert(t->left == NULL && t->right == NULL);
 			return REG_OKAY;	/* no action, parent did the work */
-			break;
 		case '|':				/* alternation */
 			assert(t->left != NULL);
 			return altdissect(v, t, begin, end);
-			break;
 		case 'b':				/* back ref -- shouldn't be calling us! */
 			return REG_ASSERT;
-			break;
 		case '.':				/* concatenation */
 			assert(t->left != NULL && t->right != NULL);
 			return condissect(v, t, begin, end);
-			break;
 		case '(':				/* capturing */
 			assert(t->left != NULL && t->right == NULL);
 			assert(t->subno > 0);
 			subset(v, t, begin, end);
 			return dissect(v, t->left, begin, end);
-			break;
 		default:
 			return REG_ASSERT;
-			break;
 	}
 }
 
@@ -710,8 +705,6 @@ cdissect(struct vars * v,
 		 chr *begin,			/* beginning of relevant substring */
 		 chr *end)				/* end of same */
 {
-	int			er;
-
 	assert(t != NULL);
 	MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
 
@@ -720,33 +713,42 @@ cdissect(struct vars * v,
 		case '=':				/* terminal node */
 			assert(t->left == NULL && t->right == NULL);
 			return REG_OKAY;	/* no action, parent did the work */
-			break;
 		case '|':				/* alternation */
 			assert(t->left != NULL);
 			return caltdissect(v, t, begin, end);
-			break;
 		case 'b':				/* back ref -- shouldn't be calling us! */
 			assert(t->left == NULL && t->right == NULL);
 			return cbrdissect(v, t, begin, end);
-			break;
 		case '.':				/* concatenation */
 			assert(t->left != NULL && t->right != NULL);
 			return ccondissect(v, t, begin, end);
-			break;
 		case '(':				/* capturing */
 			assert(t->left != NULL && t->right == NULL);
-			assert(t->subno > 0);
-			er = cdissect(v, t->left, begin, end);
-			if (er == REG_OKAY)
-				subset(v, t, begin, end);
-			return er;
-			break;
+			return ccaptdissect(v, t, begin, end);
 		default:
 			return REG_ASSERT;
-			break;
 	}
 }
 
+/*
+ * ccaptdissect - capture subexpression matches (with complications)
+ */
+static int						/* regexec return code */
+ccaptdissect(struct vars * v,
+			 struct subre * t,
+			 chr *begin,		/* beginning of relevant substring */
+			 chr *end)			/* end of same */
+{
+	int			er;
+
+	assert(t->subno > 0);
+
+	er = cdissect(v, t->left, begin, end);
+	if (er == REG_OKAY)
+		subset(v, t, begin, end);
+	return er;
+}
+
 /*
  * ccondissect - concatenation subexpression matches (with complications)
  * The retry memory stores the offset of the trial midpoint from begin,
@@ -804,17 +806,27 @@ ccondissect(struct vars * v,
 	for (;;)
 	{
 		/* try this midpoint on for size */
-		er = cdissect(v, t->left, begin, mid);
-		if (er == REG_OKAY &&
-			longest(v, d2, mid, end, (int *) NULL) == end &&
-			(er = cdissect(v, t->right, mid, end)) ==
-			REG_OKAY)
-			break;				/* NOTE BREAK OUT */
-		if (er != REG_OKAY && er != REG_NOMATCH)
+		if (longest(v, d2, mid, end, (int *) NULL) == end)
 		{
-			freedfa(d);
-			freedfa(d2);
-			return er;
+			er = cdissect(v, t->left, begin, mid);
+			if (er == REG_OKAY)
+			{
+				er = cdissect(v, t->right, mid, end);
+				if (er == REG_OKAY)
+				{
+					/* satisfaction */
+					MDEBUG(("successful\n"));
+					freedfa(d);
+					freedfa(d2);
+					return REG_OKAY;
+				}
+			}
+			if (er != REG_OKAY && er != REG_NOMATCH)
+			{
+				freedfa(d);
+				freedfa(d2);
+				return er;
+			}
 		}
 
 		/* that midpoint didn't work, find a new one */
@@ -841,11 +853,8 @@ ccondissect(struct vars * v,
 		zapmem(v, t->right);
 	}
 
-	/* satisfaction */
-	MDEBUG(("successful\n"));
-	freedfa(d);
-	freedfa(d2);
-	return REG_OKAY;
+	/* can't get here */
+	return REG_ASSERT;
 }
 
 /*
@@ -904,17 +913,27 @@ crevdissect(struct vars * v,
 	for (;;)
 	{
 		/* try this midpoint on for size */
-		er = cdissect(v, t->left, begin, mid);
-		if (er == REG_OKAY &&
-			longest(v, d2, mid, end, (int *) NULL) == end &&
-			(er = cdissect(v, t->right, mid, end)) ==
-			REG_OKAY)
-			break;				/* NOTE BREAK OUT */
-		if (er != REG_OKAY && er != REG_NOMATCH)
+		if (longest(v, d2, mid, end, (int *) NULL) == end)
 		{
-			freedfa(d);
-			freedfa(d2);
-			return er;
+			er = cdissect(v, t->left, begin, mid);
+			if (er == REG_OKAY)
+			{
+				er = cdissect(v, t->right, mid, end);
+				if (er == REG_OKAY)
+				{
+					/* satisfaction */
+					MDEBUG(("successful\n"));
+					freedfa(d);
+					freedfa(d2);
+					return REG_OKAY;
+				}
+			}
+			if (er != REG_OKAY && er != REG_NOMATCH)
+			{
+				freedfa(d);
+				freedfa(d2);
+				return er;
+			}
 		}
 
 		/* that midpoint didn't work, find a new one */
@@ -941,11 +960,8 @@ crevdissect(struct vars * v,
 		zapmem(v, t->right);
 	}
 
-	/* satisfaction */
-	MDEBUG(("successful\n"));
-	freedfa(d);
-	freedfa(d2);
-	return REG_OKAY;
+	/* can't get here */
+	return REG_ASSERT;
 }
 
 /*