#34955: Make available the string concatenation operator `||` for PostgreSQL -------------------------------------+------------------------------------- Reporter: Paolo Melchiorre | Owner: nobody Type: New feature | Status: new Component: Database layer | Version: dev (models, ORM) | Severity: Normal | Resolution: Keywords: field, database, | Triage Stage: generated, output_field | Unreviewed Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+-------------------------------------
Comment (by Paolo Melchiorre): Replying to [comment:11 Simon Charette]: > > Unfortunately we can't change Concat() to use `||` because on pg it _does_ evaluate NULLs. If it were to use `||` then we _would_ need to make use of Coalesce() to make it consistent. > > That's the crux of the issue and why we had to go back and forth on how it was implemented on Postgres when adding support for functional index and constraints. There are few tickets related to this such one such as #29582 and #30385. Thanks, for pointing us to these old issues. > > the migrations generate this SQL code (code snipped with many unnecessary `::text`) > > This is a side effect of 09ffc5c1212d4ced58b708cbbf3dfbfb77b782ca (#33308) to accommodate support for `psycopg>3` server-side bindings. See 779cd28acb1f7eb06f629c0ea4ded99b5ebb670a (#34840) which removed many of them but [https://github.com/django/django/blob/f7389c4b07ceeb036436e065898e411b247bca78/django/db/models/functions/text.py#L90 some still remain]. Are you suggesting opening an issue to remove all the remaining unnecessary `CAST`? > Based on #30385 I think that the best way forward here is to stop using `CONCAT` entirely and use a strategy where it relies on `||` with `Coalesce` and `Cast` appropriately when dealing with expressions that are nullable and/or non-text. The challenge here is that we can't trust `.null` as the our output field resolving strategy doesn't carry `null` affinity. If we want to make sure `Concat` maintains is previous behaviour on Postgres we ''must'' wrap every source expression in `Coalesce`. I understand that `GeneratedField` is only the last one affected by the fact that `CONCAT` is not `IMMUTABLE` I agree with the plan to replace `CONCAT` everywhere with `||` given how many problems it would solve. > Normally when we change the SQL generated by an expression it leaves all index generated with the previous implementation unusable and forces users to re-create them but in this case it wasn't possible to even create such index as `Concat` is not `IMMUTABLE` so I don't think that's an issue. Better this way I would say, there will be no indexes that the user needs to re-create. -- Ticket URL: <https://code.djangoproject.com/ticket/34955#comment:12> 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 django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/0107018bb4efd5fe-ec10a6cd-6349-4282-a42e-74c9d4a9515b-000000%40eu-central-1.amazonses.com.