Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored DDL generation to correctly handle quoted identifiers #2603

Merged
merged 12 commits into from
Mar 21, 2022

Conversation

rPraml
Copy link
Contributor

@rPraml rPraml commented Mar 18, 2022

This is a refactoring how DDL is generated, when quotedIdentifiers are used.

I've made an ETable entity, which uses a lot of reserved keywords.
This is something, that did not work for all platforms (especially MySql and SqlServer, as they use different quote chars than ")

I checked if the generated migration scripts will work for H2/MySql/DB2/SqlServer and Hana.

It prepares ebean generate working migration scripts, if allQuotedIdentifiers=true is set - this probably will also be an other workaround for NONKEYWORDS=KEY,VALUE in H2

To make this PR smaller, I've extracted some commits into separate PRs.
@rbygrave you can decide, if you either merge this PR or the smaller ones and I will update the PR next week

@rPraml rPraml force-pushed the remove-lowertablename branch from cf45fab to 7e3fbbb Compare March 21, 2022 10:52
@rPraml rPraml changed the title Removed 'lowerTableName' and 'lowerColumnName' Refactored DDL generation to correctly handle quoted identifiers Mar 21, 2022
/**
* Trim off the platform quoted identifier quotes like [ ' and ".
*/
public boolean notQuoted(String tableName) {
public String trimQuotes(String identifier) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just renamed

if (dbName.charAt(0) == BACK_TICK) {
if (dbName.charAt(dbName.length() - 1) == BACK_TICK) {
if (isQuote(dbName.charAt(0))) {
if (isQuote(dbName.charAt(dbName.length() - 1))) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method converts any quoted identifier into the platform specific form

if (column != null) {
target.append(' ').append(column);
target.append(' ').append(platformDdl.quote(column));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to quote table & column name here

@@ -755,7 +741,7 @@ private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) {
* Return the name of the history table given the base table name.
*/
protected String historyTable(String baseTable) {
return baseTable + historyTableSuffix;
return naming.normaliseTable(baseTable) + historyTableSuffix;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

baseTable must always be normalized (=stripped from identifiers)
Note to myself: I think, we must pay attention for an optional scheme/catalog here (see SqlServerDdl)


.append(" prepare stmt from 'alter table ").append(lowerTableName(tableName))
.append("' and tabname = '").append(naming.normaliseTable(tableName).toUpperCase()).append("') then\n")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to myself: check if this match should be changed to and lcase(tabname) =

if (addColumn == null) {
addColumn = new AddColumn();
addColumn.setTableName(name);
if (withHistory) {
if (newTable.isWithHistory()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We must enable history only, when the new table has history.
if you disable history, then the old table has history, but not the new one

create table PERSONS (
ID bigint generated by default as identity (start with 1000 increment by 40) not null,
SURNAME varchar(64) not null,
NAME varchar(64) not null,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rbygrave due the removal of "lowerTableName", we will get uppercase names here.
I think, this is OK, because it is specified as @Table(name = "PERSONS") / @Column(name = "ID")
If you want lower case names, specify them in the annotation

@Table(name = "`table`")
@Entity
@History
public class ETable {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the "Reserved-keyword" entity. It uses a keyword for each fied and tries to address as many as possible features during DDL generation


@Table(name = "`table`")
@Entity
@History // FIXME: remove later
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rbygrave It is currently impossible for some platforms to enable/disable history while there are pending drops.
(it will generate the wrong history table)
I don't mind this is a real limitation. I added a sanity check in Ddl-gneration

// This could be probably fixed, by generating history table also with dropped columns
@Column(name = "`select`")
@Index(unique = true)
private String select;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to myself: This CAN be removed now, as long as previous version is under @history

@rbygrave rbygrave added this to the 12.16.1 milestone Mar 21, 2022
@rbygrave rbygrave merged commit 66aa772 into ebean-orm:master Mar 21, 2022
@rPraml rPraml deleted the remove-lowertablename branch August 10, 2023 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants