Skip to content

Instantly share code, notes, and snippets.

@mkurz
Created October 12, 2026 15:37
Show Gist options
  • Select an option

  • Save mkurz/82c786abada55248ff873dccd39ac4a2 to your computer and use it in GitHub Desktop.

Select an option

Save mkurz/82c786abada55248ff873dccd39ac4a2 to your computer and use it in GitHub Desktop.
Play Ebean: generated 1.sql before/after playframework/play-ebean#922

Generated 1.sql before and after playframework/play-ebean#922

The first revision of this gist has the evolution scripts that Play Ebean generates without the change, the second revision has the ones it generates with it. Open Revisions at the top and choose Split to see them side by side.

The scripts were generated offline from the test models of the PR:

File Platform Models What changes
1-mysql-mariadb-procedures.sql MySQL (MariaDB generates the same procedures) Author stored procedures with delimiter $$
2-sqlserver-go-procedures.sql SQL Server Author GO and stored procedures
3-postgres-history.sql Postgres Author, Book (@History) trigger function with $$
4-oracle-sequence.sql Oracle Publisher (sequence id) PL/SQL block in the Downs that drops the sequence
5-h2-comment-with-semicolons.sql H2 (any platform) Publisher (@DbComment with ; and ;;) column comment with semicolons

Where Play already splits the DDL like Ebean, e.g. on H2 with only Author, the script stays byte-identical, so it isn't included here.

-- Created by Ebean DDL
-- To stop Ebean DDL generation, remove this comment (both lines) and start using Evolutions
-- !Ups
DROP PROCEDURE IF EXISTS usp_ebean_drop_foreign_keys;
-- !split-semicolon: never
--
-- PROCEDURE: usp_ebean_drop_foreign_keys TABLE, COLUMN
-- deletes all constraints and foreign keys referring to TABLE.COLUMN
--
CREATE PROCEDURE usp_ebean_drop_foreign_keys(IN p_table_name VARCHAR(255), IN p_column_name VARCHAR(255))
-- play-ebean-start
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE c_fk_name CHAR(255);
DECLARE curs CURSOR FOR SELECT CONSTRAINT_NAME from information_schema.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = DATABASE() and TABLE_NAME = p_table_name and COLUMN_NAME = p_column_name
AND REFERENCED_TABLE_NAME IS NOT NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN curs;
read_loop: LOOP
FETCH curs INTO c_fk_name;
IF done THEN
LEAVE read_loop;
END IF;
SET @sql = CONCAT('ALTER TABLE `', p_table_name, '` DROP FOREIGN KEY ', c_fk_name);
PREPARE stmt FROM @sql;
EXECUTE stmt;
END LOOP;
CLOSE curs;
-- play-ebean-end
END
-- !split-semicolon: always
;
DROP PROCEDURE IF EXISTS usp_ebean_drop_column;
-- !split-semicolon: never
--
-- PROCEDURE: usp_ebean_drop_column TABLE, COLUMN
-- deletes the column and ensures that all indices and constraints are dropped first
--
CREATE PROCEDURE usp_ebean_drop_column(IN p_table_name VARCHAR(255), IN p_column_name VARCHAR(255))
-- play-ebean-start
BEGIN
CALL usp_ebean_drop_foreign_keys(p_table_name, p_column_name);
SET @sql = CONCAT('ALTER TABLE `', p_table_name, '` DROP COLUMN `', p_column_name, '`');
PREPARE stmt FROM @sql;
EXECUTE stmt;
-- play-ebean-end
END
-- !split-semicolon: always
;
create table author (
id bigint auto_increment not null,
name varchar(255),
constraint pk_author primary key (id)
);
-- !Downs
-- drop all
drop table if exists author;
-- Created by Ebean DDL
-- To stop Ebean DDL generation, remove this comment (both lines) and start using Evolutions
-- !Ups
if not exists (select name from sys.types where name = 'ebean_bigint_tvp') create type ebean_bigint_tvp as table (c1 bigint);
if not exists (select name from sys.types where name = 'ebean_float_tvp') create type ebean_float_tvp as table (c1 float);
if not exists (select name from sys.types where name = 'ebean_bit_tvp') create type ebean_bit_tvp as table (c1 bit);
if not exists (select name from sys.types where name = 'ebean_date_tvp') create type ebean_date_tvp as table (c1 date);
if not exists (select name from sys.types where name = 'ebean_time_tvp') create type ebean_time_tvp as table (c1 time);
if not exists (select name from sys.types where name = 'ebean_uniqueidentifier_tvp') create type ebean_uniqueidentifier_tvp as table (c1 uniqueidentifier);
if not exists (select name from sys.types where name = 'ebean_nvarchar_tvp') create type ebean_nvarchar_tvp as table (c1 nvarchar(max));
-- !split-semicolon: never
CREATE OR ALTER PROCEDURE usp_ebean_drop_indices @tableName nvarchar(255), @columnName nvarchar(255)
AS
-- play-ebean-start
SET NOCOUNT ON
declare @sql nvarchar(1000)
declare @indexName nvarchar(255)
BEGIN
DECLARE index_cursor CURSOR FOR SELECT i.name from sys.indexes i
join sys.index_columns ic on ic.object_id = i.object_id and ic.index_id = i.index_id
join sys.columns c on c.object_id = ic.object_id and c.column_id = ic.column_id
where i.object_id = OBJECT_ID(@tableName) AND c.name = @columnName;
OPEN index_cursor
FETCH NEXT FROM index_cursor INTO @indexName
WHILE @@FETCH_STATUS = 0
BEGIN
set @sql = 'drop index ' + @indexName + ' on [' + @tableName + ']';
EXECUTE(@sql);
FETCH NEXT FROM index_cursor INTO @indexName
END;
CLOSE index_cursor;
DEALLOCATE index_cursor;
END
-- play-ebean-end
-- !split-semicolon: always
;
-- !split-semicolon: never
CREATE OR ALTER PROCEDURE usp_ebean_drop_default_constraint @tableName nvarchar(255), @columnName nvarchar(255)
AS
-- play-ebean-start
SET NOCOUNT ON
declare @tmp nvarchar(1000)
BEGIN
select @tmp = t1.name from sys.default_constraints t1
join sys.columns t2 on t1.object_id = t2.default_object_id
where t1.parent_object_id = OBJECT_ID(@tableName) and t2.name = @columnName;
if @tmp is not null EXEC('alter table [' + @tableName +'] drop constraint ' + @tmp);
END
-- play-ebean-end
-- !split-semicolon: always
;
-- !split-semicolon: never
CREATE OR ALTER PROCEDURE usp_ebean_drop_constraints @tableName nvarchar(255), @columnName nvarchar(255)
AS
-- play-ebean-start
SET NOCOUNT ON
declare @sql nvarchar(1000)
declare @constraintName nvarchar(255)
BEGIN
DECLARE name_cursor CURSOR FOR
SELECT cc.name from sys.check_constraints cc
join sys.columns c on c.object_id = cc.parent_object_id and c.column_id = cc.parent_column_id
where parent_object_id = OBJECT_ID(@tableName) AND c.name = @columnName
UNION SELECT fk.name from sys.foreign_keys fk
join sys.foreign_key_columns fkc on fkc.constraint_object_id = fk.object_id
and fkc.parent_object_id = fk.parent_object_id
join sys.columns c on c.object_id = fkc.parent_object_id and c.column_id = fkc.parent_column_id
where fkc.parent_object_id = OBJECT_ID(@tableName) AND c.name = @columnName;
OPEN name_cursor
FETCH NEXT FROM name_cursor INTO @constraintName
WHILE @@FETCH_STATUS = 0
BEGIN
set @sql = 'alter table [' + @tableName + '] drop constraint ' + @constraintName;
EXECUTE(@sql);
FETCH NEXT FROM name_cursor INTO @constraintName
END;
CLOSE name_cursor;
DEALLOCATE name_cursor;
END
-- play-ebean-end
-- !split-semicolon: always
;
-- !split-semicolon: never
CREATE OR ALTER PROCEDURE usp_ebean_drop_column @tableName nvarchar(255), @columnName nvarchar(255)
AS
-- play-ebean-start
SET NOCOUNT ON
declare @sql nvarchar(1000)
BEGIN
EXEC usp_ebean_drop_indices @tableName, @columnName;
EXEC usp_ebean_drop_default_constraint @tableName, @columnName;
EXEC usp_ebean_drop_constraints @tableName, @columnName;
set @sql = 'alter table [' + @tableName + '] drop column [' + @columnName + ']';
EXECUTE(@sql);
END
-- play-ebean-end
-- !split-semicolon: always
;
create table author (
id bigint not null,
name nvarchar(255),
constraint pk_author primary key (id)
);
create sequence author_seq as bigint start with 1 increment by 50;
-- !Downs
-- drop all
if exists (select name from sys.types where name = 'ebean_bigint_tvp') drop type ebean_bigint_tvp;
if exists (select name from sys.types where name = 'ebean_float_tvp') drop type ebean_float_tvp;
if exists (select name from sys.types where name = 'ebean_bit_tvp') drop type ebean_bit_tvp;
if exists (select name from sys.types where name = 'ebean_date_tvp') drop type ebean_date_tvp;
if exists (select name from sys.types where name = 'ebean_time_tvp') drop type ebean_time_tvp;
if exists (select name from sys.types where name = 'ebean_uniqueidentifier_tvp') drop type ebean_uniqueidentifier_tvp;
if exists (select name from sys.types where name = 'ebean_nvarchar_tvp') drop type ebean_nvarchar_tvp;
IF OBJECT_ID('author', 'U') IS NOT NULL drop table author;
IF OBJECT_ID('author_seq', 'SO') IS NOT NULL drop sequence author_seq;
-- Created by Ebean DDL
-- To stop Ebean DDL generation, remove this comment (both lines) and start using Evolutions
-- !Ups
create table author (
id bigint generated by default as identity not null,
name varchar,
constraint pk_author primary key (id)
);
create table book (
id bigint generated by default as identity not null,
author_id bigint,
title varchar,
constraint pk_book primary key (id)
);
alter table book add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
create table book_history(like book);
create view book_with_history as select * from book union all select * from book_history;
-- !split-semicolon: never
create or replace function book_history_version() returns trigger as $$
-- play-ebean-start
declare
lowerTs timestamptz;
upperTs timestamptz;
begin
lowerTs = lower(OLD.sys_period);
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
if (TG_OP = 'UPDATE') then
insert into book_history (sys_period,id, title, author_id) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.title, OLD.author_id);
NEW.sys_period = tstzrange(upperTs,null);
return new;
elsif (TG_OP = 'DELETE') then
insert into book_history (sys_period,id, title, author_id) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.title, OLD.author_id);
return old;
end if;
end;
-- play-ebean-end
$$ LANGUAGE plpgsql
-- !split-semicolon: always
;
create trigger book_history_upd
before update or delete on book
for each row execute procedure book_history_version();
create index ix_book_author_id on book (author_id);
alter table book add constraint fk_book_author_id foreign key (author_id) references author (id) on delete restrict on update restrict;
-- !Downs
-- drop all foreign keys
alter table if exists book drop constraint if exists fk_book_author_id;
drop index if exists ix_book_author_id;
-- drop all
drop table if exists author cascade;
drop trigger if exists book_history_upd on book cascade;
drop function if exists book_history_version();
drop view book_with_history;
drop table book_history;
drop table if exists book cascade;
-- Created by Ebean DDL
-- To stop Ebean DDL generation, remove this comment (both lines) and start using Evolutions
-- !Ups
create table publisher (
id number(19) not null,
name varchar2(255),
constraint pk_publisher primary key (id)
);
-- !split-semicolon: never
comment on column publisher.name is 'Semicolons: ; and ;; stay as they are'
-- !split-semicolon: always
;
create sequence publisher_seq increment by 1;
-- !Downs
drop table publisher cascade constraints purge;
-- !split-semicolon: never
declare
expected_error exception;
pragma exception_init(expected_error, -2289);
begin
execute immediate 'drop sequence publisher_seq';
exception
when expected_error then null;
end;
-- !split-semicolon: always
;
-- Created by Ebean DDL
-- To stop Ebean DDL generation, remove this comment (both lines) and start using Evolutions
-- !Ups
create table publisher (
id bigint not null,
name varchar(255),
constraint pk_publisher primary key (id)
);
-- !split-semicolon: never
comment on column publisher.name is 'Semicolons: ; and ;; stay as they are'
-- !split-semicolon: always
;
create sequence publisher_seq increment by 1;
-- !Downs
-- drop all
drop table if exists publisher;
drop sequence if exists publisher_seq;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment