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

Bug: DelayedLoadRelations uses inconsistent quoting for string-literals. #95

Merged
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
19 changes: 19 additions & 0 deletions hdtest/source/generaltest.d
Original file line number Diff line number Diff line change
Expand Up @@ -253,5 +253,24 @@ class GeneralTest : HibernateTest {
assert(allUsers.length == 2); // Should only be 2 users now
}
}

@Test("quote escape test")
void quoteEscapeTest() {
Session sess = sessionFactory.openSession();
scope(exit) sess.close();

auto a1 = new Asset();
a1.name = "Bucky O'Hare";
int id = sess.save(a1).get!int;

auto result = sess.createQuery("FROM Asset WHERE name=:Name")
.setParameter("Name", "Bucky O'Hare")
.list!Asset();
assert(result.length == 1);

result = sess.createQuery("FROM Asset WHERE name='Bucky O''Hare'")
.list!Asset();
assert(result.length == 1);
}
}

1 change: 0 additions & 1 deletion source/hibernated/annotations.d
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ struct ManyToMany {
immutable string joinColumn2;
}


unittest {
@Entity
@Table("user")
Expand Down
3 changes: 2 additions & 1 deletion source/hibernated/dialect.d
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ abstract class Dialect {
string res = "'";
foreach(ch; s) {
switch(ch) {
case '\'': res ~= "\\\'"; break;
// All dialects support the SQL-standard way of escaping a (') character via ('').
case '\'': res ~= "''"; break;
case '\"': res ~= "\\\""; break;
case '\\': res ~= "\\\\"; break;
case '\0': res ~= "\\n"; break;
Expand Down
9 changes: 7 additions & 2 deletions source/hibernated/query.d
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,12 @@ class Token {

}

/**
* Converts an HQL string into a series of tokens to be later converted to SQL.
*
* HQL follows the Jakarta Persistence specification, which requires escaping (') characters via ('').
* See: https://jakarta.ee/specifications/persistence/3.2/jakarta-persistence-spec-3.2#literals
*/
Token[] tokenize(string s) {
Token[] res;
int startpos = 0;
Expand Down Expand Up @@ -1521,11 +1527,10 @@ Token[] tokenize(string s) {
// string constant
i++;
for(int j=i; j<len; j++) {
// In SQL, (') characters are quoted as ('').
// In HQL, (') characters are quoted as (''), so undo that escaping.
if (s[j] == '\'' && j+1 < len && s[j+1] == '\'') {
text ~= s[j];
j++;
text ~= s[j];
}
else if (s[j] != '\'') {
text ~= s[j];
Expand Down
Loading