diff --git a/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java b/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java index 058990467..8409794de 100644 --- a/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java +++ b/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java @@ -1,7 +1,6 @@ package com.avaje.ebean; import java.util.ArrayList; -import java.util.Arrays; import javax.persistence.PersistenceException; @@ -57,6 +56,9 @@ final class DRawSqlColumnsParser { split = tmp.toArray(new String[tmp.size()]); } + if (split.length == 0) { + throw new PersistenceException("Huh? Not expecting length=0 when parsing column " + colInfo); + } if (split.length == 1) { // default to column the same name as the property return new ColumnMapping.Column(indexPos++, split[0], null); @@ -64,17 +66,18 @@ final class DRawSqlColumnsParser { if (split.length == 2) { return new ColumnMapping.Column(indexPos++, split[0], split[1]); } - if (split.length == 3) { - if (!split[1].equalsIgnoreCase("as")) { - String msg = "Expecting AS keyword parsing column " + colInfo; - throw new PersistenceException(msg); - } - return new ColumnMapping.Column(indexPos++, split[0], split[2]); + // Ok, we now expect/require the AS keyword and it should be the + // second to last word in the colInfo content + if (!split[split.length - 2].equalsIgnoreCase("as")) { + throw new PersistenceException("Expecting AS keyword as second to last word when parsing column " + colInfo); } - - String msg = "Expecting Max 3 words parsing column " + colInfo + ". Got " - + Arrays.toString(split); - throw new PersistenceException(msg); + // build back the 'column formula' that precedes the AS keyword + StringBuilder sb = new StringBuilder(); + sb.append(split[0]); + for (int i = 1; i < split.length-2; i++) { + sb.append(" ").append(split[i]); + } + return new ColumnMapping.Column(indexPos++, sb.toString(), split[split.length - 1]); } private int nextComma() { diff --git a/src/test/java/com/avaje/tests/rawsql/TestRawSqlAsKeyword.java b/src/test/java/com/avaje/tests/rawsql/TestRawSqlAsKeyword.java new file mode 100644 index 000000000..0222d82d2 --- /dev/null +++ b/src/test/java/com/avaje/tests/rawsql/TestRawSqlAsKeyword.java @@ -0,0 +1,82 @@ +package com.avaje.tests.rawsql; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.ebean.Query; +import com.avaje.ebean.RawSql; +import com.avaje.ebean.RawSqlBuilder; +import com.avaje.tests.model.basic.Customer; +import com.avaje.tests.model.basic.ResetBasicData; + +public class TestRawSqlAsKeyword extends BaseTestCase { + + @Test + public void test() { + + // Make this false to run this test ... as the pipe string concatenation syntax is DB specific + boolean skipTestAsDBSpecficSQL = true; + + if (skipTestAsDBSpecficSQL) { + + return; + } + + ResetBasicData.reset(); + + + // try valid query where spaces in the formula ... + RawSql rawSql = + RawSqlBuilder + .parse("select r.id, r.name || 'hello' as name from o_customer r ") + .create(); + + Query query = Ebean.find(Customer.class); + query.setRawSql(rawSql); + query.where().ilike("name", "r%"); + + List list = query.findList(); + Assert.assertNotNull(list); + + + // try valid query with no spaces + rawSql = + RawSqlBuilder + .parse("select r.id, r.name||'hello' as name from o_customer r ") + .create(); + + query = Ebean.find(Customer.class); + query.setRawSql(rawSql); + query.where().ilike("name", "r%"); + + list = query.findList(); + Assert.assertNotNull(list); + + rawSql = + RawSqlBuilder + .parse("select r.id, r.name||'hello' name from o_customer r ") + .create(); + query = Ebean.find(Customer.class); + query.setRawSql(rawSql); + query.where().ilike("name", "r%"); + + list = query.findList(); + Assert.assertNotNull(list); + + // this will barf - expecting the AS keyword now + rawSql = + RawSqlBuilder + .parse("select r.id, r.name || 'hello' name from o_customer r ") + .create(); + query = Ebean.find(Customer.class); + query.setRawSql(rawSql); + query.where().ilike("name", "r%"); + + list = query.findList(); + Assert.assertNotNull(list); + } +}