The function or procedure was declared NO SQL or READS SQL DATA but contains disallowed SQL commands, triggering error code 38001.
containing_sql_not_permitted (SQLSTATE 38001) appears when a PostgreSQL function or procedure declared NO SQL or READS SQL DATA includes SQL statements that violate that declaration. Edit the routine to remove the statements or change the SQL-data access clause (e.g., to MODIFIES SQL DATA) to resolve the error.
containing_sql_not_permitted
PostgreSQL returns SQLSTATE 38001 with the condition name containing_sql_not_permitted when a routine declared with a restrictive SQL-data access clause attempts to execute a forbidden SQL command.
The error protects the database from side effects that violate the routines contract.
It commonly surfaces after creating functions or procedures with NO SQL or READS SQL DATA clauses in PostgreSQL 14+.
The database raises error 38001 the moment the function body parses or executes a statement that contradicts its declared SQL-data access level.
For example, an INSERT inside a routine marked NO SQL violates the contract immediately.
Developers often copy code between routines and forget to change the SQL-data access modifier, or ORMs generate routines with overly strict clauses.
Fixes revolve around aligning the routines body with its declaration.
Remove the offending SQL commands or switch the declaration from NO SQL / READS SQL DATA to MODIFIES SQL DATA or CONTAINS SQL, whichever accurately reflects the behavior.
After updating the CREATE FUNCTION or CREATE PROCEDURE statement, redeploy the routine and rerun the calling query to confirm the error disappears.
Data-modifying command in NO SQL routine - change clause to MODIFIES SQL DATA.
Select query inside NO SQL routine - switch to READS SQL DATA or CONTAINS SQL.
Accidental default (NO SQL) from code generator - override with the correct clause during compilation.
Always choose the least-restrictive SQL-data access level that still meets security requirements.
Document it in code review checklists.
Automate static analysis to flag mismatches between routine declarations and their SQL bodies before deployment.
38002 - modifying_sql_not_permitted: raised when a READS SQL DATA routine performs DML. Fix by changing to MODIFIES SQL DATA.
0LP01 - invalid_function_definition: returned when function attribute combinations are illegal. Review the CREATE FUNCTION statement.
.
An INSERT, UPDATE, DELETE, or MERGE inside a NO SQL routine instantly violates the contract.
READS SQL DATA allows SELECTs only.
Any data change triggers error 38001 in PostgreSQL 15+ when the stricter 38002 code is unavailable.
Some tools set NO SQL by default for portability, causing unexpected failures after developers add SQL statements.
Developers paste code containing side-effect statements into an old routine without updating its header.
.
No. SQL-data access clauses were added in PostgreSQL 14. Earlier versions ignore NO SQL and will not raise 38001.
PostgreSQL validates at parse time. You cannot disable the check but you can omit the clause if you need unrestricted access.
No. The clause is only a metadata marker. It does not affect the execution plan or speed.
Galaxys SQL editor highlights SQL-data access clauses and warns when routine bodies violate them, reducing runtime errors like 38001.