6 - SQM based on JPA type system

This commit is contained in:
Steve Ebersole 2019-05-21 16:29:57 -05:00 committed by Andrea Boriero
parent ef87991fa3
commit 26ff169db2
494 changed files with 35102 additions and 14983 deletions

View File

@ -1,5 +1,3 @@
import org.apache.tools.ant.filters.ReplaceTokens
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@ -21,12 +19,14 @@ buildscript {
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.7'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.3'
classpath 'de.thetaphi:forbiddenapis:2.5'
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.1'
}
}
plugins {
id 'com.gradle.build-scan' version '1.16'
id 'me.champeau.buildscan-recipes' version '0.2.3'
id 'org.jetbrains.gradle.plugin.idea-ext' version '0.5'
}
allprojects {
@ -41,11 +41,13 @@ allprojects {
}
}
apply plugin: 'idea'
apply plugin: 'eclipse'
// minimize changes, at least for now (gradle uses 'build' by default)..
buildDir = "target"
apply from: rootProject.file( 'gradle/base-information.gradle' )
}
@ -100,17 +102,23 @@ buildScanRecipes {
recipe 'git-commit', baseUrl: 'https://github.com/hibernate/hibernate-orm/tree'
}
//idea {
idea {
// project {
// jdkName = baselineJavaVersion
// languageLevel = baselineJavaVersion
//
// vcs = 'Git'
//
// settings {
// taskTriggers {
// afterSync tasks.getByName("projects"), tasks.getByName("tasks")
// }
// }
// }
// module {
// name = "hibernate-orm"
// }
//}
module {
name = "hibernate-orm"
}
}

View File

@ -0,0 +1,47 @@
= Type System
The Hibernate "type system" is multi-layered....
== JavaTypeDescriptor
At the lowest level we have `JavaTypeDescriptor` which describes very rudimentary information about
Java types (`Class`). This level makes no distinctions based about the nature of the type. E.g.
it does not understand that `Person` is an entity.
== JPA type system (SQM)
[plantuml,SqmTypeSystem,png]
.SqmTypeSystem
....
@startuml
skinparam handwritten true
interface SqmExpressable
interface SqmPathSource
interface EntityDomainType
interface BasicDomainType
interface PeristentAttribute
interface SingularePersistentAttribute
interface PluralPersistentAttribute
SqmExpressable <|-- SqmPathSource
SqmExpressable <|-- BasicDomainType
SqmPathSource <|-- EntityDomainType
SqmPathSource <|-- PeristentAttribute
PeristentAttribute <|-- SingularePersistentAttribute
PeristentAttribute <|-- PluralPersistentAttribute
@enduml
....
== Mapping model
- persisters, etc...
todo : document this one

View File

@ -8,12 +8,12 @@
apply plugin: 'base'
ext {
ormVersion = new HibernateVersion( '5.4.5-SNAPSHOT', project )
ormVersion = new HibernateVersion( '6.0.0-SNAPSHOT', project )
baselineJavaVersion = '1.8'
jpaVersion = new JpaVersion('2.2')
}
group = 'org.hibernate'
group = 'org.hibernate.orm'
version = project.ormVersion.fullName
class JpaVersion {

View File

@ -1,3 +1,5 @@
import org.apache.tools.ant.filters.ReplaceTokens
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@ -38,7 +40,7 @@ ext {
'jdbc.url' : 'jdbc:postgresql:hibernate_orm_test'
],
pgsql_docker : [
'db.dialect' : 'org.hibernate.dialect.PostgreSQL10Dialect',
'db.dialect' : 'org.hibernate.dialect.PostgreSQL95Dialect',
'jdbc.driver': 'org.postgresql.Driver',
'jdbc.user' : 'hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test',
@ -116,3 +118,10 @@ ext {
]
]
}
def processTestResourcesTask = project.tasks.findByName( 'processTestResources' )
if ( processTestResourcesTask != null ) {
processTestResourcesTask.inputs.property( 'db', db )
processTestResourcesTask.filter( ReplaceTokens, tokens: dbBundle[db] )
}

View File

@ -5,22 +5,24 @@
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'de.thetaphi:forbiddenapis:2.6'
}
}
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import org.apache.tools.ant.filters.ReplaceTokens
/**
* Support for modules that contain Java code
*/
//
//buildscript {
// repositories {
// mavenCentral()
// }
// dependencies {
// classpath 'de.thetaphi:forbiddenapis:2.6'
// }
//}
//import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import org.apache.tools.ant.filters.ReplaceTokens
apply from: rootProject.file( 'gradle/base-information.gradle' )
apply from: rootProject.file( 'gradle/libraries.gradle' )
apply from: rootProject.file( 'gradle/databases.gradle' )
@ -32,6 +34,13 @@ apply plugin: 'checkstyle'
apply plugin: 'build-dashboard'
apply plugin: 'project-report'
// Attempt to leverage JetBrain's Gradle extension to automatically define
// `copyResourcesToIntelliJOutFolder` as a "build trigger" on import.
//
// However, see https://github.com/JetBrains/gradle-idea-ext-plugin/issues/8
apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'
ext {
java9ModuleNameBase = project.name.startsWith( 'hibernate-' ) ? name.drop( 'hibernate-'.length() ): name
java9ModuleName = "org.hibernate.orm.$project.java9ModuleNameBase"
@ -57,7 +66,7 @@ configurations {
description = 'Non-exported compile-time dependencies.'
}
asciidoclet {
description = "Dependencies for Asciidoctor Javadoc taglet"
description = 'Dependencies for Asciidoctor Javadoc taglet'
}
}
@ -73,7 +82,18 @@ dependencies {
annotationProcessor( libraries.logging )
annotationProcessor( libraries.logging_annotations )
// JUnit dependencies made up of:
// * JUnit 5
// * the Jupiter engine which runs JUnit 5 based tests
// * the "vintage" engine - which runs JUnit 3 and 4 based tests
testCompile( libraries.junit5_api )
testRuntime( libraries.junit5_jupiter )
testCompile( libraries.junit5_params )
testCompile( libraries.junit )
testRuntime( libraries.junit5_vintage )
testCompile( libraries.byteman )
testCompile( libraries.byteman_install )
testCompile( libraries.byteman_bmunit )
@ -92,7 +112,7 @@ dependencies {
testRuntime( libraries.informix )
testRuntime( libraries.hana )
asciidoclet 'org.asciidoctor:asciidoclet:1.+'
asciidoclet( libraries.asciidoclet )
if ( db.equalsIgnoreCase( 'oracle' ) ) {
testRuntime( libraries.oracle ) {
@ -161,57 +181,58 @@ if ( ext.toolsJar.exists() ) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
tasks.withType( Test.class ).all { task ->
tasks.withType( Test.class ).each { test ->
test.useJUnitPlatform()
if ( JavaVersion.current().isJava9Compatible() ) {
// Byteman needs this property to be set, https://developer.jboss.org/thread/274997
task.jvmArgs += ["-Djdk.attach.allowAttachSelf=true"]
test.jvmArgs += ["-Djdk.attach.allowAttachSelf=true"]
}
task.jvmArgs += [
test.jvmArgs += [
'-XX:+HeapDumpOnOutOfMemoryError',
"-XX:HeapDumpPath=${file( "${buildDir}/OOM-dump.hprof" ).absolutePath}",
'-XX:MetaspaceSize=512M'
]
task.maxHeapSize = '4G'
test.maxHeapSize = '4G'
task.systemProperties['hibernate.test.validatefailureexpected'] = true
task.systemProperties += System.properties.findAll { it.key.startsWith( "hibernate." ) }
test.systemProperties['hibernate.test.validatefailureexpected'] = true
test.systemProperties += System.properties.findAll { it.key.startsWith( "hibernate." ) }
test.enableAssertions = true
if ( project.name != 'hibernate-testing' ) {
test.dependsOn ':hibernate-testing:test'
}
}
sourceSets {
test {
resources {
// add `src/test/java` as a test-resources dir
configure( srcDir('src/test/java') ) {
filter {
include '**/*.properties'
include '**/*.xml'
}
}
configure( srcDir('src/test/resources') ) {
filter {
include '*.properties'
include '*.xml'
include '**/*.properties'
include '**/*.xml'
exclude 'src/test/resources/arquillian.xml'
}
}
}
}
}
processTestResources {
inputs.property( "db", db )
doLast {
copy {
from( sourceSets.test.java.srcDirs ) {
include '**/*.properties'
include '**/*.xml'
}
into sourceSets.test.java.outputDir
}
copy {
from file( 'src/test/resources' )
into file( "${buildDir}/resources/test" )
exclude 'src/test/resources/arquillian.xml'
exclude 'src/test/resources/hibernate.properties'
}
copy {
from file( 'src/test/resources/hibernate.properties' )
into file( "${buildDir}/resources/test" )
filter( ReplaceTokens, tokens: dbBundle[db] )
}
}
}
// Enable the experimental features of ByteBuddy with JDK 12+
test {
//Only safe to attempt to parse the version as an integer since JDK11
if ( JavaVersion.current().isJava11Compatible() ) {
int majorJVMVersionInt = Integer.valueOf(JavaVersion.current().toString());
//Set the -Dnet.bytebuddy.experimental=true property only when we need it:
if (majorJVMVersionInt >= 12) {
systemProperty 'net.bytebuddy.experimental', true
}
}
filter( ReplaceTokens, tokens: dbBundle[db] )
}
test {
@ -259,7 +280,7 @@ test {
A solution is to enable the 'After Build' Execution of the copyResourcesToIntelliJOutFolder task
from the 'Gradle project' IntelliJ tool window ( The task can be found under hibernate-orm > Task > other)
*/
task copyResourcesToIntelliJOutFolder {
task copyResourcesToIntelliJOutFolder(type: Task, dependsOn: project.tasks.processTestResources) {
doLast {
copy {
from "$buildDir/resources/test"
@ -325,36 +346,36 @@ task nonFatalCheckstyle(type:Checkstyle) {
checkstyleMain.exclude '**/org/hibernate/cfg/**'
checkstyleMain.exclude '**/org/hibernate/cfg/*'
task forbiddenApisSystemOut(type: CheckForbiddenApis, dependsOn: compileJava) {
classesDirs = project.sourceSets.main.output.classesDirs
classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
targetCompatibility = project.forbiddenAPITargetJDKCompatibility
bundledSignatures += 'jdk-system-out'
suppressAnnotations += ['org.hibernate.internal.build.AllowSysOut', 'org.hibernate.internal.build.AllowPrintStacktrace']
}
task forbiddenApisUnsafe(type: CheckForbiddenApis, dependsOn: compileJava) {
classesDirs = project.sourceSets.main.output.classesDirs
classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
targetCompatibility = project.forbiddenAPITargetJDKCompatibility
bundledSignatures += "jdk-unsafe-${baselineJavaVersion}".toString()
// unfortunately we currently have many uses of default Locale implicitly (~370) which need to be fixed
// before we can fully enabled this check
//
// No idea how findbugs was missing these b4
ignoreFailures = true
}
task forbiddenApisNonPortable(type: CheckForbiddenApis, dependsOn: compileJava) {
classesDirs = project.sourceSets.main.output.classesDirs
classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
targetCompatibility = project.forbiddenAPITargetJDKCompatibility
bundledSignatures += 'jdk-non-portable'
}
task forbiddenApis
project.tasks.withType( CheckForbiddenApis ).each { task -> forbiddenApis.finalizedBy task }
project.tasks.check.finalizedBy forbiddenApis
//
//task forbiddenApisSystemOut(type: CheckForbiddenApis, dependsOn: compileJava) {
// classesDirs = project.sourceSets.main.output.classesDirs
// classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
// targetCompatibility = project.forbiddenAPITargetJDKCompatibility
// bundledSignatures += 'jdk-system-out'
// suppressAnnotations += ['org.hibernate.internal.build.AllowSysOut', 'org.hibernate.internal.build.AllowPrintStacktrace']
//}
//
//task forbiddenApisUnsafe(type: CheckForbiddenApis, dependsOn: compileJava) {
// classesDirs = project.sourceSets.main.output.classesDirs
// classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
// targetCompatibility = project.forbiddenAPITargetJDKCompatibility
// bundledSignatures += "jdk-unsafe-${baselineJavaVersion}".toString()
//
// // unfortunately we currently have many uses of default Locale implicitly (~370) which need to be fixed
// // before we can fully enabled this check
// //
// // No idea how findbugs was missing these b4
// ignoreFailures = true
//}
//
//task forbiddenApisNonPortable(type: CheckForbiddenApis, dependsOn: compileJava) {
// classesDirs = project.sourceSets.main.output.classesDirs
// classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
// targetCompatibility = project.forbiddenAPITargetJDKCompatibility
// bundledSignatures += 'jdk-non-portable'
//}
//
//task forbiddenApis
//project.tasks.withType( CheckForbiddenApis ).each { task -> forbiddenApis.finalizedBy task }
//
//project.tasks.check.finalizedBy forbiddenApis

View File

@ -10,6 +10,9 @@
ext {
junitVersion = '4.12'
junitVintageVersion = '5.3.1'
junit5Version = '5.3.1'
h2Version = '1.4.196'
bytemanVersion = '4.0.3' //Compatible with JDK10
jnpVersion = '5.0.6.CR1'
@ -46,7 +49,7 @@ ext {
ant: 'org.apache.ant:ant:1.8.2',
// Antlr
antlr: 'antlr:antlr:2.7.7',
antlr: 'org.antlr:antlr4:4.7.1',
// Annotations
commons_annotations: "org.hibernate.common:hibernate-commons-annotations:${hibernateCommonsVersion}",
@ -100,8 +103,15 @@ ext {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~ testing
junit5_api: "org.junit.jupiter:junit-jupiter-api:${junit5Version}",
junit5_jupiter: "org.junit.jupiter:junit-jupiter-engine:${junit5Version}",
junit5_params : "org.junit.jupiter:junit-jupiter-params:${junit5Version}",
junit: "junit:junit:${junitVersion}",
junit5_vintage: "org.junit.vintage:junit-vintage-engine:${junitVintageVersion}",
log4j: "log4j:log4j:1.2.17",
junit: "junit:junit:${junitVersion}",
byteman: "org.jboss.byteman:byteman:${bytemanVersion}",
byteman_install: "org.jboss.byteman:byteman-install:${bytemanVersion}",
byteman_bmunit: "org.jboss.byteman:byteman-bmunit:${bytemanVersion}",
@ -129,7 +139,7 @@ ext {
// EL required by Hibernate Validator at test runtime
expression_language: "org.glassfish:javax.el:${elVersion}",
c3p0: "com.mchange:c3p0:0.9.5.3",
c3p0: "com.mchange:c3p0:0.9.5.2",
ehcache: "net.sf.ehcache:ehcache:2.10.6",
ehcache3: "org.ehcache:ehcache:3.6.1",
jcache: "javax.cache:cache-api:1.0.0",
@ -161,8 +171,12 @@ ext {
wildfly_transaction_client : 'org.wildfly.transaction:wildfly-transaction-client:1.0.3.Final',
jboss_ejb_spec_jar : 'org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:1.0.0.Final',
jboss_annotation_spec_jar : 'org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec:1.0.0.Final'
]
jboss_annotation_spec_jar : 'org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec:1.0.0.Final',
asciidoclet : 'org.asciidoctor:asciidoclet:1.+'
//asciidoclet : 'org.asciidoctor:asciidoclet:1.5.7-SNAPSHOT'
]
}
configurations.all {

View File

@ -87,6 +87,8 @@ javadoc {
final int currentYear = new GregorianCalendar().get( Calendar.YEAR )
configure( options ) {
// docletpath = configurations.asciidoclet.files.asType(List)
// doclet = 'org.asciidoctor.Asciidoclet'
windowTitle = "$project.name JavaDocs"
docTitle = "$project.name JavaDocs ($project.version)"
bottom = "Copyright &copy; 2001-$currentYear <a href=\"http://redhat.com\">Red Hat, Inc.</a> All Rights Reserved."
@ -110,13 +112,20 @@ javadoc {
}
if ( JavaVersion.current().isJava8Compatible() ) {
options.addStringOption( 'Xdoclint:none', '-quiet' )
addStringOption( 'Xdoclint:none', '-quiet' )
}
doFirst {
// ordering problems if we try to do this during config phase :(
classpath += project.sourceSets.main.output + project.sourceSets.main.compileClasspath + project.configurations.provided
}
tags(
'todo:X"',
'apiNote:a:"API Note:"',
'implSpec:a:"Implementation Requirements:"',
'implNote:a:"Implementation Note:"'
)
}
doFirst {
// ordering problems if we try to do this during config phase :(
classpath += project.sourceSets.main.output + project.sourceSets.main.compileClasspath + project.configurations.provided
}
}
@ -143,7 +152,75 @@ publishing {
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Relocation for the published artifacts based on the old groupId
publishing {
publications {
relocationArtifacts( MavenPublication ) {
pom {
name = project.name + ' - relocation'
groupId = 'org.hibernate'
artifactId = project.name
version = project.version
description = project.description
url = 'http://hibernate.org/orm'
organization {
name = 'Hibernate.org'
url = 'http://hibernate.org'
}
licenses {
license {
name = 'GNU Library General Public License v2.1 or later'
url = 'http://www.opensource.org/licenses/LGPL-2.1'
comments = 'See discussion at http://hibernate.org/community/license/ for more details.'
distribution = 'repo'
}
}
scm {
url = 'http://github.com/hibernate/hibernate-orm'
connection = 'scm:git:http://github.com/hibernate/hibernate-orm.git'
developerConnection = 'scm:git:git@github.com:hibernate/hibernate-orm.git'
}
developers {
developer {
id = 'hibernate-team'
name = 'The Hibernate Development Team'
organization = 'Hibernate.org'
organizationUrl = 'http://hibernate.org'
}
}
issueManagement {
system = 'jira'
url = 'https://hibernate.atlassian.net/browse/HHH'
}
distributionManagement {
relocation {
groupId = 'org.hibernate.orm'
artifactId = project.name
version = project.version
}
}
}
}
}
}
task ciBuild( dependsOn: [test, publish] )
task release( dependsOn: [test, bintrayUpload] )
afterEvaluate { Project project ->
project.rootProject.subprojects { Project subproject ->
// NOTE : we want this even when `project == subproject`
project.tasks.bintrayUpload.dependsOn( subproject.tasks.build )
}
}

View File

@ -36,7 +36,7 @@ bintray {
user = project.bintrayUser
key = project.bintrayKey
publications = ['publishedArtifacts']
publications = ['publishedArtifacts','relocationArtifacts']
pkg {
userOrg = 'hibernate'
@ -47,13 +47,14 @@ bintray {
version {
name = project.version
description ="Hibernate ORM ${project.version} release. See http://hibernate.org/orm/releases/${project.ormVersion.family}"
released = new Date()
vcsTag = project.version
gpg {
sign = true
}
attributes = [
'jpa': project.jpaVersion,
'jpa': project.jpaVersion.name,
'family': project.ormVersion.family
]
mavenCentralSync {

View File

@ -7,8 +7,9 @@
import org.apache.tools.ant.filters.ReplaceTokens
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
apply plugin: 'antlr'
apply plugin: Antlr4Plugin
apply plugin: 'hibernate-matrix-testing'
apply plugin: 'org.hibernate.build.gradle.xjc'
description = 'Hibernate\'s core ORM functionality'
@ -20,11 +21,9 @@ configurations {
}
dependencies {
compile( libraries.jpa )
// Javassist is no longer the default enhancer but still required for other purposes, e.g. Scanning
compile( libraries.javassist )
// Could be made optional?
compile( libraries.byteBuddy )
compile( libraries.antlr )
compile( libraries.jta )
@ -105,30 +104,30 @@ jar {
mainAttributes( 'Main-Class': 'org.hibernate.Version' )
instructionFirst 'Import-Package',
'javax.security.auth;resolution:=optional',
'javax.security.jacc;resolution:=optional',
'javax.validation;resolution:=optional',
'javax.validation.constraints;resolution:=optional',
'javax.validation.groups;resolution:=optional',
'javax.validation.metadata;resolution:=optional',
// TODO: Shouldn't have to explicitly list this, but the plugin
// generates it with a [1.0,2) version.
"javax.persistence;version=\"${project.jpaVersion.osgiName}\"",
// optionals
'javax.management;resolution:=optional',
'javax.naming.event;resolution:=optional',
'javax.naming.spi;resolution:=optional',
'org.apache.tools.ant;resolution:=optional',
'org.apache.tools.ant.taskdefs;resolution:=optional',
'org.apache.tools.ant.types;resolution:=optional',
'!javax.enterprise*',
'javax.enterprise.context.spi;resolution:=optional',
'javax.enterprise.inject.spi;resolution:=optional',
'javax.inject;resolution:=optional',
'net.bytebuddy.*;resolution:=optional',
// We must specify the version explicitly to allow Karaf
// to use an older version of JAXB (the only one we can use in Karaf)
"javax.xml.bind.*;version=\"${project.jaxbApiVersionOsgiRange}\""
'javax.security.auth;resolution:=optional',
'javax.security.jacc;resolution:=optional',
'javax.validation;resolution:=optional',
'javax.validation.constraints;resolution:=optional',
'javax.validation.groups;resolution:=optional',
'javax.validation.metadata;resolution:=optional',
// TODO: Shouldn't have to explicitly list this, but the plugin
// generates it with a [1.0,2) version.
"javax.persistence;version=\"${project.jpaVersion.osgiName}\"",
// optionals
'javax.management;resolution:=optional',
'javax.naming.event;resolution:=optional',
'javax.naming.spi;resolution:=optional',
'org.apache.tools.ant;resolution:=optional',
'org.apache.tools.ant.taskdefs;resolution:=optional',
'org.apache.tools.ant.types;resolution:=optional',
'!javax.enterprise*',
'javax.enterprise.context.spi;resolution:=optional',
'javax.enterprise.inject.spi;resolution:=optional',
'javax.inject;resolution:=optional',
'net.bytebuddy.*;resolution:=optional',
// We must specify the version explicitly to allow Karaf
// to use an older version of JAXB (the only one we can use in Karaf)
"javax.xml.bind.*;version=\"${project.jaxbApiVersionOsgiRange}\""
// // TODO: Uncomment once EntityManagerFactoryBuilderImpl no longer
// // uses ClassLoaderServiceImpl.
@ -139,7 +138,7 @@ jar {
}
ext {
jaxbTargetDir = file( "${buildDir}/generated-src/jaxb/main" )
jaxbTargetDir = file( "${buildDir}/generated-src/jaxb/main" )
}
sourceSets.main {
@ -151,11 +150,11 @@ sourceSets.test.resources {
setSrcDirs( ['src/test/java','src/test/resources'] )
}
//idea {
// module {
// sourceDirs += file( "${buildDir}/generated-src/antlr/main" )
// }
//}
idea {
module {
sourceDirs += file( "${buildDir}/generated-src/antlr/main" )
}
}
xjc {
outputDir = project.jaxbTargetDir
@ -175,8 +174,11 @@ xjc {
//sourceSets.main.sourceGeneratorsTask.dependsOn xjc
//sourceSets.main.sourceGeneratorsTask.dependsOn generateGrammarSource
tasks.compile.dependsOn generateGrammarSource
//sourceSets.main.sourceGeneratorsTask.dependsOn antlr
tasks.compile.dependsOn antlr
// todo (6.0) : remove this once we get 6.0 stable-ish
tasks.withType( JavaCompile ).forEach({ JavaCompile c -> c.options.compilerArgs += ["-Xmaxerrs", "4999"]})
task copyBundleResources (type: Copy) {
ext {
@ -204,21 +206,69 @@ artifacts {
tests testJar
}
processTestResources {
doLast {
copy {
from file( 'src/test/resources' )
into file( "${buildDir}/resources/test" )
include 'arquillian.xml'
include 'org/hibernate/test/wf/ddl/manifest.mf'
expand wildFlyInstallDir: project( ':hibernate-orm-modules' ).wildFlyInstallDir,
hibernateMajorMinorVersion: "${project.ormVersion.family}",
arquillianDeploymentExportDir: "${rootProject.buildDir.absolutePath}/arquillian-deployments"
}
}
}
task generateEnversStaticMetamodel(
type: JavaCompile,
description: "Generate the Hibernate Envers revision entity static metamodel classes." ) {
source = sourceSets.main.java
// we only want to include these specific classes for metamodel generation.
// if envers adds any additional revision entity classes, they must be listed here.
include 'org/hibernate/envers/DefaultRevisionEntity.java'
include 'org/hibernate/envers/DefaultTrackingModifiedEntitiesRevisionEntity.java'
include 'org/hibernate/envers/enhanced/SequenceIdRevisionEntity.java'
include 'org/hibernate/envers/enhanced/SequenceIdTrackingModifiedEntitiesRevisionEntity.java'
test.dependsOn ':hibernate-orm-modules:prepareWildFlyForTests'
classpath = sourceSets.main.runtimeClasspath + sourceSets.test.compileClasspath
options.compilerArgs = [
"-proc:only",
"-processor",
"org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor"
]
// put static metamodel classes back out to the source tree since they're version controlled.
destinationDir = new File( "${projectDir}/src/main/java" )
}
//
//if ( JavaVersion.current().isJava9Compatible() ) {
// logger.warn( '[WARN] Skipping Javassist-related tests for hibernate-core due to Javassist JDK 9 incompatibility' )
//
// // we need to exclude tests using Javassist enhancement, which does not properly support
// // Java 9 yet - https://issues.jboss.org/browse/JASSIST-261
// test {
// // rather than wild-cards, keep an explicit list
// exclude 'org/hibernate/jpa/test/enhancement/InterceptFieldClassFileTransformerTest.class'
// exclude 'org/hibernate/jpa/test/enhancement/runtime/JpaRuntimeEnhancementTest.class'
// exclude 'org/hibernate/test/bytecode/enhancement/EnhancerTest.class'
// exclude 'org/hibernate/test/bytecode/enhancement/basic/BasicInSessionTest.class'
//
// // also, any tests using Arquillian for in-container testing with WildFly currently
// // need to be excluded because WildFly does not yet work with Java 9
// exclude 'org/hibernate/test/wf/ddl/**'
// exclude 'org/hibernate/jpa/test/cdi/**'
// exclude 'org/hibernate/envers/internal/tools/MapProxyTest.class'
// exclude 'org/hibernate/envers/test/integration/components/dynamic/AuditedDynamicComponentTest.class'
// exclude 'org/hibernate/envers/test/integration/components/dynamic/AuditedDynamicComponentsAdvancedCasesTest.class'
// }
//}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// todo (6.0) : fix after fixing hibernate-spatial
//processTestResources {
// doLast {
// copy {
// from file( 'src/test/resources' )
// into file( "${buildDir}/resources/test" )
// include 'arquillian.xml'
// include 'org/hibernate/test/wf/ddl/manifest.mf'
// expand wildFlyInstallDir: project( ':hibernate-orm-modules' ).wildFlyInstallDir,
// hibernateMajorMinorVersion: "${project.ormVersion.family}",
// arquillianDeploymentExportDir: "${rootProject.buildDir.absolutePath}/arquillian-deployments"
// }
// }
//}
//
//test.dependsOn ':hibernate-orm-modules:prepareWildFlyForTests'
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test {
systemProperty 'file.encoding', 'utf-8'
@ -226,3 +276,121 @@ test {
//println "Starting test: " + descriptor
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Custom Antlr v4 Plugin (to work with Gradle 3)
ext {
baseAntlrInputPath = 'src/main/antlr'
baseAntlrOutputPath = 'generated-src/antlr/main'
}
class GrammarDescriptor {
String packageName
String grammarName
GrammarDescriptor(String packageName, String grammarName) {
this.packageName = packageName
this.grammarName = grammarName
}
File resolveSourceFile(Project project) {
return project.file(
project.baseAntlrInputPath +
'/' + packageName.replace( '.', '/' ) +
'/' + grammarName + '.g4'
)
}
File resolveOutputFile(Project project) {
final File baseOutputDir = project.file( "${project.buildDir}/${project.baseAntlrOutputPath}/" )
final File packagedOutputDirectory = new File( baseOutputDir, packageName.replace( '.', '/' ) )
return new File( packagedOutputDirectory, grammarName + '.g4' )
}
}
class Antlr4Plugin implements Plugin<Project> {
void apply(Project project) {
project.with {
apply plugin : 'java'
configurations.maybeCreate 'antlr'
Antlr4GenerationTask genTask = tasks.create 'antlr', Antlr4GenerationTask
genTask.group = 'Build'
genTask.description = 'Generate source code from ANTLR grammar'
tasks.getByName('compileJava').dependsOn genTask
SourceSet mainSourceSet = project.convention.getPlugin( JavaPluginConvention ).sourceSets.getByName( SourceSet.MAIN_SOURCE_SET_NAME );
mainSourceSet.compileClasspath += configurations.antlr
SourceSet testSourceSet = project.convention.getPlugin( JavaPluginConvention ).sourceSets.getByName( SourceSet.TEST_SOURCE_SET_NAME );
testSourceSet.compileClasspath += configurations.antlr
project.afterEvaluate({
mainSourceSet.java.srcDir( genTask.outputDirectory )
})
}
}
}
class Antlr4GenerationTask extends DefaultTask {
static final String HQL_PCKG = 'org.hibernate.query.hql.internal'
static final String IMPORT_SQL_PCKG = 'org.hibernate.tool.hbm2ddl.grammar'
static final String GRAPH_PCKG = 'org.hibernate.graph.internal.parse'
List<GrammarDescriptor> grammarDescriptors = [
new GrammarDescriptor( HQL_PCKG, 'HqlLexer' ),
new GrammarDescriptor( HQL_PCKG, 'HqlParser' ),
new GrammarDescriptor( IMPORT_SQL_PCKG, 'SqlStatementLexer' ),
new GrammarDescriptor( IMPORT_SQL_PCKG, 'SqlStatementParser' ),
new GrammarDescriptor( GRAPH_PCKG, 'GraphLanguageLexer' ),
new GrammarDescriptor( GRAPH_PCKG, 'GraphLanguageParser' )
]
@InputFiles
@SkipWhenEmpty
FileCollection getSource() {
// only used for UP-TO-DATE checking
return project.files( grammarDescriptors*.resolveSourceFile( project ) )
}
@OutputDirectory
File getOutputDirectory() {
// only used for UP-TO-DATE checking
return project.file( "${project.buildDir}/${project.baseAntlrOutputPath}" )
}
@TaskAction
void antlrGeneration() {
logger.lifecycle( "Starting custom Antlr (v4) grammar generation" )
grammarDescriptors.forEach( { grammarDescriptor -> generate( grammarDescriptor ) } )
}
def generate(GrammarDescriptor grammarDescriptor) {
final File sourceFile = grammarDescriptor.resolveSourceFile( project )
final File outputFile = grammarDescriptor.resolveOutputFile( project )
logger.lifecycle( "Starting Antlr grammar generation `${grammarDescriptor.grammarName} : [${sourceFile.absolutePath}] -> [${outputFile.absolutePath}]" )
outputFile.parentFile.mkdirs()
project.javaexec {
main 'org.antlr.v4.Tool'
classpath project.configurations.antlr
args '-o', outputFile.parentFile.absolutePath
// args '-lib', sourceFile.parentFile.absolutePath
args '-long-messages'
args '-listener'
args '-visitor'
args sourceFile.absolutePath
}
}
}

View File

@ -1,136 +0,0 @@
header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.graph.internal.parse;
}
/**
* Antlr grammar describing the Hibernate EntityGraph Language.
*/
class GeneratedGraphParser extends Parser;
options {
// call the vocabulary (H)ibernate (E)ntity(G)raph (L)anguage
exportVocab=HEGL;
k = 2;
// buildAST = true;
buildAST = false;
}
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// semantic actions/callouts
protected void startAttribute(Token attributeName) {
}
protected void startQualifiedAttribute(Token attributeName, Token qualifier) {
}
protected void finishAttribute() {
}
protected void startSubGraph(Token subType) {
}
protected void finishSubGraph() {
}
}
graph
: attributeNode (COMMA attributeNode)*
;
attributeNode
: attributePath (subGraph)? { finishAttribute(); }
;
attributePath
: path:NAME (DOT qualifier:NAME)? {
if ( qualifier == null ) {
startAttribute( path );
}
else {
startQualifiedAttribute( path, qualifier );
}
}
;
subGraph
: LPAREN (subtype:NAME COLON)? { startSubGraph( subtype ); } attributeNode (COMMA attributeNode )* RPAREN {
finishSubGraph();
}
;
// **** LEXER ******************************************************************
/**
* Lexer for the Hibernate EntityGraph Language grammar
*/
class GraphLexer extends Lexer;
options {
// call the vocabulary (H)ibernate (E)ntity(G)raph (L)anguage
exportVocab=HEGL;
k = 2;
// Allow any char but \uffff (16 bit -1, ANTLR's EOF character)
charVocabulary = '\u0000'..'\ufffe';
caseSensitive = false;
testLiterals = false;
}
COLON: ':';
COMMA: ',';
DOT: '.';
LPAREN: '(';
RPAREN: ')';
WHITESPACE
: ( ' '
| '\t'
| '\r' '\n' { newline(); }
| '\n' { newline(); }
| '\r' { newline(); }
)
{$setType(Token.SKIP);} //ignore this token
;
/**
* In this grammar, basically any string since we (atm) have no keywords
*/
NAME
: NAME_START ( NAME_CONTINUATION )*
;
protected
NAME_START
: '_'
| '$'
| 'a'..'z'
// HHH-558 : Allow unicode chars in identifiers
//| '\u0080'..'\ufffe'
;
protected
NAME_CONTINUATION
: NAME_START
| '0'..'9'
;

View File

@ -1,819 +0,0 @@
header
{
package org.hibernate.hql.internal.antlr;
import java.util.Stack;
import org.hibernate.internal.CoreMessageLogger;
import org.jboss.logging.Logger;
}
/**
* Hibernate Query Language to SQL Tree Transform.<br>
* This is a tree grammar that transforms an HQL AST into a intermediate SQL AST
* with bindings to Hibernate interfaces (Queryable, etc.). The Hibernate specific methods
* are all implemented in the HqlSqlWalker subclass, allowing the ANTLR-generated class
* to have only the minimum dependencies on the Hibernate code base. This will also allow
* the sub-class to be easily edited using an IDE (most IDE's don't support ANTLR).
* <br>
* <i>NOTE:</i> The java class is generated from hql-sql.g by ANTLR.
* <i>DO NOT EDIT THE GENERATED JAVA SOURCE CODE.</i>
* @author Joshua Davis (joshua@hibernate.org)
*/
class HqlSqlBaseWalker extends TreeParser;
options
{
// Note: importVocab and exportVocab cause ANTLR to share the token type numbers between the
// two grammars. This means that the token type constants from the source tree are the same
// as those in the target tree. If this is not the case, tree translation can result in
// token types from the *source* tree being present in the target tree.
importVocab=Hql; // import definitions from "Hql"
exportVocab=HqlSql; // Call the resulting definitions "HqlSql"
buildAST=true;
}
tokens
{
FROM_FRAGMENT; // A fragment of SQL that represents a table reference in a FROM clause.
IMPLIED_FROM; // An implied FROM element.
JOIN_FRAGMENT; // A JOIN fragment.
ENTITY_JOIN; // An "ad-hoc" join to an entity
SELECT_CLAUSE;
LEFT_OUTER;
RIGHT_OUTER;
ALIAS_REF; // An IDENT that is a reference to an entity via it's alias.
PROPERTY_REF; // A DOT that is a reference to a property in an entity.
SQL_TOKEN; // A chunk of SQL that is 'rendered' already.
SELECT_COLUMNS; // A chunk of SQL representing a bunch of select columns.
SELECT_EXPR; // A select expression, generated from a FROM element.
THETA_JOINS; // Root of theta join condition subtree.
FILTERS; // Root of the filters condition subtree.
METHOD_NAME; // An IDENT that is a method name.
NAMED_PARAM; // A named parameter (:foo).
BOGUS; // Used for error state detection, etc.
RESULT_VARIABLE_REF; // An IDENT that refers to result variable
// (i.e, an alias for a select expression)
}
// -- Declarations --
{
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, HqlSqlBaseWalker.class.getName());
private int level = 0;
private boolean inSelect = false;
private boolean inFunctionCall = false;
private boolean inCase = false;
private boolean inFrom = false;
private boolean inCount = false;
private boolean inCountDistinct = false;
private int statementType;
private String statementTypeName;
// Note: currentClauseType tracks the current clause within the current
// statement, regardless of level; currentTopLevelClauseType, on the other
// hand, tracks the current clause within the top (or primary) statement.
// Thus, currentTopLevelClauseType ignores the clauses from any subqueries.
private int currentClauseType;
private int currentTopLevelClauseType;
private int currentStatementType;
private Stack<Integer> parentClauses = new Stack<Integer>();
public final boolean isSubQuery() {
return level > 1;
}
public final boolean isInFrom() {
return inFrom;
}
public final boolean isInFunctionCall() {
return inFunctionCall;
}
public final boolean isInSelect() {
return inSelect;
}
public final boolean isInCase() {
return inCase;
}
public final boolean isInCount() {
return inCount;
}
public final boolean isInCountDistinct() {
return inCountDistinct;
}
public final int getStatementType() {
return statementType;
}
public final int getCurrentClauseType() {
return currentClauseType;
}
public final int getCurrentTopLevelClauseType() {
return currentTopLevelClauseType;
}
public final int getCurrentStatementType() {
return currentStatementType;
}
public final boolean isComparativeExpressionClause() {
// Note: once we add support for "JOIN ... ON ...",
// the ON clause needs to get included here
return getCurrentClauseType() == WHERE ||
getCurrentClauseType() == WITH ||
isInCase();
}
public final boolean isSelectStatement() {
return statementType == SELECT;
}
private void beforeStatement(String statementName, int statementType) {
inFunctionCall = false;
level++;
if ( level == 1 ) {
this.statementTypeName = statementName;
this.statementType = statementType;
}
currentStatementType = statementType;
LOG.debugf("%s << begin [level=%s, statement=%s]", statementName, level, this.statementTypeName);
}
private void beforeStatementCompletion(String statementName) {
LOG.debugf("%s : finishing up [level=%s, statement=%s]", statementName, level, this.statementTypeName);
}
private void afterStatementCompletion(String statementName) {
LOG.debugf("%s >> end [level=%s, statement=%s]", statementName, level, this.statementTypeName);
level--;
}
private void handleClauseStart(int clauseType) {
parentClauses.push(currentClauseType);
currentClauseType = clauseType;
if ( level == 1 ) {
currentTopLevelClauseType = clauseType;
}
}
private void handleClauseEnd() {
currentClauseType = parentClauses.pop();
}
///////////////////////////////////////////////////////////////////////////
// NOTE: The real implementations for the following are in the subclass.
protected void evaluateAssignment(AST eq) throws SemanticException { }
/** Pre-process the from clause input tree. **/
protected void prepareFromClauseInputTree(AST fromClauseInput) {}
/** Sets the current 'FROM' context. **/
protected void pushFromClause(AST fromClause,AST inputFromNode) {}
protected AST createFromElement(String path,AST alias,AST propertyFetch) throws SemanticException {
return null;
}
protected void createFromJoinElement(AST path,AST alias,int joinType,AST fetch,AST propertyFetch,AST with) throws SemanticException {}
protected AST createFromFilterElement(AST filterEntity,AST alias) throws SemanticException {
return null;
}
protected void processQuery(AST select,AST query) throws SemanticException { }
protected void postProcessUpdate(AST update) throws SemanticException { }
protected void postProcessDelete(AST delete) throws SemanticException { }
protected void postProcessInsert(AST insert) throws SemanticException { }
protected void beforeSelectClause() throws SemanticException { }
protected void processIndex(AST indexOp) throws SemanticException { }
protected void processConstant(AST constant) throws SemanticException { }
protected void processBoolean(AST constant) throws SemanticException { }
protected void processNumericLiteral(AST literal) throws SemanticException { }
protected void resolve(AST node) throws SemanticException { }
protected void resolve(AST node, AST predicateNode) throws SemanticException { }
protected void resolveSelectExpression(AST dotNode) throws SemanticException { }
protected void processFunction(AST functionCall,boolean inSelect) throws SemanticException { }
protected void processCastFunction(AST functionCall,boolean inSelect) throws SemanticException { }
protected void processAggregation(AST node, boolean inSelect) throws SemanticException { }
protected void processConstructor(AST constructor) throws SemanticException { }
protected AST generateNamedParameter(AST delimiterNode, AST nameNode) throws SemanticException {
return #( [NAMED_PARAM, nameNode.getText()] );
}
protected AST generatePositionalParameter(AST delimiterNode, AST numberNode) throws SemanticException {
return #( [PARAM, numberNode.getText()] );
}
protected void lookupAlias(AST ident) throws SemanticException { }
protected void setAlias(AST selectExpr, AST ident) { }
protected boolean isOrderExpressionResultVariableRef(AST ident) throws SemanticException {
return false;
}
protected void handleResultVariableRef(AST resultVariableRef) throws SemanticException {
}
protected AST lookupProperty(AST dot,boolean root,boolean inSelect) throws SemanticException {
return dot;
}
protected boolean isNonQualifiedPropertyRef(AST ident) { return false; }
protected AST lookupNonQualifiedProperty(AST property) throws SemanticException { return property; }
protected void setImpliedJoinType(int joinType) { }
protected AST createIntoClause(String path, AST propertySpec) throws SemanticException {
return null;
};
protected void prepareVersioned(AST updateNode, AST versionedNode) throws SemanticException {}
protected void prepareLogicOperator(AST operator) throws SemanticException { }
protected void prepareArithmeticOperator(AST operator) throws SemanticException { }
protected void processMapComponentReference(AST node) throws SemanticException { }
protected void validateMapPropertyExpression(AST node) throws SemanticException { }
protected void finishFromClause (AST fromClause) throws SemanticException { }
}
// The main statement rule.
statement
: selectStatement | updateStatement | deleteStatement | insertStatement
;
selectStatement
: query
;
// Cannot use just the fromElement rule here in the update and delete queries
// because fromElement essentially relies on a FromClause already having been
// built :(
updateStatement!
: #( u:UPDATE { beforeStatement( "update", UPDATE ); } (v:VERSIONED)? f:fromClause s:setClause (w:whereClause)? ) {
#updateStatement = #(#u, #f, #s, #w);
beforeStatementCompletion( "update" );
prepareVersioned( #updateStatement, #v );
postProcessUpdate( #updateStatement );
afterStatementCompletion( "update" );
}
;
deleteStatement
: #( DELETE { beforeStatement( "delete", DELETE ); } fromClause (whereClause)? ) {
beforeStatementCompletion( "delete" );
postProcessDelete( #deleteStatement );
afterStatementCompletion( "delete" );
}
;
insertStatement
// currently only "INSERT ... SELECT ..." statements supported;
// do we also need support for "INSERT ... VALUES ..."?
//
: #( INSERT { beforeStatement( "insert", INSERT ); } intoClause query ) {
beforeStatementCompletion( "insert" );
postProcessInsert( #insertStatement );
afterStatementCompletion( "insert" );
}
;
intoClause! {
String p = null;
}
: #( INTO { handleClauseStart( INTO ); } (p=path) ps:insertablePropertySpec ) {
#intoClause = createIntoClause(p, ps);
handleClauseEnd();
}
;
insertablePropertySpec
: #( RANGE (IDENT)+ )
;
setClause
: #( SET { handleClauseStart( SET ); } (assignment)* ) {
handleClauseEnd();
}
;
assignment
// Note: the propertyRef here needs to be resolved
// *before* we evaluate the newValue rule...
: #( EQ (p:propertyRef) { resolve(#p); } (newValue) ) {
evaluateAssignment( #assignment );
}
;
// For now, just use expr. Revisit after ejb3 solidifies this.
newValue
: expr [ null ] | query
;
// The query / subquery rule. Pops the current 'from node' context
// (list of aliases).
query!
: #( QUERY { beforeStatement( "select", SELECT ); }
// The first phase places the FROM first to make processing the SELECT simpler.
#(SELECT_FROM
f:fromClause
(s:selectClause)?
)
(w:whereClause)?
(g:groupClause)?
(o:orderClause)?
) {
// Antlr note: #x_in refers to the input AST, #x refers to the output AST
#query = #([SELECT,"SELECT"], #s, #f, #w, #g, #o);
beforeStatementCompletion( "select" );
processQuery( #s, #query );
afterStatementCompletion( "select" );
}
;
orderClause
: #(ORDER { handleClauseStart( ORDER ); } orderExprs) {
handleClauseEnd();
}
;
orderExprs
: orderExpr ( ASCENDING | DESCENDING )? ( nullOrdering )? (orderExprs)?
;
nullOrdering
: NULLS nullPrecedence
;
nullPrecedence
: FIRST
| LAST
;
orderExpr
: { isOrderExpressionResultVariableRef( _t ) }? resultVariableRef
| expr [ null ]
;
resultVariableRef!
: i:identifier {
// Create a RESULT_VARIABLE_REF node instead of an IDENT node.
#resultVariableRef = #([RESULT_VARIABLE_REF, i.getText()]);
handleResultVariableRef(#resultVariableRef);
}
;
groupClause
: #(GROUP { handleClauseStart( GROUP ); } (expr [ null ])+ ( #(HAVING logicalExpr) )? ) {
handleClauseEnd();
}
;
selectClause!
: #(SELECT { handleClauseStart( SELECT ); beforeSelectClause(); } (d:DISTINCT)? x:selectExprList ) {
#selectClause = #([SELECT_CLAUSE,"{select clause}"], #d, #x);
handleClauseEnd();
}
;
selectExprList {
boolean oldInSelect = inSelect;
inSelect = true;
}
: ( selectExpr | aliasedSelectExpr )+ {
inSelect = oldInSelect;
}
;
aliasedSelectExpr!
: #(AS se:selectExpr i:identifier) {
setAlias(#se,#i);
#aliasedSelectExpr = #se;
}
;
selectExpr
: p:propertyRef { resolveSelectExpression(#p); }
| #(ALL ar2:aliasRef) { resolveSelectExpression(#ar2); #selectExpr = #ar2; }
| #(OBJECT ar3:aliasRef) { resolveSelectExpression(#ar3); #selectExpr = #ar3; }
| con:constructor { processConstructor(#con); }
| functionCall
| count
| collectionFunction // elements() or indices()
| constant
| arithmeticExpr [ null ]
| logicalExpr
| parameter
| query
;
count
: #(COUNT { inCount = true; } ( DISTINCT { inCountDistinct = true; } | ALL )? ( aggregateExpr | ROW_STAR ) ) {
inCount = false;
inCountDistinct = false;
}
;
constructor
{ String className = null; }
: #(CONSTRUCTOR className=path ( selectExpr | aliasedSelectExpr )* )
;
aggregateExpr
: expr [ null ] //p:propertyRef { resolve(#p); }
| collectionFunction
| selectStatement
;
// Establishes the list of aliases being used by this query.
fromClause {
// NOTE: This references the INPUT AST! (see http://www.antlr.org/doc/trees.html#Action%20Translation)
// the ouput AST (#fromClause) has not been built yet.
prepareFromClauseInputTree(#fromClause_in);
}
: #(f:FROM { pushFromClause(#fromClause,f); handleClauseStart( FROM ); } fromElementList ) {
finishFromClause( #f );
handleClauseEnd();
}
;
fromElementList {
boolean oldInFrom = inFrom;
inFrom = true;
}
: (fromElement)+ {
inFrom = oldInFrom;
}
;
fromElement! {
String p = null;
}
// A simple class name, alias element.
: #(RANGE p=path (a:ALIAS)? (pf:FETCH)? ) {
#fromElement = createFromElement(p,a, pf);
}
| je:joinElement {
#fromElement = #je;
}
// A from element created due to filter compilation
| fe:FILTER_ENTITY a3:ALIAS {
#fromElement = createFromFilterElement(fe,a3);
}
;
joinElement! {
int j = INNER;
}
// A from element with a join. This time, the 'path' should be treated as an AST
// and resolved (like any path in a WHERE clause). Make sure all implied joins
// generated by the property ref use the join type, if it was specified.
: #(JOIN (j=joinType { setImpliedJoinType(j); } )? (f:FETCH)? ref:propertyRef (a:ALIAS)? (pf:FETCH)? (with:WITH)? ) {
//createFromJoinElement(#ref,a,j,f, pf);
createFromJoinElement(#ref,a,j,f, pf, with);
setImpliedJoinType(INNER); // Reset the implied join type.
}
;
// Returns a node type integer that represents the join type
// tokens.
joinType returns [int j] {
j = INNER;
}
: ( (left:LEFT | right:RIGHT) (outer:OUTER)? ) {
if (left != null) j = LEFT_OUTER;
else if (right != null) j = RIGHT_OUTER;
else if (outer != null) j = RIGHT_OUTER;
}
| FULL {
j = FULL;
}
| INNER {
j = INNER;
}
;
// Matches a path and returns the normalized string for the path (usually
// fully qualified a class name).
path returns [String p] {
p = "???";
String x = "?x?";
}
: a:identifier { p = a.getText(); }
| #(DOT x=path y:identifier) {
StringBuilder buf = new StringBuilder();
buf.append(x).append(".").append(y.getText());
p = buf.toString();
}
;
// Returns a path as a single identifier node.
pathAsIdent {
String text = "?text?";
}
: text=path {
#pathAsIdent = #([IDENT,text]);
}
;
withClause
// Note : this is used internally from the HqlSqlWalker to
// parse the node recognized with the with keyword earlier.
// Done this way because it relies on the join it "qualifies"
// already having been processed, which would not be the case
// if withClause was simply referenced from the joinElement
// rule during recognition...
: #(w:WITH { handleClauseStart( WITH ); } b:logicalExpr ) {
#withClause = #(w , #b);
handleClauseEnd();
}
;
whereClause
: #(w:WHERE { handleClauseStart( WHERE ); } b:logicalExpr ) {
// Use the *output* AST for the boolean expression!
#whereClause = #(w , #b);
handleClauseEnd();
}
;
logicalExpr
: #(AND logicalExpr logicalExpr)
| #(OR logicalExpr logicalExpr)
| #(NOT logicalExpr)
| comparisonExpr
;
// TODO: Add any other comparison operators here.
// We pass through the comparisonExpr AST to the expressions so that joins can be avoided for EQ/IN/NULLNESS
comparisonExpr
:
( #(EQ exprOrSubquery [ currentAST.root ] exprOrSubquery [ currentAST.root ])
| #(NE exprOrSubquery [ currentAST.root ] exprOrSubquery [ currentAST.root ])
| #(LT exprOrSubquery [ null ] exprOrSubquery [ null ])
| #(GT exprOrSubquery [ null ] exprOrSubquery [ null ])
| #(LE exprOrSubquery [ null ] exprOrSubquery [ null ])
| #(GE exprOrSubquery [ null ] exprOrSubquery [ null ])
| #(LIKE exprOrSubquery [ null ] expr [ null ] ( #(ESCAPE expr [ null ]) )? )
| #(NOT_LIKE exprOrSubquery [ null ] expr [ null ] ( #(ESCAPE expr [ null ]) )? )
| #(BETWEEN exprOrSubquery [ null ] exprOrSubquery [ null ] exprOrSubquery [ null ])
| #(NOT_BETWEEN exprOrSubquery [ null ] exprOrSubquery [ null ] exprOrSubquery [ null ])
| #(IN exprOrSubquery [ currentAST.root ] inRhs [ currentAST.root ] )
| #(NOT_IN exprOrSubquery [ currentAST.root ] inRhs [ currentAST.root ] )
| #(IS_NULL exprOrSubquery [ currentAST.root ])
| #(IS_NOT_NULL exprOrSubquery [ currentAST.root ])
// | #(IS_TRUE expr [ null ])
// | #(IS_FALSE expr [ null ])
| #(EXISTS ( expr [ null ] | collectionFunctionOrSubselect ) )
) {
prepareLogicOperator( #comparisonExpr );
}
;
inRhs [ AST predicateNode ]
: #(IN_LIST ( collectionFunctionOrSubselect | ( (expr [ predicateNode ])* ) ) )
;
exprOrSubquery [ AST predicateNode ]
: expr [ predicateNode ]
| query
| #(ANY collectionFunctionOrSubselect)
| #(ALL collectionFunctionOrSubselect)
| #(SOME collectionFunctionOrSubselect)
;
collectionFunctionOrSubselect
: collectionFunction
| query
;
expr [ AST predicateNode ]
: ae:addrExpr [ true ] { resolve(#ae, predicateNode); } // Resolve the top level 'address expression'
| #( VECTOR_EXPR (expr [ predicateNode ])* )
| constant
| arithmeticExpr [ predicateNode ]
| functionCall // Function call, not in the SELECT clause.
| parameter
| count // Count, not in the SELECT clause.
;
arithmeticExpr [ AST predicateNode ]
: #(PLUS exprOrSubquery [ null ] exprOrSubquery [ null ]) { prepareArithmeticOperator( #arithmeticExpr ); }
| #(MINUS exprOrSubquery [ null ] exprOrSubquery [ null ]) { prepareArithmeticOperator( #arithmeticExpr ); }
| #(DIV exprOrSubquery [ null ] exprOrSubquery [ null ]) { prepareArithmeticOperator( #arithmeticExpr ); }
| #(MOD exprOrSubquery [ null ] exprOrSubquery [ null ]) { prepareArithmeticOperator( #arithmeticExpr ); }
| #(STAR exprOrSubquery [ null ] exprOrSubquery [ null ]) { prepareArithmeticOperator( #arithmeticExpr ); }
// | #(CONCAT expr [ null ] (expr [ null ])+ ) { prepareArithmeticOperator( #arithmeticExpr ); }
| #(UNARY_MINUS expr [ null ]) { prepareArithmeticOperator( #arithmeticExpr ); }
| caseExpr [ predicateNode ]
;
caseExpr [ AST predicateNode ]
: simpleCaseExpression [ predicateNode ]
| searchedCaseExpression [ predicateNode ]
;
expressionOrSubQuery [ AST predicateNode ]
: expr [ predicateNode ]
| query
;
simpleCaseExpression [ AST predicateNode ]
: #(CASE2 {inCase=true;} expressionOrSubQuery [ currentAST.root ] (simpleCaseWhenClause [ currentAST.root, predicateNode ])+ (elseClause [ predicateNode ])?) {inCase=false;}
;
simpleCaseWhenClause [ AST predicateNode, AST superPredicateNode ]
: #(WHEN expressionOrSubQuery [ predicateNode ] expressionOrSubQuery [ superPredicateNode ])
;
elseClause [ AST predicateNode ]
: #(ELSE expressionOrSubQuery [ predicateNode ])
;
searchedCaseExpression [ AST predicateNode ]
: #(CASE {inCase = true;} (searchedCaseWhenClause [ predicateNode ])+ (elseClause [ predicateNode ])?) {inCase = false;}
;
searchedCaseWhenClause [ AST predicateNode ]
: #(WHEN logicalExpr expressionOrSubQuery [ predicateNode ])
;
//TODO: I don't think we need this anymore .. how is it different to
// maxelements, etc, which are handled by functionCall
collectionFunction
: #(e:ELEMENTS {inFunctionCall=true;} p1:propertyRef { resolve(#p1); } )
{ processFunction(#e,inSelect); } {inFunctionCall=false;}
| #(i:INDICES {inFunctionCall=true;} p2:propertyRef { resolve(#p2); } )
{ processFunction(#i,inSelect); } {inFunctionCall=false;}
;
functionCall
: #(METHOD_CALL {inFunctionCall=true;} pathAsIdent ( #(EXPR_LIST (exprOrSubquery [ null ])* ) )? ) {
processFunction( #functionCall, inSelect );
inFunctionCall=false;
}
| #(CAST {inFunctionCall=true;} exprOrSubquery [ null ] pathAsIdent) {
processCastFunction( #functionCall, inSelect );
inFunctionCall=false;
}
| #(AGGREGATE aggregateExpr )
;
constant
: literal
| NULL
| TRUE { processBoolean(#constant); }
| FALSE { processBoolean(#constant); }
| JAVA_CONSTANT
;
literal
: NUM_INT { processNumericLiteral( #literal ); }
| NUM_LONG { processNumericLiteral( #literal ); }
| NUM_FLOAT { processNumericLiteral( #literal ); }
| NUM_DOUBLE { processNumericLiteral( #literal ); }
| NUM_BIG_INTEGER { processNumericLiteral( #literal ); }
| NUM_BIG_DECIMAL { processNumericLiteral( #literal ); }
| QUOTED_STRING
;
identifier
: (IDENT | WEIRD_IDENT)
;
addrExpr! [ boolean root ]
: #(d:DOT lhs:addrExprLhs rhs:propertyName ) {
// This gives lookupProperty() a chance to transform the tree
// to process collection properties (.elements, etc).
#addrExpr = #(#d, #lhs, #rhs);
#addrExpr = lookupProperty(#addrExpr,root,false);
}
| #(i:INDEX_OP lhs2:addrExprLhs rhs2:expr [ null ]) {
#addrExpr = #(#i, #lhs2, #rhs2);
processIndex(#addrExpr);
}
| mcr:mapComponentReference {
#addrExpr = #mcr;
}
| p:identifier {
// #addrExpr = #p;
// resolve(#addrExpr);
// In many cases, things other than property-refs are recognized
// by this addrExpr rule. Some of those I have seen:
// 1) select-clause from-aliases
// 2) sql-functions
if ( isNonQualifiedPropertyRef(#p) ) {
#addrExpr = lookupNonQualifiedProperty(#p);
}
else {
resolve(#p);
#addrExpr = #p;
}
}
;
addrExprLhs
: addrExpr [ false ]
;
propertyName
: identifier
| CLASS
| ELEMENTS
| INDICES
;
propertyRef!
: mcr:mapComponentReference {
resolve( #mcr );
#propertyRef = #mcr;
}
| #(d:DOT lhs:propertyRefLhs rhs:propertyName ) {
// This gives lookupProperty() a chance to transform the tree to process collection properties (.elements, etc).
#propertyRef = #(#d, #lhs, #rhs);
#propertyRef = lookupProperty(#propertyRef,false,true);
}
|
p:identifier {
// In many cases, things other than property-refs are recognized
// by this propertyRef rule. Some of those I have seen:
// 1) select-clause from-aliases
// 2) sql-functions
if ( isNonQualifiedPropertyRef(#p) ) {
#propertyRef = lookupNonQualifiedProperty(#p);
}
else {
resolve(#p);
#propertyRef = #p;
}
}
;
propertyRefLhs
: propertyRef
;
aliasRef!
: i:identifier {
#aliasRef = #([ALIAS_REF,i.getText()]); // Create an ALIAS_REF node instead of an IDENT node.
lookupAlias(#aliasRef);
}
;
mapComponentReference
: #( KEY mapPropertyExpression )
| #( VALUE mapPropertyExpression )
| #( ENTRY mapPropertyExpression )
;
mapPropertyExpression
: e:expr [ null ] {
validateMapPropertyExpression( #e );
}
;
parameter!
: #(c:COLON a:identifier) {
// Create a NAMED_PARAM node instead of (COLON IDENT) - semantics ftw!
#parameter = generateNamedParameter( c, a );
}
| #(p:PARAM (n:NUM_INT)? ) {
// Create a (POSITIONAL_)PARAM node instead of (PARAM NUM_INT) - semantics ftw!
#parameter = generatePositionalParameter( p, n );
}
;
numericInteger
: NUM_INT
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
lexer grammar GraphLanguageLexer;
@header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.graph.internal.parse;
}
@members {
/*
* Lexer for the Hibernate EntityGraph Language
*
* It is generated by Antlr via the lexer grammar file `GraphLanguageLexer.g4`
*/
}
channels {
WHITESPACE_CHANNEL
}
WS : ( ' ' | '\t' | '\f' | EOL ) -> channel(WHITESPACE_CHANNEL);
fragment EOL : [\r\n]+;
COLON: ':';
COMMA: ',';
DOT: '.';
LPAREN: '(';
RPAREN: ')';
/**
* In this grammar, basically any string since we (atm) have no keywords
*/
NAME : NAME_START ( NAME_CONTINUATION )*;
fragment NAME_START
: '_'
| '$'
| 'a'..'z'
// HHH-558 : Allow unicode chars in identifiers
//| '\u0080'..'\ufffe'
;
fragment NAME_CONTINUATION
: NAME_START
| '0'..'9'
;

View File

@ -0,0 +1,53 @@
parser grammar GraphLanguageParser;
options {
tokenVocab=GraphLanguageLexer;
}
@header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.graph.internal.parse;
}
@members {
/*
* Antlr grammar describing the Hibernate EntityGraph Language - for parsing a structured
* textual representation of an entity graph
*
* `GraphLanguageParser.g4`
*/
}
graph
: attributeList
;
attributeList
: attributeNode (COMMA attributeNode)*
;
attributeNode
: attributePath (subGraph)?
;
attributePath
: NAME attributeQualifier?
;
attributeQualifier
: DOT NAME
;
subGraph
: LPAREN (subType COLON)? attributeList RPAREN
;
subType
: NAME
;

View File

@ -0,0 +1,253 @@
lexer grammar HqlLexer;
@header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.query.hql.internal;
}
WS : ( ' ' | '\t' | '\f' | EOL ) -> skip;
fragment
EOL : [\r\n]+;
INTEGER_LITERAL : INTEGER_NUMBER ;
fragment
INTEGER_NUMBER : ('0' | '1'..'9' '0'..'9'*) ;
LONG_LITERAL : INTEGER_NUMBER ('l'|'L');
BIG_INTEGER_LITERAL : INTEGER_NUMBER ('bi'|'BI') ;
HEX_LITERAL : '0' ('x'|'X') HEX_DIGIT+ ('l'|'L')? ;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
OCTAL_LITERAL : '0' ('0'..'7')+ ('l'|'L')? ;
FLOAT_LITERAL : FLOATING_POINT_NUMBER ('f'|'F')? ;
fragment
FLOATING_POINT_NUMBER
: ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
| '.' ('0'..'9')+ EXPONENT?
| ('0'..'9')+ EXPONENT
| ('0'..'9')+
;
DOUBLE_LITERAL : FLOATING_POINT_NUMBER ('d'|'D') ;
BIG_DECIMAL_LITERAL : FLOATING_POINT_NUMBER ('bd'|'BD') ;
fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
CHARACTER_LITERAL
: '\'' ( ESCAPE_SEQUENCE | ~('\''|'\\') ) '\'' {setText(getText().substring(1, getText().length()-1));}
;
STRING_LITERAL
: '"' ( ESCAPE_SEQUENCE | ~('\\'|'"') )* '"' {setText(getText().substring(1, getText().length()-1));}
| ('\'' ( ESCAPE_SEQUENCE | ~('\\'|'\'') )* '\'')+ {setText(getText().substring(1, getText().length()-1).replace("''", "'"));}
;
fragment
ESCAPE_SEQUENCE
: '\\' ('b'|'t'|'n'|'f'|'r'|'\\"'|'\''|'\\')
| UNICODE_ESCAPE
| OCTAL_ESCAPE
;
fragment
OCTAL_ESCAPE
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESCAPE
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
// ESCAPE start tokens
TIMESTAMP_ESCAPE_START : '{ts';
DATE_ESCAPE_START : '{d';
TIME_ESCAPE_START : '{t';
EQUAL : '=';
NOT_EQUAL : '!=' | '^=' | '<>';
GREATER : '>';
GREATER_EQUAL : '>=';
LESS : '<';
LESS_EQUAL : '<=';
COMMA : ',';
DOT : '.';
LEFT_PAREN : '(';
RIGHT_PAREN : ')';
LEFT_BRACKET : '[';
RIGHT_BRACKET : ']';
LEFT_BRACE : '{';
RIGHT_BRACE : '}';
PLUS : '+';
MINUS : '-';
ASTERISK : '*';
SLASH : '/';
PERCENT : '%';
AMPERSAND : '&';
SEMICOLON : ';';
COLON : ':';
PIPE : '|';
DOUBLE_PIPE : '||';
QUESTION_MARK : '?';
ARROW : '->';
// Keywords
ABS : [aA] [bB] [sS];
AS : [aA] [sS];
ALL : [aA] [lL] [lL];
AND : [aA] [nN] [dD];
ANY : [aA] [nN] [yY];
ASC : [aA] [sS] [cC];
AVG : [aA] [vV] [gG];
BY : [bB] [yY];
BETWEEN : [bB] [eE] [tT] [wW] [eE] [eE] [nN];
BOTH : [bB] [oO] [tT] [hH];
CASE : [cC] [aA] [sS] [eE];
CAST : [cC] [aA] [sS] [tT];
CEILING : [cC] [eE] [iI] [lL] [iI] [nN] [gG];
CLASS : [cC] [lL] [aA] [sS] [sS];
COALESCE : [cC] [oO] [aA] [lL] [eE] [sS] [cC] [eE];
COLLATE : [cC] [oO] [lL] [lL] [aA] [tT] [eE];
CONCAT : [cC] [oO] [nN] [cC] [aA] [tT];
COUNT : [cC] [oO] [uU] [nN] [tT];
CURRENT_DATE : [cC] [uU] [rR] [rR] [eE] [nN] [tT] '_' [dD] [aA] [tT] [eE];
CURRENT_INSTANT : [cC] [uU] [rR] [rR] [eE] [nN] [tT] '_' [iI] [nN] [sS] [tT] [aA] [nN] [tT];
CURRENT_TIME : [cC] [uU] [rR] [rR] [eE] [nN] [tT] '_' [tT] [iI] [mM] [eE];
CURRENT_TIMESTAMP : [cC] [uU] [rR] [rR] [eE] [nN] [tT] '_' [tT] [iI] [mM] [eE] [sS] [tT] [aA] [mM] [pP];
CROSS : [cC] [rR] [oO] [sS] [sS];
DAY : [dD] [aA] [yY];
DELETE : [dD] [eE] [lL] [eE] [tT] [eE];
DESC : [dD] [eE] [sS] [cC];
DISTINCT : [dD] [iI] [sS] [tT] [iI] [nN] [cC] [tT];
ELEMENTS : [eE] [lL] [eE] [mM] [eE] [nN] [tT] [sS];
ELSE : [eE] [lL] [sS] [eE];
EMPTY : [eE] [mM] [pP] [tT] [yY];
END : [eE] [nN] [dD];
ENTRY : [eE] [nN] [tT] [rR] [yY];
ESCAPE : [eE] [sS] [cC] [aA] [pP] [eE];
EXISTS : [eE] [xX] [iI] [sS] [tT] [sS];
EXP : [eE] [xX] [pP];
EXTRACT : [eE] [xX] [tT] [rR] [aA] [cC] [tT];
FETCH : [fF] [eE] [tT] [cC] [hH];
FLOOR : [fF] [lL] [oO] [oO] [rR];
FROM : [fF] [rR] [oO] [mM];
FOR : [fF] [oO] [rR];
FULL : [fF] [uU] [lL] [lL];
FUNCTION : [fF] [uU] [nN] [cC] [tT] [iI] [oO] [nN];
GREATEST : [gG] [rR] [eE] [aA] [tT] [eE] [sS] [tT];
GROUP : [gG] [rR] [oO] [uU] [pP];
HAVING : [hH] [aA] [vV] [iI] [nN] [gG];
HOUR : [hH] [oO] [uU] [rR];
IFNULL : [iI] [fF] [nN] [uU] [lL] [lL];
IN : [iI] [nN];
INDEX : [iI] [nN] [dD] [eE] [xX];
INNER : [iI] [nN] [nN] [eE] [rR];
INSERT : [iI] [nN] [sS] [eE] [rR] [tT];
INTO : [iI] [nN] [tT] [oO];
IS : [iI] [sS];
JOIN : [jJ] [oO] [iI] [nN];
KEY : [kK] [eE] [yY];
LEADING : [lL] [eE] [aA] [dD] [iI] [nN] [gG];
LEAST : [lL] [eE] [aA] [sS] [tT];
LEFT : [lL] [eE] [fF] [tT];
LENGTH : [lL] [eE] [nN] [gG] [tT] [hH];
LIMIT : [lL] [iI] [mM] [iI] [tT];
LIKE : [lL] [iI] [kK] [eE];
LIST : [lL] [iI] [sS] [tT];
LN : [lL] [nN];
LOCATE : [lL] [oO] [cC] [aA] [tT] [eE];
LOWER : [lL] [oO] [wW] [eE] [rR];
MAP : [mM] [aA] [pP];
MAX : [mM] [aA] [xX];
MAXELEMENT : [mM] [aA] [xX] [eE] [lL] [eE] [mM] [eE] [nN] [tT];
MAXINDEX : [mM] [aA] [xX] [iI] [nN] [dD] [eE] [xX];
MEMBER : [mM] [eE] [mM] [bB] [eE] [rR];
MICROSECOND : [mM] [iI] [cC] [rR] [oO] [sS] [eE] [cC] [oO] [nN] [dD];
MILLISECOND : [mM] [iI] [lL] [lL] [iI] [sS] [eE] [cC] [oO] [nN] [dD];
MIN : [mM] [iI] [nN];
MINELEMENT : [mM] [iI] [nN] [eE] [lL] [eE] [mM] [eE] [nN] [tT];
MININDEX : [mM] [iI] [nN] [iI] [nN] [dD] [eE] [xX];
MINUTE : [mM] [iI] [nN] [uU] [tT] [eE];
MOD : [mM] [oO] [dD];
MONTH : [mM] [oO] [nN] [tT] [hH];
NEW : [nN] [eE] [wW];
NOT : [nN] [oO] [tT];
NULLIF : [nN] [uU] [lL] [lL] [iI] [fF];
OBJECT : [oO] [bB] [jJ] [eE] [cC] [tT];
OF : [oO] [fF];
OFFSET : [oO] [fF] [fF] [sS] [eE] [tT];
ON : [oO] [nN];
OR : [oO] [rR];
ORDER : [oO] [rR] [dD] [eE] [rR];
OUTER : [oO] [uU] [tT] [eE] [rR];
POSITION : [pP] [oO] [sS] [iI] [tT] [iI] [oO] [nN];
POWER : [pP] [oO] [wW] [eE] [rR];
QUARTER : [qQ] [uU] [aA] [rR] [tT] [eE] [rR];
REPLACE : [rR] [eE] [pP] [lL] [aA] [cC] [eE];
RIGHT : [rR] [iI] [gG] [hH] [tT];
ROUND : [rR] [oO] [uU] [nN] [dD];
SECOND : [sS] [eE] [cC] [oO] [nN] [dD];
SELECT : [sS] [eE] [lL] [eE] [cC] [tT];
SET : [sS] [eE] [tT];
SIGN : [sS] [iI] [gG] [nN];
SIZE : [sS] [iI] [zZ] [eE];
SQRT : [sS] [qQ] [rR] [tT];
STR : [sS] [tT] [rR];
SUBSTRING : [sS] [uU] [bB] [sS] [tT] [rR] [iI] [nN] [gG];
SUM : [sS] [uU] [mM];
THEN : [tT] [hH] [eE] [nN];
TIMEZONE_HOUR : [tT] [iI] [mM] [eE] [zZ] [oO] [nN] [eE] '_' [hH] [oO] [uU] [rR];
TIMEZONE_MINUTE : [tT] [iI] [mM] [eE] [zZ] [oO] [nN] [eE] '_' [mM] [iI] [nN] [uU] [tT] [eE];
TRAILING : [tT] [rR] [aA] [iI] [lL] [iI] [nN] [gG];
TREAT : [tT] [rR] [eE] [aA] [tT];
TRIM : [tT] [rR] [iI] [mM];
TYPE : [tT] [yY] [pP] [eE];
UPDATE : [uU] [pP] [dD] [aA] [tT] [eE];
UPPER : [uU] [pP] [pP] [eE] [rR];
VALUE : [vV] [aA] [lL] [uU] [eE];
WEEK : [wW] [eE] [eE] [kK];
WHEN : [wW] [hH] [eE] [nN];
WHERE : [wW] [hH] [eE] [rR] [eE];
WITH : [wW] [iI] [tT] [hH];
YEAR : [yY] [eE] [aA] [rR];
ASIN : [aA] [sS] [iI] [nN];
ATAN : [aA] [cC] [oO] [sH];
ATAN2 : [aA] [tT] [aA] [nN] '2';
ACOS : [aA] [tT] [aA] [nN];
SIN : [sS] [iI] [nN];
COS : [cC] [oO] [sH];
TAN : [tT] [aA] [nN];
// case-insensitive true, false and null recognition (split vote :)
TRUE : [tT] [rR] [uU] [eE];
FALSE : [fF] [aA] [lL] [sS] [eE];
NULL : [nN] [uU] [lL] [lL];
// Identifiers
IDENTIFIER
: ('a'..'z'|'A'..'Z'|'_'|'$'|'\u0080'..'\ufffe')('a'..'z'|'A'..'Z'|'_'|'$'|'0'..'9'|'\u0080'..'\ufffe')*
;
QUOTED_IDENTIFIER
: '`' ( ESCAPE_SEQUENCE | ~('\\'|'`') )* '`'
;

View File

@ -0,0 +1,938 @@
parser grammar HqlParser;
options {
tokenVocab=HqlLexer;
}
@header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.query.hql.internal;
}
@members {
protected void logUseOfReservedWordAsIdentifier(Token token) {
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Statements
statement
: ( selectStatement | updateStatement | deleteStatement | insertStatement ) EOF
;
selectStatement
: querySpec
;
subQuery
: querySpec
;
deleteStatement
: DELETE FROM? entityName identificationVariableDef? whereClause?
;
updateStatement
: UPDATE FROM? entityName identificationVariableDef? setClause whereClause?
;
setClause
: SET assignment+
;
assignment
: dotIdentifierSequence EQUAL expression
;
insertStatement
// todo (6.0 : VERSIONED
: INSERT insertSpec querySpec
;
insertSpec
: intoSpec targetFieldsSpec
;
intoSpec
: INTO entityName
;
targetFieldsSpec
:
LEFT_PAREN dotIdentifierSequence (COMMA dotIdentifierSequence)* RIGHT_PAREN
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// QUERY SPEC - general structure of root sqm or sub sqm
querySpec
: selectClause? fromClause whereClause? ( groupByClause havingClause? )? orderByClause? limitClause? offsetClause?
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FROM clause
fromClause
: FROM fromClauseSpace (COMMA fromClauseSpace)*
;
fromClauseSpace
: pathRoot ( crossJoin | jpaCollectionJoin | qualifiedJoin )*
;
pathRoot
: entityName (identificationVariableDef)?
;
/**
* Rule for dotIdentifierSequence where we expect an entity-name. The extra
* "rule layer" allows the walker to specially handle such a case (to use a special
* org.hibernate.query.hql.DotIdentifierConsumer, etc)
*/
entityName
: dotIdentifierSequence
;
identificationVariableDef
: (AS identifier)
| IDENTIFIER
;
crossJoin
: CROSS JOIN pathRoot (identificationVariableDef)?
;
jpaCollectionJoin
: COMMA IN LEFT_PAREN path RIGHT_PAREN (identificationVariableDef)?
;
qualifiedJoin
: joinTypeQualifier JOIN FETCH? qualifiedJoinRhs (qualifiedJoinPredicate)?
;
joinTypeQualifier
: INNER?
| (LEFT|RIGHT|FULL)? OUTER?
;
qualifiedJoinRhs
: path (identificationVariableDef)?
;
qualifiedJoinPredicate
: (ON | WITH) predicate
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SELECT clause
selectClause
: SELECT DISTINCT? selectionList
;
selectionList
: selection (COMMA selection)*
;
selection
: selectExpression (resultIdentifier)?
;
selectExpression
: dynamicInstantiation
| jpaSelectObjectSyntax
| mapEntrySelection
| expression
;
resultIdentifier
: (AS identifier)
| IDENTIFIER
;
mapEntrySelection
: ENTRY LEFT_PAREN path RIGHT_PAREN
;
dynamicInstantiation
: NEW dynamicInstantiationTarget LEFT_PAREN dynamicInstantiationArgs RIGHT_PAREN
;
dynamicInstantiationTarget
: LIST
| MAP
| dotIdentifierSequence
;
dynamicInstantiationArgs
: dynamicInstantiationArg ( COMMA dynamicInstantiationArg )*
;
dynamicInstantiationArg
: dynamicInstantiationArgExpression (AS? identifier)?
;
dynamicInstantiationArgExpression
: expression
| dynamicInstantiation
;
jpaSelectObjectSyntax
: OBJECT LEFT_PAREN identifier RIGHT_PAREN
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Path structures
dotIdentifierSequence
: identifier dotIdentifierSequenceContinuation*
;
dotIdentifierSequenceContinuation
: DOT identifier
;
/**
* A path which needs to be resolved semantically. This recognizes
* any path-like structure. Generally, the path is semantically
* interpreted by the consumer of the parse-tree. However, there
* are certain cases where we can syntactically recognize a navigable
* path; see `syntacticNavigablePath` rule
*/
path
: syntacticDomainPath (pathContinuation)?
| generalPathFragment
;
pathContinuation
: DOT dotIdentifierSequence
;
/**
* Rule for cases where we syntactically know that the path is a
* "domain path" because it is one of these special cases:
*
* * TREAT( path )
* * ELEMENTS( path )
* * VALUE( path )
* * KEY( path )
* * path[ selector ]
*/
syntacticDomainPath
: treatedNavigablePath
| collectionElementNavigablePath
| mapKeyNavigablePath
| dotIdentifierSequence indexedPathAccessFragment
;
/**
* The main path rule. Recognition for all normal path structures including
* class, field and enum references as well as navigable paths.
*
* NOTE : this rule does *not* cover the special syntactic navigable path
* cases: TREAT, KEY, ELEMENTS, VALUES
*/
generalPathFragment
: dotIdentifierSequence (indexedPathAccessFragment)?
;
indexedPathAccessFragment
: LEFT_BRACKET expression RIGHT_BRACKET (DOT generalPathFragment)?
;
treatedNavigablePath
: TREAT LEFT_PAREN path AS dotIdentifierSequence RIGHT_PAREN (pathContinuation)?
;
collectionElementNavigablePath
: (VALUE | ELEMENTS) LEFT_PAREN path RIGHT_PAREN (pathContinuation)?
;
mapKeyNavigablePath
: KEY LEFT_PAREN path RIGHT_PAREN (pathContinuation)?
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// GROUP BY clause
groupByClause
: GROUP BY groupingSpecification
;
groupingSpecification
: groupingValue ( COMMA groupingValue )*
;
groupingValue
: expression collationSpecification?
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//HAVING clause
havingClause
: HAVING predicate
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ORDER BY clause
orderByClause
// todo (6.0) : null precedence
: ORDER BY sortSpecification (COMMA sortSpecification)*
;
sortSpecification
: sortExpression collationSpecification? orderingSpecification?
;
sortExpression
: identifier
| INTEGER_LITERAL
| expression
;
collationSpecification
: COLLATE collateName
;
collateName
: dotIdentifierSequence
;
orderingSpecification
: ASC
| DESC
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LIMIT/OFFSET clause
limitClause
: LIMIT parameterOrNumberLiteral
;
offsetClause
: OFFSET parameterOrNumberLiteral
;
parameterOrNumberLiteral
: parameter
| INTEGER_LITERAL
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// WHERE clause & Predicates
whereClause
: WHERE predicate
;
predicate
: LEFT_PAREN predicate RIGHT_PAREN # GroupedPredicate
| predicate OR predicate # OrPredicate
| predicate AND predicate # AndPredicate
| NOT predicate # NegatedPredicate
| expression IS (NOT)? NULL # IsNullPredicate
| expression IS (NOT)? EMPTY # IsEmptyPredicate
| expression EQUAL expression # EqualityPredicate
| expression NOT_EQUAL expression # InequalityPredicate
| expression GREATER expression # GreaterThanPredicate
| expression GREATER_EQUAL expression # GreaterThanOrEqualPredicate
| expression LESS expression # LessThanPredicate
| expression LESS_EQUAL expression # LessThanOrEqualPredicate
| expression (NOT)? IN inList # InPredicate
| expression (NOT)? BETWEEN expression AND expression # BetweenPredicate
| expression (NOT)? LIKE expression (likeEscape)? # LikePredicate
| MEMBER OF path # MemberOfPredicate
;
inList
: ELEMENTS? LEFT_PAREN dotIdentifierSequence RIGHT_PAREN # PersistentCollectionReferenceInList
| LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN # ExplicitTupleInList
| expression # SubQueryInList
;
likeEscape
: ESCAPE expression
;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Expression
expression
: expression DOUBLE_PIPE expression # ConcatenationExpression
| expression PLUS expression # AdditionExpression
| expression MINUS expression # SubtractionExpression
| expression ASTERISK expression # MultiplicationExpression
| expression SLASH expression # DivisionExpression
| expression PERCENT expression # ModuloExpression
// todo (6.0) : should these unary plus/minus rules only apply to literals?
// if so, move the MINUS / PLUS recognition to the `literal` rule
// specificcally for numeric literals
| MINUS expression # UnaryMinusExpression
| PLUS expression # UnaryPlusExpression
| caseStatement # CaseExpression
| coalesce # CoalesceExpression
| nullIf # NullIfExpression
| literal # LiteralExpression
| parameter # ParameterExpression
| entityTypeReference # EntityTypeExpression
| path # PathExpression
| function # FunctionExpression
| LEFT_PAREN subQuery RIGHT_PAREN # SubQueryExpression
;
entityTypeReference
: TYPE LEFT_PAREN (path | parameter) RIGHT_PAREN
;
caseStatement
: simpleCaseStatement
| searchedCaseStatement
;
simpleCaseStatement
: CASE expression (simpleCaseWhen)+ (caseOtherwise)? END
;
simpleCaseWhen
: WHEN expression THEN expression
;
caseOtherwise
: ELSE expression
;
searchedCaseStatement
: CASE (searchedCaseWhen)+ (caseOtherwise)? END
;
searchedCaseWhen
: WHEN predicate THEN expression
;
greatestFunction
: GREATEST LEFT_PAREN expression (COMMA expression)+ RIGHT_PAREN
;
leastFunction
: LEAST LEFT_PAREN expression (COMMA expression)+ RIGHT_PAREN
;
coalesce
: COALESCE LEFT_PAREN expression (COMMA expression)+ RIGHT_PAREN
| IFNULL LEFT_PAREN expression COMMA expression RIGHT_PAREN
;
nullIf
: NULLIF LEFT_PAREN expression COMMA expression RIGHT_PAREN
;
literal
: STRING_LITERAL
| CHARACTER_LITERAL
| INTEGER_LITERAL
| LONG_LITERAL
| BIG_INTEGER_LITERAL
| FLOAT_LITERAL
| DOUBLE_LITERAL
| BIG_DECIMAL_LITERAL
| HEX_LITERAL
| OCTAL_LITERAL
| NULL
| TRUE
| FALSE
| timestampLiteral
| dateLiteral
| timeLiteral
;
// todo (6.0) : expand temporal literal support to Java 8 temporal types
// * Instant -> {instant '...'}
// * LocalDate -> {localDate '...'}
// * LocalDateTime -> {localDateTime '...'}
// * OffsetDateTime -> {offsetDateTime '...'}
// * OffsetTime -> {offsetTime '...'}
// * ZonedDateTime -> {localDate '...'}
// * ...
//
// Few things:
// 1) the markers above are just initial thoughts. They are obviously verbose. Maybe acronyms or shortened forms would be better
// 2) we may want to stay away from all of the timezone headaches by not supporting local, zoned and offset forms
timestampLiteral
: TIMESTAMP_ESCAPE_START dateTimeLiteralText RIGHT_BRACE
;
dateLiteral
: DATE_ESCAPE_START dateTimeLiteralText RIGHT_BRACE
;
timeLiteral
: TIME_ESCAPE_START dateTimeLiteralText RIGHT_BRACE
;
dateTimeLiteralText
: STRING_LITERAL | CHARACTER_LITERAL
;
parameter
: COLON identifier # NamedParameter
| QUESTION_MARK INTEGER_LITERAL? # PositionalParameter
;
function
: standardFunction
| aggregateFunction
| jpaCollectionFunction
| hqlCollectionFunction
| jpaNonStandardFunction
| nonStandardFunction
;
jpaNonStandardFunction
: FUNCTION LEFT_PAREN jpaNonStandardFunctionName (COMMA nonStandardFunctionArguments)? RIGHT_PAREN
;
jpaNonStandardFunctionName
: STRING_LITERAL
;
nonStandardFunction
: nonStandardFunctionName LEFT_PAREN nonStandardFunctionArguments? RIGHT_PAREN
;
nonStandardFunctionName
: dotIdentifierSequence
;
nonStandardFunctionArguments
: expression (COMMA expression)*
;
jpaCollectionFunction
: SIZE LEFT_PAREN path RIGHT_PAREN # CollectionSizeFunction
| INDEX LEFT_PAREN identifier RIGHT_PAREN # CollectionIndexFunction
;
hqlCollectionFunction
: MAXINDEX LEFT_PAREN path RIGHT_PAREN # MaxIndexFunction
| MAXELEMENT LEFT_PAREN path RIGHT_PAREN # MaxElementFunction
| MININDEX LEFT_PAREN path RIGHT_PAREN # MinIndexFunction
| MINELEMENT LEFT_PAREN path RIGHT_PAREN # MinElementFunction
;
aggregateFunction
: avgFunction
| sumFunction
| minFunction
| maxFunction
| countFunction
;
avgFunction
: AVG LEFT_PAREN DISTINCT? expression RIGHT_PAREN
;
sumFunction
: SUM LEFT_PAREN DISTINCT? expression RIGHT_PAREN
;
minFunction
: MIN LEFT_PAREN DISTINCT? expression RIGHT_PAREN
;
maxFunction
: MAX LEFT_PAREN DISTINCT? expression RIGHT_PAREN
;
countFunction
: COUNT LEFT_PAREN DISTINCT? (expression | ASTERISK) RIGHT_PAREN
;
standardFunction
: castFunction
| extractFunction
| concatFunction
| substringFunction
| replaceFunction
| trimFunction
| upperFunction
| lowerFunction
| locateFunction
| positionFunction
| lengthFunction
| absFunction
| signFunction
| sqrtFunction
| lnFunction
| expFunction
| modFunction
| powerFunction
| ceilingFunction
| floorFunction
| roundFunction
| trigFunction
| atan2Function
| strFunction
| greatestFunction
| leastFunction
| currentDateFunction
| currentTimeFunction
| currentTimestampFunction
| currentInstantFunction
;
castFunction
: CAST LEFT_PAREN expression AS castTarget RIGHT_PAREN
;
castTarget
// todo (6.0) : should allow either
// - named cast (IDENTIFIER)
// - JavaTypeDescriptorRegistry (imported) key
// - java.sql.Types field NAME (alias for its value as a coded cast)
// - "pass through"
// - coded cast (INTEGER_LITERAL)
// - SqlTypeDescriptorRegistry key
: identifier
;
concatFunction
: CONCAT LEFT_PAREN expression (COMMA expression)+ RIGHT_PAREN
;
substringFunction
: SUBSTRING LEFT_PAREN expression COMMA substringFunctionStartArgument (COMMA substringFunctionLengthArgument)? RIGHT_PAREN
| SUBSTRING LEFT_PAREN expression FROM substringFunctionStartArgument (FOR substringFunctionLengthArgument)? RIGHT_PAREN
;
substringFunctionStartArgument
: expression
;
substringFunctionLengthArgument
: expression
;
trimFunction
: TRIM LEFT_PAREN trimSpecification? trimCharacter? FROM? expression RIGHT_PAREN
;
trimSpecification
: LEADING
| TRAILING
| BOTH
;
trimCharacter
: CHARACTER_LITERAL | STRING_LITERAL
;
upperFunction
: UPPER LEFT_PAREN expression RIGHT_PAREN
;
lowerFunction
: LOWER LEFT_PAREN expression RIGHT_PAREN
;
locateFunction
: LOCATE LEFT_PAREN locateFunctionPatternArgument COMMA locateFunctionStringArgument (COMMA locateFunctionStartArgument)? RIGHT_PAREN
;
locateFunctionPatternArgument
: expression
;
locateFunctionStringArgument
: expression
;
locateFunctionStartArgument
: expression
;
replaceFunction
: REPLACE LEFT_PAREN replaceFunctionStringArgument COMMA replaceFunctionPatternArgument COMMA replaceFunctionReplacementArgument RIGHT_PAREN
;
replaceFunctionStringArgument
: expression
;
replaceFunctionPatternArgument
: expression
;
replaceFunctionReplacementArgument
: expression
;
lengthFunction
: LENGTH LEFT_PAREN expression RIGHT_PAREN
;
absFunction
: ABS LEFT_PAREN expression RIGHT_PAREN
;
signFunction
: SIGN LEFT_PAREN expression RIGHT_PAREN
;
sqrtFunction
: SQRT LEFT_PAREN expression RIGHT_PAREN
;
lnFunction
: LN LEFT_PAREN expression RIGHT_PAREN
;
expFunction
: EXP LEFT_PAREN expression RIGHT_PAREN
;
powerFunction
: POWER LEFT_PAREN powerBaseArgument COMMA powerPowerArgument RIGHT_PAREN
;
powerBaseArgument
: expression
;
powerPowerArgument
: expression
;
modFunction
: MOD LEFT_PAREN modDividendArgument COMMA modDivisorArgument RIGHT_PAREN
;
modDividendArgument
: expression
;
modDivisorArgument
: expression
;
ceilingFunction
: CEILING LEFT_PAREN expression RIGHT_PAREN
;
floorFunction
: FLOOR LEFT_PAREN expression RIGHT_PAREN
;
roundFunction
: ROUND LEFT_PAREN expression COMMA roundFunctionPrecision RIGHT_PAREN
;
roundFunctionPrecision
: expression
;
trigFunction
: trigFunctionName LEFT_PAREN expression RIGHT_PAREN
;
trigFunctionName
: SIN | COS | TAN | ASIN | ACOS | ATAN
;
atan2Function
: ATAN2 LEFT_PAREN expression COMMA expression RIGHT_PAREN
;
strFunction
: STR LEFT_PAREN expression RIGHT_PAREN
;
currentDateFunction
: CURRENT_DATE (LEFT_PAREN RIGHT_PAREN)?
;
currentTimeFunction
: CURRENT_TIME (LEFT_PAREN RIGHT_PAREN)?
;
currentTimestampFunction
: CURRENT_TIMESTAMP (LEFT_PAREN RIGHT_PAREN)?
;
currentInstantFunction
: CURRENT_INSTANT (LEFT_PAREN RIGHT_PAREN)?
;
extractFunction
: EXTRACT LEFT_PAREN extractField FROM expression RIGHT_PAREN
| datetimeField LEFT_PAREN expression RIGHT_PAREN
;
extractField
: datetimeField
| timeZoneField
| secondsField
;
datetimeField
: YEAR
| MONTH
| DAY
| WEEK
| QUARTER
| HOUR
| MINUTE
| SECOND
;
secondsField
: MILLISECOND
| MICROSECOND
;
timeZoneField
: TIMEZONE_HOUR
| TIMEZONE_MINUTE
;
positionFunction
: POSITION LEFT_PAREN positionFunctionPatternArgument IN positionFunctionStringArgument RIGHT_PAREN
;
positionFunctionPatternArgument
: expression
;
positionFunctionStringArgument
: expression
;
/**
* The `identifier` is used to provide "keyword as identifier" handling.
*
* The lexer hands us recognized keywords using their specific tokens. This is important
* for the recognition of sqm structure, especially in terms of performance!
*
* However we want to continue to allow users to use mopst keywords as identifiers (e.g., attribute names).
* This parser rule helps with that. Here we expect that the caller already understands their
* context enough to know that keywords-as-identifiers are allowed.
*/
identifier
: IDENTIFIER
| (ABS
| ALL
| AND
| ANY
| AS
| ASC
| ATAN2
| AVG
| BY
| BETWEEN
| BOTH
| CAST
| CEILING
| COALESCE
| COLLATE
| CONCAT
| COUNT
| CROSS
| DAY
| DELETE
| DESC
| DISTINCT
| ELEMENTS
| ENTRY
| EXP
| FLOOR
| FROM
| FOR
| FULL
| FUNCTION
| GREATEST
| GROUP
| HOUR
| IFNULL
| IN
| INDEX
| INNER
| INSERT
| JOIN
| KEY
| LEADING
| LEAST
| LEFT
| LENGTH
| LIKE
| LIMIT
| LIST
| LN
| LOWER
| MAP
| MAX
| MICROSECOND
| MILLISECOND
| MIN
| MINUTE
| MEMBER
| MONTH
| NULLIF
| OBJECT
| OFFSET
| ON
| OR
| ORDER
| OUTER
| POSITION
| QUARTER
| POWER
| REPLACE
| ROUND
| RIGHT
| SELECT
| SECOND
| SET
| SIGN
| SQRT
| STR
| SUBSTRING
| SUM
| TRAILING
| TREAT
| UPDATE
| UPPER
| VALUE
| WEEK
| WHERE
| WITH
| YEAR
| trigFunctionName) {
logUseOfReservedWordAsIdentifier(getCurrentToken());
}
;

View File

@ -0,0 +1,60 @@
lexer grammar SqlStatementLexer;
@header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.tool.hbm2ddl.grammar;
}
STMT_END
: ';' ( '\t' | ' ' | '\r' | '\n' )*
;
MULTILINE_COMMENT
: '/*' .*? '*/' -> skip
;
LINE_COMMENT
: ('//' | '--') ~[\r\n]* -> skip
;
NEWLINE
: ('\r'? '\n' | '\r') -> skip
;
WORD
: ~[;]
;
QUOTED_TEXT
: '\'' ( ESCAPE_SEQUENCE | ~('\\'|'\'') )* '\''
;
fragment
ESCAPE_SEQUENCE
: '\\' ('b'|'t'|'n'|'f'|'r'|'\\"'|'\''|'\\')
| UNICODE_ESCAPE
| OCTAL_ESCAPE
;
fragment
OCTAL_ESCAPE
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESCAPE
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
fragment
HEX_DIGIT
: ('0'..'9'|'a'..'f'|'A'..'F')
;

View File

@ -1,17 +1,29 @@
parser grammar SqlStatementParser;
options {
tokenVocab=SqlStatementLexer;
}
@header {
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.query.criteria.internal.compile;
/**
* @author Steve Ebersole
*/
public interface CompilableCriteria {
public void validate();
public CriteriaInterpretation interpret(RenderingContext renderingContext);
package org.hibernate.tool.hbm2ddl.grammar;
}
statements
: (statement)*
;
statement
: (text)* STMT_END
;
text :
WORD | QUOTED_TEXT
;

View File

@ -1,512 +0,0 @@
header
{
package org.hibernate.hql.internal.antlr;
}
/**
* SQL Generator Tree Parser, providing SQL rendering of SQL ASTs produced by the previous phase, HqlSqlWalker. All
* syntax decoration such as extra spaces, lack of spaces, extra parens, etc. should be added by this class.
* <br>
* This grammar processes the HQL/SQL AST and produces an SQL string. The intent is to move dialect-specific
* code into a sub-class that will override some of the methods, just like the other two grammars in this system.
* @author Joshua Davis (joshua@hibernate.org)
*/
class SqlGeneratorBase extends TreeParser;
options {
// Note: importVocab and exportVocab cause ANTLR to share the token type numbers between the
// two grammars. This means that the token type constants from the source tree are the same
// as those in the target tree. If this is not the case, tree translation can result in
// token types from the *source* tree being present in the target tree.
importVocab=HqlSql; // import definitions from "HqlSql"
exportVocab=Sql; // Call the resulting definitions "Sql"
buildAST=false; // Don't build an AST.
}
{
/** the buffer resulting SQL statement is written to */
private StringBuilder buf = new StringBuilder();
private boolean captureExpression = false;
protected java.util.List<StringBuilder> exprs = new java.util.ArrayList<StringBuilder>(java.util.Arrays.asList(new StringBuilder()));
protected void out(String s) {
getStringBuilder().append( s );
}
/**
* Returns the last character written to the output, or -1 if there isn't one.
*/
protected int getLastChar() {
int len = buf.length();
if ( len == 0 )
return -1;
else
return buf.charAt( len - 1 );
}
/**
* Add a aspace if the previous token was not a space or a parenthesis.
*/
protected void optionalSpace() {
// Implemented in the sub-class.
}
protected void out(AST n) {
out(n.getText());
}
protected void separator(AST n, String sep) {
if (n.getNextSibling() != null)
out(sep);
}
protected boolean hasText(AST a) {
String t = a.getText();
return t != null && t.length() > 0;
}
protected void fromFragmentSeparator(AST a) {
// moved this impl into the subclass...
}
protected void nestedFromFragment(AST d,AST parent) {
// moved this impl into the subclass...
}
protected StringBuilder getStringBuilder() {
return captureExpression ? exprs.get(exprs.size() - 1) : buf;
}
protected void nyi(AST n) {
throw new UnsupportedOperationException("Unsupported node: " + n);
}
protected void beginFunctionTemplate(AST m,AST i) {
// if template is null we just write the function out as it appears in the hql statement
out(i);
out("(");
}
protected void endFunctionTemplate(AST m) {
out(")");
}
protected void betweenFunctionArguments() {
out( ", " );
}
protected void captureExpressionStart() {
if ( captureExpression ) {
exprs.add( new StringBuilder() );
} else {
captureExpression = true;
}
}
protected void captureExpressionFinish() {
// Capturing will only stop when we leave the last capture context
if ( exprs.size() == 1 ) {
captureExpression = false;
}
}
protected String resetCapture() {
StringBuilder sb = exprs.remove( exprs.size() - 1 );
final String expression = sb.toString();
if ( exprs.isEmpty() ) {
sb.setLength(0);
exprs.add( sb );
}
return expression;
}
/**
* Implementation note: This is just a stub. SqlGenerator contains the effective implementation.
*/
protected String renderOrderByElement(String expression, String order, String nulls) {
throw new UnsupportedOperationException("Concrete SQL generator should override this method.");
}
}
statement
: selectStatement
| updateStatement
| deleteStatement
| insertStatement
;
selectStatement
: #(SELECT { out("select "); }
selectClause
from
( #(WHERE { out(" where "); } whereExpr ) )?
( #(GROUP { out(" group by "); } groupExprs ( #(HAVING { out(" having "); } booleanExpr[false]) )? ) )?
( #(ORDER { out(" order by "); } orderExprs ) )?
)
;
// Note: eats the FROM token node, as it is not valid in an update statement.
// It's outlived its usefulness after analysis phase :)
// TODO : needed to use conditionList directly here and deleteStatement, as whereExprs no longer works for this stuff
updateStatement
: #(UPDATE { out("update "); }
#( FROM fromTable )
setClause
(whereClause)?
)
;
deleteStatement
// Note: not space needed at end of "delete" because the from rule included one before the "from" it outputs
: #(DELETE { out("delete"); }
from
(whereClause)?
)
;
insertStatement
: #(INSERT { out( "insert " ); }
i:INTO { out( i ); out( " " ); }
selectStatement
)
;
setClause
// Simply re-use comparisionExpr, because it already correctly defines the EQ rule the
// way it is needed here; not the most aptly named, but ah
: #( SET { out(" set "); } comparisonExpr[false] ( { out(", "); } comparisonExpr[false] )* )
;
whereClause
: #(WHERE { out(" where "); } whereClauseExpr )
;
whereClauseExpr
: (SQL_TOKEN) => conditionList
| booleanExpr[ false ]
;
orderExprs { String ordExp = null; String ordDir = null; String ordNul = null; }
// TODO: remove goofy space before the comma when we don't have to regression test anymore.
// Dialect is provided a hook to render each ORDER BY element, so the expression is being captured instead of
// printing to the SQL output directly. See Dialect#renderOrderByElement(String, String, String, NullPrecedence).
: { captureExpressionStart(); } ( expr ) { captureExpressionFinish(); ordExp = resetCapture(); }
(dir:orderDirection { ordDir = #dir.getText(); })? (ordNul=nullOrdering)?
{ out( renderOrderByElement( ordExp, ordDir, ordNul ) ); }
( {out(", "); } orderExprs )?
;
groupExprs
// TODO: remove goofy space before the comma when we don't have to regression test anymore.
: expr ( {out(" , "); } groupExprs)?
;
orderDirection
: ASCENDING
| DESCENDING
;
nullOrdering returns [String nullOrdExp = null]
: NULLS fl:nullPrecedence { nullOrdExp = #fl.getText(); }
;
nullPrecedence
: FIRST
| LAST
;
whereExpr
// Expect the filter subtree, followed by the theta join subtree, followed by the HQL condition subtree.
// Might need parens around the HQL condition if there is more than one subtree.
// Put 'and' between each subtree.
: filters
( { out(" and "); } thetaJoins )?
( { out(" and "); } booleanExpr [ true ] )?
| thetaJoins
( { out(" and "); } booleanExpr [ true ] )?
| booleanExpr[false]
;
filters
: #(FILTERS conditionList )
;
thetaJoins
: #(THETA_JOINS conditionList )
;
conditionList
: sqlToken ( { out(" and "); } conditionList )?
;
selectClause
: #(SELECT_CLAUSE (distinctOrAll)? ( selectColumn )+ )
;
selectColumn
: p:selectExpr (sc:SELECT_COLUMNS { out(sc); } )? { separator( (sc != null) ? sc : p,", "); }
;
selectExpr
: e:selectAtom { out(e); }
| mcr:mapComponentReference { out(mcr); }
| count
| #(CONSTRUCTOR (DOT | IDENT) ( selectColumn )+ )
| methodCall
| aggregate
| c:constant { out(c); }
| arithmeticExpr
| selectBooleanExpr[false]
| parameter
| sn:SQL_NODE { out(sn); }
| { out("("); } selectStatement { out(")"); }
;
count
: #(COUNT { out("count("); } ( distinctOrAll ) ? countExpr { out(")"); } )
;
distinctOrAll
: DISTINCT { out("distinct "); }
| ALL { out("all "); }
;
countExpr
// Syntacitic predicate resolves star all by itself, avoiding a conflict with STAR in expr.
: ROW_STAR { out("*"); }
| simpleExpr
;
selectAtom
: DOT
| SQL_TOKEN
| ALIAS_REF
| SELECT_EXPR
;
mapComponentReference
: KEY
| VALUE
| ENTRY
;
// The from-clause piece is all goofed up. Currently, nodes of type FROM_FRAGMENT
// and JOIN_FRAGMENT can occur at any level in the FromClause sub-tree. We really
// should come back and clean this up at some point; which I think will require
// a post-HqlSqlWalker phase to "re-align" the FromElements in a more sensible
// manner.
from
: #(f:FROM { out(" from "); }
(fromTable)* )
;
fromTable
// Write the table node (from fragment) and all the join fragments associated with it.
: #( a:FROM_FRAGMENT { out(a); } (tableJoin [ a ])* { fromFragmentSeparator(a); } )
| #( b:JOIN_FRAGMENT { out(b); } (tableJoin [ b ])* { fromFragmentSeparator(b); } )
| #( e:ENTITY_JOIN { out(e); } (tableJoin [ e ])* { fromFragmentSeparator(e); } )
;
tableJoin [ AST parent ]
: #( c:JOIN_FRAGMENT { out(" "); out(c); } (tableJoin [ c ] )* )
| #( d:FROM_FRAGMENT { nestedFromFragment(d,parent); } (tableJoin [ d ] )* )
;
booleanOp[ boolean parens ]
: #(AND booleanExpr[true] { out(" and "); } booleanExpr[true])
| #(OR { if (parens) out("("); } booleanExpr[false] { out(" or "); } booleanExpr[false] { if (parens) out(")"); })
| #(NOT { out(" not ("); } booleanExpr[false] { out(")"); } )
;
selectBooleanExpr[ boolean parens ]
: booleanOp [ parens ]
| comparisonExpr [ parens ]
;
booleanExpr[ boolean parens ]
: booleanOp [ parens ]
| comparisonExpr [ parens ]
| st:SQL_TOKEN { out(st); } // solely for the purpose of mapping-defined where-fragments
;
comparisonExpr[ boolean parens ]
: binaryComparisonExpression
| { if (parens) out("("); } exoticComparisonExpression { if (parens) out(")"); }
;
binaryComparisonExpression
: #(EQ expr { out("="); } expr)
| #(NE expr { out("<>"); } expr)
| #(GT expr { out(">"); } expr)
| #(GE expr { out(">="); } expr)
| #(LT expr { out("<"); } expr)
| #(LE expr { out("<="); } expr)
;
exoticComparisonExpression
: #(LIKE expr { out(" like "); } expr likeEscape )
| #(NOT_LIKE expr { out(" not like "); } expr likeEscape)
| #(BETWEEN expr { out(" between "); } expr { out(" and "); } expr)
| #(NOT_BETWEEN expr { out(" not between "); } expr { out(" and "); } expr)
| #(IN expr { out(" in"); } inList )
| #(NOT_IN expr { out(" not in "); } inList )
| #(EXISTS { optionalSpace(); out("exists "); } quantified )
| #(IS_NULL expr) { out(" is null"); }
| #(IS_NOT_NULL expr) { out(" is not null"); }
;
likeEscape
: ( #(ESCAPE { out(" escape "); } expr) )?
;
inList
: #(IN_LIST { out(" "); } ( parenSelect | simpleExprList ) )
;
simpleExprList
: { out("("); } (e:simpleOrTupleExpr { separator(e," , "); } )* { out(")"); }
;
simpleOrTupleExpr
: simpleExpr
| tupleExpr
;
// A simple expression, or a sub-select with parens around it.
expr
: simpleExpr
| tupleExpr
| parenSelect
| #(ANY { out("any "); } quantified )
| #(ALL { out("all "); } quantified )
| #(SOME { out("some "); } quantified )
;
tupleExpr
: #( VECTOR_EXPR { out("("); } (e:expr { separator(e," , "); } )* { out(")"); } )
;
quantified
: { out("("); } ( sqlToken | selectStatement ) { out(")"); }
;
parenSelect
: { out("("); } selectStatement { out(")"); }
;
simpleExpr
: c:constant { out(c); }
| NULL { out("null"); }
| addrExpr
| sqlToken
| aggregate
| methodCall
| count
| parameter
| arithmeticExpr
| selectBooleanExpr[false]
;
constant
: NUM_DOUBLE
| NUM_FLOAT
| NUM_INT
| NUM_LONG
| NUM_BIG_INTEGER
| NUM_BIG_DECIMAL
| QUOTED_STRING
| CONSTANT
| JAVA_CONSTANT
| TRUE
| FALSE
| IDENT
;
arithmeticExpr
: additiveExpr
| multiplicativeExpr
// | #(CONCAT { out("("); } expr ( { out("||"); } expr )+ { out(")"); } )
| #(UNARY_MINUS { out("-"); } nestedExprAfterMinusDiv)
| caseExpr
;
additiveExpr
: #(PLUS expr { out("+"); } expr)
| #(MINUS expr { out("-"); } nestedExprAfterMinusDiv)
;
multiplicativeExpr
: #(STAR nestedExpr { out("*"); } nestedExpr)
| #(DIV nestedExpr { out("/"); } nestedExprAfterMinusDiv)
| #(MOD nestedExpr { out(" % "); } nestedExprAfterMinusDiv)
;
nestedExpr
// Generate parens around nested additive expressions, use a syntactic predicate to avoid conflicts with 'expr'.
: (additiveExpr) => { out("("); } additiveExpr { out(")"); }
| expr
;
nestedExprAfterMinusDiv
// Generate parens around nested arithmetic expressions, use a syntactic predicate to avoid conflicts with 'expr'.
: (arithmeticExpr) => { out("("); } arithmeticExpr { out(")"); }
| expr
;
caseExpr
: #(CASE { out("case"); }
( #(WHEN { out( " when "); } booleanExpr[false] { out(" then "); } expr) )+
( #(ELSE { out(" else "); } expr) )?
{ out(" end"); } )
| #(CASE2 { out("case "); } expr
( #(WHEN { out( " when "); } expr { out(" then "); } expr) )+
( #(ELSE { out(" else "); } expr) )?
{ out(" end"); } )
;
aggregate
: #(
a:AGGREGATE { beginFunctionTemplate( a, a ); }
expr
{ endFunctionTemplate( a ); }
)
;
methodCall
: #(m:METHOD_CALL i:METHOD_NAME { beginFunctionTemplate(m,i); }
( #(EXPR_LIST (arguments)? ) )?
{ endFunctionTemplate(m); } )
| #( c:CAST { beginFunctionTemplate(c,c); } castExpression {betweenFunctionArguments();} castTargetType { endFunctionTemplate(c); } )
;
arguments
: expr ( { betweenFunctionArguments(); } expr )*
;
castExpression
: selectExpr
| NULL { out("null"); }
;
castTargetType
: i:IDENT { out(i); }
;
parameter
: n:NAMED_PARAM { out(n); }
| p:PARAM { out(p); }
;
addrExpr
: #(r:DOT . .) { out(r); }
| i:ALIAS_REF { out(i); }
| j:INDEX_OP { out(j); }
| v:RESULT_VARIABLE_REF { out(v); }
| mcr:mapComponentReference { out(mcr); }
;
sqlToken
: t:SQL_TOKEN { out(t); }
;

View File

@ -1,148 +0,0 @@
header
{
package org.hibernate.hql.internal.antlr;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import org.hibernate.hql.internal.ast.ErrorReporter;
}
/**
* Lexer and parser used to extract single statements from import SQL script. Supports instructions/comments and quoted
* strings spread over multiple lines. Each statement must end with semicolon.
*
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
class SqlStatementParser extends Parser;
options {
buildAST = false;
}
{
private ErrorHandler errorHandler = new ErrorHandler();
@Override
public void reportError(RecognitionException e) {
errorHandler.reportError( e );
}
@Override
public void reportError(String s) {
errorHandler.reportError( s );
}
@Override
public void reportWarning(String s) {
errorHandler.reportWarning( s );
}
public void throwExceptionIfErrorOccurred() {
if ( errorHandler.hasErrors() ) {
throw new StatementParserException( errorHandler.getErrorMessage() );
}
}
/** List of all SQL statements. */
private List<String> statementList = new LinkedList<String>();
/** Currently processing SQL statement. */
private StringBuilder current = new StringBuilder();
protected void out(String stmt) {
current.append( stmt );
}
protected void out(Token token) {
out( token.getText() );
}
public List<String> getStatementList() {
return statementList;
}
protected void statementEnd() {
statementList.add( current.toString().trim() );
current = new StringBuilder();
}
public class StatementParserException extends RuntimeException {
public StatementParserException(String message) {
super( message );
}
}
private class ErrorHandler implements ErrorReporter {
private List<String> errorList = new LinkedList<String>();
@Override
public void reportError(RecognitionException e) {
reportError( e.toString() );
}
@Override
public void reportError(String s) {
errorList.add( s );
}
@Override
public void reportWarning(String s) {
}
public boolean hasErrors() {
return !errorList.isEmpty();
}
public String getErrorMessage() {
StringBuilder buf = new StringBuilder();
for ( Iterator iterator = errorList.iterator(); iterator.hasNext(); ) {
buf.append( (String) iterator.next() );
if ( iterator.hasNext() ) {
buf.append( "\n" );
}
}
return buf.toString();
}
}
}
script
: ( statement )*
;
statement
: ( s:NOT_STMT_END { out( s ); } | q:QUOTED_STRING { out( q ); } )* STMT_END { statementEnd(); }
;
class SqlStatementLexer extends Lexer;
options {
k = 2;
charVocabulary = '\u0000'..'\uFFFE';
}
STMT_END
: ';' ( '\t' | ' ' | '\r' | '\n' )*
;
NOT_STMT_END
: ~( ';' )
;
QUOTED_STRING
: '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
;
protected
ESCqs
: '\'' '\''
;
LINE_COMMENT
: ( "//" | "--" ) ( ~('\n'|'\r') )* { $setType(Token.SKIP); }
;
MULTILINE_COMMENT
: "/*" ( options {greedy=false;} : . )* "*/" { $setType(Token.SKIP); }
;

View File

@ -0,0 +1,26 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate;
/**
* Thrown from methods added for 6.0 that are not yet implemented.
*
* todo (6.0) : prior going final, we need to find all usages of this and implement all methods (or throw a different exception)
*/
public class NotYetImplementedFor6Exception extends RuntimeException {
public NotYetImplementedFor6Exception(String message) {
super( message );
}
public NotYetImplementedFor6Exception(Class clazz) {
super( clazz.getName() );
}
public NotYetImplementedFor6Exception() {
super( "Not yet implemented" );
}
}

View File

@ -7,16 +7,8 @@
package org.hibernate;
import java.io.Closeable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Blob;
import java.sql.Clob;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.hibernate.type.Type;
import org.hibernate.query.Query;
/**
* A result iterator that allows moving around within the results
@ -31,7 +23,13 @@ import org.hibernate.type.Type;
*
* @author Gavin King
*/
public interface ScrollableResults extends AutoCloseable, Closeable {
public interface ScrollableResults<R> extends AutoCloseable, Closeable {
/**
* Get the current row of results.
*
* @return The array of results
*/
R get();
/**
* Release resources immediately.
@ -117,245 +115,4 @@ public interface ScrollableResults extends AutoCloseable, Closeable {
* @return true if there is a row at that row number
*/
boolean setRowNumber(int rowNumber);
/**
* Get the current row of results.
*
* @return The array of results
*/
Object[] get();
/**
* Get the <tt>i</tt>th object in the current row of results, without
* initializing any other results in the row. This method may be used
* safely, regardless of the type of the column (ie. even for scalar
* results).
*
* @param i the column, numbered from zero
*
* @return The requested result object; may return {@code null}
*
* @throws IndexOutOfBoundsException If i is an invalid index.
*/
Object get(int i);
/**
* Get the type of the <tt>i</tt>th column of results.
*
* @param i the column, numbered from zero
*
* @return the Hibernate type
*
* @throws IndexOutOfBoundsException If i is an invalid index.
*/
Type getType(int i);
/**
* Convenience method to read an integer.
*
* @param col The column, numbered from zero
*
* @return The column value as an integer
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Integer getInteger(int col);
/**
* Convenience method to read a long.
*
* @param col The column, numbered from zero
*
* @return The column value as a long
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Long getLong(int col);
/**
* Convenience method to read a float.
*
* @param col The column, numbered from zero
*
* @return The column value as a float
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Float getFloat(int col);
/**
* Convenience method to read a boolean.
*
* @param col The column, numbered from zero
*
* @return The column value as a boolean
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Boolean getBoolean(int col);
/**
* Convenience method to read a double.
*
* @param col The column, numbered from zero
*
* @return The column value as a double
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Double getDouble(int col);
/**
* Convenience method to read a short.
*
* @param col The column, numbered from zero
*
* @return The column value as a short
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Short getShort(int col);
/**
* Convenience method to read a byte.
*
* @param col The column, numbered from zero
*
* @return The column value as a byte
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Byte getByte(int col);
/**
* Convenience method to read a char.
*
* @param col The column, numbered from zero
*
* @return The column value as a char
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Character getCharacter(int col);
/**
* Convenience method to read a binary (byte[]).
*
* @param col The column, numbered from zero
*
* @return The column value as a binary (byte[])
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
byte[] getBinary(int col);
/**
* Convenience method to read a String using streaming.
*
* @param col The column, numbered from zero
*
* @return The column value as a String
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
String getText(int col);
/**
* Convenience method to read a blob.
*
* @param col The column, numbered from zero
*
* @return The column value as a Blob
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Blob getBlob(int col);
/**
* Convenience method to read a clob.
*
* @param col The column, numbered from zero
*
* @return The column value as a Clob
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Clob getClob(int col);
/**
* Convenience method to read a string.
*
* @param col The column, numbered from zero
*
* @return The column value as a String
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
String getString(int col);
/**
* Convenience method to read a BigDecimal.
*
* @param col The column, numbered from zero
*
* @return The column value as a BigDecimal
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
BigDecimal getBigDecimal(int col);
/**
* Convenience method to read a BigInteger.
*
* @param col The column, numbered from zero
*
* @return The column value as a BigInteger
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
BigInteger getBigInteger(int col);
/**
* Convenience method to read a Date.
*
* @param col The column, numbered from zero
*
* @return The column value as a Date
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Date getDate(int col);
/**
* Convenience method to read a Locale.
*
* @param col The column, numbered from zero
*
* @return The column value as a Locale
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Locale getLocale(int col);
/**
* Convenience method to read a Calendar.
*
* @param col The column, numbered from zero
*
* @return The column value as a Calendar
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
Calendar getCalendar(int col);
/**
* Convenience method to read a TimeZone.
*
* @param col The column, numbered from zero
*
* @return The column value as a TimeZone
*
* @throws IndexOutOfBoundsException If col is an invalid index.
*/
TimeZone getTimeZone(int col);
}

View File

@ -0,0 +1,43 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate;
/**
* @author Steve Ebersole
*/
public enum SortOrder {
ASCENDING {
@Override
public SortOrder reverse() {
return DESCENDING;
}
},
DESCENDING {
@Override
public SortOrder reverse() {
return ASCENDING;
}
};
public abstract SortOrder reverse();
public static SortOrder interpret(String value) {
if ( value == null ) {
return null;
}
if ( value.equalsIgnoreCase( "ascending" ) || value.equalsIgnoreCase( "asc" ) ) {
return ASCENDING;
}
if ( value.equalsIgnoreCase( "descending" ) || value.equalsIgnoreCase( "desc" ) ) {
return DESCENDING;
}
throw new IllegalArgumentException( "Unknown sort order : " + value );
}
}

View File

@ -18,6 +18,7 @@ import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.internal.ParameterMetadataImpl;
import org.hibernate.query.spi.QueryPlanCache;
import org.hibernate.resource.beans.container.spi.ExtendedBeanManager;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
@ -1210,14 +1211,14 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
String PREFERRED_POOLED_OPTIMIZER = "hibernate.id.optimizer.pooled.preferred";
/**
* The maximum number of strong references maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 128.
* The maximum number of strong references maintained by {@link QueryPlanCache}. Default is 128.
* @deprecated in favor of {@link #QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE}
*/
@Deprecated
String QUERY_PLAN_CACHE_MAX_STRONG_REFERENCES = "hibernate.query.plan_cache_max_strong_references";
/**
* The maximum number of soft references maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 2048.
* The maximum number of soft references maintained by {@link QueryPlanCache}. Default is 2048.
* @deprecated in favor of {@link #QUERY_PLAN_CACHE_MAX_SIZE}
*/
@Deprecated
@ -1231,13 +1232,13 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
* <li>{@link org.hibernate.engine.query.spi.NativeSQLQueryPlan}</li>
* </ul>
*
* maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 2048.
* maintained by {@link QueryPlanCache}. Default is 2048.
*/
String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size";
/**
* The maximum number of {@link ParameterMetadataImpl} maintained
* by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 128.
* by {@link QueryPlanCache}. Default is 128.
*/
String QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE = "hibernate.query.plan_parameter_metadata_max_size";

View File

@ -40,7 +40,7 @@ import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.profile.FetchProfile;
import org.hibernate.engine.query.spi.QueryPlanCache;
import org.hibernate.query.spi.QueryPlanCache;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.id.IdentifierGenerator;

View File

@ -31,7 +31,8 @@ import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.profile.FetchProfile;
import org.hibernate.engine.query.spi.QueryPlanCache;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryPlanCache;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.id.IdentifierGenerator;
@ -46,6 +47,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.Type;
import org.hibernate.type.TypeResolver;
/**
* Defines the internal contract between the <tt>SessionFactory</tt> and other parts of
* Hibernate such as implementors of <tt>Type</tt>.
@ -74,6 +76,11 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory, Quer
*/
String getName();
QueryEngine getQueryEngine();
@Override
NodeBuilder getCriteriaBuilder();
@Override
SessionBuilderImplementor withOptions();

View File

@ -74,7 +74,7 @@ import org.hibernate.engine.jndi.spi.JndiService;
import org.hibernate.engine.profile.Association;
import org.hibernate.engine.profile.Fetch;
import org.hibernate.engine.profile.FetchProfile;
import org.hibernate.engine.query.spi.QueryPlanCache;
import org.hibernate.query.spi.QueryPlanCache;
import org.hibernate.engine.query.spi.ReturnMetadata;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.NamedQueryDefinition;

View File

@ -0,0 +1,30 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model;
import javax.persistence.metamodel.Attribute.PersistentAttributeType;
public enum AttributeClassification {
BASIC( PersistentAttributeType.BASIC ),
EMBEDDED( PersistentAttributeType.EMBEDDED ),
ANY( null ),
ONE_TO_ONE( PersistentAttributeType.ONE_TO_ONE ),
MANY_TO_ONE( PersistentAttributeType.EMBEDDED ),
ELEMENT_COLLECTION( PersistentAttributeType.ELEMENT_COLLECTION ),
ONE_TO_MANY( PersistentAttributeType.MANY_TO_ONE ),
MANY_TO_MANY( PersistentAttributeType.MANY_TO_MANY );
private final PersistentAttributeType jpaClassification;
AttributeClassification(PersistentAttributeType jpaClassification) {
this.jpaClassification = jpaClassification;
}
public PersistentAttributeType getJpaClassification() {
return jpaClassification;
}
}

View File

@ -10,19 +10,14 @@ import java.util.Objects;
import javax.persistence.metamodel.BasicType;
import org.hibernate.HibernateException;
import org.hibernate.query.sqm.SqmExpressable;
/**
* Hibernate extension to the JPA {@link BasicType} contract.
*
* Describes the mapping between a Java type and a SQL type.
*
* @apiNote Again, like {@link CollectionDomainType} and
* {@link EmbeddedDomainType}, this is a per-usage descriptor as it
* encompasses both the Java and SQL types.
*
* @author Steve Ebersole
*/
public interface BasicDomainType<J> extends SimpleDomainType<J>, BasicType<J> {
public interface BasicDomainType<J> extends SimpleDomainType<J>, BasicType<J>, SqmExpressable<J> {
@Override
default PersistenceType getPersistenceType() {
return PersistenceType.BASIC;

View File

@ -1,25 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain;
/**
* Descriptor for persistent collections. This includes mapping
* information, so it is specific to each usage (attribute). JPA
* has no construct as a type for collections
*
* @author Steve Ebersole
*/
public interface CollectionDomainType<C,E> extends DomainType<C> {
interface Element<E> {
/**
* The Java type of the collection elements.
*/
Class<E> getJavaType();
}
Element<E> getElementDescriptor();
}

View File

@ -6,25 +6,21 @@
*/
package org.hibernate.metamodel.model.domain;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Base contract for Hibernate's extension of the JPA type system.
* Describes any type that occurs in the application's domain model.
*
* @apiNote The "real" JPA type system is more akin to
* {@link SimpleDomainType}. We begin our JPA type system extension
* a "level above" that. This is to allow for:
* 1) JPA does not define a Type for collections. It's
* understandable why, but leads to limitations in
* regards to being able to understand the type of an
* attribute - in JPA, when the attribute is plural the
* only descriptor info available is for the the collection
* is its Java type (Class).
* 2) specialized types like ANY
* The base for Hibernate's extension of the JPA type system.
*
* Encapsulates a {@link JavaTypeDescriptor} describing the more rudimentary
* aspects of the Java type. The DomainType is a higher-level construct
* incorporating information such as bean properties, constructors, etc
*
* @param <J> The Java type for this JPA Type
*
* @apiNote The `*DomainType` naming pattern is used to more easily (visually)
* differentiate these extensions from the JPA ones in application use.
* @implNote The actual JPA type system is more akin to {@link SimpleDomainType}.
* This contract represents a "higher level" than JPA
* including descriptors for collections (which JPA does not define) as well as
* Hibernate-specific features (like dynamic models or ANY mappings).
*
* @author Steve Ebersole
*/
@ -34,4 +30,6 @@ public interface DomainType<J> extends javax.persistence.metamodel.Type<J> {
* non-pojo mappings, etc.
*/
String getTypeName();
JavaTypeDescriptor<J> getJavaTypeDescriptor();
}

View File

@ -8,10 +8,13 @@ package org.hibernate.metamodel.model.domain;
import javax.persistence.metamodel.EntityType;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Extension to the JPA {@link EntityType} contract
*
* @author Steve Ebersole
*/
public interface EntityDomainType<J> extends IdentifiableDomainType<J>, EntityType<J> {
public interface EntityDomainType<J> extends IdentifiableDomainType<J>, EntityType<J>, SqmPathSource<J,J> {
String getHibernateEntityName();
}

View File

@ -11,5 +11,5 @@ import javax.persistence.metamodel.ManagedType;
/**
* @author Steve Ebersole
*/
public interface ManagedDomainType<J> extends SimpleDomainType<J>, ManagedType<J> {
public interface ManagedDomainType<J> extends SimpleDomainType<J>, ManagedType<J>, Navigable<J,J> {
}

View File

@ -8,15 +8,20 @@ package org.hibernate.metamodel.model.domain;
import javax.persistence.metamodel.Attribute;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link Attribute} contract
*
* @author Steve Ebersole
*/
public interface PersistentAttribute<D,J> extends Attribute<D,J> {
public interface PersistentAttribute<D,J,B> extends Attribute<D,J>, SqmPathSource<J,B> {
@Override
ManagedDomainType<D> getDeclaringType();
AttributeClassification getAttributeClassification();
SimpleDomainType<?> getValueGraphType();
SimpleDomainType<?> getKeyGraphType();
}

View File

@ -15,9 +15,12 @@ import java.lang.reflect.Method;
import javax.persistence.metamodel.Attribute;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.spi.ManagedTypeDescriptor;
import org.hibernate.metamodel.model.domain.spi.PersistentAttributeDescriptor;
import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Models the commonality of the JPA {@link Attribute} hierarchy.
@ -27,14 +30,15 @@ import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
*
* @author Steve Ebersole
*/
public abstract class AbstractAttribute<D, J>
implements PersistentAttributeDescriptor<D, J>, Serializable {
public abstract class AbstractAttribute<D,J,B>
implements PersistentAttributeDescriptor<D,J,B>, Serializable {
private final ManagedTypeDescriptor<D> declaringType;
private final String name;
private final JavaTypeDescriptor<J> attributeType;
private final PersistentAttributeType attributeNature;
private final AttributeClassification attributeClassification;
private final SimpleTypeDescriptor<?> valueType;
private final SimpleTypeDescriptor<B> valueType;
private transient Member member;
@ -42,12 +46,14 @@ public abstract class AbstractAttribute<D, J>
protected AbstractAttribute(
ManagedTypeDescriptor<D> declaringType,
String name,
PersistentAttributeType attributeNature,
SimpleTypeDescriptor<?> valueType,
JavaTypeDescriptor<J> attributeType,
AttributeClassification attributeClassification,
SimpleTypeDescriptor<B> valueType,
Member member) {
this.declaringType = declaringType;
this.name = name;
this.attributeNature = attributeNature;
this.attributeType = attributeType;
this.attributeClassification = attributeClassification;
this.valueType = valueType;
this.member = member;
}
@ -57,6 +63,26 @@ public abstract class AbstractAttribute<D, J>
return name;
}
@Override
public String getNavigableName() {
return getName();
}
@Override
public Class<J> getJavaType() {
return attributeType.getJavaType();
}
@Override
public DomainType<B> getSqmNodeType() {
return valueType;
}
@Override
public JavaTypeDescriptor<J> getJavaTypeDescriptor() {
return attributeType;
}
@Override
public ManagedTypeDescriptor<D> getDeclaringType() {
return declaringType;
@ -67,9 +93,14 @@ public abstract class AbstractAttribute<D, J>
return member;
}
@Override
public AttributeClassification getAttributeClassification() {
return attributeClassification;
}
@Override
public PersistentAttributeType getPersistentAttributeType() {
return attributeNature;
return getAttributeClassification().getJpaClassification();
}
@Override
@ -79,7 +110,7 @@ public abstract class AbstractAttribute<D, J>
@Override
public String toString() {
return declaringType.getName() + '#' + name + '(' + attributeNature + ')';
return declaringType.getName() + '#' + name + '(' + attributeClassification + ')';
}
/**

View File

@ -25,6 +25,7 @@ import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.spi.PersistentAttributeDescriptor;
import org.hibernate.metamodel.model.domain.spi.BagPersistentAttribute;
import org.hibernate.metamodel.model.domain.spi.DomainModelHelper;
@ -75,6 +76,11 @@ public abstract class AbstractManagedType<J>
return getTypeName();
}
@Override
public DomainType<J> getType() {
return this;
}
@Override
public ManagedTypeDescriptor<? super J> getSuperType() {
return superType;

View File

@ -11,6 +11,10 @@ import java.util.Collection;
import org.hibernate.metamodel.model.domain.spi.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @param <D> The (D)eclaring type
@ -20,28 +24,25 @@ import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
* @author Emmanuel Bernard
* @author Steve Ebersole
*/
public abstract class AbstractPluralAttribute<D, C, E>
extends AbstractAttribute<D,C>
public abstract class AbstractPluralAttribute<D,C,E>
extends AbstractAttribute<D,C,E>
implements PluralPersistentAttribute<D,C,E>, Serializable {
private final Class<C> collectionClass;
protected AbstractPluralAttribute(PluralAttributeBuilder<D,C,E,?> builder) {
super(
builder.getDeclaringType(),
builder.getProperty().getName(),
builder.getAttributeNature(),
builder.getCollectionJavaTypeDescriptor(),
builder.getAttributeClassification(),
builder.getValueType(),
builder.getMember()
);
this.collectionClass = builder.getCollectionClass();
}
public static <X,C,E,K> PluralAttributeBuilder<X,C,E,K> create(
AbstractManagedType<X> ownerType,
SimpleTypeDescriptor<E> attrType,
Class<C> collectionClass,
JavaTypeDescriptor<C> collectionClass,
SimpleTypeDescriptor<K> keyType) {
return new PluralAttributeBuilder<>( ownerType, attrType, collectionClass, keyType );
}
@ -86,7 +87,13 @@ public abstract class AbstractPluralAttribute<D, C, E>
@Override
public Class<C> getJavaType() {
return collectionClass;
return getJavaTypeDescriptor().getJavaType();
}
@Override
public SqmPath createSqmPath(
SqmPath<?> lhs,
SqmCreationState creationState) {
return new SqmPluralValuedSimplePath( );
}
}

View File

@ -8,7 +8,9 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.spi.BasicTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Emmanuel Bernard
@ -34,4 +36,14 @@ public class BasicTypeImpl<J> implements BasicTypeDescriptor<J>, Serializable {
public String getTypeName() {
return clazz.getName();
}
@Override
public DomainType<J> getType() {
return this;
}
@Override
public JavaTypeDescriptor<J> getJavaTypeDescriptor() {
return getType().getJavaTypeDescriptor();
}
}

View File

@ -50,6 +50,11 @@ public class EntityTypeImpl<J>
return jpaEntityName;
}
@Override
public String getHibernateEntityName() {
return super.getTypeName();
}
@Override
public BindableType getBindableType() {
return BindableType.ENTITY_TYPE;

View File

@ -11,11 +11,12 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.metamodel.Attribute;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.model.domain.spi.ManagedTypeDescriptor;
import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* A "parameter object" for creating a plural attribute
@ -24,23 +25,23 @@ public class PluralAttributeBuilder<D, C, E, K> {
private final ManagedTypeDescriptor<D> declaringType;
private final SimpleTypeDescriptor<E> valueType;
private Attribute.PersistentAttributeType attributeNature;
private SimpleTypeDescriptor<K> keyType;
private JavaTypeDescriptor<C> collectionJavaTypeDescriptor;
private AttributeClassification attributeClassification;
private Property property;
private Member member;
private Class<C> collectionClass;
private SimpleTypeDescriptor<K> keyType;
public PluralAttributeBuilder(
ManagedTypeDescriptor<D> ownerType,
SimpleTypeDescriptor<E> elementType,
Class<C> collectionClass,
JavaTypeDescriptor<C> collectionJavaTypeDescriptor,
SimpleTypeDescriptor<K> keyType) {
this.declaringType = ownerType;
this.valueType = elementType;
this.collectionClass = collectionClass;
this.collectionJavaTypeDescriptor = collectionJavaTypeDescriptor;
this.keyType = keyType;
}
@ -48,16 +49,16 @@ public class PluralAttributeBuilder<D, C, E, K> {
return declaringType;
}
public Attribute.PersistentAttributeType getAttributeNature() {
return attributeNature;
public AttributeClassification getAttributeClassification() {
return attributeClassification;
}
public SimpleTypeDescriptor<K> getKeyType() {
return keyType;
}
public Class<C> getCollectionClass() {
return collectionClass;
public JavaTypeDescriptor<C> getCollectionJavaTypeDescriptor() {
return collectionJavaTypeDescriptor;
}
public SimpleTypeDescriptor<E> getValueType() {
@ -82,33 +83,33 @@ public class PluralAttributeBuilder<D, C, E, K> {
return this;
}
public PluralAttributeBuilder<D,C,E,K> persistentAttributeType(Attribute.PersistentAttributeType attrType) {
this.attributeNature = attrType;
public PluralAttributeBuilder<D,C,E,K> persistentAttributeClassification(AttributeClassification classification) {
this.attributeClassification = classification;
return this;
}
@SuppressWarnings( "unchecked" )
public AbstractPluralAttribute<D,C,E> build() {
//apply strict spec rules first
if ( Map.class.equals( collectionClass ) ) {
if ( Map.class.equals( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D,Map<K,E>,E,K> builder = (PluralAttributeBuilder<D,Map<K,E>,E,K>) this;
return (AbstractPluralAttribute<D, C, E>) new MapAttributeImpl<>(
builder
);
}
else if ( Set.class.equals( collectionClass ) ) {
else if ( Set.class.equals( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D,Set<E>, E,?> builder = (PluralAttributeBuilder<D, Set<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new SetAttributeImpl<>(
builder
);
}
else if ( List.class.equals( collectionClass ) ) {
else if ( List.class.equals( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D, List<E>, E,?> builder = (PluralAttributeBuilder<D, List<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new ListAttributeImpl<>(
builder
);
}
else if ( Collection.class.equals( collectionClass ) ) {
else if ( Collection.class.equals( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D, Collection<E>,E,?> builder = (PluralAttributeBuilder<D, Collection<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new BagAttributeImpl<>(
builder
@ -116,37 +117,37 @@ public class PluralAttributeBuilder<D, C, E, K> {
}
//apply loose rules
if ( collectionClass.isArray() ) {
if ( collectionJavaTypeDescriptor.getJavaType().isArray() ) {
final PluralAttributeBuilder<D, List<E>, E,?> builder = (PluralAttributeBuilder<D, List<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new ListAttributeImpl<>(
builder
);
}
if ( Map.class.isAssignableFrom( collectionClass ) ) {
if ( Map.class.isAssignableFrom( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D,Map<K,E>,E,K> builder = (PluralAttributeBuilder<D,Map<K,E>,E,K>) this;
return (AbstractPluralAttribute<D, C, E>) new MapAttributeImpl<>(
builder
);
}
else if ( Set.class.isAssignableFrom( collectionClass ) ) {
else if ( Set.class.isAssignableFrom( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D,Set<E>, E,?> builder = (PluralAttributeBuilder<D, Set<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new SetAttributeImpl<>(
builder
);
}
else if ( List.class.isAssignableFrom( collectionClass ) ) {
else if ( List.class.isAssignableFrom( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D, List<E>, E,?> builder = (PluralAttributeBuilder<D, List<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new ListAttributeImpl<>(
builder
);
}
else if ( Collection.class.isAssignableFrom( collectionClass ) ) {
else if ( Collection.class.isAssignableFrom( collectionJavaTypeDescriptor.getJavaType() ) ) {
final PluralAttributeBuilder<D, Collection<E>,E,?> builder = (PluralAttributeBuilder<D, Collection<E>, E,?>) this;
return (AbstractPluralAttribute<D, C, E>) new BagAttributeImpl<>(
builder
);
}
throw new UnsupportedOperationException( "Unkown collection: " + collectionClass );
throw new UnsupportedOperationException( "Unknown collection: " + collectionJavaTypeDescriptor.getJavaType() );
}
}

View File

@ -8,20 +8,28 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.util.Locale;
import java.util.function.Supplier;
import org.hibernate.graph.spi.GraphHelper;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.model.domain.spi.ManagedTypeDescriptor;
import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
import org.hibernate.metamodel.model.domain.spi.SingularPersistentAttribute;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
* @author Emmanuel Bernard
* @author Steve Ebersole
*/
public class SingularAttributeImpl<D, J>
extends AbstractAttribute<D, J>
implements SingularPersistentAttribute<D, J>, Serializable {
public class SingularAttributeImpl<D,J>
extends AbstractAttribute<D,J,J>
implements SingularPersistentAttribute<D,J>, Serializable {
private final boolean isIdentifier;
private final boolean isVersion;
private final boolean isOptional;
@ -34,13 +42,13 @@ public class SingularAttributeImpl<D, J>
public SingularAttributeImpl(
ManagedTypeDescriptor<D> declaringType,
String name,
PersistentAttributeType attributeNature,
AttributeClassification attributeClassification,
SimpleTypeDescriptor<J> attributeType,
Member member,
boolean isIdentifier,
boolean isVersion,
boolean isOptional) {
super( declaringType, name, attributeNature, attributeType, member );
super( declaringType, name, attributeType.getJavaTypeDescriptor(), attributeClassification, attributeType, member );
this.isIdentifier = isIdentifier;
this.isVersion = isVersion;
this.isOptional = isOptional;
@ -59,7 +67,6 @@ public class SingularAttributeImpl<D, J>
}
/**
* Subclass used to simplify instantiation of singular attributes representing an entity's
* identifier.
@ -70,8 +77,8 @@ public class SingularAttributeImpl<D, J>
String name,
SimpleTypeDescriptor<J> attributeType,
Member member,
PersistentAttributeType attributeNature) {
super( declaringType, name, attributeNature, attributeType, member, true, false, false );
AttributeClassification attributeClassification) {
super( declaringType, name, attributeClassification, attributeType, member, true, false, false );
}
}
@ -83,10 +90,10 @@ public class SingularAttributeImpl<D, J>
public Version(
ManagedTypeDescriptor<X> declaringType,
String name,
PersistentAttributeType attributeNature,
AttributeClassification attributeClassification,
SimpleTypeDescriptor<Y> attributeType,
Member member) {
super( declaringType, name, attributeNature, attributeType, member, false, true, false );
super( declaringType, name, attributeClassification, attributeType, member, false, true, false );
}
}
@ -131,6 +138,38 @@ public class SingularAttributeImpl<D, J>
return attributeType.getJavaType();
}
@Override
public SqmPath createSqmPath(
SqmPath lhs,
SqmCreationState creationState) {
switch ( getAttributeClassification() ) {
case BASIC: {
return new SqmBasicValuedSimplePath( );
}
case EMBEDDED: {
return new SqmEmbeddedValuedSimplePath( );
}
case ANY: {
return new SqmAnyValuedSimplePath( );
}
case ONE_TO_ONE:
case MANY_TO_ONE: {
return new SqmEntityValuedSimplePath( );
}
default: {
throw new UnsupportedOperationException(
String.format(
Locale.ROOT,
"Cannot create SqmPath from singular attribute [%s#%s] - unknown classification : %s",
getDeclaringType().getName(),
getName(),
getAttributeClassification()
)
);
}
}
}
private class DelayedKeyTypeAccess implements Supplier<SimpleTypeDescriptor<J>>, Serializable {
private boolean resolved;
private SimpleTypeDescriptor<J> type;

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain.spi;
/**
* Specialization of DomainType for types that can be used as function returns
*
* @author Steve Ebersole
*/
public interface AllowableFunctionReturnType<T> extends SimpleTypeDescriptor<T> {
}

View File

@ -0,0 +1,19 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain.spi;
/**
* Specialization of DomainType for types that can be used as a
* parameter output for a {@link org.hibernate.procedure.ProcedureCall}
*
* @apiNote Generally speaking, an allowable output parameter type
* can only effectively be a basic type.
*
* @author Steve Ebersole
*/
public interface AllowableOutputParameterType<J> extends AllowableParameterType<J> {
}

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain.spi;
/**
* Specialization of DomainType for types that can be used as query parameter bind values
*
* @author Steve Ebersole
*/
public interface AllowableParameterType<J> extends SimpleTypeDescriptor<J> {
}

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain.spi;
import javax.persistence.TemporalType;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Specialization of DomainType for types that can be used as temporal bind values
* for a query parameter
*
* @author Steve Ebersole
*/
public interface AllowableTemporalParameterType extends AllowableParameterType {
/**
* Convert the value and/or type to the specified temporal precision
*/
AllowableParameterType resolveTemporalPrecision(TemporalType temporalType, TypeConfiguration typeConfiguration);
}

View File

@ -9,11 +9,12 @@ package org.hibernate.metamodel.model.domain.spi;
import javax.persistence.metamodel.BasicType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link BasicType} descriptor
*
* @author Steve Ebersole
*/
public interface BasicTypeDescriptor<J> extends BasicDomainType<J>, SimpleTypeDescriptor<J> {
public interface BasicTypeDescriptor<J> extends BasicDomainType<J>, SimpleTypeDescriptor<J>, SqmPathSource<J,J> {
}

View File

@ -22,7 +22,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
*
* @author Steve Ebersole
*/
public interface ManagedTypeDescriptor<J> extends SimpleTypeDescriptor<J>, ManagedDomainType<J> {
public interface ManagedTypeDescriptor<J> extends SimpleTypeDescriptor<J>, ManagedDomainType<J>, NavigableDescriptor<J,J> {
/**
* Get this ManagedType's super type descriptor. ATM only supported for the
* {@link IdentifiableTypeDescriptor} branch of the ManagedType tree

View File

@ -15,7 +15,7 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
*
* @author Steve Ebersole
*/
public interface PersistentAttributeDescriptor<D, J> extends PersistentAttribute<D, J> {
public interface PersistentAttributeDescriptor<D,J,B> extends PersistentAttribute<D,J,B> {
@Override
ManagedTypeDescriptor<D> getDeclaringType();

View File

@ -11,9 +11,12 @@ import javax.persistence.metamodel.PluralAttribute;
/**
* Hibernate extension to the JPA {@link PluralAttribute} descriptor
*
* todo (6.0) : Create an form of plural attribute (and singular) in the API package (org.hibernate.metamodel.model.domain)
* and have this extend it
*
* @author Steve Ebersole
*/
public interface PluralPersistentAttribute<D,C,E> extends PluralAttribute<D,C,E>, PersistentAttributeDescriptor<D,C> {
public interface PluralPersistentAttribute<D,C,E> extends PluralAttribute<D,C,E>, PersistentAttributeDescriptor<D,C,E> {
@Override
ManagedTypeDescriptor<D> getDeclaringType();

View File

@ -11,9 +11,12 @@ import javax.persistence.metamodel.SingularAttribute;
/**
* Hibernate extension to the JPA {@link SingularAttribute} descriptor
*
* todo (6.0) : Create an form of singular attribute (and plural) in the API package (org.hibernate.metamodel.model.domain)
* and have this extend it
*
* @author Steve Ebersole
*/
public interface SingularPersistentAttribute<D,J> extends SingularAttribute<D,J>, PersistentAttributeDescriptor<D,J> {
public interface SingularPersistentAttribute<D,J> extends SingularAttribute<D,J>, PersistentAttributeDescriptor<D,J,J> {
@Override
SimpleTypeDescriptor<J> getType();

View File

@ -0,0 +1,14 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.persister;
/**
* @author Steve Ebersole
*/
public interface SqlExpressableType {
// todo (6.0) : define this contract (what should it expose?)- see PropertyMapping
}

View File

@ -5,7 +5,10 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.persister.entity;
import org.hibernate.QueryException;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.persister.SqlExpressableType;
import org.hibernate.type.Type;
/**
@ -21,10 +24,49 @@ import org.hibernate.type.Type;
* of how Hibernate originally understood composites (embeddables) internally. That is in the process of changing
* as Hibernate has added {@link org.hibernate.loader.plan.build.internal.spaces.CompositePropertyMapping}
*
* todo (6.0) : move to {@link org.hibernate.persister.spi} - that is its more logic home. AFAIK this
* has never been documented as a public API
*
* todo (6.0) : re-word these Javadocs
*
* @author Gavin King
* @author Steve Ebersole
*/
public interface PropertyMapping {
/**
* Get the type of the thing containing the properties
*
* todo (6.0) : this really should be defined in terms of the Hibernate mapping model, not (just?) the JPA model
* - meaning maybe it exposes both
*/
DomainType getDomainType();
SqlExpressableType getMappingType();
//
/**
* @asciidoc
*
* Resolve a sub-reference relative to this PropertyMapping. E.g.,
* given the PropertyMapping for an entity named `Person` with an embedded
* property `#name` calling this method with `"name"` returns the
* PropertyMapping for the `Name` embeddable
*
* todo (6.0) : define an exception in the signature for cases where the PropertyMapping
* cannot be de-referenced (basic values)
*/
PropertyMapping resolveSubMapping(String name);
// todo (6.0) : add capability to create SqmPath, i.e.
// SqmPath createSqmPath(SqmPath<?> lhs, SqmCreationState creationState);
// todo (6.0) : add capability to resolve SQL tree Expression
// actually define this in ter
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// todo (6.0) remove
/**
* Given a component path expression, get the type of the property
*/
@ -34,12 +76,9 @@ public interface PropertyMapping {
* Obtain aliased column/formula fragments for the specified property path.
*/
public String[] toColumns(String alias, String propertyName) throws QueryException;
/**
* Given a property path, return the corresponding column name(s).
*/
public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException;
/**
* Get the type of the thing containing the properties
*/
public Type getType();
}

View File

@ -0,0 +1,103 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
/**
* @author Steve Ebersole
*/
public enum BinaryArithmeticOperator {
ADD {
@Override
public String toLoggableText(String lhs, String rhs) {
return standardToLoggableText( lhs, this, rhs );
}
@Override
public char getOperatorSqlText() {
return '+';
}
},
SUBTRACT {
@Override
public String toLoggableText(String lhs, String rhs) {
return standardToLoggableText( lhs, this, rhs );
}
@Override
public char getOperatorSqlText() {
return '-';
}
},
MULTIPLY {
@Override
public String toLoggableText(String lhs, String rhs) {
return standardToLoggableText( lhs, this, rhs );
}
@Override
public char getOperatorSqlText() {
return '*';
}
},
DIVIDE {
@Override
public String toLoggableText(String lhs, String rhs) {
return standardToLoggableText( lhs, this, rhs );
}
@Override
public char getOperatorSqlText() {
return '/';
}
},
QUOT {
@Override
public String toLoggableText(String lhs, String rhs) {
return standardToLoggableText( lhs, this, rhs );
}
@Override
public char getOperatorSqlText() {
return '/';
}
},
MODULO {
@Override
public String toLoggableText(String lhs, String rhs) {
// return lhs + " % " + rhs;
return "mod(" + lhs + "," + rhs + ")";
}
@Override
public char getOperatorSqlText() {
return '%';
}
},
;
public abstract String toLoggableText(String lhs, String rhs);
public abstract char getOperatorSqlText();
public String getOperatorSqlTextString() {
return Character.toString( getOperatorSqlText() );
}
private static String standardToLoggableText(String lhs, BinaryArithmeticOperator operator, String rhs) {
return standardToLoggableText( lhs, operator.getOperatorSqlText(), rhs );
}
private static String standardToLoggableText(String lhs, char operator, String rhs) {
return '(' + lhs + operator + rhs + ')';
}
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
/**
* Describes the allowable ways in which entity references
* can be handled as dynamic-instantiation (ctor result) argument.
* <p/>
* NOTE that this only applies to Hibernate extension to JPA. JPA
* does not allow ctor-result arguments to be anything other than
* scalar values (column result).
*
* @author Steve Ebersole
*/
public enum ConstructorEntityArgumentMode {
/**
* The id of the entity will be used as the ctor arg. This
* is the legacy Hibernate behavior.
*/
SCALAR,
/**
* The entity reference will be passed as the ctor arg. Whether
* the entity ref is initialized or not depends on whether
* the entity is fetched in the query or is otherwise already
* part of the persistence context.
*/
ENTITY,
/**
* This mode says to chose based on what ctors are available on
* the target class.
*/
CHOOSE
}

View File

@ -0,0 +1,27 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import org.hibernate.HibernateException;
/**
* Indicates an attempt to perform some operation on a Query that is illegal
* based on its state, e.g., attempt to call {@link Query#executeUpdate} on a
* SELECT query.
*
* @author Steve Ebersole
*/
public class IllegalQueryOperationException extends HibernateException {
public IllegalQueryOperationException(String message) {
super( message );
}
public IllegalQueryOperationException(String message, Throwable cause) {
super( message, cause );
}
}

View File

@ -1,8 +1,8 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import javax.persistence.Tuple;
/**
* @author Steve Ebersole
*/
public interface JpaTuple extends Tuple {
}

View File

@ -0,0 +1,65 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
/**
* @author Steve Ebersole
*/
public class Limit {
/**
* Singleton access for "no limit"
*/
public static final Limit NONE = new Limit();
private Integer firstRow;
private Integer maxRows;
public Integer getFirstRow() {
return firstRow;
}
public int getFirstRowJpa() {
// JPA defines this return as a primitive with magic values...
// - specifically the "magic number" 0 (ZERO) as defined by the spec.
return firstRow == null ? 0 : firstRow;
}
public void setFirstRow(Integer firstRow) {
this.firstRow = firstRow;
}
public Integer getMaxRows() {
return maxRows;
}
public int getMaxRowsJpa() {
// JPA defines this return as a primitive with magic values...
// - specifically the "magic number" Integer.MAX_VALUE as defined by the spec.
return maxRows == null ? Integer.MAX_VALUE : maxRows;
}
public void setMaxRows(int maxRows) {
if ( maxRows <= 0 ) {
// treat zero and negatives specially as meaning no limit...
this.maxRows = null;
}
else {
this.maxRows = maxRows;
}
}
public void setMaxRows(Integer maxRows) {
if ( maxRows != null && maxRows <= 0 ) {
// treat zero and negatives specially as meaning no limit...
this.maxRows = null;
}
else {
this.maxRows = maxRows;
}
}
}

View File

@ -0,0 +1,110 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import java.util.Objects;
import org.hibernate.DotIdentifierSequence;
import org.hibernate.internal.util.Loggable;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.model.domain.NavigableRole;
/**
* A representation of the path to a particular Navigable
* as part of a query relative to a "navigable root".
*
* @see NavigableRole
*
* @author Steve Ebersole
*/
public class NavigablePath implements DotIdentifierSequence, Loggable {
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
private final NavigablePath parent;
private final String localName;
private final String fullPath;
private final int hashCode;
public NavigablePath(NavigablePath parent, String navigableName) {
this.parent = parent;
this.localName = navigableName;
// the _identifierMapper is a "hidden property" on entities with composite keys.
// concatenating it will prevent the path from correctly being used to look up
// various things such as criteria paths and fetch profile association paths
if ( IDENTIFIER_MAPPER_PROPERTY.equals( navigableName ) ) {
this.fullPath = parent != null ? parent.getFullPath() : "";
}
else {
final String prefix;
if ( parent != null ) {
final String resolvedParent = parent.getFullPath();
if ( StringHelper.isEmpty( resolvedParent ) ) {
prefix = "";
}
else {
prefix = resolvedParent + '.';
}
}
else {
prefix = "";
}
this.fullPath = prefix + navigableName;
}
this.hashCode = fullPath.hashCode();
}
public NavigablePath(String localName) {
this( null, localName );
}
public NavigablePath() {
this( "" );
}
public NavigablePath append(String property) {
return new NavigablePath( this, property );
}
public NavigablePath getParent() {
return parent;
}
public String getLocalName() {
return localName;
}
public String getFullPath() {
return fullPath;
}
@Override
public String toString() {
return getClass().getSimpleName() + '[' + fullPath + ']';
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
final NavigablePath other = (NavigablePath) o;
return Objects.equals( getFullPath(), other.getFullPath() );
}
}

View File

@ -1,22 +1,76 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import java.util.Collection;
import java.util.Set;
import java.util.function.Consumer;
import javax.persistence.Parameter;
import org.hibernate.Incubating;
/**
* Access to known information about the parameters for a query.
*
* @author Steve Ebersole
*/
public interface ParameterMetadata {
@Incubating
public interface ParameterMetadata<P extends QueryParameter<?>> {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
// General purpose
/**
* The total number of registered parameters.
*/
int getParameterCount();
/**
* Resolve the QueryParameter reference registered here under the
* given name, if one.
*
* @return The registered parameter
*
* @throws IllegalArgumentException if no parameter is registered under that name
*/
P getQueryParameter(String name);
/**
* Resolve the QueryParameter reference registered here under the
* given position/ordinal label, if one.
*
* @return The registered parameter
*
* @throws IllegalArgumentException if no parameter is registered under that label
*/
P getQueryParameter(int positionLabel);
/**
* A deeper resolution attempt from a JPA parameter reference to Hibernate's
* contract. Generally should return the same param reference.
*
* According to the spec, only Parameter references obtained from the provider
* are valid.
*/
P resolve(Parameter param);
/**
* Is this parameter reference registered in this collection?
*/
boolean containsReference(P parameter);
Set<P> getRegistrations();
/**
* General purpose visitation using functional
*/
void visitRegistrations(Consumer<P> action);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
// Named parameters
/**
* Does this parameter set contain any named parameters?
@ -25,6 +79,17 @@ public interface ParameterMetadata {
*/
boolean hasNamedParameters();
/**
* Return the names of all named parameters of the query.
*
* @return the parameter names
*/
Set<String> getNamedParameterNames();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
// "positional" parameters
/**
* Does this parameter set contain any positional parameters?
*
@ -32,37 +97,5 @@ public interface ParameterMetadata {
*/
boolean hasPositionalParameters();
Set<QueryParameter<?>> collectAllParameters();
Set<Parameter<?>> collectAllParametersJpa();
/**
* Return the names of all named parameters of the query.
*
* @return the parameter names, in no particular order
*/
Set<String> getNamedParameterNames();
/**
* Returns the number of positional parameters.
*
* @return The number of positional parameters.
*/
int getPositionalParameterCount();
<T> QueryParameter<T> getQueryParameter(String name);
<T> QueryParameter<T> getQueryParameter(Integer position);
<T> QueryParameter<T> resolve(Parameter<T> param);
Collection<QueryParameter> getPositionalParameters();
Collection<QueryParameter> getNamedParameters();
int getParameterCount();
boolean containsReference(QueryParameter parameter);
void visitRegistrations(Consumer<QueryParameter> action);
Set<Integer> getOrdinalParameterLabels();
}

View File

@ -0,0 +1,91 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import java.util.Locale;
import org.hibernate.query.criteria.LiteralHandlingMode;
/**
* Defines possible ways we can handle query literals in terms of JDBC.
*
* @author Steve Ebersole
*
* @since 6.0
*/
public enum QueryLiteralRendering {
/**
* The default - more-or-less an alias for {@link #AS_PARAM_OUTSIDE_SELECT}
*/
AUTO( "auto" ),
/**
* Always render as a SQL literal, never a parameter
*/
AS_LITERAL( "literal" ),
/**
* Always as a parameter, never as a literal
*/
AS_PARAM( "param" ),
/**
* As a parameter when the literal occurs outside the SELECT clause,
* otherwise render as a SQL literal.
*/
AS_PARAM_OUTSIDE_SELECT( "param-outside-select" );
private final String externalForm;
QueryLiteralRendering(String externalForm) {
this.externalForm = externalForm;
}
public String toExternalForm() {
return externalForm;
}
public static QueryLiteralRendering fromExternalForm(Object externalValue) {
if ( externalValue != null ) {
if ( externalValue instanceof QueryLiteralRendering ) {
return (QueryLiteralRendering) externalValue;
}
if ( externalValue instanceof LiteralHandlingMode ) {
return ( (LiteralHandlingMode) externalValue ).getCounterpart();
}
final String externalValueString = externalValue.toString().trim().toLowerCase( Locale.ROOT );
if ( externalValueString.isEmpty() ) {
return null;
}
if ( AS_LITERAL.externalForm.equals( externalValueString ) ) {
return AS_LITERAL;
}
if ( AS_PARAM.externalForm.equals( externalValueString ) ) {
return AS_PARAM;
}
if ( AS_PARAM_OUTSIDE_SELECT.externalForm.equals( externalValueString ) ) {
return AS_PARAM_OUTSIDE_SELECT;
}
try {
final LiteralHandlingMode legacy = LiteralHandlingMode.interpret( externalValue );
return legacy.getCounterpart();
}
catch (Exception ignore) {
}
}
// the default...
return AS_PARAM_OUTSIDE_SELECT;
}
}

View File

@ -0,0 +1,49 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import org.hibernate.HibernateException;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.Cause;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.logging.annotations.ValidIdRange;
import static org.jboss.logging.Logger.Level.ERROR;
/**
* @author Steve Ebersole
*/
@MessageLogger( projectCode = "HHH" )
@ValidIdRange( min = 90003001, max = 90004000 )
public interface QueryLogger extends BasicLogger {
String LOGGER_NAME = "org.hibernate.orm.query";
QueryLogger QUERY_LOGGER = Logger.getMessageLogger( QueryLogger.class, LOGGER_NAME );
boolean TRACE_ENABLED = QUERY_LOGGER.isTraceEnabled();
boolean DEBUG_ENABLED = QUERY_LOGGER.isDebugEnabled();
static String subLoggerName(String subName) {
return LOGGER_NAME + '.' + subName;
}
static Logger subLogger(String subName) {
return Logger.getLogger( subLoggerName( subName ) );
}
static <T> T subLogger(String subName, Class<T> loggerJavaType) {
return Logger.getMessageLogger( loggerJavaType, subLoggerName( subName ) );
}
@LogMessage(level = ERROR)
@Message(value = "Error in named query: %s", id = 90003001)
void namedQueryError(String queryName, @Cause HibernateException e);
}

View File

@ -1,15 +1,20 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import javax.persistence.ParameterMode;
import org.hibernate.Incubating;
import org.hibernate.type.Type;
import org.hibernate.metamodel.model.mapping.spi.AllowableParameterType;
/**
* Represents a parameter defined in the source (HQL/JPQL or criteria) query.
*
* NOTE: Consider this contract (and its sub-contracts) as incubating as we transition to 6.0 and SQM
*
* @author Steve Ebersole
@ -17,15 +22,33 @@ import org.hibernate.type.Type;
@Incubating
public interface QueryParameter<T> extends javax.persistence.Parameter<T> {
/**
* Get the Hibernate Type associated with this parameter.
* Is this a {@code IN}, {@code OUT} or {@code INOUT} parameter.
* <p/>
* Only really pertinent in regards to procedure/function calls. In all
* other cases the mode would be {@link ParameterMode#IN}
*
* @return The Hibernate Type.
* @return The parameter mode.
*/
Type getHibernateType();
default ParameterMode getMode() {
return ParameterMode.IN;
}
int[] getSourceLocations();
/**
* Does this parameter allow multi-valued (collection, array, etc) binding?
* <p/>
* This is only valid for HQL/JPQL and (I think) Criteria queries, and is
* determined based on the context of the parameters declaration.
*
* @return {@code true} indicates that multi-valued binding is allowed for this
* parameter
*/
boolean allowsMultiValuedBinding();
// todo : add a method indicating whether this parameter is valid for use in "parameter list binding"
// actually this already implemented in 6.0 code and I'm not going to mess with
// this in earlier versions
/**
* Get the Hibernate Type associated with this parameter, if one. May
* return {@code null}.
*
* @return The associated Hibernate Type, may be {@code null}.
*/
AllowableParameterType<T> getHibernateType();
}

View File

@ -0,0 +1,33 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import java.util.List;
/**
* Allows defining transformation of the result List from a Query to some
* other form.
*
* @see org.hibernate.transform.ResultTransformer
*
* @author Steve Ebersole
* @author Gavin King
*/
public interface ResultListTransformer {
/**
* Here we have an opportunity to perform transformation on the
* query result as a whole. This might be useful to convert from
* one collection type to another or to remove duplicates from the
* result, etc.
*
* @param resultList The result list as would otherwise be returned from
* the Query without the intervention of this ResultListTransformer
*
* @return The transformed result.
*/
List transformList(List resultList);
}

View File

@ -0,0 +1,65 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import java.util.Collection;
import org.hibernate.MappingException;
/**
* A unifying interface for queries which can define tables (query spaces) to synchronize on.
*
* These query spaces affect the process of auto-flushing by determining which entities will be
* processed by auto-flush based on the table to which those entities are mapped and which are
* determined to have pending state changes.
*
* In a similar manner, these query spaces also affect how query result caching can recognize invalidated results.
*
* @author Steve Ebersole
*/
public interface SynchronizeableQuery {
/**
* Obtain the list of query spaces the query is synchronized on.
*
* @return The list of query spaces upon which the query is synchronized.
*/
Collection<String> getSynchronizedQuerySpaces();
/**
* Adds a query space.
*
* @param querySpace The query space to be auto-flushed for this query.
*
* @return {@code this}, for method chaining
*/
SynchronizeableQuery addSynchronizedQuerySpace(String querySpace);
/**
* Adds an entity name for (a) auto-flush checking and (b) query result cache invalidation checking. Same as
* {@link #addSynchronizedQuerySpace} for all tables associated with the given entity.
*
* @param entityName The name of the entity upon whose defined query spaces we should additionally synchronize.
*
* @return {@code this}, for method chaining
*
* @throws MappingException Indicates the given name could not be resolved as an entity
*/
SynchronizeableQuery addSynchronizedEntityName(String entityName) throws MappingException;
/**
* Adds an entity for (a) auto-flush checking and (b) query result cache invalidation checking. Same as
* {@link #addSynchronizedQuerySpace} for all tables associated with the given entity.
*
* @param entityClass The class of the entity upon whose defined query spaces we should additionally synchronize.
*
* @return {@code this}, for method chaining
*
* @throws MappingException Indicates the given class could not be resolved as an entity
*/
SynchronizeableQuery addSynchronizedEntityClass(Class entityClass) throws MappingException;
}

View File

@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
/**
* User hook for applying transformations of the query result tuples (the result "row").
*
* Ultimately, gets wrapped in a
* {@link org.hibernate.sql.exec.internal.RowTransformerTupleTransformerAdapter}
* to adapt the TupleTransformer to the {@link org.hibernate.sql.exec.spi.RowTransformer}
* contract, which is the thing actually used to process the results internally.
*
* Note that {@link JpaTupleTransformer} is a special sub-type applications may use
* to transform the row into a JPA {@link javax.persistence.Tuple}. JpaTupleTransformer is
* deprecated as it is much more appropriate (and simpler) to simply specify the Query
* return type as Tuple
*
* @see org.hibernate.transform.ResultTransformer
* @see org.hibernate.sql.exec.spi.RowTransformer
*
* @author Steve Ebersole
* @author Gavin King
*/
public interface TupleTransformer<T> {
/**
* Tuples are the elements making up each "row" of the query result.
* The contract here is to transform these elements into the final
* row shape.
*
* @param tuple The result elements
* @param aliases The result aliases ("parallel" array to tuple)
*
* @return The transformed row.
*/
T transformTuple(Object[] tuple, String[] aliases);
/**
* How many result elements will this transformation produce?
*/
default int determineNumberOfResultElements(int rawElementCount) {
return rawElementCount;
}
}

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
/**
* @author Steve Ebersole
*/
public enum UnaryArithmeticOperator {
UNARY_PLUS,
UNARY_MINUS
}

View File

@ -0,0 +1,21 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query;
import org.hibernate.HibernateException;
/**
* Generally indicates an attempt to bind a parameter value for an unknown parameter.
*
* @author Steve Ebersole
*/
public class UnknownParameterException extends HibernateException {
public UnknownParameterException(String message) {
super( message );
}
}

View File

@ -1,22 +1,610 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Tuple;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;
import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.Subquery;
import org.hibernate.NullPrecedence;
import org.hibernate.SortOrder;
import org.hibernate.metamodel.model.domain.DomainType;
/**
* Hibernate extensions to the JPA CriteriaBuilder. Currently there are no extensions; these are coming in 6.0
* Hibernate extensions to the JPA CriteriaBuilder.
*
* @author Steve Ebersole
*/
public interface HibernateCriteriaBuilder extends CriteriaBuilder {
<X, T> JpaExpression<X> cast(JpaExpression<T> expression, Class<X> castTargetJavaType);
JpaPredicate wrap(Expression<Boolean> expression);
@SuppressWarnings("unchecked")
JpaPredicate wrap(Expression<Boolean>... expressions);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Criteria creation
@Override
JpaCriteriaQuery<Object> createQuery();
@Override
<T> JpaCriteriaQuery<T> createQuery(Class<T> resultClass);
@Override
JpaCriteriaQuery<Tuple> createTupleQuery();
@Override
<T> JpaCriteriaUpdate<T> createCriteriaUpdate(Class<T> targetEntity);
@Override
<T> JpaCriteriaDelete<T> createCriteriaDelete(Class<T> targetEntity);
<T> JpaCriteriaInsertSelect<T> createCriteriaInsertSelect(Class<T> targetEntity);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Paths
@Override
<X, T extends X> JpaPath<T> treat(Path<X> path, Class<T> type);
@Override
<X, T extends X> JpaRoot<T> treat(Root<X> root, Class<T> type);
@Override
<X, T, V extends T> JpaJoin<X, V> treat(Join<X, T> join, Class<V> type);
@Override
<X, T, E extends T> JpaCollectionJoin<X, E> treat(CollectionJoin<X, T> join, Class<E> type);
@Override
<X, T, E extends T> JpaSetJoin<X, E> treat(SetJoin<X, T> join, Class<E> type);
@Override
<X, T, E extends T> JpaListJoin<X, E> treat(ListJoin<X, T> join, Class<E> type);
@Override
<X, K, T, V extends T> JpaMapJoin<X, K, V> treat(MapJoin<X, K, T> join, Class<V> type);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Selections
@Override
<Y> JpaCompoundSelection<Y> construct(Class<Y> resultClass, Selection<?>[] selections);
<Y> JpaCompoundSelection<Y> construct(Class<Y> resultClass, List<? extends JpaSelection<?>> arguments);
@Override
JpaCompoundSelection<Tuple> tuple(Selection<?>[] selections);
JpaCompoundSelection<Tuple> tuple(List<? extends JpaSelection<?>> selections);
@Override
JpaCompoundSelection<Object[]> array(Selection<?>[] selections);
JpaCompoundSelection<Object[]> array(List<? extends JpaSelection<?>> selections);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Expressions
@Override
<N extends Number> JpaExpression<Double> avg(Expression<N> argument);
@Override
<N extends Number> JpaExpression<N> sum(Expression<N> argument);
@Override
JpaExpression<Long> sumAsLong(Expression<Integer> argument);
@Override
JpaExpression<Double> sumAsDouble(Expression<Float> argument);
@Override
<N extends Number> JpaExpression<N> max(Expression<N> argument);
@Override
<N extends Number> JpaExpression<N> min(Expression<N> argument);
@Override
<X extends Comparable<? super X>> JpaExpression<X> greatest(Expression<X> argument);
@Override
<X extends Comparable<? super X>> JpaExpression<X> least(Expression<X> argument);
@Override
JpaExpression<Long> count(Expression<?> argument);
@Override
JpaExpression<Long> countDistinct(Expression<?> x);
@Override
<N extends Number> JpaExpression<N> neg(Expression<N> x);
@Override
<N extends Number> JpaExpression<N> abs(Expression<N> x);
@Override
<N extends Number> JpaExpression<N> sum(Expression<? extends N> x, Expression<? extends N> y);
@Override
<N extends Number> JpaExpression<N> sum(Expression<? extends N> x, N y);
@Override
<N extends Number> JpaExpression<N> sum(N x, Expression<? extends N> y);
@Override
<N extends Number> JpaExpression<N> prod(Expression<? extends N> x, Expression<? extends N> y);
@Override
<N extends Number> JpaExpression<N> prod(Expression<? extends N> x, N y);
@Override
<N extends Number> JpaExpression<N> prod(N x, Expression<? extends N> y);
@Override
<N extends Number> JpaExpression<N> diff(Expression<? extends N> x, Expression<? extends N> y);
@Override
<N extends Number> JpaExpression<N> diff(Expression<? extends N> x, N y);
@Override
<N extends Number> JpaExpression<N> diff(N x, Expression<? extends N> y);
@Override
JpaExpression<Number> quot(Expression<? extends Number> x, Expression<? extends Number> y);
@Override
JpaExpression<Number> quot(Expression<? extends Number> x, Number y);
@Override
JpaExpression<Number> quot(Number x, Expression<? extends Number> y);
@Override
JpaExpression<Integer> mod(Expression<Integer> x, Expression<Integer> y);
@Override
JpaExpression<Integer> mod(Expression<Integer> x, Integer y);
@Override
JpaExpression<Integer> mod(Integer x, Expression<Integer> y);
@Override
JpaExpression<Double> sqrt(Expression<? extends Number> x);
@Override
JpaExpression<Long> toLong(Expression<? extends Number> number);
@Override
JpaExpression<Integer> toInteger(Expression<? extends Number> number);
@Override
JpaExpression<Float> toFloat(Expression<? extends Number> number);
@Override
JpaExpression<Double> toDouble(Expression<? extends Number> number);
@Override
JpaExpression<BigDecimal> toBigDecimal(Expression<? extends Number> number);
@Override
JpaExpression<BigInteger> toBigInteger(Expression<? extends Number> number);
@Override
JpaExpression<String> toString(Expression<Character> character);
@Override
<T> JpaExpression<T> literal(T value);
<T> List<? extends JpaExpression<T>> literals(T[] values);
<T> List<? extends JpaExpression<T>> literals(List<T> values);
@Override
<T> JpaExpression<T> nullLiteral(Class<T> resultClass);
@Override
<T> JpaParameterExpression<T> parameter(Class<T> paramClass);
@Override
<T> JpaParameterExpression<T> parameter(Class<T> paramClass, String name);
@Override
JpaExpression<String> concat(Expression<String> x, Expression<String> y);
@Override
JpaExpression<String> concat(Expression<String> x, String y);
@Override
JpaExpression<String> concat(String x, Expression<String> y);
JpaExpression<String> concat(String x, String y);
@Override
JpaFunction<String> substring(Expression<String> x, Expression<Integer> from);
@Override
JpaFunction<String> substring(Expression<String> x, int from);
@Override
JpaFunction<String> substring(
Expression<String> x,
Expression<Integer> from,
Expression<Integer> len);
@Override
JpaFunction<String> substring(Expression<String> x, int from, int len);
@Override
JpaFunction<String> trim(Expression<String> x);
@Override
JpaFunction<String> trim(Trimspec ts, Expression<String> x);
@Override
JpaFunction<String> trim(Expression<Character> t, Expression<String> x);
@Override
JpaFunction<String> trim(Trimspec ts, Expression<Character> t, Expression<String> x);
@Override
JpaFunction<String> trim(char t, Expression<String> x);
@Override
JpaFunction<String> trim(Trimspec ts, char t, Expression<String> x);
@Override
JpaFunction<String> lower(Expression<String> x);
@Override
JpaFunction<String> upper(Expression<String> x);
@Override
JpaFunction<Integer> length(Expression<String> x);
@Override
JpaFunction<Integer> locate(Expression<String> x, Expression<String> pattern);
@Override
JpaFunction<Integer> locate(Expression<String> x, String pattern);
@Override
JpaFunction<Integer> locate(
Expression<String> x,
Expression<String> pattern,
Expression<Integer> from);
@Override
JpaFunction<Integer> locate(Expression<String> x, String pattern, int from);
@Override
JpaFunction<Date> currentDate();
@Override
JpaFunction<Timestamp> currentTimestamp();
JpaFunction<Instant> currentInstant();
@Override
<T> JpaFunction<T> function(String name, Class<T> type, Expression<?>[] args);
@Override
<Y> JpaExpression<Y> all(Subquery<Y> subquery);
@Override
<Y> JpaExpression<Y> some(Subquery<Y> subquery);
@Override
<Y> JpaExpression<Y> any(Subquery<Y> subquery);
@Override
<K, M extends Map<K, ?>> JpaExpression<Set<K>> keys(M map);
<K, L extends List<?>> JpaExpression<Set<K>> indexes(L list);
<V, C extends Collection<V>> JpaExpression<Collection<V>> values(C collection);
@Override
<V, M extends Map<?, V>> Expression<Collection<V>> values(M map);
@Override
<C extends Collection<?>> JpaExpression<Integer> size(Expression<C> collection);
@Override
<C extends Collection<?>> JpaExpression<Integer> size(C collection);
@Override
<T> JpaCoalesce<T> coalesce();
@Override
<Y> JpaCoalesce<Y> coalesce(Expression<? extends Y> x, Expression<? extends Y> y);
@Override
<Y> JpaCoalesce<Y> coalesce(Expression<? extends Y> x, Y y);
@Override
<Y> JpaExpression<Y> nullif(Expression<Y> x, Expression<?> y);
@Override
<Y> JpaExpression<Y> nullif(Expression<Y> x, Y y);
@Override
<C, R> JpaSimpleCase<C, R> selectCase(Expression<? extends C> expression);
@Override
<R> JpaSearchedCase<R> selectCase();
/**
* Create a tuple, as in a composite value, usable in any
* part of the query.
*
* @apiNote This is different from the purely JPA form
* {@link CriteriaBuilder#tuple} which is intended only for use as
* the selection in a root query.
*
* @param tupleType The Java type
* @param expressions The individual expressions making up the tuple
*/
<R> JpaCompoundSelection<R> tuple(
Class<R> tupleType,
JpaExpression<?>... expressions);
/**
* Create a tuple, as in a composite value, usable in any
* part of the query.
*
* @apiNote This is different from the purely JPA form
* {@link CriteriaBuilder#tuple} which is intended only for use as
* the selection in a root query.
*
* @param tupleType The Java type
* @param expressions The individual expressions making up the tuple
*/
<R> JpaCompoundSelection<R> tuple(
Class<R> tupleType,
List<JpaExpression<?>> expressions);
/**
* Create a tuple, as in a composite value, usable in any
* part of the query.
*
* @apiNote This is different from the purely JPA form
* {@link CriteriaBuilder#tuple} which is intended only for use as
* the selection in a root query.
*
* @param tupleType The metamodel DomainType descriptor to apply to the tuple
* @param expressions The individual expressions making up the tuple
*/
<R> JpaCompoundSelection<R> tuple(
DomainType<R> tupleType,
JpaExpression<?>... expressions);
/**
* Create a tuple, as in a composite value, usable in any
* part of the query.
*
* @apiNote This is different from the purely JPA form
* {@link CriteriaBuilder#tuple} which is intended only for use as
* the selection in a root query.
*
* @param tupleType The metamodel DomainType descriptor to apply to the tuple
* @param expressions The individual expressions making up the tuple
*/
<R> JpaCompoundSelection<R> tuple(
DomainType<R> tupleType,
List<JpaExpression<?>> expressions);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Predicates
@Override
JpaPredicate and(Expression<Boolean> x, Expression<Boolean> y);
@Override
JpaPredicate and(Predicate... restrictions);
@Override
JpaPredicate or(Expression<Boolean> x, Expression<Boolean> y);
@Override
JpaPredicate or(Predicate... restrictions);
@Override
JpaPredicate not(Expression<Boolean> restriction);
@Override
JpaPredicate conjunction();
@Override
JpaPredicate disjunction();
@Override
JpaPredicate isTrue(Expression<Boolean> x);
@Override
JpaPredicate isFalse(Expression<Boolean> x);
@Override
JpaPredicate isNull(Expression<?> x);
@Override
JpaPredicate isNotNull(Expression<?> x);
@Override
JpaPredicate equal(Expression<?> x, Expression<?> y);
@Override
JpaPredicate equal(Expression<?> x, Object y);
@Override
JpaPredicate notEqual(Expression<?> x, Expression<?> y);
@Override
JpaPredicate notEqual(Expression<?> x, Object y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate greaterThan(
Expression<? extends Y> x,
Expression<? extends Y> y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate greaterThan(Expression<? extends Y> x, Y y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate greaterThanOrEqualTo(
Expression<? extends Y> x,
Expression<? extends Y> y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate greaterThanOrEqualTo(Expression<? extends Y> x, Y y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate lessThan(
Expression<? extends Y> x,
Expression<? extends Y> y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate lessThan(Expression<? extends Y> x, Y y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate lessThanOrEqualTo(
Expression<? extends Y> x,
Expression<? extends Y> y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate lessThanOrEqualTo(Expression<? extends Y> x, Y y);
@Override
<Y extends Comparable<? super Y>> JpaPredicate between(
Expression<? extends Y> value,
Expression<? extends Y> lower,
Expression<? extends Y> upper);
@Override
<Y extends Comparable<? super Y>> JpaPredicate between(Expression<? extends Y> value, Y lower, Y upper);
@Override
JpaPredicate gt(Expression<? extends Number> x, Expression<? extends Number> y);
@Override
JpaPredicate gt(Expression<? extends Number> x, Number y);
@Override
JpaPredicate ge(Expression<? extends Number> x, Expression<? extends Number> y);
@Override
JpaPredicate ge(Expression<? extends Number> x, Number y);
@Override
JpaPredicate lt(Expression<? extends Number> x, Expression<? extends Number> y);
@Override
JpaPredicate lt(Expression<? extends Number> x, Number y);
@Override
JpaPredicate le(Expression<? extends Number> x, Expression<? extends Number> y);
@Override
JpaPredicate le(Expression<? extends Number> x, Number y);
@Override
<C extends Collection<?>> JpaPredicate isEmpty(Expression<C> collection);
@Override
<C extends Collection<?>> JpaPredicate isNotEmpty(Expression<C> collection);
@Override
<E, C extends Collection<E>> JpaPredicate isMember(Expression<E> elem, Expression<C> collection);
@Override
<E, C extends Collection<E>> JpaPredicate isMember(E elem, Expression<C> collection);
@Override
<E, C extends Collection<E>> JpaPredicate isNotMember(Expression<E> elem, Expression<C> collection);
@Override
<E, C extends Collection<E>> JpaPredicate isNotMember(E elem, Expression<C> collection);
@Override
JpaPredicate like(Expression<String> x, Expression<String> pattern);
@Override
JpaPredicate like(Expression<String> x, String pattern);
@Override
JpaPredicate like(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar);
@Override
JpaPredicate like(Expression<String> x, Expression<String> pattern, char escapeChar);
@Override
JpaPredicate like(Expression<String> x, String pattern, Expression<Character> escapeChar);
@Override
JpaPredicate like(Expression<String> x, String pattern, char escapeChar);
@Override
JpaPredicate notLike(Expression<String> x, Expression<String> pattern);
@Override
JpaPredicate notLike(Expression<String> x, String pattern);
@Override
JpaPredicate notLike(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar);
@Override
JpaPredicate notLike(Expression<String> x, Expression<String> pattern, char escapeChar);
@Override
JpaPredicate notLike(Expression<String> x, String pattern, Expression<Character> escapeChar);
@Override
JpaPredicate notLike(Expression<String> x, String pattern, char escapeChar);
@Override
<T> JpaInPredicate<T> in(Expression<? extends T> expression);
@SuppressWarnings("unchecked")
<T> JpaInPredicate<T> in(Expression<? extends T> expression, Expression<? extends T>... values);
@SuppressWarnings("unchecked")
<T> JpaInPredicate<T> in(Expression<? extends T> expression, T... values);
<T> JpaInPredicate<T> in(Expression<? extends T> expression, List<T> values);
@Override
JpaPredicate exists(Subquery<?> subquery);
/**
* Create a predicate that tests whether a Map is empty.
* <p/>
@ -29,7 +617,7 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
*
* @return is-empty predicate
*/
<M extends Map<?,?>> Predicate isMapEmpty(Expression<M> mapExpression);
<M extends Map<?,?>> JpaPredicate isMapEmpty(JpaExpression<M> mapExpression);
/**
* Create a predicate that tests whether a Map is
@ -43,7 +631,7 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
*
* @return is-not-empty predicate
*/
<M extends Map<?,?>> Predicate isMapNotEmpty(Expression<M> mapExpression);
<M extends Map<?,?>> JpaPredicate isMapNotEmpty(JpaExpression<M> mapExpression);
/**
* Create an expression that tests the size of a map.
@ -56,7 +644,7 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
*
* @return size expression
*/
<M extends Map<?,?>> Expression<Integer> mapSize(Expression<M> mapExpression);
<M extends Map<?,?>> JpaExpression<Integer> mapSize(JpaExpression<M> mapExpression);
/**
* Create an expression that tests the size of a map.
@ -65,6 +653,19 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
*
* @return size expression
*/
<M extends Map<?,?>> Expression<Integer> mapSize(M map);
<M extends Map<?,?>> JpaExpression<Integer> mapSize(M map);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Ordering
JpaOrder sort(JpaExpression<?> sortExpression, SortOrder sortOrder, NullPrecedence nullPrecedence);
JpaOrder sort(JpaExpression<?> sortExpression, SortOrder sortOrder);
JpaOrder sort(JpaExpression<?> sortExpression);
@Override
JpaOrder asc(Expression<?> x);
@Override
JpaOrder desc(Expression<?> x);
}

View File

@ -0,0 +1,26 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
/**
* @author Steve Ebersole
*/
public interface JpaCoalesce<T> extends JpaExpression<T>, CriteriaBuilder.Coalesce<T> {
@Override
JpaCoalesce<T> value(T value);
@Override
JpaCoalesce<T> value(Expression<? extends T> value);
JpaCoalesce<T> value(JpaExpression<? extends T> value);
@SuppressWarnings("unchecked")
JpaCoalesce<T> values(T... values);
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
/**
* Specialization of {@link JpaJoin} for {@link java.util.Collection} typed attribute joins
*
* @author Steve Ebersole
*/
public interface JpaCollectionJoin<O, T> extends JpaJoin<O, T>, CollectionJoin<O, T> {
@Override
JpaCollectionJoin<O, T> correlateTo(JpaSubQuery<T> subquery);
@Override
JpaCollectionJoin<O, T> on(JpaExpression<Boolean> restriction);
@Override
JpaCollectionJoin<O, T> on(Expression<Boolean> restriction);
@Override
JpaCollectionJoin<O, T> on(JpaPredicate... restrictions);
@Override
JpaCollectionJoin<O, T> on(Predicate... restrictions);
@Override
<S extends T> JpaCollectionJoin<O, S> treatAs(Class<S> treatAsType);
}

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CompoundSelection;
/**
* @author Steve Ebersole
*/
public interface JpaCompoundSelection<T> extends JpaSelection<T>, CompoundSelection<T> {
}

View File

@ -0,0 +1,20 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CommonAbstractCriteria;
/**
* @author Steve Ebersole
*/
public interface JpaCriteriaBase extends CommonAbstractCriteria, JpaCriteriaNode {
@Override
<U> JpaSubQuery<U> subquery(Class<U> type);
@Override
JpaPredicate getRestriction();
}

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CriteriaDelete;
/**
* @author Steve Ebersole
*/
public interface JpaCriteriaDelete<T> extends JpaManipulationCriteria<T>, CriteriaDelete<T> {
}

View File

@ -0,0 +1,19 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
/**
* A representation of SqmInsertSelectStatement at the
* {@link org.hibernate.query.criteria} level, even though JPA does
* not define support for insert-select criteria.
*
* @see org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement
*
* @author Steve Ebersole
*/
public interface JpaCriteriaInsertSelect<T> extends JpaManipulationCriteria<T> {
}

View File

@ -0,0 +1,17 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.io.Serializable;
/**
* Base contract for nodes making up the criteria tree
*
* @author Steve Ebersole
*/
public interface JpaCriteriaNode extends Serializable {
}

View File

@ -0,0 +1,89 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.util.List;
import java.util.Set;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Selection;
import javax.persistence.metamodel.EntityType;
/**
* Extension of the JPA {@link CriteriaQuery}
*
* @author Steve Ebersole
*/
public interface JpaCriteriaQuery<T> extends CriteriaQuery<T>, JpaQueryableCriteria<T>, JpaSelectCriteria<T> {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Accessors
@Override
@SuppressWarnings("unchecked")
default List<Order> getOrderList() {
return (List) getQuerySpec().getSortSpecifications();
}
/**
* {@inheritDoc}
*
* @apiNote Warning! This actually walks the criteria tree looking
* for parameters nodes.
*/
@Override
Set<ParameterExpression<?>> getParameters();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Mutators
@Override
<X> JpaRoot<X> from(Class<X> entityClass);
@Override
<X> JpaRoot<X> from(EntityType<X> entity);
@Override
JpaCriteriaQuery<T> distinct(boolean distinct);
@Override
JpaCriteriaQuery<T> select(Selection<? extends T> selection);
@Override
JpaCriteriaQuery<T> multiselect(Selection<?>... selections);
@Override
JpaCriteriaQuery<T> multiselect(List<Selection<?>> selectionList);
@Override
JpaCriteriaQuery<T> where(Expression<Boolean> restriction);
@Override
JpaCriteriaQuery<T> where(Predicate... restrictions);
@Override
JpaCriteriaQuery<T> groupBy(Expression<?>... grouping);
@Override
JpaCriteriaQuery<T> groupBy(List<Expression<?>> grouping);
@Override
JpaCriteriaQuery<T> having(Expression<Boolean> restriction);
@Override
JpaCriteriaQuery<T> having(Predicate... restrictions);
@Override
JpaCriteriaQuery<T> orderBy(Order... o);
@Override
JpaCriteriaQuery<T> orderBy(List<Order> o);
}

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CriteriaUpdate;
/**
* @author Steve Ebersole
*/
public interface JpaCriteriaUpdate<T> extends JpaManipulationCriteria<T>, CriteriaUpdate<T> {
}

View File

@ -0,0 +1,13 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
/**
* @author Steve Ebersole
*/
public interface JpaDmlCriteria<E> {
}

View File

@ -0,0 +1,55 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import javax.persistence.criteria.Expression;
/**
* API extension to the JPA {@link Expression} contract
*
* @author Steve Ebersole
*/
public interface JpaExpression<T> extends JpaSelection<T>, Expression<T> {
JpaExpression<Long> asLong();
JpaExpression<Integer> asInteger();
JpaExpression<Float> asFloat();
JpaExpression<Double> asDouble();
JpaExpression<BigDecimal> asBigDecimal();
JpaExpression<BigInteger> asBigInteger();
JpaExpression<String> asString();
@Override
<X> JpaExpression<X> as(Class<X> type);
@Override
JpaPredicate isNull();
@Override
JpaPredicate isNotNull();
@Override
JpaPredicate in(Object... values);
@Override
JpaPredicate in(Expression<?>... values);
@Override
JpaPredicate in(Collection<?> values);
@Override
JpaPredicate in(Expression<Collection<?>> values);
}

View File

@ -0,0 +1,53 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.util.Set;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
/**
* @author Steve Ebersole
*/
public interface JpaFetch<O,T> extends JpaFetchParent<O,T>, Fetch<O,T> {
@Override
Set<Fetch<T, ?>> getFetches();
@Override
<Y> JpaFetch<T, Y> fetch(SingularAttribute<? super T, Y> attribute);
@Override
<Y> JpaFetch<T, Y> fetch(SingularAttribute<? super T, Y> attribute, JoinType jt);
@Override
<Y> JpaFetch<T, Y> fetch(PluralAttribute<? super T, ?, Y> attribute);
@Override
<Y> JpaFetch<T, Y> fetch(PluralAttribute<? super T, ?, Y> attribute, JoinType jt);
@Override
<X, Y> JpaFetch<X, Y> fetch(String attributeName);
@Override
<X, Y> JpaFetch<X, Y> fetch(String attributeName, JoinType jt);
/**
* Add a restriction to the fetch.
*
* @apiNote JPA does not allow restricting a fetch
*/
JpaJoin<O, T> on(JpaExpression<Boolean> restriction);
/**
* Add a restriction to the fetch.
*
* @apiNote JPA does not allow restricting a fetch
*/
JpaJoin<O, T> on(JpaPredicate... restrictions);
}

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.util.Set;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.FetchParent;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
/**
* @author Steve Ebersole
*/
public interface JpaFetchParent<O,T> extends FetchParent<O,T> {
@Override
Set<Fetch<T, ?>> getFetches();
@Override
<Y> JpaFetch<T, Y> fetch(SingularAttribute<? super T, Y> attribute);
@Override
<Y> JpaFetch<T, Y> fetch(SingularAttribute<? super T, Y> attribute, JoinType jt);
@Override
<Y> JpaFetch<T, Y> fetch(PluralAttribute<? super T, ?, Y> attribute);
@Override
<Y> JpaFetch<T, Y> fetch(PluralAttribute<? super T, ?, Y> attribute, JoinType jt);
@Override
<X, Y> JpaFetch<X, Y> fetch(String attributeName);
@Override
<X, Y> JpaFetch<X, Y> fetch(String attributeName, JoinType jt);
}

View File

@ -0,0 +1,21 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.From;
/**
* API extension to the JPA {@link From} contract
*
* @author Steve Ebersole
*/
public interface JpaFrom<O,T> extends JpaPath<T>, JpaFetchParent<O,T>, From<O,T> {
@Override
JpaFrom<O,T> getCorrelationParent();
JpaFrom<O, T> correlateTo(JpaSubQuery<T> subquery);
}

View File

@ -0,0 +1,23 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
/**
* Contract for expressions which model a SQL function call.
*
* @param <T> The type of the function result.
*
* @author Steve Ebersole
*/
public interface JpaFunction<T> extends JpaExpression<T> {
/**
* Retrieve the name of the function.
*
* @return The function name.
*/
String getFunctionName();
}

View File

@ -0,0 +1,35 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CriteriaBuilder;
/**
* @author Steve Ebersole
*/
public interface JpaInPredicate<T> extends JpaPredicate, CriteriaBuilder.In<T> {
/**
* Return the expression to be tested against the
* list of values.
* @return expression
*/
JpaExpression<T> getExpression();
/**
* Add to list of values to be tested against.
* @param value value
* @return in predicate
*/
JpaInPredicate<T> value(T value);
/**
* Add to list of values to be tested against.
* @param value expression
* @return in predicate
*/
JpaInPredicate<T> value(JpaExpression<? extends T> value);
}

View File

@ -0,0 +1,38 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Consolidates the {@link Join} and {@link Fetch} hierarchies since that is how we implement them.
* This allows us to treat them polymorphically.
*
* @author Steve Ebersole
*/
public interface JpaJoin<O, T> extends JpaFrom<O, T>, Join<O, T> {
@Override
PersistentAttribute<? super O, ?> getAttribute();
JpaJoin<O, T> on(JpaExpression<Boolean> restriction);
@Override
JpaJoin<O, T> on(Expression<Boolean> restriction);
JpaJoin<O, T> on(JpaPredicate... restrictions);
@Override
JpaJoin<O, T> on(Predicate... restrictions);
@Override
JpaFrom<O, T> correlateTo(JpaSubQuery<T> subquery);
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Predicate;
/**
* Specialization of {@link JpaJoin} for {@link java.util.List} typed attribute joins
*
* @author Steve Ebersole
*/
public interface JpaListJoin<O, T> extends JpaJoin<O, T>, ListJoin<O, T> {
@Override
JpaListJoin<O, T> on(JpaExpression<Boolean> restriction);
@Override
JpaListJoin<O, T> on(Expression<Boolean> restriction);
@Override
JpaListJoin<O, T> on(JpaPredicate... restrictions);
@Override
JpaListJoin<O, T> on(Predicate... restrictions);
@Override
JpaListJoin<O, T> correlateTo(JpaSubQuery<T> subquery);
@Override
<S extends T> JpaListJoin<O, S> treatAs(Class<S> treatAsType);
}

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import org.hibernate.query.sqm.tree.from.SqmRoot;
/**
* @author Steve Ebersole
*/
public interface JpaManipulationCriteria<E> extends JpaQueryableCriteria<E> {
/**
* Get the root path that is the target of the DML statement.
*/
JpaRoot<E> getTarget();
/**
* Set the root path
*/
void setTarget(SqmRoot<E> root);
}

View File

@ -0,0 +1,35 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Predicate;
/**
* Specialization of {@link JpaJoin} for {@link java.util.Map} typed attribute joins
*
* @author Steve Ebersole
*/
public interface JpaMapJoin<O,K,V> extends JpaJoin<O,V>, MapJoin<O,K,V> {
@Override
JpaMapJoin<O, K, V> on(JpaExpression<Boolean> restriction);
@Override
JpaMapJoin<O, K, V> on(Expression<Boolean> restriction);
@Override
JpaMapJoin<O, K, V> on(JpaPredicate... restrictions);
@Override
JpaMapJoin<O, K, V> on(Predicate... restrictions);
@Override
JpaMapJoin<O, K, V> correlateTo(JpaSubQuery<V> subquery);
<S extends V> JpaMapJoin<O, K, S> treatAs(Class<S> treatAsType);
}

View File

@ -0,0 +1,39 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Order;
import org.hibernate.NullPrecedence;
import org.hibernate.SortOrder;
/**
* @author Steve Ebersole
*/
public interface JpaOrder extends Order, JpaCriteriaNode {
SortOrder getSortOrder();
/**
* Set the precedence for nulls for this order element
*/
JpaOrder nullPrecedence(NullPrecedence precedence);
/**
* The precedence for nulls for this order element
*/
NullPrecedence getNullPrecedence();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Co-variants
@Override
JpaOrder reverse();
@Override
JpaExpression<?> getExpression();
}

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.ParameterExpression;
/**
* @author Steve Ebersole
*/
public interface JpaParameterExpression<T> extends ParameterExpression<T>, JpaCriteriaNode {
}

View File

@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Path;
import org.hibernate.query.NavigablePath;
/**
* API extension to the JPA {@link Path} contract
*
* @author Steve Ebersole
*/
public interface JpaPath<T> extends JpaExpression<T>, Path<T> {
/**
* Get this path's NavigablePath
*/
NavigablePath getNavigablePath();
/**
* The source (think "left hand side") of this path
*/
JpaPath<?> getLhs();
/**
* Support for JPA's explicit (TREAT) down-casting.
*/
<S extends T> JpaPath<S> treatAs(Class<S> treatJavaType) throws PathException;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant overrides
@Override
default JpaPath<?> getParentPath() {
return getLhs();
}
}

View File

@ -0,0 +1,20 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.metamodel.ManagedType;
/**
* @author Steve Ebersole
*
* @deprecated This makes the SQM tree awkward and is not needed for
* JPA - JPA has no notion of a "path source" as a tree contract.
*/
@Deprecated
public interface JpaPathSource<T> extends JpaPath<T> {
ManagedType<T> getManagedType();
}

View File

@ -0,0 +1,17 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public interface JpaPredicate extends JpaExpression<Boolean>, Predicate {
@Override
JpaPredicate not();
}

View File

@ -0,0 +1,98 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.util.List;
import java.util.Set;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
/**
* Models a {@code SELECT} query. Used as a delegate in
* implementing {@link javax.persistence.criteria.CriteriaQuery}
* and {@link javax.persistence.criteria.Subquery}.
*
* @apiNote Internally (HQL and SQM) Hibernate supports ordering and limiting
* for both root- and sub- criteria even though JPA only defines support for
* them on a root.
*
* @see JpaCriteriaQuery
* @see JpaSubQuery
*
* @author Steve Ebersole
*/
public interface JpaQueryStructure<T> extends JpaCriteriaNode {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Select clause
boolean isDistinct();
JpaQueryStructure setDistinct(boolean distinct);
JpaSelection<T> getSelection();
JpaQueryStructure setSelection(JpaSelection<T> selection);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// From clause
Set<? extends JpaRoot<?>> getRoots();
JpaQueryStructure addRoot(JpaRoot<?> root);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Where clause
JpaPredicate getRestriction();
JpaQueryStructure<T> setRestriction(JpaPredicate restriction);
JpaQueryStructure<T> setRestriction(Expression<Boolean> restriction);
JpaQueryStructure<T> setRestriction(Predicate... restrictions);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Grouping (group-by / having) clause
List<? extends JpaExpression> getGroupingExpressions();
JpaQueryStructure<T> setGroupingExpressions(List<? extends JpaExpression<?>> grouping);
JpaQueryStructure<T> setGroupingExpressions(JpaExpression<?>... grouping);
JpaPredicate getGroupRestriction();
JpaQueryStructure<T> setGroupRestriction(JpaPredicate restrictions);
JpaQueryStructure<T> setGroupRestriction(Expression<Boolean> restriction);
JpaQueryStructure<T> setGroupRestriction(Predicate... restrictions);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Ordering clause
List<? extends JpaOrder> getSortSpecifications();
JpaQueryStructure<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Limit clause
<X> JpaExpression<X> getLimit();
JpaQueryStructure<T> setLimit(JpaExpression<?> limit);
<X> JpaExpression<X> getOffset();
JpaQueryStructure<T> setOffset(JpaExpression offset);
}

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CommonAbstractCriteria;
/**
* Common contract for the forms of criteria that are "queryable" - can be
* converted into a {@link org.hibernate.query.Query}.
*
* Hibernate extension to the JPA {@link CommonAbstractCriteria} contract.
*
* @see JpaCriteriaQuery
* @see JpaCriteriaDelete
* @see JpaCriteriaUpdate
*
* @author Steve Ebersole
*/
public interface JpaQueryableCriteria<T> extends JpaCriteriaBase, JpaCriteriaNode {
}

View File

@ -0,0 +1,21 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.Root;
import org.hibernate.metamodel.model.domain.EntityDomainType;
/**
* @author Steve Ebersole
*/
public interface JpaRoot<T> extends JpaFrom<T,T>, Root<T> {
@Override
EntityDomainType<T> getModel();
EntityDomainType<T> getManagedType();
}

View File

@ -0,0 +1,27 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
/**
* @author Steve Ebersole
*/
public interface JpaSearchedCase<T> extends JpaExpression<T>, CriteriaBuilder.Case<T> {
@Override
JpaSearchedCase<T> when(Expression<Boolean> condition, T result);
@Override
JpaSearchedCase<T> when(Expression<Boolean> condition, Expression<? extends T> result);
@Override
JpaExpression<T> otherwise(T result);
@Override
JpaExpression<T> otherwise(Expression<? extends T> result);
}

View File

@ -0,0 +1,62 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.util.List;
import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.metamodel.EntityType;
/**
* Commonality between a JPA {@link JpaCriteriaQuery} and {@link JpaSubQuery},
* mainly in the form of delegation to {@link JpaQueryStructure}
*
* @author Steve Ebersole
*/
public interface JpaSelectCriteria<T> extends AbstractQuery<T>, JpaCriteriaBase {
/**
* The query structure. See {@link JpaQueryStructure} for details
*/
JpaQueryStructure<T> getQuerySpec();
@Override
JpaSelectCriteria<T> distinct(boolean distinct);
@Override
JpaSelection<T> getSelection();
@Override
<X> JpaRoot<X> from(Class<X> entityClass);
@Override
<X> JpaRoot<X> from(EntityType<X> entity);
@Override
JpaPredicate getRestriction();
@Override
JpaSelectCriteria<T> where(Expression<Boolean> restriction);
@Override
JpaSelectCriteria<T> where(Predicate... restrictions);
@Override
JpaSelectCriteria<T> groupBy(Expression<?>... grouping);
@Override
JpaSelectCriteria<T> groupBy(List<Expression<?>> grouping);
@Override
JpaPredicate getGroupRestriction();
@Override
JpaSelectCriteria<T> having(Expression<Boolean> restriction);
@Override
JpaSelectCriteria<T> having(Predicate... restrictions);
}

View File

@ -0,0 +1,28 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.criteria;
import java.util.List;
import javax.persistence.criteria.Selection;
/**
* API extension to the JPA {@link Selection} contract
*
* @author Steve Ebersole
*/
public interface JpaSelection<T> extends JpaTupleElement<T>, Selection<T> {
List<? extends JpaSelection<?>> getSelectionItems();
@Override
@SuppressWarnings("unchecked")
default List<Selection<?>> getCompoundSelectionItems() {
return (List) getSelectionItems();
}
@Override
JpaSelection<T> alias(String name);
}

Some files were not shown because too many files have changed in this diff Show More