Votre première erreur a été de stocker une date sous forme de colonne varchar. Vous ne devriez pas faire ça.
La solution appropriée à votre problème consiste à convertir la colonne en une vraie date
colonne .
Maintenant, je suis à peu près sûr que la réponse à cette affirmation est "Je n'ai pas conçu la base de données et je ne peux pas la modifier", alors voici une solution de contournement :
CAST
et to_char()
ne sont pas immuables car ils peuvent renvoyer des valeurs différentes pour la même valeur d'entrée en fonction des paramètres de la session en cours.
Si vous savez que vous avez un format cohérent de toutes les valeurs de la table (ce qui - si vous l'aviez - signifierait que vous pouvez convertir la colonne en une vraie date
column) alors vous pouvez créer votre propre fonction qui convertit un varchar en une date et est marquée comme immuable.
create or replace function fix_bad_datatype(the_date varchar)
returns date
language sql
immutable
as
$body$
select to_date(the_date, 'yyyy-mm-dd');
$body$
ROWS 1
/
Avec cette définition, vous pouvez créer un index sur l'expression :
CREATE INDEX date_index ON table_name (fix_bad_datatype(varchar_column));
Mais vous avez pour utiliser exactement cet appel de fonction dans votre requête afin que Postgres l'utilise :
select *
from foo
where fix_bad_datatype(varchar_column) < current_date;
Notez que cette approche échouera gravement si vous n'avez qu'une seule valeur "illégale" dans votre colonne varchar. La seule solution sensée est pour stocker les dates sous la forme date
s,