Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be 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/jpql"

(JPQL)
(JPQL)
Line 78: Line 78:
 
'''Parser Updates'''
 
'''Parser Updates'''
  
comparison_expression ::= …………. |  entity_type_expression}
+
''comparison_expression ::= …………. |  entity_type_expression}
  
 
entity_type_expression ::=
 
entity_type_expression ::=
Line 98: Line 98:
 
identification_variable |
 
identification_variable |
 
KEY(identification_variable) |
 
KEY(identification_variable) |
VALUE(identification_variable)
+
VALUE(identification_variable)''
 
+
  
 
* The JPQL grammar file will be updated with the new KEY, VALUE and ENTRY keywords.
 
* The JPQL grammar file will be updated with the new KEY, VALUE and ENTRY keywords.

Revision as of 11:41, 12 June 2009

JPQL Updates

JPA 2.0 Root | Enhancement Request

Issue Summary

JPA 2.0 introduces a number of JPQL updates. Each upate will implemented as either one or two of small features. For features where there is no current EclipseLink Expression framework support, Expression support will be first added. When Expression Framework support is available, our JPQL parser will be updated to make use of that support.

The following is the list of changes to JPQL we are currently aware of:

  • Navigation across embeddeds (e.g. select e from Entity e where e.embedded.value = :value)
  • Key/Value/Entry access for maps (e.g. select KEY(m) from Entity e join e.map m where VALUE(m) = :value) - depends on Extended Maps <Complete>
  • Add an "AS" keyword to Select (e.g. select e as y from Entity e)
  • Added alloable arguments to constructor expressions (e.g. select new MyObject(e, 11) from Entity e)
  • Subselects can now collection information (e.g. select e from Entity e where e.id in (select a.id from AEntity a join a.collection c where .....)
  • IN can now take a collection as a parameter (e.g. select e from Entity e where e.id in :value)
  • Expressions referring to collection members now use entity_or_value_expression
  • Entity type Expressions have been added (e.g. select e from EntitySuperClass e where TYPE(e) = EntitySubclass.class)
  • Case Expression have now been added (e.g. updateEntity e SET e.value = CASE WHEN e.value2 = 1 THEN 11 WHEN e.value2 = 2 THEN 22 ELSE 0

END

  • A list Index operator has now been added for ordered lists - depends on Ordered lists
  • Concat can now take an additional argument

Feature design

Maps

JPQL now allows keywords KEY, VALUE and ENTRY for navigation into mappings that are Maps. KEY and VALUE can be used either in the SELECT clause or the WHERE clause. ENTRY can only be used in the FROM clause.

Examples:

  • select KEY(m) from Entity e join e.map m where KEY(m) = :value
  • select VALUE(m) from Entity e join e.map m where VALUE(m).id = :id
  • select ENTRY(m) from Entity e join e.map m where e.id = :id

Expression Design

By default, Expressions that navigate over a Map in EclipseLink navigate to the Map value. As a result, no Expression changes are required to support VALUE().

Examples

We will add mayKey() and mapEntry() to Expression. Here are some same expressions. Assume map is an attribute of type Map:

In the SELECT

  • expressionBuilder.get("map").mapKey()
  • expressionBuilder.get("map").mapKey().get("id")
  • expressionBuilder.get("map").mapEntry()

In the WHERE

  • expressionBuilder.get("map").mapKey().equal(1);
  • expressionBuilder.get("map").mapKey().equal(myEntity);
  • expressionBuilder.get("map").mapKey().get("myAggregate").get("string").equal("string1");

Code Updates

The following is a summary of the main changes that will be required:

  • The internal code to support this will be in a new subclass of QueryKeyExpression called: MapEntryExpression. MapEntryExpression will hold a variable called returnMapEntry which will be set to true if the ENTRY should be returned and false if the KEY should be returned.
  • ReportQueryResult will be updated to properly build results that are KEY or ENTRY
  • MapContainerPolicy, MappedKeyMapContainerPolicy and DirectMapContainerPolicy will all be updated to be able to calculate the Java type of their key

Testing

Expression based testing will be added for the following scenarios

  • DirectCollectionMapping with mapKey accessed in WHERE clause for Direct, Aggregate and Entity keys
  • AggregateCollectionMapping with mapKey accessed in WHERE clause for Direct, Aggregate and Entity keys
  • ManyToManyMapping with mapKey accessed in WHERE clause for Direct, Aggregate and Entity keys
  • UnidirectionalOneToManyMapping with mapKey accessed in WHERE clause for Direct, Aggregate and Entity keys
  • OneToManyMapping with mapKey accessed in WHERE clause for Direct, Aggregate and Entity keys
  • OneToManyMapping with mapKey accessed in SELECT clause for Direct, Aggregate and Entity keys
  • OneToManyMapping with mapEntry accessed in SELECT clause
  • In Memory OneToManyMapping with mapKey accessed in WHERE clause
  • Expression that navigate through map keys. e.g. expressionBuilder.get("map").mapKey().get("myAggregate").get("string").equal("string1");

JPQL

Parser Updates

comparison_expression ::= …………. | entity_type_expression}

entity_type_expression ::= type_discriminator | entity_type_literal | input_parameter

type_discriminator ::= TYPE(identification_variable | single_valued_object_path_expression | input_parameter)

qualified_identification_variable ::= KEY(identification_variable) | VALUE(identification_variable) | ENTRY(identification_variable)

general_identification_variable ::= identification_variable | KEY(identification_variable) | VALUE(identification_variable)

  • The JPQL grammar file will be updated with the new KEY, VALUE and ENTRY keywords.
  • VALUE will be treated as a no-op as the functionality necessary to make value work is already the default behavior.
  • A MapKeyNode and a MapEntryNode will be added to the collection of nodes that can compose the parse tree. They will be designed to create the appropriate Expression instance

Validation

Validation will be done in several places

  • At Expression validation time, MapEntryExpression will ensure the mapping exists, is a collection mapping and contains a container policy that is appropriate to a map mapping
  • ParameterExpression will have added functionality to match the type of they Parameter against the type of the map key
  • MapKeyExpression will calculate the type of the MapKey for type Validation
  • MapEntryExpression will set it's type to Map.Entry for type Validation
  • In cases where EclipseLink does not have the type of the Map Key in it's metadata we will avoid doing type checking and assume expressions are valid

Testing

A selection of tests will be added to cover various possibilities

  • Selecting a MapEntry
  • Selecting a MapKey
  • Selecting a MapValue
  • MapKey in WHERE clause
  • MapValue in WHERE clause
  • navigating through a MapKey in the WHERE clause
  • navigating through a MapValue in the WHERE clause



Collection Parameters for IN

Expression Design

This is already supported by the EclipseLink Expression framework

JPQL

Example

  • select e from employee e where e.id in :param

Parser Only two changes are required for JPQL

  1. The parser will be updated to accept a list parameter for inExpression
  2. The validation will be updated to treat a list parameter as type Collection which will allow validation to proceed normally

Testing

A test will be added to the JUnitJPQLSimpleTestSuite




TYPE Expressions

Expression Design

http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/entity_type_expressions

JPQL Design

Examples

  • select p from Project p where type(p) = LargeProject // LargeProject is an entity_type_literal that refers to an entity name
  • select p from Project p where type(p) = :param
  • select p from Project p where type(p) in (LargeProject, SmallProject)

Parser Updates

The BNF for types makes is somewhat non-deterministic in certain cases. The following rule can make it confusing for the parser to determine the user's intent:

entity_type_expression ::= type_discriminator | entity_type_literal | input_parameter

entity_type_literal in indistinguishable from a variable reference

As a result it is impossible to tell if a query like 'select e from Employee e where SmallProject = LargeProject' is an incorrectly written query or a TYPE query that evaluates constants. We have decided that any string that evaluates to the name of an Entity will be treated as an EntityTypeLiteral and not a variable.

  • The new TYPE token will be added to the Lexer
  • inItem will be updated to accept an abstract schema name - for a entity_type_literal
  • arithmeticPrimary will be update to accent entityTypeExpression
  • an entityTypeExpression rule will be added that maps to a new parse tree node - ClassForInheritanceNode
  • ClassForInheritanceNode will implement logic to build a type expression
  • VariableNode has been updated to allow it to represent an entity_type_literal

Validation

  • ClassForInheritanceNode will set its type to Class.class

Testing

We will add the following tests:

  • TYPE with = and a entity_type_literal
  • TYPE with = and a parameter
  • TYPE with IN and a set of entity_type_literals
  • TYPE with IN and a parameter


Concat

JQPL now allows more than two arguments to CONCAT

Expression Design

We will reuse the current concat expression and call it multiple times

JPQL Design

Examples

  • select e from employee e where concat(e.lastName, e.ssn, e.id) = :param

Parser Updates

The parser currently creates an expression for the first argument and does an Expresson.concat() on it with the second argument. We will simply update this code to repeatedly call Expression.concat on arguments 2 through n.

Vaidation

Validation is unchanged except that each arguement of the concat is validated.

Testing

  • A simple 3 argument concat test will be added.

Substring

The third argument to substring is now optional.

Expression Design

NOT YET IMPLEMENTED

Parser Design

Parser Updates

The parser will be modified to make the 3rd argument to substring optional.

Validation

Validation will be unchanged

Testing

  • NOT YET IMPLEMENTED

Case

Expression Design

NOT YET IMPLEMENTED

Parser Design

Parser Updates

The spec defines 4 types of case statements:

  1. A general case expression that uses conditional expressions to determine the result
  2. A simple case expression that uses comparison to a set of values to determine the result
  3. A coalesce expression that returns the first non-null argument
  4. A nullif expression that tests if arguments are equal and returns null if they are


Validation

NOT YET IMPLEMENTED

Testing

  • NOT YET IMPLEMENTED

Index

Expression Design

NOT YET IMPLEMENTED

Parser Design

Parser Updates

NOT YET IMPLEMENTED

Validation

NOT YET IMPLEMENTED

Testing

  • NOT YET IMPLEMENTED

Scalar Expression

Expression Design

NOT YET IMPLEMENTED

Parser Design

Parser Updates

NOT YET IMPLEMENTED

Validation

NOT YET IMPLEMENTED

Testing

  • NOT YET IMPLEMENTED

Back to the top