diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index f295558..7bf29a6 100644
*** a/src/backend/optimizer/path/indxpath.c
--- b/src/backend/optimizer/path/indxpath.c
*************** typedef struct
*** 67,72 ****
--- 67,73 ----
  	List	   *quals;			/* the WHERE clauses it uses */
  	List	   *preds;			/* predicates of its partial index(es) */
  	Bitmapset  *clauseids;		/* quals+preds represented as a bitmapset */
+ 	bool		unclassifiable;	/* has too many quals+preds to process? */
  } PathClauseUsage;
  
  /* Callback argument for ec_member_matches_indexcol */
*************** choose_bitmap_and(PlannerInfo *root, Rel
*** 1447,1455 ****
  		Path	   *ipath = (Path *) lfirst(l);
  
  		pathinfo = classify_index_clause_usage(ipath, &clauselist);
  		for (i = 0; i < npaths; i++)
  		{
! 			if (bms_equal(pathinfo->clauseids, pathinfoarray[i]->clauseids))
  				break;
  		}
  		if (i < npaths)
--- 1448,1465 ----
  		Path	   *ipath = (Path *) lfirst(l);
  
  		pathinfo = classify_index_clause_usage(ipath, &clauselist);
+ 
+ 		/* If it's unclassifiable, treat it as distinct from all others */
+ 		if (pathinfo->unclassifiable)
+ 		{
+ 			pathinfoarray[npaths++] = pathinfo;
+ 			continue;
+ 		}
+ 
  		for (i = 0; i < npaths; i++)
  		{
! 			if (!pathinfoarray[i]->unclassifiable &&
! 				bms_equal(pathinfo->clauseids, pathinfoarray[i]->clauseids))
  				break;
  		}
  		if (i < npaths)
*************** choose_bitmap_and(PlannerInfo *root, Rel
*** 1484,1489 ****
--- 1494,1503 ----
  	 * For each surviving index, consider it as an "AND group leader", and see
  	 * whether adding on any of the later indexes results in an AND path with
  	 * cheaper total cost than before.  Then take the cheapest AND group.
+ 	 *
+ 	 * Note: paths that are either clauseless or unclassifiable will have
+ 	 * empty clauseids, so that they will not be rejected by the clauseids
+ 	 * filter here, nor will they cause later paths to be rejected by it.
  	 */
  	for (i = 0; i < npaths; i++)
  	{
*************** classify_index_clause_usage(Path *path, 
*** 1711,1716 ****
--- 1725,1745 ----
  	result->preds = NIL;
  	find_indexpath_quals(path, &result->quals, &result->preds);
  
+ 	/*
+ 	 * Some machine-generated queries have outlandish numbers of qual clauses.
+ 	 * To avoid getting into O(N^2) behavior even in this preliminary
+ 	 * classification step, we want to limit the number of entries we can
+ 	 * accumulate in *clauselist.  Treat any path with more than 100 quals +
+ 	 * preds as unclassifiable, which will cause calling code to consider it
+ 	 * distinct from all other paths.
+ 	 */
+ 	if (list_length(result->quals) + list_length(result->preds) > 100)
+ 	{
+ 		result->clauseids = NULL;
+ 		result->unclassifiable = true;
+ 		return result;
+ 	}
+ 
  	/* Build up a bitmapset representing the quals and preds */
  	clauseids = NULL;
  	foreach(lc, result->quals)
*************** classify_index_clause_usage(Path *path, 
*** 1728,1733 ****
--- 1757,1763 ----
  								   find_list_position(node, clauselist));
  	}
  	result->clauseids = clauseids;
+ 	result->unclassifiable = false;
  
  	return result;
  }
