File: src/BTrees/BTreeTemplate.c
Function: BTree_rangeSearch
Error: returning (PyObject*)NULL without setting an exception
1472 static PyObject *
1473 BTree_rangeSearch(BTree *self, PyObject *args, PyObject *kw, char type)
1474 {
when considering range: -128 <= value <= 1
taking False path
1475   PyObject *min = Py_None;
1476   PyObject *max = Py_None;
1477   int excludemin = 0;
1478   int excludemax = 0;
1479   int rc;
1480   Bucket *lowbucket = NULL;
1481   Bucket *highbucket = NULL;
1482   int lowoffset;
1483   int highoffset;
1484   PyObject *result;
1485 
1486   if (args) {
taking True path
1487     if (! PyArg_ParseTupleAndKeywords(args, kw, "|OOii", search_keywords,
when PyArg_ParseTupleAndKeywords() succeeds
taking False path
1488                                       &min,
1489                                       &max,
1490                                       &excludemin,
1491                                       &excludemax))
1492       return NULL;
1493   }
1494 
1495   UNLESS (PER_USE(self)) return NULL;
when considering range: -128 <= value <= -2
taking True path
when considering range: -128 <= value <= -1
taking False path
taking False path
1496 
1497   UNLESS (self->data && self->len) goto empty;
when treating unknown struct BTreeItem * from src/BTrees/BTreeTemplate.c:1497 as non-NULL
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
1498 
1499   /* Find the low range */
1500   if (min != Py_None) {
taking True path
1501     if ((rc = BTree_findRangeEnd(self, min, 1, excludemin,
when considering range: 1 <= value <= 0x7fffffff
taking False path
1502                                  &lowbucket, &lowoffset)) <= 0) {
1503       if (rc < 0) goto err;
1504       goto empty;
1505     }
1506   }
1507   else {
1508     lowbucket = self->firstbucket;
1509     lowoffset = 0;
1510     if (excludemin) {
1511       int bucketlen;
1512       UNLESS (PER_USE(lowbucket)) goto err;
1513       bucketlen = lowbucket->len;
1514       PER_UNUSE(lowbucket);
1515       if (bucketlen > 1)
1516         lowoffset = 1;
1517       else if (self->len < 2)
1518         goto empty;
1519       else {	/* move to first item in next bucket */
1520         Bucket *next;
1521         UNLESS (PER_USE(lowbucket)) goto err;
1522         next = lowbucket->next;
1523         PER_UNUSE(lowbucket);
1524         assert(next != NULL);
1525         lowbucket = next;
1526         /* and lowoffset is still 0 */
1527         assert(lowoffset == 0);
1528       }
1529     }
1530     Py_INCREF(lowbucket);
1531   }
1532 
1533   /* Find the high range */
1534   if (max != Py_None) {
taking True path
1535     if ((rc = BTree_findRangeEnd(self, max, 0, excludemax,
when considering range: -0x80000000 <= value <= 0
taking True path
1536                                  &highbucket, &highoffset)) <= 0) {
1537       Py_DECREF(lowbucket);
when treating unknown struct Bucket * * from src/BTrees/BTreeTemplate.c:1501 as non-NULL
when considering value == (Py_ssize_t)0 from src/BTrees/BTreeTemplate.c:1537
taking False path
when treating unknown struct _typeobject * from src/BTrees/BTreeTemplate.c:1537 as non-NULL
calling unknown void (*destructor) (struct PyObject *) from src/BTrees/BTreeTemplate.c:1537
1538       if (rc < 0) goto err;
when considering range: -0x80000000 <= value <= -1
taking True path
1539       goto empty;
1540     }
1541   }
1542   else {
1543     int bucketlen;
1544     highbucket = BTree_lastBucket(self);
1545     assert(highbucket != NULL);  /* we know self isn't empty */
1546     UNLESS (PER_USE(highbucket)) goto err_and_decref_buckets;
1547     bucketlen = highbucket->len;
1548     PER_UNUSE(highbucket);
1549     highoffset = bucketlen - 1;
1550     if (excludemax) {
1551       if (highoffset > 0)
1552         --highoffset;
1553       else if (self->len < 2)
1554         goto empty_and_decref_buckets;
1555       else {	/* move to last item of preceding bucket */
1556         int status;
1557         assert(highbucket != self->firstbucket);
1558         Py_DECREF(highbucket);
1559         status = PreviousBucket(&highbucket, self->firstbucket);
1560         if (status < 0) {
1561           Py_DECREF(lowbucket);
1562           goto err;
1563         }
1564         assert(status > 0);
1565         Py_INCREF(highbucket);
1566         UNLESS (PER_USE(highbucket)) goto err_and_decref_buckets;
1567         highoffset = highbucket->len - 1;
1568         PER_UNUSE(highbucket);
1569       }
1570     }
1571     assert(highoffset >= 0);
1572   }
1573 
1574   /* It's still possible that the range is empty, even if min < max.  For
1575    * example, if min=3 and max=4, and 3 and 4 aren't in the BTree, but 2 and
1576    * 5 are, then the low position points to the 5 now and the high position
1577    * points to the 2 now.  They're not necessarily even in the same bucket,
1578    * so there's no trick we can play with pointer compares to get out
1579    * cheap in general.
1580    */
1581   if (lowbucket == highbucket && lowoffset > highoffset)
1582     goto empty_and_decref_buckets;      /* definitely empty */
1583 
1584   /* The buckets differ, or they're the same and the offsets show a non-
1585    * empty range.
1586    */
1587   if (min != Py_None && max != Py_None && /* both args user-supplied */
1588       lowbucket != highbucket)   /* and different buckets */ {
1589     KEY_TYPE first;
1590     KEY_TYPE last;
1591     int cmp;
1592 
1593     /* Have to check the hard way:  see how the endpoints compare. */
1594     UNLESS (PER_USE(lowbucket)) goto err_and_decref_buckets;
1595     COPY_KEY(first, lowbucket->keys[lowoffset]);
1596     PER_UNUSE(lowbucket);
1597 
1598     UNLESS (PER_USE(highbucket)) goto err_and_decref_buckets;
1599     COPY_KEY(last, highbucket->keys[highoffset]);
1600     PER_UNUSE(highbucket);
1601 
1602     TEST_KEY_SET_OR(cmp, first, last) goto err_and_decref_buckets;
1603     if (cmp > 0) goto empty_and_decref_buckets;
1604   }
1605 
1606   PER_UNUSE(self);
1607 
1608   result = newBTreeItems(type, lowbucket, lowoffset, highbucket, highoffset);
1609   Py_DECREF(lowbucket);
1610   Py_DECREF(highbucket);
1611   return result;
1612 
1613  err_and_decref_buckets:
1614   Py_DECREF(lowbucket);
1615   Py_DECREF(highbucket);
1616 
1617  err:
1618   PER_UNUSE(self);
when treating unknown struct cPersistenceCAPIstruct * from src/persistent/cPersistence.h:112 as non-NULL
calling unknown void (*) (struct cPersistentObject *) from src/BTrees/BTreeTemplate.c:1618
1619   return NULL;
1620 
1621  empty_and_decref_buckets:
1622   Py_DECREF(lowbucket);
1623   Py_DECREF(highbucket);
1624 
1625  empty:
1626   PER_UNUSE(self);
1627   return newBTreeItems(type, 0, 0, 0, 0);
1628 }
returning (PyObject*)NULL without setting an exception
found 7 similar trace(s) to this