Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/Development/JPA 2.0/undelimited identifiers"

(Open Issues)
 
(11 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
[http://bugs.eclipse.org/251908 Enhancement Request]
 
[http://bugs.eclipse.org/251908 Enhancement Request]
 
==Issue Summary==
 
==Issue Summary==
The specification has added support to always treat meta data identifiers as if
+
The specification has added support to always treat metadata identifiers as if
 
they are "quoted" preserving case and allowing reserved words to be used.
 
they are "quoted" preserving case and allowing reserved words to be used.
  
  
 
See JPA 2.0 ED section 2.13 for details.
 
See JPA 2.0 ED section 2.13 for details.
 +
 +
This means SQL is sent to the database with a delimiter (usually the double quote).  For instance:
 +
 +
SELECT "id", "username" from "USER"
  
 
==General Solution==
 
==General Solution==
  
====Under Construction====
+
==== ORM.xml Parsing ====
 +
 
 +
A new attribute called useDelimitedIdentifiers will be added to our XMLPersistenceUnit defaults class and we will add parsing code to populate it from orm.xml.  useDelimitedIdentifiers will default to false and be accessible through a getter method.
 +
 
 +
==== Delimiters ====
 +
 
 +
Helper will store two delimiters, a start delimiter and an end delimiter.  By default, they will both be set to the double quote.  These delimiters will be used as the default.  Anyone specifying delimiters in annotations or orm.xml will be expected to use these default identifiers.
 +
 
 +
DatabasePlatform and subclasses will have instance variables added for start and end delimiter.  These will be initialized to the double quote by default and overridden as appropriate in other platforms.  In the initial implementation, only MySQL will have the delimiter overridden. (The default delimiter in MySQL is the backtick "`")  Note: Althrough SQLServer supports using square brackets as delimiters, a default installation also supports double quotes.
 +
 
 +
==== DatabaseField and DatabaseTable ====
 +
 
 +
The use of delimited identifiers will be represented on the DatabaseTable and DatabaseField with a boolean instance variable.  The following modifications will be made to the classes
 +
 
 +
DatabaseField
 +
* add setUseDelimiters(boolean) method to set the instance variable
 +
* add getNameDelimited(DatasourcePlatform) method that returns the name with delimiters
 +
* add getQualifiedNameDelimited(DatasourcePlatform) method to return a delimited version of the qualified name
 +
* change code that initializes the name instance variable to check for delimiters remove them from the name and set the flag
 +
* setName() will have versions added that take a delimiter and parse the delimiters
 +
 
 +
DatabaseTable
 +
* add setUseDelimiters(boolean) method to set the instance variable
 +
* add getNameDelimited(DatasourcePlatform) method that returns the name with delimiters
 +
* add getQualifiedNameDelimited(DatasourcePlatform) method to return a delimited version of the qualified name
 +
* alter getTableQualifier() to return the delimited version of the table qualifier
 +
* change code that initializes the name instance variable to check for delimiters remove them from the name and set the flag
 +
 
 +
The reason we have chose to manage delimiters with a flag rather than simply storing the quoted values as the name in DatabaseField and DatabaseTable is as follows:
  
At the moment, we already handle delimiters when they are specified in quoted field namesWe simply need to update to handle when delimited-identifiers is specified in orm.xml.
+
* It makes it easier for metadata processing code to avoid adding delimiters twice
 +
* Result sets from database reads never come back with delimiters.  As a result, in order to be able to look up fields in rows from the database, we need to be able to do a lookup without the delimiters
  
The first step is to add parsing logic to our orm.xml parser to get the data.
+
In the case where the delimited-identifiers flag is set as a persistence unit default and a field is delimited in the column definition (annotation or xml) we will delimit the field only once.
  
When the parsing is done, we will update our Field and Column name construction code to use the data.
+
==== Metadata processing ====
  
==Work Required==
+
Anywhere the metadata processing code creates a DatabaseField or DatabaseTable, a check will be done for useDelimitedIdentifiers in the persistence unit defaults and the useDelimitedIdentifiers flag on the DatabaseField or DatabaseTable will be set as appropriate.  Additionally, the setName() method will be called using the default delimiter (the double quote) on all processed attributes.
# Develop tests
+
#: approx 1 day
+
# Implement API
+
#: approx 3 days
+
  
== Open Issues==
+
==== Database Interaction ====
  
* Although double quote is usable in most cases, there are some cases where other delimiters would be useful. (e.g. In the default mode, MySQL requires a single quote be used for delimiters and will throw an error is a double quote is used as a delimiter for a table name)   
+
All calls to databaseField.getName() and databaseTable.getName(platform) that are used to build SQL will be changed to getNameDelimited(platform). Additionally schema generation code will be updated to use the delimited name.  This will require all calls that build SQL have access to the DatasoucePlatformA number of changes will be made to call stacks to allow this.
** DatabasePlatform is not available at processing time, so we may need to provide a eclipselink.sql.delimiter property
+
* Do we want any special handling if delimited-identifiers is specified in the orm.xml and also in an identifier
+
* When we use Delimited Identifiers, rowsets returned from the database to not include the delimitersThis will cause issues anywhere we try to look up values by Name (Native Queries, Max Results)
+

Latest revision as of 15:34, 9 September 2009

Undelimited Identifiers

JPA 2.0 Root | Enhancement Request

Issue Summary

The specification has added support to always treat metadata identifiers as if they are "quoted" preserving case and allowing reserved words to be used.


See JPA 2.0 ED section 2.13 for details.

This means SQL is sent to the database with a delimiter (usually the double quote). For instance:

SELECT "id", "username" from "USER"

General Solution

ORM.xml Parsing

A new attribute called useDelimitedIdentifiers will be added to our XMLPersistenceUnit defaults class and we will add parsing code to populate it from orm.xml. useDelimitedIdentifiers will default to false and be accessible through a getter method.

Delimiters

Helper will store two delimiters, a start delimiter and an end delimiter. By default, they will both be set to the double quote. These delimiters will be used as the default. Anyone specifying delimiters in annotations or orm.xml will be expected to use these default identifiers.

DatabasePlatform and subclasses will have instance variables added for start and end delimiter. These will be initialized to the double quote by default and overridden as appropriate in other platforms. In the initial implementation, only MySQL will have the delimiter overridden. (The default delimiter in MySQL is the backtick "`") Note: Althrough SQLServer supports using square brackets as delimiters, a default installation also supports double quotes.

DatabaseField and DatabaseTable

The use of delimited identifiers will be represented on the DatabaseTable and DatabaseField with a boolean instance variable. The following modifications will be made to the classes

DatabaseField

  • add setUseDelimiters(boolean) method to set the instance variable
  • add getNameDelimited(DatasourcePlatform) method that returns the name with delimiters
  • add getQualifiedNameDelimited(DatasourcePlatform) method to return a delimited version of the qualified name
  • change code that initializes the name instance variable to check for delimiters remove them from the name and set the flag
  • setName() will have versions added that take a delimiter and parse the delimiters

DatabaseTable

  • add setUseDelimiters(boolean) method to set the instance variable
  • add getNameDelimited(DatasourcePlatform) method that returns the name with delimiters
  • add getQualifiedNameDelimited(DatasourcePlatform) method to return a delimited version of the qualified name
  • alter getTableQualifier() to return the delimited version of the table qualifier
  • change code that initializes the name instance variable to check for delimiters remove them from the name and set the flag

The reason we have chose to manage delimiters with a flag rather than simply storing the quoted values as the name in DatabaseField and DatabaseTable is as follows:

  • It makes it easier for metadata processing code to avoid adding delimiters twice
  • Result sets from database reads never come back with delimiters. As a result, in order to be able to look up fields in rows from the database, we need to be able to do a lookup without the delimiters

In the case where the delimited-identifiers flag is set as a persistence unit default and a field is delimited in the column definition (annotation or xml) we will delimit the field only once.

Metadata processing

Anywhere the metadata processing code creates a DatabaseField or DatabaseTable, a check will be done for useDelimitedIdentifiers in the persistence unit defaults and the useDelimitedIdentifiers flag on the DatabaseField or DatabaseTable will be set as appropriate. Additionally, the setName() method will be called using the default delimiter (the double quote) on all processed attributes.

Database Interaction

All calls to databaseField.getName() and databaseTable.getName(platform) that are used to build SQL will be changed to getNameDelimited(platform). Additionally schema generation code will be updated to use the delimited name. This will require all calls that build SQL have access to the DatasoucePlatform. A number of changes will be made to call stacks to allow this.

Back to the top