#28261: django paging after ordering use slicing return wrong result
-------------------------------------+-------------------------------------
Reporter: wqz | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: oracle, slicing | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by wqz):
* has_patch: 1 => 0
Old description:
> detail in PR with address https://github.com/django/django/pull/8580
New description:
Background: I want to get the paging use slicing after ordering, if
offset=20 and limit=10, code should be :
{{{
Computer.objects.select_related().order_by('-installed_agent')[20:
30].values_list('id', flat=True)
}}}
But look:
{{{
In [27]:
list(Computer.objects.select_related().order_by('-installed_agent')[20:
30].values_list('id', flat=True))
Out[27]: [1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 3221]
In [28]:
list(Computer.objects.select_related().order_by('-installed_agent')[10:
20].values_list('id', flat=True))
Out[28]: [1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 3221]
}}}
If array[20: 30] and array[10: 20] return the same result,the result of
the paging is wrong, why this?
Now django automatically generated sql for
"Computer.objects.select_related().order_by('-installed_agent')[20:
30].values_list('id', flat=True)" is:
{{{
SELECT *
FROM (SELECT "_SUB".*, ROWNUM AS "_RN"
FROM (SELECT "OM_COMPUTER"."ID" AS Col1
FROM "OM_COMPUTER"
ORDER BY "OM_COMPUTER"."INSTALLED_AGENT" DESC) "_SUB"
WHERE ROWNUM <= 30)
WHERE "_RN" > 20
}}}
If the generate sql like this:
{{{
SELECT SUB2.*
FROM (SELECT SUB1.*, ROWNUM AS "_RN"
FROM (SELECT "OM_COMPUTER"."ID" AS COL1
FROM "OM_COMPUTER"
ORDER BY "OM_COMPUTER"."INSTALLED_AGENT" DESC) SUB1) SUB2
WHERE "_RN" <= 30
AND "_RN" > 20
}}}
Then the result of the paging is right.
test:
{{{
In [3]:
list(Computer.objects.select_related().order_by('-installed_agent')[:10].values_list('id',
flat=True))
Out[3]: [8148, 7042, 7666, 6027, 6029, 8160, 8161, 8164, 8165, 8171]
In [5]:
list(Computer.objects.select_related().order_by('-installed_agent')[10
:20].values_list('id', flat=True))
Out[5]: [8173, 8174, 8175, 8176, 8177, 8180, 8181, 8186, 8187, 4397]
In [6]:
list(Computer.objects.select_related().order_by('-installed_agent')[20
:30].values_list('id', flat=True))
Out[6]: [4408, 4419, 4430, 4441, 4458, 8087, 8090, 8091, 8093, 8096]
In [10]:
list(Computer.objects.select_related().order_by('-installed_agent')[10
:].values_list('id', flat=True))
Out[10]:
[8173,
8174,
8175,
...
]
In [7]:
str(Computer.objects.select_related().order_by('-installed_agent')[:10].values_list('id',
flat=True).query)
Out[7]: 'SELECT "__SUB".* FROM (SELECT "_SUB".*,ROWNUM AS "_RN" FROM
(SELECT "OM_COMPUTER"."ID" AS Col1 FROM "OM_COMPUTER" ORDER BY
"OM_COMPUTER"."INSTALLED_AGENT" DESC) "_SUB") "__SUB" WHERE "_RN" <= 10
AND "_RN" > 0'
In [8]:
str(Computer.objects.select_related().order_by('-installed_agent')[10
:].values_list('id', flat=True).query)
Out[8]: 'SELECT "__SUB".* FROM (SELECT "_SUB".*,ROWNUM AS "_RN" FROM
(SELECT "OM_COMPUTER"."ID" AS Col1 FROM "OM_COMPUTER" ORDER BY
"OM_COMPUTER"."INSTALLED_AGENT" DESC) "_SUB") "__SUB" WHERE "_RN" > 10'
In [9]:
str(Computer.objects.select_related().order_by('-installed_agent')[20
:30].values_list('id', flat=True).query)
Out[9]: 'SELECT "__SUB".* FROM (SELECT "_SUB".*,ROWNUM AS "_RN" FROM
(SELECT "OM_COMPUTER"."ID" AS Col1 FROM "OM_COMPUTER" ORDER BY
"OM_COMPUTER"."INSTALLED_AGENT" DESC) "_SUB") "__SUB" WHERE "_RN" <= 30
AND "_RN" > 20'
}}}
works good.
detail in PR with address https://github.com/django/django/pull/8580
--
--
Ticket URL: <https://code.djangoproject.com/ticket/28261#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/067.7ee8a06b3495e60d67c711c5c48866bd%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.