Skip to content
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

Fix QuerySpecification doesn't support selecting non-lowercase columns #3263

Open
wants to merge 3 commits into
base: 4.10.x
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,16 @@ private boolean containsColumnName(ResultSet resultSet, String name) {
int columnsCount = rsmd.getColumnCount();
knownColumns = CollectionUtils.newHashSet(columnsCount);
for (int x = 1; x <= columnsCount; x++) {
knownColumns.add(rsmd.getColumnLabel(x).toLowerCase());
knownColumns.add(toLowerCase(rsmd.getColumnLabel(x)));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
return knownColumns.contains(name);
return knownColumns.contains(toLowerCase(name));
}

private static String toLowerCase(String str) {
return str == null ? null : str.toLowerCase();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ class H2RepositorySpec extends AbstractRepositorySpec implements H2TestPropertyP
@Shared
H2BookEntityRepository bookEntityRepository = context.getBean(H2BookEntityRepository)

@Shared
H2ExampleEntityRepository exampleEntityRepo = context.getBean(H2ExampleEntityRepository)

@Override
EntityWithIdClassRepository getEntityWithIdClassRepository() {
return entityWithIdClassRepo
Expand Down Expand Up @@ -221,6 +224,11 @@ class H2RepositorySpec extends AbstractRepositorySpec implements H2TestPropertyP
return pageRepo
}

@Override
ExampleEntityRepository getExampleEntityRepository() {
return exampleEntityRepo
}

@Override
boolean isSupportsArrays() {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ class MariaRepositorySpec extends AbstractRepositorySpec implements MariaTestPro
return context.getBean(MySqlEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(MySqlExampleEntityRepository)
}

@Override
protected boolean skipCustomSchemaAndCatalogTest() {
// INSERT command denied to user 'test'@'172.17.0.1' for table 'cars'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ class MySqlRepositorySpec extends AbstractRepositorySpec implements MySQLTestPro
return context.getBean(MySqlEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(MySqlExampleEntityRepository)
}

def "for update is in the correct location"() {
given:
setupBooks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ class OracleXERepositorySpec extends AbstractRepositorySpec implements OracleTes
return context.getBean(OracleXEEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(OracleExampleEntityRepository)
}

@Override
protected boolean skipCustomSchemaAndCatalogTest() {
// ORA-04043: object "FORD"."CARS" does not exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ class PostgresRepositorySpec extends AbstractRepositorySpec implements PostgresT
return context.getBean(PostgresEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(PostgresExampleEntityRepository)
}

@Memoized
@Override
boolean isSupportsArrays() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,10 @@ class SqlServerRepositorySpec extends AbstractRepositorySpec implements MSSQLTes
EntityWithIdClass2Repository getEntityWithIdClass2Repository() {
return context.getBean(MSEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(MSExampleEntityRepository)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.jdbc.h2;

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@JdbcRepository(dialect = Dialect.H2)
public interface H2ExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.jdbc.mysql;

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@JdbcRepository(dialect = Dialect.MYSQL)
public interface MySqlExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.jdbc.oraclexe;

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@JdbcRepository(dialect = Dialect.ORACLE)
public interface OracleExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.jdbc.postgres;

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@JdbcRepository(dialect = Dialect.POSTGRES)
public interface PostgresExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.jdbc.sqlserver;

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@JdbcRepository(dialect = Dialect.SQL_SERVER)
public interface MSExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ class H2RepositorySpec extends AbstractRepositorySpec implements H2TestPropertyP
return context.getBean(H2EntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(H2ExampleEntityRepository)
}

@Override
protected boolean skipQueryByDataArray() {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ class MariaDbRepositorySpec extends AbstractRepositorySpec implements MariaDbTes
return context.getBean(MySqlPageRepository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(MySqlExampleEntityRepository)
}

@Override
protected boolean skipCustomSchemaAndCatalogTest() {
// INSERT command denied to user 'test'@'172.17.0.1' for table 'cars'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ class MySqlRepositorySpec extends AbstractRepositorySpec implements MySqlTestPro
return context.getBean(MySqlEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(MySqlExampleEntityRepository)
}

@Override
protected boolean skipCustomSchemaAndCatalogTest() {
// INSERT command denied to user 'test'@'172.17.0.1' for table 'cars'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ class OracleXERepositorySpec extends AbstractRepositorySpec implements OracleXET
return context.getBean(OracleXEEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(OracleExampleEntityRepository)
}

@Override
protected boolean skipCustomSchemaAndCatalogTest() {
// ORA-04043: object "FORD"."CARS" does not exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ class PostgresRepositorySpec extends AbstractRepositorySpec implements PostgresT
return context.getBean(PostgresEntityWithIdClass2Repository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(PostgresExampleEntityRepository)
}

@Override
boolean isSupportsArrays() {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ class SqlServerRepositorySpec extends AbstractRepositorySpec implements SqlServe
return context.getBean(MSPageRepository)
}

@Memoized
@Override
ExampleEntityRepository getExampleEntityRepository() {
return context.getBean(MSExampleEntityRepository)
}

@Override
boolean supportsNullCharacter() {
false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.r2dbc.h2;

import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.r2dbc.annotation.R2dbcRepository;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@R2dbcRepository(dialect = Dialect.H2)
public interface H2ExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.r2dbc.mysql;

import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.r2dbc.annotation.R2dbcRepository;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@R2dbcRepository(dialect = Dialect.MYSQL)
public interface MySqlExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.r2dbc.oraclexe;

import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.r2dbc.annotation.R2dbcRepository;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@R2dbcRepository(dialect = Dialect.ORACLE)
public interface OracleExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.r2dbc.postgres;

import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.r2dbc.annotation.R2dbcRepository;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@R2dbcRepository(dialect = Dialect.POSTGRES)
public interface PostgresExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.micronaut.data.r2dbc.sqlserver;

import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.r2dbc.annotation.R2dbcRepository;
import io.micronaut.data.tck.repositories.ExampleEntityRepository;

@R2dbcRepository(dialect = Dialect.SQL_SERVER)
public interface MSExampleEntityRepository extends ExampleEntityRepository {
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import io.micronaut.data.tck.entities.CountryRegionCity
import io.micronaut.data.tck.entities.EntityIdClass
import io.micronaut.data.tck.entities.EntityWithIdClass
import io.micronaut.data.tck.entities.EntityWithIdClass2
import io.micronaut.data.tck.entities.ExampleEntity
import io.micronaut.data.tck.entities.Face
import io.micronaut.data.tck.entities.Food
import io.micronaut.data.tck.entities.Genre
Expand Down Expand Up @@ -120,6 +121,7 @@ abstract class AbstractRepositorySpec extends Specification {
abstract PageRepository getPageRepository()
abstract EntityWithIdClassRepository getEntityWithIdClassRepository()
abstract EntityWithIdClass2Repository getEntityWithIdClass2Repository()
abstract ExampleEntityRepository getExampleEntityRepository()

abstract Map<String, String> getProperties()

Expand Down Expand Up @@ -3416,6 +3418,33 @@ abstract class AbstractRepositorySpec extends Specification {
books.size() > 0
}

void "test query specification with uppercase/lowercase column names"() {
given:
exampleEntityRepository.save(new ExampleEntity(1, "foo", "bar"))
when:
QuerySpecification<ExampleEntity> qs = (root, query, criteriaBuilder) -> {
query.multiselect(
root.get("id"),
root.get("lowercaseColumn"))
return criteriaBuilder.equal(root.get("id"), 1)
}
def entity = exampleEntityRepository.find(qs)
then:
entity.lowercaseColumn() == "bar"
when:
qs = (root, query, criteriaBuilder) -> {
query.multiselect(
root.get("id"),
root.get("uppercaseColumn"))
return criteriaBuilder.equal(root.get("id"), 1)
}
entity = exampleEntityRepository.find(qs)
then:
entity.uppercaseColumn() == "foo"
cleanup:
exampleEntityRepository.deleteById(1)
}

private GregorianCalendar getYearMonthDay(Date dateCreated) {
def cal = dateCreated.toCalendar()
def localDate = LocalDate.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.micronaut.data.tck.entities;

import io.micronaut.core.annotation.Nullable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public record ExampleEntity(
@Id Integer id,
@Nullable @Column(name = "UPPERCASE_COLUMN") String uppercaseColumn,
@Nullable @Column(name = "lowercase_column") String lowercaseColumn) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.micronaut.data.tck.repositories;

import io.micronaut.data.repository.GenericRepository;
import io.micronaut.data.repository.jpa.criteria.QuerySpecification;
import io.micronaut.data.tck.entities.ExampleEntity;

public interface ExampleEntityRepository extends GenericRepository<ExampleEntity, Integer> {
void save(ExampleEntity entity);

ExampleEntity find(QuerySpecification<ExampleEntity> querySpecification);

void deleteById(Integer id);
}
Loading