JPA-SQL language specification

  • 0 or more
    + 1 or more
    ? optional
    | or
    & and, without defined order
    RQL is case-sensitive.

Script:
    ImportStatement*
    QueryMethod*
;

ImportStatement:
    'import' QualifiedName;

QueryMethod:
    DocComment?
    ID '(' (Parameter (',' Parameter)*)? ')'
    '{'
        SelectStatement
    '}'
;

Parameter:
    Type ID;

Type:
    PrimitiveType |
    QualifiedName
;

SelectStatement:
    (
    SelectClause? &
    FromClause
    )
    JoinClause*
    (
    WhereClause? &
    GroupByClause? &
    OrderByClause? &
    OffsetClause? &
    LimitClause? &
    ResultClause? &
    LockModeClause? &
    FetchClause? &
    IntoClause?
    )
;

SelectClause:
    'select' 'distinct'? Selection;

Selection:
    '*' |
    SelectionElement (',' SelectionElement)*
;

SelectionElement:
    Expression Alias?;

FromClause:
    'from' FromElement (',' FromElement)*;

FromElement:
    QualifiedName Alias?;

JoinClause:
    JoinType? 'join' JoinElement Alias? OnClause?;

JoinElement:
    AttributeRef;

OnClause:
    'on' Condition;

WhereClause:
    'where' Condition;

GroupByClause:
    'group' 'by' GroupByElement (',' GroupByElement)* HavingClause?;

GroupByElement:
    Expression;

HavingClause
    'having' Condition;

OrderByClause:
    'order' 'by' OrderByElement (',' OrderByElement)*;

OrderByElement:
    Expression Order?;

OffsetClause:
    'offset' PaginationValue;

LimitClause:
    'limit' PaginationValue;

PaginationValue:
    IntegerLiteral |
    ParameterRef
;

ResultClause:
    'result' ResultCount;

LockModeClause:
    'lockmode' LockModeType;

FetchClause:
    'fetch' FetchElement (',' FetchElement)*;

FetchElement:
    AttributeRef;

IntoClause:
    'into' Type | 'tuple';

Alias:
    'as' ID;

Condition:
    ConditionalOR;

ConditionalOR:
    ConditionalAND ('or' ConditionalAND)*;

ConditionalAND:
    ConditionalNOT ('and' ConditionalNOT)*;

ConditionalNOT:
    ConditionalPrimary | ('not' ConditionalPrimary);

ConditionalPrimary:
    ('(' ConditionalOR ')') |
    BooleanExpression
;

BooleanExpression:
    Expression
    (
        (ComparisonOperator ComparisonExpressionRight) |
        ('between' Expression 'and' Expression) |
        ('like' Expression ('escape' Expression)?) |
        ('in' '(' CollectionExpression ')')
    ) |
    ('exists' '(' SubQuery ')')
;

ComparisonExpressionRight:
    Expression |
    CollectionComparisonExpression
;

CollectionComparisonExpression:
    CollectionComparisonFunction '(' SubQuery ')';

CollectionExpression:
    (Expression (',' Expression)*) |
    SubQuery
;

Expression:
    ArithmeticLine;

ArithmeticLine:
    ArithmeticTerm (AddSubOperator ArithmeticTerm)*;

ArithmeticTerm:
    ArithmeticFactor (MultDivOperator ArithmeticFactor)*;

ArithmeticFactor:
    ArithmeticPrimary | (AddSubOperator ArithmeticPrimary);

ArithmeticPrimary:
    ('(' (ArithmeticLine | SubQuery) ')') |
    AttributeRef |
    Literal |
    Function |
    AggregateExpression
;

Function:
    LengthFunction |
    LocateFunction |
    ModFunction |
    AbsFunction |
    SizeFunction |
    SqrtFunction |
    UpperFunction |
    LowerFunction |
    ConcatFunction |
    SubstringFunction |
    TrimFunction |
    CurrentDateFunction |
    CurrentTimeFunction |
    CurrentTimestampFunction |
    CustomFunction
;

LengthFunction:
    'length' '(' Expression ')';

LocateFunction:
    'locate' '(' Expression ',' Expression (',' Expression)? ')';

ModFunction:
    'mod' '(' Expression ',' Expression ')';

AbsFunction:
    'abs' '(' Expression ')';

SizeFunction:
    'size' '(' Expression ')';

SqrtFunction:
    'sqrt' '(' Expression ')';

UpperFunction:
    'upper' '(' Expression ')';

LowerFunction:
    'lower' '(' Expression ')';

ConcatFunction:
    'concat' '(' Expression ',' Expression ')';

SubstringFunction:
    'substring' '(' Expression ',' Expression (',' Expression)? ')';

TrimFunction:
    'trim' '(' TrimSpecifiction? Expression? 'from' Expression ')';

// since 3.1.1
CustomFuction:
    'function' '(' StringLiteral ',' Type (',' Expression)* ')'

CurrentDateFunction:
    'current_date' ('(' ')')?;

CurrentTimeFunction:
    'current_time' ('(' ')')?;

CurrentTimestampFunction:
    'current_timestamp' ('(' ')')?;

SubQuery:
    (
    SelectClause? &
    FromClause
    )
    (
    WhereClause? &
    GroupByClause? &
    OrderByClause? &
    OffsetClause? &
    LimitClause?
    )
;

AggregateExpression:
    AggregateFunction '(' Expression ')';

AttributeRef:
    AttributeRefStart ('.' AttributeRefPart)*;

AttributeRefStart:
    SimpleName |
    ParameterRef
;

AttributeRefPart:
    SimpleName;

SimpleName:
    ID;

QualifiedName:
    ID ('.' ID)*;

ParameterRef:
    ':' Parameter;

Literal:
    NumericLiteral | StringLiteral | CharacterLiteral | BooleanLiteral | NullLiteral;

NumericLiteral:
    IntegerLiteral | DoubleLiteral;

IntegerLiteral:
    INT;

DoubleLiteral:
    DOUBLE;

StringLiteral:
    STRING;

CharacterLiteral:
    CHAR;

BooleanLiteral:
    'true'|'false';

NullLiteral:
    'null';

enum PrimitiveType:
    byte | short | int | long | float | double | boolean | char;

enum JoinType:
    inner | left | right;

enum Order:
    asc | desc;

enum AggregateFunction:
    avg | min | max | sum | sumAsLong | sumAsDouble | count | countDistinct;

enum CollectionComparisonFunction:
    all | any | some;

enum TrimSpecifiction:
    both | // default
    leading |
    trailing;

enum AddSubOperator
    plus='+' | minus='-';

enum MultDivOperator:
    mult='*' | div='/';

enum ComparisonOperator:
    lessThan='<' |
    greaterThan='>' |
    lessEqual='<=' |
    greaterEqual='>=' |
    equal='=' |
    notEqual='!=' |
    notEqual2='<>'
;

enum ResultCount:
    list | // default
    single;

enum LockModeType:
    NONE='none' |
    READ='read' |
    WRITE='write' |
    OPTIMISTIC='optimistic' |
    OPTIMISTIC_FORCE_INCREMENT='optimisticForceIncrement' |
    PESSIMISTIC_READ='pessimisticRead' |
    PESSIMISTIC_WRITE='pessimisticWrite' |
    PESSIMISTIC_FORCE_INCREMENT='pessimisticForceIncrement'
;