Skip to content

Commit

Permalink
Merge pull request #4686 from kobotoolbox/fix-array-position-postgres
Browse files Browse the repository at this point in the history
Fix 500 error when loading projects list with PostgreSQL 13 and older
  • Loading branch information
bufke committed Oct 17, 2023
2 parents 6c40a42 + 2b590f7 commit eb1e7f3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
8 changes: 5 additions & 3 deletions kpi/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
SearchQueryTooShortException,
)
from kpi.models.asset import AssetDeploymentStatus, UserAssetSubscription
from kpi.utils.django_orm_helper import OrderRandom
from kpi.utils.django_orm_helper import OrderCustom
from kpi.utils.query_parser import get_parsed_parameters, parse, ParseError
from kpi.utils.object_permission import (
get_objects_for_user,
Expand Down Expand Up @@ -120,8 +120,10 @@ def filter_queryset(self, request, queryset, view):
else:
# Default ordering
return queryset.order_by(
OrderRandom(
'_deployment_status', self.DEPLOYMENT_STATUS_DEFAULT_ORDER
OrderCustom(
'_deployment_status',
self.DEPLOYMENT_STATUS_DEFAULT_ORDER,
array_type='varchar',
),
'-date_modified',
)
Expand Down
20 changes: 17 additions & 3 deletions kpi/utils/django_orm_helper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# coding: utf-8
from __future__ import annotations

import json
from typing import Optional, Literal

from django.db.models import Lookup, Field
from django.db.models.expressions import Func, Value
Expand Down Expand Up @@ -38,13 +40,25 @@ def __init__(self, expression: str, keyname: str, increment: int, **extra):
)


class OrderRandom(Func):
class OrderCustom(Func):

function = 'array_position'
template = '%(function)s(ARRAY%(order_list)s, %(expressions)s)'
arity = 1

def __init__(self, expression: str, order_list: list, **extra):
def __init__(
self,
expression: str,
order_list: list,
array_type: Optional[Literal['varchar']] = None,
**extra
):

# With PostgreSQL 13 (and older), `array_position` needs explicit type
# casts to work. By default, `order_list` is treated as `text[]`
# TODO Remove this condition when PostgreSQL 13 becomes deprecated.
if array_type == 'varchar':
self.template = '%(function)s(ARRAY%(order_list)s::varchar[], %(expressions)s)'

if expression.startswith('-'):
order_list.reverse()
Expand Down

0 comments on commit eb1e7f3

Please sign in to comment.