#26355: Add support for PostgreSQL's array_append to ArrayField
----------------------------------+------------------------------------
     Reporter:  graup             |                    Owner:
         Type:  New feature       |                   Status:  new
    Component:  contrib.postgres  |                  Version:  1.9
     Severity:  Normal            |               Resolution:
     Keywords:                    |             Triage Stage:  Accepted
    Has patch:  0                 |      Needs documentation:  0
  Needs tests:  0                 |  Patch needs improvement:  0
Easy pickings:  0                 |                    UI/UX:  0
----------------------------------+------------------------------------

Comment (by pope1ni):

 I would consider expanding the scope of this somewhat...

 In the following examples, `value` is the array `[1, 2, 3]`.

 Taking this back to the simple case, the following should be supported for
 `array_append` (or the `||` operator):

 {{{
 Python: Item.objects.update(value=F('value') + 3)
 SQL:    UPDATE item SET value = array_append(value, 3)
 SQL:    UPDATE item SET value = value || 3
 Result: [1, 2, 3, 3]
 }}}

 In addition, the `array_cat` function or `||` operator can be used to
 concatenate arrays:

 {{{
 Python: Item.objects.update(value=F('value') + [3, 4])
 SQL:    UPDATE item SET value = array_cat(value, ARRAY[3, 4])
 SQL:    UPDATE item SET value = value || ARRAY[3, 4]
 Result: [1, 2, 3, 3, 4]
 }}}

 Going back to the original description, we could implement set-like
 updates to arrays (using bitwise-or):

 {{{
 Python: Item.objects.exclude(value__contains=[3]).update(value=F('value')
 + 3)
 Python: Item.objects.update(value=F('value') | 3)
 SQL:    UPDATE item SET value = array_append(value, 3)
             WHERE NOT (value @> ARRAY[3]::int[])
 Result: [1, 2, 3]
 }}}

 The main challenge in all this is how to sensibly handle nested arrays.

 Also note that PostgreSQL supports assigning to indexes or slices of
 arrays - maybe this could also be added somehow:

 {{{
 Python: Item.objects.update(value__1=5)  # would need different syntax?
 SQL:    UPDATE item SET value[2] = 5
 Result: [1, 5, 3]
 }}}

 {{{
 Python: Item.objects.update(value__1_2=[5])  # would need different
 syntax?
 SQL:    UPDATE item SET value[2:2] = ARRAY[5]
 Result: [1, 5, 3]
 }}}

 {{{
 Python: Item.objects.update(value__1_3=[2, 1])  # would need different
 syntax?
 SQL:    UPDATE item SET value[2:3] = ARRAY[2, 1]
 Result: [1, 2, 1]
 }}}

 {{{
 Python: Item.objects.update(value__1_1=[4, 5, 6])  # would need different
 syntax?
 SQL:    UPDATE item SET value = value[array_lower(value, 1):1]
             || ARRAY[4, 5, 6] || value[3:array_upper(value, 1)];
 Result: [1, 4, 5, 6, 3]
 }}}

 Another consideration is for the `array_prepend` function, but I'm not
 sure how that could be handled nicely in the expressions syntax.

 We could also use `array_remove`, but this will remove all values that
 match - a bit like set difference:

 {{{
 Python: Item.objects.update(value=F('value') - 2)
 SQL:    UPDATE item SET value = array_remove(value, 2)
 Result: [1, 3]
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/26355#comment:3>
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/063.ae15b06a0987342d0a3606b4ed445d5b%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to