Skip to content

Conversation

tobyhede
Copy link
Contributor

Given an encrypted column and an index defined as

CREATE INDEX encrypted_index ON encrypted (e eql_v2.encrypted_operator_class);

Indexes are not being used when the compared value was cast.

SELECT e::jsonb FROM encrypted WHERE e = '{"hm": "abc"}'::jsonb;
SELECT e::jsonb FROM encrypted WHERE e = '{"hm": "abc"}'::jsonb::encrypted;

Indexes are used when the value is the full literal tuple type

SELECT e::jsonb FROM encrypted WHERE e = '("{\"hm\": \"abc\"}")';

Adding the IMMUTABLE volatility category to the the type cast functions resolves the issue.

Copy link
Contributor

@yujiyokoo yujiyokoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why IMMUTABLE resolves the issue here 😅 but code LGTM

@tobyhede
Copy link
Contributor Author

@yujiyokoo What I wish I knew earlier: https://www.postgresql.org/docs/current/sql-createindex.html

All functions and operators used in an index definition must be “immutable”, that is, their results must depend only on their arguments and never on any outside influence (such as the contents of another table or the current time). This restriction ensures that the behavior of the index is well-defined. To use a user-defined function in an index expression or WHERE clause, remember to mark the function immutable when you create it.

@tobyhede tobyhede merged commit c338529 into main Jul 31, 2025
4 checks passed
@tobyhede tobyhede deleted the fix/cast-for-indexing branch July 31, 2025 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants