Skip to content

DATAJDBC-479 - Use SqlIdentifier in SQL AST #187

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>2.0.0.DATAJDBC-476-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data Relational Parent</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-jdbc-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>2.0.0.DATAJDBC-476-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
4 changes: 2 additions & 2 deletions spring-data-jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>

<artifactId>spring-data-jdbc</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>2.0.0.DATAJDBC-476-SNAPSHOT</version>

<name>Spring Data JDBC</name>
<description>Spring Data module for JDBC repositories.</description>
Expand All @@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>2.0.0.DATAJDBC-476-SNAPSHOT</version>
</parent>

<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.sql.Column;
import org.springframework.data.relational.core.sql.SQL;
import org.springframework.data.relational.core.sql.Table;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.data.relational.core.sql.Table;

/**
* Utility to get from path to SQL DSL elements.
Expand All @@ -35,21 +33,19 @@ class SqlContext {

private final RelationalPersistentEntity<?> entity;
private final Table table;
private final IdentifierProcessing identifierProcessing;

SqlContext(RelationalPersistentEntity<?> entity, IdentifierProcessing identifierProcessing) {
SqlContext(RelationalPersistentEntity<?> entity) {

this.identifierProcessing = identifierProcessing;
this.entity = entity;
this.table = SQL.table(entity.getTableName().toSql(this.identifierProcessing));
this.table = Table.create(entity.getTableName());
}

Column getIdColumn() {
return table.column(entity.getIdColumn().toSql(identifierProcessing));
return table.column(entity.getIdColumn());
}

Column getVersionColumn() {
return table.column(entity.getRequiredVersionProperty().getColumnName().toSql(identifierProcessing));
return table.column(entity.getRequiredVersionProperty().getColumnName());
}

Table getTable() {
Expand All @@ -59,17 +55,15 @@ Table getTable() {
Table getTable(PersistentPropertyPathExtension path) {

SqlIdentifier tableAlias = path.getTableAlias();
Table table = SQL.table(path.getTableName().toSql(identifierProcessing));
return tableAlias == null ? table : table.as(tableAlias.toSql(identifierProcessing));
Table table = Table.create(path.getTableName());
return tableAlias == null ? table : table.as(tableAlias);
}

Column getColumn(PersistentPropertyPathExtension path) {
return getTable(path).column(path.getColumnName().toSql(identifierProcessing))
.as(path.getColumnAlias().toSql(identifierProcessing));
return getTable(path).column(path.getColumnName()).as(path.getColumnAlias());
}

Column getReverseColumn(PersistentPropertyPathExtension path) {
return getTable(path).column(path.getReverseColumnName().toSql(identifierProcessing))
.as(path.getReverseColumnNameAlias().toSql(identifierProcessing));
return getTable(path).column(path.getReverseColumnName()).as(path.getReverseColumnNameAlias());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.RenderContextFactory;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.*;
import org.springframework.data.relational.core.sql.render.RenderContext;
import org.springframework.data.relational.core.sql.render.SqlRenderer;
import org.springframework.data.relational.domain.Identifier;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.data.util.Lazy;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
Expand All @@ -69,7 +70,7 @@ class SqlGenerator {
private static final Pattern parameterPattern = Pattern.compile("\\W");
private final RelationalPersistentEntity<?> entity;
private final MappingContext<RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext;
private final IdentifierProcessing identifierProcessing;
private final RenderContext renderContext;

private final SqlContext sqlContext;
private final Columns columns;
Expand All @@ -93,16 +94,15 @@ class SqlGenerator {
*
* @param mappingContext must not be {@literal null}.
* @param entity must not be {@literal null}.
* @param identifierProcessing must not be {@literal null}.
* @param dialect must not be {@literal null}.
*/
SqlGenerator(RelationalMappingContext mappingContext, RelationalPersistentEntity<?> entity,
IdentifierProcessing identifierProcessing) {
SqlGenerator(RelationalMappingContext mappingContext, RelationalPersistentEntity<?> entity, Dialect dialect) {

this.mappingContext = mappingContext;
this.entity = entity;
this.identifierProcessing = identifierProcessing;
this.sqlContext = new SqlContext(entity, identifierProcessing);
this.sqlContext = new SqlContext(entity);
this.columns = new Columns(entity, mappingContext);
this.renderContext = new RenderContextFactory(dialect).createRenderContext();
}

/**
Expand All @@ -126,10 +126,9 @@ private Condition getSubselectCondition(PersistentPropertyPathExtension path,
return rootCondition.apply(filterColumn);
}

Table subSelectTable = SQL.table(parentPath.getTableName().toSql(identifierProcessing));
Column idColumn = subSelectTable.column(parentPath.getIdColumnName().toSql(identifierProcessing));
Column selectFilterColumn = subSelectTable
.column(parentPath.getEffectiveIdColumnName().toSql(identifierProcessing));
Table subSelectTable = Table.create(parentPath.getTableName());
Column idColumn = subSelectTable.column(parentPath.getIdColumnName());
Column selectFilterColumn = subSelectTable.column(parentPath.getEffectiveIdColumnName());

Condition innerCondition;

Expand All @@ -152,7 +151,7 @@ private Condition getSubselectCondition(PersistentPropertyPathExtension path,
}

private BindMarker getBindMarker(SqlIdentifier columnName) {
return SQL.bindMarker(":" + parameterPattern.matcher(columnName.getReference(identifierProcessing)).replaceAll(""));
return SQL.bindMarker(":" + parameterPattern.matcher(renderReference(columnName)).replaceAll(""));
}

/**
Expand Down Expand Up @@ -191,21 +190,19 @@ String getFindAllByProperty(Identifier parentIdentifier, @Nullable SqlIdentifier
Assert.isTrue(keyColumn != null || !ordered,
"If the SQL statement should be ordered a keyColumn to order by must be provided.");

Table table = getTable();

SelectBuilder.SelectWhere builder = selectBuilder( //
keyColumn == null //
? Collections.emptyList() //
: Collections.singleton(keyColumn.toSql(identifierProcessing)) //
: Collections.singleton(keyColumn) //
);

Table table = getTable();

Condition condition = buildConditionForBackReference(parentIdentifier, table);
SelectBuilder.SelectWhereAndOr withWhereClause = builder.where(condition);

Select select = ordered //
? withWhereClause
.orderBy(table.column(keyColumn.toSql(identifierProcessing)).as(keyColumn.toSql(identifierProcessing)))
.build() //
? withWhereClause.orderBy(table.column(keyColumn).as(keyColumn)).build() //
: withWhereClause.build();

return render(select);
Expand All @@ -216,8 +213,7 @@ private Condition buildConditionForBackReference(Identifier parentIdentifier, Ta
Condition condition = null;
for (SqlIdentifier backReferenceColumn : parentIdentifier.toMap().keySet()) {

Condition newCondition = table.column(backReferenceColumn.toSql(identifierProcessing))
.isEqualTo(getBindMarker(backReferenceColumn));
Condition newCondition = table.column(backReferenceColumn).isEqualTo(getBindMarker(backReferenceColumn));
condition = condition == null ? newCondition : condition.and(newCondition);
}

Expand Down Expand Up @@ -353,7 +349,7 @@ private SelectBuilder.SelectWhere selectBuilder() {
return selectBuilder(Collections.emptyList());
}

private SelectBuilder.SelectWhere selectBuilder(Collection<String> keyColumns) {
private SelectBuilder.SelectWhere selectBuilder(Collection<SqlIdentifier> keyColumns) {

Table table = getTable();

Expand All @@ -377,7 +373,7 @@ private SelectBuilder.SelectWhere selectBuilder(Collection<String> keyColumns) {
}
}

for (String keyColumn : keyColumns) {
for (SqlIdentifier keyColumn : keyColumns) {
columnExpressions.add(table.column(keyColumn).as(keyColumn));
}

Expand Down Expand Up @@ -440,8 +436,8 @@ Join getJoin(PersistentPropertyPathExtension path) {

return new Join( //
currentTable, //
currentTable.column(path.getReverseColumnName().toSql(identifierProcessing)), //
parentTable.column(idDefiningParentPath.getIdColumnName().toSql(identifierProcessing)) //
currentTable.column(path.getReverseColumnName()), //
parentTable.column(idDefiningParentPath.getIdColumnName()) //
);
}

Expand Down Expand Up @@ -481,14 +477,14 @@ private String createInsertSql(Set<SqlIdentifier> additionalColumns) {

Table table = getTable();

Set<SqlIdentifier> columnNamesForInsert = new TreeSet<>(Comparator.comparing(id -> id.toSql(identifierProcessing)));
Set<SqlIdentifier> columnNamesForInsert = new TreeSet<>(Comparator.comparing(SqlIdentifier::getReference));
columnNamesForInsert.addAll(columns.getInsertableColumns());
columnNamesForInsert.addAll(additionalColumns);

InsertBuilder.InsertIntoColumnsAndValuesWithBuild insert = Insert.builder().into(table);

for (SqlIdentifier cn : columnNamesForInsert) {
insert = insert.column(table.column(cn.toSql(identifierProcessing)));
insert = insert.column(table.column(cn));
}

InsertBuilder.InsertValuesWithBuild insertWithValues = null;
Expand All @@ -506,8 +502,7 @@ private String createUpdateSql() {
private String createUpdateWithVersionSql() {

Update update = createBaseUpdate() //
.and(getVersionColumn()
.isEqualTo(SQL.bindMarker(":" + VERSION_SQL_PARAMETER.getReference(identifierProcessing)))) //
.and(getVersionColumn().isEqualTo(SQL.bindMarker(":" + renderReference(VERSION_SQL_PARAMETER)))) //
.build();

return render(update);
Expand All @@ -520,7 +515,7 @@ private UpdateBuilder.UpdateWhereAndOr createBaseUpdate() {
List<AssignValue> assignments = columns.getUpdateableColumns() //
.stream() //
.map(columnName -> Assignments.value( //
table.column(columnName.toSql(identifierProcessing)), //
table.column(columnName), //
getBindMarker(columnName))) //
.collect(Collectors.toList());

Expand All @@ -537,28 +532,27 @@ private String createDeleteSql() {
private String createDeleteByIdAndVersionSql() {

Delete delete = createBaseDeleteById(getTable()) //
.and(getVersionColumn()
.isEqualTo(SQL.bindMarker(":" + VERSION_SQL_PARAMETER.getReference(identifierProcessing)))) //
.and(getVersionColumn().isEqualTo(SQL.bindMarker(":" + renderReference(VERSION_SQL_PARAMETER)))) //
.build();

return render(delete);
}

private DeleteBuilder.DeleteWhereAndOr createBaseDeleteById(Table table) {
return Delete.builder().from(table)
.where(getIdColumn().isEqualTo(SQL.bindMarker(":" + ID_SQL_PARAMETER.getReference(identifierProcessing))));
.where(getIdColumn().isEqualTo(SQL.bindMarker(":" + renderReference(ID_SQL_PARAMETER))));
}

private String createDeleteByPathAndCriteria(PersistentPropertyPathExtension path,
Function<Column, Condition> rootCondition) {

Table table = SQL.table(path.getTableName().toSql(identifierProcessing));
Table table = Table.create(path.getTableName());

DeleteBuilder.DeleteWhere builder = Delete.builder() //
.from(table);
Delete delete;

Column filterColumn = table.column(path.getReverseColumnName().toSql(identifierProcessing));
Column filterColumn = table.column(path.getReverseColumnName());

if (path.getLength() == 1) {

Expand Down Expand Up @@ -587,19 +581,19 @@ private String createDeleteByListSql() {
}

private String render(Select select) {
return SqlRenderer.create().render(select);
return SqlRenderer.create(renderContext).render(select);
}

private String render(Insert insert) {
return SqlRenderer.create().render(insert);
return SqlRenderer.create(renderContext).render(insert);
}

private String render(Update update) {
return SqlRenderer.create().render(update);
return SqlRenderer.create(renderContext).render(update);
}

private String render(Delete delete) {
return SqlRenderer.create().render(delete);
return SqlRenderer.create(renderContext).render(delete);
}

private Table getTable() {
Expand All @@ -614,6 +608,10 @@ private Column getVersionColumn() {
return sqlContext.getVersionColumn();
}

private String renderReference(SqlIdentifier identifier) {
return identifier.getReference(renderContext.getIdentifierProcessing());
}

/**
* Value object representing a {@code JOIN} association.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* domain type, the same generator will get returned.
*
* @author Jens Schauder
* @author Mark Paluch
*/
@RequiredArgsConstructor
public class SqlGeneratorSource {
Expand All @@ -37,14 +38,15 @@ public class SqlGeneratorSource {
private final Dialect dialect;

/**
* @return the {@link Dialect} used by the created {@link SqlGenerator} instances. Guaranteed to be not {@literal null}.
* @return the {@link Dialect} used by the created {@link SqlGenerator} instances. Guaranteed to be not
* {@literal null}.
*/
public Dialect getDialect() {
return dialect;
}


SqlGenerator getSqlGenerator(Class<?> domainType) {
return CACHE.computeIfAbsent(domainType, t -> new SqlGenerator(context, context.getRequiredPersistentEntity(t), dialect.getIdentifierProcessing()));
return CACHE.computeIfAbsent(domainType,
t -> new SqlGenerator(context, context.getRequiredPersistentEntity(t), dialect));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ protected <T> RelationalPersistentEntity<T> createPersistentEntity(TypeInformati
@Override
protected RelationalPersistentProperty createPersistentProperty(Property property,
RelationalPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
return new BasicJdbcPersistentProperty(property, owner, simpleTypeHolder, this);
BasicJdbcPersistentProperty persistentProperty = new BasicJdbcPersistentProperty(property, owner, simpleTypeHolder,
this);
persistentProperty.setForceQuote(isForceQuote());
return persistentProperty;
}

@Override
Expand Down
Loading