Repository navigation
Conversation
Since JSQLParser#2700, every PostgreSQL ALTER DATABASE fails to parse, while 5.4 returned an UnsupportedStatement. Model RENAME TO, OWNER TO, SET TABLESPACE, REFRESH COLLATION VERSION, the [WITH] options and SET/RESET of configuration parameters. Outside the MySQL dialect, other ALTER DATABASE forms are unsupported statements again, and ALTER SCHEMA with MySQL options no longer requires that dialect. Extract the SET/RESET state of AlterRole into ConfigurationParameterChange, which ALTER DATABASE shares; AlterRole keeps its accessors. Type each PostgreSQL CREATE DATABASE option, accept the CHAR SET and CHARSET spellings, keep CreateDatabase options in one list and drop the empty raw option that added a trailing space. Signed-off-by: minleejae <mmj9808@gmail.com>
This was referenced Oct 14, 2026
…outine definers Model PostgreSQL ALTER FUNCTION/PROCEDURE/ROUTINE and MySQL ALTER FUNCTION/PROCEDURE as AlterRoutine with typed RoutineCharacteristic items shared by both dialects; SET/RESET reuse ConfigurationParameterChange and the MySQL COMMENT keeps its literal as a StringValue. Add PostgreSQL ALTER TRIGGER as AlterTrigger. Unmodelled forms remain unsupported statements. Keep the MySQL DEFINER of CREATE FUNCTION/PROCEDURE, accept CREATE TRIGGER IF NOT EXISTS, keep MariaDB's OR REPLACE, and capture procedural trigger bodies with the routine body boundary so the next statement is split correctly. Signed-off-by: minleejae <mmj9808@gmail.com>
minleejae
force-pushed
the
feat/routine-alterations-20261014
branch
from
October 14, 2026 09:24
e9df9d9 to
c458ecb
Compare
This was referenced Oct 14, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #2811, which adds
ConfigurationParameterChange; please review that PR first. This PR is the second commit on top of it.Purpose
Parse the routine and trigger changes that PostgreSQL and MySQL dumps and migrations emit:
ALTER FUNCTION,ALTER PROCEDUREandALTER ROUTINE, andALTER TRIGGER, areUnsupportedStatements. pg_dump writesALTER FUNCTION f(int) OWNER TO rolefor every function.ALTER FUNCTION/ALTER PROCEDUREcharacteristics, such asALTER PROCEDURE p COMMENT 'x' SQL SECURITY INVOKER, areUnsupportedStatements.CREATE DEFINER = ... FUNCTION|PROCEDUREandCREATE TRIGGER IF NOT EXISTSfail.FOR EACH ROW BEGIN IF ... END IF; END, fails. A body of plain statements parses, but it takes the;afterEND, so a script fails at the next statement.Current design (As-is)
Alter()has no alternative for these statements, so its fallback captures them asUnsupportedStatements.Create()sends everyDEFINERprefix toCreateTrigger(), soCREATE DEFINER = ... FUNCTIONfails.CreateFunctionalStatementhas no definer.CreateTrigger()reads its body withSingleStatement() | Block().Block()accepts SQL statements only and consumes a following semicolon. The MySQL trigger path also dropsOR REPLACE.Target design (To-be)
AlterRoutinefor PostgreSQLALTER FUNCTION|PROCEDURE|ROUTINEand MySQLALTER FUNCTION|PROCEDURE. Both dialects share one statement because they change the same routine characteristics; only the spelling differs.getRoutineType()andgetRoutine(), the existingRoutineReferencewith the optional PostgreSQL argument types.Action:CHARACTERISTICS(the default),RENAME,OWNER,SET_SCHEMAandDEPENDS_ON_EXTENSIONwithisNoDependency(). Payloads of other actions are kept, as inAlterDatabase.getCharacteristics(): a mutable list of the newRoutineCharacteristicin source order, plus PostgreSQL'sisRestrict().RoutineCharacteristic.Kindhas one value per characteristic, and each renders its own keywords:IMMUTABLE,STABLE,VOLATILE,CALLED_ON_NULL_INPUT,RETURNS_NULL_ON_NULL_INPUT,STRICT,[NOT_]LEAKPROOF,PARALLEL_*,COST,ROWS,SUPPORTandCONFIGURATION_PARAMETER;COMMENT,LANGUAGE_SQL,CONTAINS_SQL,NO_SQL,READS_SQL_DATAandMODIFIES_SQL_DATA;SECURITY_DEFINERandSECURITY_INVOKER.getSecurityClause()keeps theSECURITY,EXTERNAL SECURITYor MySQLSQL SECURITYspelling.COST,ROWS,SUPPORTandCOMMENTkeep their value as SQL text ingetValue().getComment()returns theCOMMENTliteral as aStringValue, read with the parser's dialect escaping, sogetNotExcapedValue()is the text MySQL stores.SET/RESETreuseConfigurationParameterChangeand its grammar production from Parse PostgreSQL ALTER DATABASE and share typed database options #2811.AlterTriggerfor PostgreSQLALTER TRIGGER name ON table RENAME TO | [NO] DEPENDS ON EXTENSION, with the table as aTable.AlterRoutineonly when a known alteration follows the routine name and signature. Other forms, such as Oracle'sCOMPILE, DB2'sNOT FENCEDor SQL Server definitions without the SQL Server dialect, remainUnsupportedStatements; withDialect.SQLSERVERthey are stillCreateFunctionalStatements.RESTRICT; MySQL characteristics take no argument list and noALTER ROUTINE. Invalid combinations, such as commas orRENAME TO g RESTRICT, are errors.ALTER TRIGGERis selected only when the whole statement matches.CREATE:CreateFunctionalStatement.getDefiner()holds theDEFINERaccount as theMySqlDefinerthat views and triggers use.Create()now picks the trigger or routine after the definer.CreateTrigger.isIfNotExists()recordsIF NOT EXISTS. MariaDB'sOR REPLACEis kept on the MySQL path; combining it withIF NOT EXISTSis an error.BEGIN ... ENDtrigger body with only SQL statements remains aBlock. Other compound bodies (IF,CASE, loops,DECLARE, labels) are captured with the existingRoutineBodyBoundary, as forCREATE PROCEDURE, and kept as anUnsupportedStatementbody. Both leave the;afterENDto separate statements.Block()now uses a sharedBeginEndBlock()production; its behavior is unchanged.StatementVisitordefaults,StatementVisitorAdapter,StatementDeParser(SET values through the expression deparser) andTablesNamesFinder(theALTER TRIGGERtable);alterFunctionandalterProcedurefeatures and newalterRoutineandalterTrigger. PostgreSQL enables all four, MySQL and MariaDB the first two;MODIFIES_SCHEMA;Validation
Dialect.POSTGRESQL,Dialect.MYSQL,Dialect.MARIADBand without a dialect, plus statement boundaries in scripts;COMMENTliterals ('it\'s','it''s',"dq", backslash escapes, Korean text and emoji) against the text MySQL stores;UnsupportedStatement, rejected combinations, and unchanged SQL Server routines;IF NOT EXISTS/OR REPLACE, structured and procedural trigger bodies, and unterminated bodies;spotlessApply check: 10,550 tests, 10,525 passed, 25 skipped, zero failures/errors. The grammar choice conflict check passes.master(bdf8ac31) on a corpus of 635 MySQL 8.4 and PostgreSQL 18 DDL/DCL statements, each accepted by the server, plus variants (theALTER DATABASE/CHARSETfixes come from Parse PostgreSQL ALTER DATABASE and share typed database options #2811):Dialect.POSTGRESQLand without a dialect:ALTER FUNCTION f2(int) OWNER TO/RENAME TO/SET search_path = ...,ALTER PROCEDURE p1(int) SECURITY DEFINER,ALTER ROUTINE f2(int) IMMUTABLEandALTER TRIGGER trg ON users RENAME TO trg_new.Dialect.MYSQLand without a dialect:ALTER PROCEDURE ... COMMENT ... SQL SECURITY INVOKER,ALTER FUNCTION ... READS SQL DATA,CREATE DEFINER = ... FUNCTION|PROCEDURE,CREATE [DEFINER = ...] TRIGGER IF NOT EXISTSand the trigger with anIFbody.toString()on a second, identical server, in the same order. All 211 MySQL and 338 PostgreSQL statements give the same result (success, or the same error).Integration validation
Applied #2806–#2819 together on
master(bdf8ac31), with the stacked PRs on top of their bases (#2806 → #2807 → #2808, #2806 → #2809 → #2810 and #2811 → #2812).master. Between the branches, conflicts are limited to adjacent additions (README/index rows, usage sections, imports, visitor and feature lists, one enum line and one alias guard).spotlessApply check: 11,494 tests, 11,469 passed, 25 skipped, zero failures/errors. The grammar choice conflict check passes.master: 206) and 363 of 364 PostgreSQL statements (master: 328). Every MySQL 8.4 non-reserved word and PostgreSQL 18 unreserved or column-name keyword parses as a column and table name.