diff --git a/odata/src/main/java/org/teiid/odata/ODataSQLBuilder.java b/odata/src/main/java/org/teiid/odata/ODataSQLBuilder.java index 120eba5f1c..1e62c60e09 100644 --- a/odata/src/main/java/org/teiid/odata/ODataSQLBuilder.java +++ b/odata/src/main/java/org/teiid/odata/ODataSQLBuilder.java @@ -205,29 +205,31 @@ public Query selectString(String entityName, QueryInfo info, OEntityKey key, Str visitNode(info.filter); } - // order by - List orderBy = info.orderBy; - if (orderBy != null && !orderBy.isEmpty()) { - for (OrderByExpression expr:info.orderBy) { - visitNode(expr); - } - query.setOrderBy(this.orderBy); - } - else { - KeyRecord record = resultEntityTable.getPrimaryKey(); - if (record == null) { - // if PK is not available there MUST at least one unique key - record = resultEntityTable.getUniqueKeys().get(0); + if (!countStar) { + // order by + List orderBy = info.orderBy; + if (orderBy != null && !orderBy.isEmpty()) { + for (OrderByExpression expr:info.orderBy) { + visitNode(expr); + } + query.setOrderBy(this.orderBy); } - // provide implicit ordering for cursor logic - for (Column column:record.getColumns()) { - OrderByExpression expr = org.odata4j.expression.Expression.orderBy(org.odata4j.expression.Expression.simpleProperty(column.getName()), Direction.ASCENDING); - visitNode(expr); + else { + KeyRecord record = resultEntityTable.getPrimaryKey(); + if (record == null) { + // if PK is not available there MUST at least one unique key + record = resultEntityTable.getUniqueKeys().get(0); + } + // provide implicit ordering for cursor logic + for (Column column:record.getColumns()) { + OrderByExpression expr = org.odata4j.expression.Expression.orderBy(org.odata4j.expression.Expression.simpleProperty(column.getName()), Direction.ASCENDING); + visitNode(expr); + } + query.setOrderBy(this.orderBy); } - query.setOrderBy(this.orderBy); + + select.setDistinct(this.distinct); } - - select.setDistinct(this.distinct); From from = new From(); from.addClause(this.fromCluse); query.setSelect(select); @@ -368,20 +370,6 @@ private Select buildSelectColumns(HashMap selectColumns, Table return select; } - public Query countStarString(String entityName, QueryInfo info) { - Table table = findTable(entityName, metadata); - AggregateSymbol aggregateSymbol = new AggregateSymbol(AggregateSymbol.Type.COUNT.name(), false, null); - - query.setSelect(new Select(Arrays.asList(aggregateSymbol))); - query.setFrom(new From(Arrays.asList(new UnaryFromClause(new GroupSymbol(table.getFullName()))))); - - if (info.filter != null) { - visitNode(info.filter); - } - query.setCriteria(this.criteria); - return this.query; - } - @Override public void visit(String type) { throw new UnsupportedOperationException(); diff --git a/odata/src/main/java/org/teiid/odata/TeiidProducer.java b/odata/src/main/java/org/teiid/odata/TeiidProducer.java index 65c1b5326e..d0688f89bd 100644 --- a/odata/src/main/java/org/teiid/odata/TeiidProducer.java +++ b/odata/src/main/java/org/teiid/odata/TeiidProducer.java @@ -81,6 +81,7 @@ public EntitiesResponse getEntities(ODataContext context, String entitySetName, @Override public EntitiesResponse getNavProperty(ODataContext context, String entitySetName, OEntityKey entityKey, String navProp, final QueryInfo queryInfo) { + checkExpand(queryInfo); getEntitySet(entitySetName); // validate entity ODataSQLBuilder visitor = new ODataSQLBuilder(this.client.getMetadataStore(), true); Query query = visitor.selectString(entitySetName, queryInfo, entityKey, navProp, false); @@ -110,6 +111,12 @@ public String getSkipToken() { }; } + private void checkExpand(QueryInfo queryInfo) { + if (queryInfo != null && queryInfo.expand != null && !queryInfo.expand.isEmpty()) { + throw new UnsupportedOperationException("Expand is not supported"); //$NON-NLS-1$ + } + } + private EdmEntitySet getEntitySet(String entitySetName) { EdmDataServices eds = getMetadata(); EdmEntitySet entity = eds.findEdmEntitySet(entitySetName); @@ -263,6 +270,7 @@ public void deleteLink(ODataContext context, OEntityId sourceEntity, String targ public BaseResponse callFunction(ODataContext context, EdmFunctionImport function, Map params, QueryInfo queryInfo) { + checkExpand(queryInfo); EdmEntityContainer eec = findEntityContainer(function); StringBuilder sql = new StringBuilder(); // fully qualify the procedure name diff --git a/odata/src/test/java/org/teiid/odata/TestODataIntegration.java b/odata/src/test/java/org/teiid/odata/TestODataIntegration.java index da8d6651e6..bbbc277f28 100644 --- a/odata/src/test/java/org/teiid/odata/TestODataIntegration.java +++ b/odata/src/test/java/org/teiid/odata/TestODataIntegration.java @@ -21,21 +21,21 @@ */ package org.teiid.odata; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyListOf; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.stub; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; import java.io.IOException; import java.io.StringWriter; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; import javax.ws.rs.core.MediaType; @@ -49,7 +49,11 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.odata4j.core.*; +import org.odata4j.core.OEntities; +import org.odata4j.core.OEntity; +import org.odata4j.core.OEntityKey; +import org.odata4j.core.OProperties; +import org.odata4j.core.OProperty; import org.odata4j.edm.EdmDataServices; import org.odata4j.edm.EdmEntitySet; import org.odata4j.edm.EdmSimpleType; @@ -57,7 +61,11 @@ import org.odata4j.format.xml.EdmxFormatWriter; import org.odata4j.producer.QueryInfo; import org.odata4j.producer.Responses; -import org.odata4j.producer.resources.*; +import org.odata4j.producer.resources.EntitiesRequestResource; +import org.odata4j.producer.resources.EntityRequestResource; +import org.odata4j.producer.resources.MetadataResource; +import org.odata4j.producer.resources.ODataBatchProvider; +import org.odata4j.producer.resources.ServiceDocumentResource; import org.teiid.adminapi.Admin.SchemaObjectType; import org.teiid.adminapi.Model.Type; import org.teiid.adminapi.impl.ModelMetaData; @@ -543,6 +551,11 @@ public void testProcedureCall() throws Exception { contentHandler.value = null; parser.parse(response.getEntity(), contentHandler); assertNotNull(contentHandler.value); + + request = new ClientRequest(TestPortProvider.generateURL("/odata/northwind/x/$count")); + response = request.get(String.class); + assertEquals(200, response.getStatus()); + assertEquals("2", response.getEntity()); } finally { es.stop(); } diff --git a/odata/src/test/java/org/teiid/odata/TestODataSQLStringVisitor.java b/odata/src/test/java/org/teiid/odata/TestODataSQLStringVisitor.java index 17b29fc081..f7e6729b4b 100644 --- a/odata/src/test/java/org/teiid/odata/TestODataSQLStringVisitor.java +++ b/odata/src/test/java/org/teiid/odata/TestODataSQLStringVisitor.java @@ -191,7 +191,7 @@ private void testSelectCountStar(String expected, String tableName, String filte TransformationMetadata metadata = RealMetadataFactory.example1(); ODataSQLBuilder visitor = new ODataSQLBuilder(metadata.getMetadataStore(), false); QueryInfo qi = buildQueryInfo(filter, select, orderby, top); - Query query = visitor.countStarString(tableName, qi); + Query query = visitor.selectString(tableName, qi, null, null, true); assertEquals(expected, query.toString()); // comma inserted by visitor } @@ -230,7 +230,7 @@ public void testBadSelect() throws Exception { @Test public void testSelectCount() throws Exception { testSelectCountStar( - "SELECT COUNT(*) FROM pm1.g1 WHERE (e1 >= 10) AND (e1 < 20)", + "SELECT COUNT(*) FROM pm1.g1 AS g0 WHERE (g0.e1 >= 10) AND (g0.e1 < 20)", "pm1.g1", "e1 ge 10 and e1 lt 20", "e1,x5", "e1 desc, e2", 10); }