PostgreSQL Error 22019: Invalid Escape Character
PostgreSQL error code 22019 (invalid_escape_character) is raised when the ESCAPE clause in a LIKE or SIMILAR TO expression receives a value that is not exactly one character long. The SQL standard strictly requires the escape character to be a single character — an empty string or a multi-character string will both trigger this error immediately.
Top 3 Causes
1. Empty or Multi-Character String in ESCAPE Clause
The most common cause is passing an empty string or a string with more than one character to the ESCAPE clause.
-- ❌ Empty string as escape character
SELECT * FROM products
WHERE name LIKE '50\%' ESCAPE '';
-- ❌ Two-character escape sequence
SELECT * FROM products
WHERE name LIKE '50!_%' ESCAPE '!!';
-- ✅ Correct: exactly one character
SELECT * FROM products
WHERE name LIKE '50!%' ESCAPE '!';
2. Dynamically Generated Queries Without Input Validation
When applications or ORMs build SQL queries dynamically, the escape character value may come from user input or a variable that hasn't been validated for length. This often surfaces in production when edge-case inputs are entered.
-- ✅ Safe PL/pgSQL function with validated escape character
CREATE OR REPLACE FUNCTION search_items(p_keyword TEXT)
RETURNS TABLE(id INT, name TEXT) AS $$
DECLARE
v_esc CHAR(1) := '!';
v_pattern TEXT;
BEGIN
-- Safely escape special LIKE characters in the input
v_pattern := replace(replace(replace(p_keyword, '!', '!!'), '%', '!%'), '_', '!_');
RETURN QUERY
SELECT i.id, i.name
FROM items i
WHERE i.name LIKE '%' || v_pattern || '%' ESCAPE v_esc;
END;
$$ LANGUAGE plpgsql;
-- Usage
SELECT * FROM search_items('50% off');
SELECT * FROM search_items('size_M');
3. Confusion with standard_conforming_strings Setting
Since PostgreSQL 9.1, standard_conforming_strings defaults to on, meaning backslashes are treated as literal characters, not escape sequences. Developers accustomed to older behavior may write patterns that result in an unintended multi-character value being passed to ESCAPE.
-- Check current setting
SHOW standard_conforming_strings;
-- ❌ Can cause confusion when standard_conforming_strings = on
SELECT * FROM orders WHERE ref LIKE E'100\\%' ESCAPE E'\\';
-- ✅ Avoid confusion by using a non-backslash escape character
SELECT * FROM orders WHERE ref LIKE '100#%' ESCAPE '#';
-- ✅ SIMILAR TO example with proper escape
SELECT * FROM users WHERE email SIMILAR TO '%(gmail|yahoo)\.com' ESCAPE '\';
Quick Fix Solutions
Create a reusable utility function to safely escape LIKE patterns across your entire codebase:
CREATE OR REPLACE FUNCTION escape_like(
p_input TEXT,
p_esc CHAR(1) DEFAULT '!'
)
RETURNS TEXT AS $$
BEGIN
RETURN replace(
replace(
replace(p_input, p_esc, p_esc || p_esc),
'%', p_esc || '%'
),
'_', p_esc || '_'
);
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
-- Test it
SELECT escape_like('hello_world%test');
-- Returns: hello!_world!%test
-- Use in a query
SELECT * FROM products
WHERE name LIKE '%' || escape_like('50% discount') || '%' ESCAPE '!';
Prevention Tips
Standardize your escape character: Choose one escape character (e.g.,
!) for your entire project and enforce it through a shared utility function likeescape_like()above. Document this in your team's coding conventions.Always use parameterized queries: Never interpolate raw user input directly into SQL strings. Use prepared statements and parameter binding in your application layer. Add unit tests that cover edge cases such as empty strings,
%,_, and multi-character inputs to catch this error before it reaches production.
Related Errors
| Code | Name | Description |
|---|---|---|
22025 |
invalid_escape_sequence |
Valid escape character, but the sequence itself is malformed (e.g., E'\q') |
2200C |
invalid_use_of_escape_character |
Escape character used in a context where it is not permitted |
42601 |
syntax_error |
Completely malformed escape syntax may surface as a syntax error instead |
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)