Skip to content

CONCEPT Cited by 1 source

Postgres stored-procedure language pluggability

Postgres stored procedures and functions can be written in any registered procedural language — PL/pgSQL (the default), PL/Python, PL/Perl, PL/Tcl, PL/V8 (JavaScript), PL/Ruby, PL/Java, and others loaded as extensions. MySQL stored procedures must be written in standard SQL.

MySQL requires that the procedure is written in the standard SQL syntax. This contrasts with Postgres, where the Procedures are based on functions and can be written in other languages, such as Ruby, Perl, SQL, Python, JavaScript, and others.

sources/2026-04-21-planetscale-migrating-from-postgres-to-mysql

What Postgres gives you

CREATE FUNCTION parse_json(raw TEXT) RETURNS JSONB
  AS $$ ... Python code ... $$
  LANGUAGE plpython3u;

Any code that the registered interpreter can execute, run inside the database session with full access to arguments and return values. The procedural-language layer is part of Postgres's extension story — the same mechanism that makes Aurora DSQL's Rust-in-Postgres story possible. See sources/2025-05-27-allthingsdistributed-aurora-dsql-rust-journey.

What MySQL restricts you to

CREATE PROCEDURE parse_json(IN raw TEXT)
BEGIN
  -- standard SQL only
END;

MySQL procedures are SQL-only — no interpreter pluggability, no extension story. User-defined functions (UDFs) in C are possible but are a different, installation-level extension.

Migration implication

A Postgres → MySQL migration has to enumerate every procedure written in a non-SQL language and make one of three choices:

  1. Port to SQL — if the logic is expressible in SQL.
  2. Move the logic into the application — if the procedural language was used for complex branching or external library access.
  3. Move the logic into a MySQL UDF — compiled C extension installed at the server level. High-friction; usually not worth it unless the procedure is performance-critical.

The PlanetScale post adds a parallel hazard for Postgres extensions:

If you're using [extensions in Postgres], it can make a migration even trickier, so make sure to audit each of these individually before migrating.

MySQL has no analogue to the Postgres extension API; every extension that was in use (pg_cron, postgis, pg_stat_statements, etc.) has to be replaced with a MySQL equivalent (scheduled events, spatial types, performance schema) or the functionality has to move out of the database.

Last updated · 378 distilled / 1,213 read