diff options
| author | Andrew Johnson | 2019-11-12 13:32:17 +0000 |
|---|---|---|
| committer | Andrew Johnson | 2019-11-12 13:38:03 +0000 |
| commit | ef25b8ce2971dfc7dbb9ea934193345ff49fb1ad (patch) | |
| tree | 9d98d522d4c880d492628cc78d4d54578b65f648 | |
| parent | 82f921226970bfc8ae2348553bf93bc7d5134f04 (diff) | |
| download | org.eclipse.mat-ef25b8ce2971dfc7dbb9ea934193345ff49fb1ad.tar.gz org.eclipse.mat-ef25b8ce2971dfc7dbb9ea934193345ff49fb1ad.tar.xz org.eclipse.mat-ef25b8ce2971dfc7dbb9ea934193345ff49fb1ad.zip | |
552879: OQL enhancements for sub-selects, maps, context providers
Read sub-select as key/values pairs not arrays
more tests
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=552879
Change-Id: I65054a2eac3688c5c9e2b3f921b42abbb8c31697
5 files changed, 408 insertions, 122 deletions
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/collectionextract/IMapExtractor.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/collectionextract/IMapExtractor.java index 230cb9af..6708a2ce 100644 --- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/collectionextract/IMapExtractor.java +++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/collectionextract/IMapExtractor.java @@ -153,7 +153,7 @@ public interface IMapExtractor extends ICollectionExtractor public String toString() { - return getKey().getDisplayName()+ "=" +getValue().getDisplayName(); //$NON-NLS-1$ + return "" + getKey() + "=" + getValue(); //$NON-NLS-1$ //$NON-NLS-2$ } @Override diff --git a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/OQLQueryImpl.java b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/OQLQueryImpl.java index ccba4212..8eff4b3c 100644 --- a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/OQLQueryImpl.java +++ b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/OQLQueryImpl.java @@ -14,6 +14,7 @@ package org.eclipse.mat.parser.internal.oql; import java.io.StringReader;
import java.lang.reflect.Array;
import java.util.AbstractList;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -71,7 +72,7 @@ public class OQLQueryImpl implements IOQLQuery // result set implementations
// //////////////////////////////////////////////////////////////
- private interface CustomTableResultSet extends IOQLQuery.Result, IResultTable, List<Object>
+ private interface CustomTableResultSet extends IOQLQuery.Result, IResultTable, List<AbstractCustomTableResultSet.RowMap>
{}
/**
@@ -99,29 +100,119 @@ public class OQLQueryImpl implements IOQLQuery return newrows;
}
- private static abstract class AbstractCustomTableResultSet extends AbstractList<Object> implements CustomTableResultSet
+ private static abstract class AbstractCustomTableResultSet extends AbstractList<AbstractCustomTableResultSet.RowMap> implements CustomTableResultSet
{
- @Override
- public Object get(int index)
+ /**
+ * Holds a row from a sub-select with columns ready for a select.
+ */
+ private static class RowMap extends AbstractMap<String,Object>
{
- int cols = getColumns().length;
- if (cols == 1)
- return getColumnValue(getRow(index), 0);
- // Delay resolving columns until needed
- List<Object>l = new AbstractList<Object>() {
- @Override
- public Object get(int col)
+ IStructuredResult isr;
+ IResultTable irtb;
+ IResultTree irtr;
+ int index;
+ public RowMap(IStructuredResult irt, int index)
+ {
+ this.isr = irt;
+ if (isr instanceof IResultTable)
+ this.irtb = (IResultTable)irt;
+ if (isr instanceof IResultTree)
+ this.irtr = (IResultTree)irt;
+ this.index = index;
+ }
+
+ @Override
+ public int size()
+ {
+ return isr.getColumns().length;
+ }
+
+ @Override
+ public Object get(Object colname)
+ {
+ for (int col = 0; col < isr.getColumns().length; ++col)
{
- return getColumnValue(getRow(index), col);
+ if (isr.getColumns()[col].getLabel().equals(colname))
+ {
+ Object row;
+ if (irtb != null)
+ row = irtb.getRow(index);
+ else if (irtr != null)
+ row = irtr.getElements().get(index);
+ else
+ return null;
+ return isr.getColumnValue(row, col);
+ }
}
+ return null;
+ }
+
+ public int getObjectId()
+ {
+ IContextObject cx = isr.getContext(index);
+ if (cx != null)
+ return cx.getObjectId();
+ return -1;
+ }
- @Override
- public int size()
+ @Override
+ public Set<Entry<String, Object>> entrySet()
+ {
+ Set<Entry<String, Object>> set = new LinkedHashSet<Entry<String, Object>>();
+ for (int col = 0; col < isr.getColumns().length; ++col)
{
- return cols;
+ set.add(new SimpleEntry<String, Object>(isr.getColumns()[col].getLabel(), null) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 378783918135046563L;
+
+ final Object NULL_VALUE = new Object();
+
+ public Object getValue()
+ {
+ Object o = super.getValue();
+ if (o == NULL_VALUE)
+ return null;
+ else if (o != null)
+ return o;
+ o = get(getKey());
+ super.setValue(o);
+ return o;
+ }
+
+ public Object setValue(Object o)
+ {
+ throw new UnsupportedOperationException();
+ }
+ });
}
- };
- return l;
+ return Collections.unmodifiableSet(set);
+ }
+ }
+
+ /**
+ * Find the object ID of an IObject or a row backed by an IObject
+ * @param o
+ * @return
+ */
+ static int getObjectId(Object o)
+ {
+ if (o instanceof IObject)
+ return ((IObject)o).getObjectId();
+ //else if (o instanceof RowMap)
+ // return ((RowMap)o).getObjectId();
+ return -1;
+ }
+
+ @Override
+ public RowMap get(int index)
+ {
+ // Always return a map not a single item for consistency.
+ //if (false && getColumns().length == 1)
+ // return getColumnValue(getRow(index), 0);
+ // Delay resolving columns until needed
+ return new RowMap(this, index);
}
@Override
@@ -146,27 +237,20 @@ public class OQLQueryImpl implements IOQLQuery for (int ii = 0; ii < columns.length; ++ii)
{
// Find an example object for each column
- Object sample = getColumnValue(getRow(0), ii);
+ Object sample = getRowCount() > 0 ? getColumnValue(getRow(0), ii) : null;
// See if it is one or more objects from the dump
- if (sample instanceof IObject || sample instanceof Iterable<?> && ((Iterable<?>)sample).iterator().hasNext() && ((Iterable<?>)sample).iterator().next() instanceof IObject)
+ if (getObjectId(sample) != -1 || sample instanceof Iterable<?> && ((Iterable<?>)sample).iterator().hasNext() && getObjectId(((Iterable<?>)sample).iterator().next()) != -1)
{
// Also add the underlying row
if (prov == 0 && getContext(getRow(0)) != null)
{
String label;
FromClause fc = query.getFromClause();
- if (fc != null)
- {
- String alias = fc.getAlias();
- if (alias != null)
- label = alias;
- else
- label = fc.toString();
- }
+ String alias = fc.getAlias();
+ if (alias != null)
+ label = alias;
else
- {
- label = query.toString();
- }
+ label = fc.toString();
// Distinguish the select for all the columns
label = "SELECT ... " + label; //$NON-NLS-1$
builder.addContext(new ContextProvider(label) {
@@ -185,23 +269,23 @@ public class OQLQueryImpl implements IOQLQuery public IContextObject getContext(Object row)
{
Object o = getColumnValue(row, columnIndex);
- if (o instanceof IObject)
+ int objectId = getObjectId(o);
+ if (objectId != -1)
{
- IObject io = (IObject)o;
return new IContextObjectSet() {
@Override
public int getObjectId()
{
- return io.getObjectId();
+ return objectId;
}
@Override
public int[] getObjectIds()
{
- return new int[] {io.getObjectId()};
+ return new int[] {objectId};
}
@Override
@@ -221,7 +305,7 @@ public class OQLQueryImpl implements IOQLQuery if (selectId != -1)
return "SELECT "+column.toString()+" FROM OBJECTS " + selectId+alias2; //$NON-NLS-1$ //$NON-NLS-2$
}
- return OQL.forObjectId(getObjectId());
+ return OQL.forObjectId(objectId);
}
};
}
@@ -246,9 +330,10 @@ public class OQLQueryImpl implements IOQLQuery ArrayInt ai = new ArrayInt();
for (Object o : l)
{
- if (o instanceof IObject)
+ int objectId = AbstractCustomTableResultSet.getObjectId(o);
+ if (objectId != -1)
{
- ai.add(((IObject)o).getObjectId());
+ ai.add(objectId);
}
}
return ai.toArray();
@@ -322,7 +407,7 @@ public class OQLQueryImpl implements IOQLQuery try
{
for (int ii = 0; ii < columns.length; ii++)
- columns[ii] = buildColumn(selectList.get(ii), getColumnValue(getRow(0), ii));
+ columns[ii] = buildColumn(selectList.get(ii), getRowCount() > 0 ? getColumnValue(getRow(0), ii) : null);
}
catch (RuntimeException e)
{
@@ -378,13 +463,14 @@ public class OQLQueryImpl implements IOQLQuery if (!(objects[index] instanceof ValueHolder))
resolve(index);
- if (((ValueHolder) objects[index]).subject instanceof IObject)
+ int objectId = getObjectId(((ValueHolder) objects[index]).subject);
+ if (objectId != -1)
{
return new IContextObjectSet()
{
public int getObjectId()
{
- return ((IObject) ((ValueHolder) objects[index]).subject).getObjectId();
+ return objectId;
}
public int[] getObjectIds()
@@ -461,7 +547,7 @@ public class OQLQueryImpl implements IOQLQuery try
{
for (int ii = 0; ii < columns.length; ii++)
- columns[ii] = buildColumn(selectList.get(ii), getColumnValue(getRow(0), ii));
+ columns[ii] = buildColumn(selectList.get(ii), getRowCount() > 0 ? getColumnValue(getRow(0), ii) : null);
}
catch (RuntimeException e)
{
@@ -613,7 +699,7 @@ public class OQLQueryImpl implements IOQLQuery // Look in each table in case single columns have blanks
for (IResultTable tab : resultSets)
{
- Object o = tab.getColumnValue(tab.getRow(0), ii);
+ Object o = tab.getRowCount() > 0 ? tab.getColumnValue(tab.getRow(0), ii) : null;
if (o != null)
{
sample = o;
@@ -623,25 +709,18 @@ public class OQLQueryImpl implements IOQLQuery }
}
// See if it is one or more objects from the dump
- if (sample instanceof IObject || sample instanceof Iterable<?> && ((Iterable<?>)sample).iterator().hasNext() && ((Iterable<?>)sample).iterator().next() instanceof IObject)
+ if (getObjectId(sample) != -1 || sample instanceof Iterable<?> && ((Iterable<?>)sample).iterator().hasNext() && getObjectId(((Iterable<?>)sample).iterator().next()) != -1)
{
// Also add the underlying row
if (prov == 0 && sampleContext != null)
{
String label;
FromClause fc = queries.get(0).getFromClause();
- if (fc != null)
- {
- String alias = fc.getAlias();
- if (alias != null)
- label = alias;
- else
- label = fc.toString();
- }
+ String alias = fc.getAlias();
+ if (alias != null)
+ label = alias;
else
- {
- label = queries.get(0).toString();
- }
+ label = fc.toString();
// Distinguish the select for all the columns
label = "SELECT ... " + label; //$NON-NLS-1$
builder.addContext(new ContextProvider(label) {
@@ -660,22 +739,22 @@ public class OQLQueryImpl implements IOQLQuery public IContextObject getContext(Object row)
{
Object o = getColumnValue(row, columnIndex);
- if (o instanceof IObject)
+ int objectId = getObjectId(o);
+ if (objectId != -1)
{
- IObject io = (IObject)o;
return new IContextObjectSet() {
@Override
public int getObjectId()
{
- return io.getObjectId();
+ return objectId;
}
@Override
public int[] getObjectIds()
{
- return new int[] {io.getObjectId()};
+ return new int[] {objectId};
}
@Override
@@ -720,9 +799,10 @@ public class OQLQueryImpl implements IOQLQuery ArrayInt ai = new ArrayInt();
for (Object o : l)
{
- if (o instanceof IObject)
+ int objectId = UnionResultSet.getObjectId(o);
+ if (objectId != -1)
{
- ai.add(((IObject)o).getObjectId());
+ ai.add(objectId);
}
}
return ai.toArray();
@@ -1090,6 +1170,15 @@ public class OQLQueryImpl implements IOQLQuery unionIntResult = new IntArrayResult(intResult.size());
unionIntResult.addAll(intResult);
}
+ else
+ {
+ // Create a dummy result to hold the query for redisplay later
+ if (!(this.query.getSelectClause().getSelectList().isEmpty() || this.query.getSelectClause().isAsObjects()))
+ {
+ unionResultSet = new UnionResultSet();
+ unionResultSet.addResultSet(query, new ResultSet(getSelectQuery(), new int[0]));
+ }
+ }
for (Query q : query.getUnionQueries())
{
@@ -1132,9 +1221,17 @@ public class OQLQueryImpl implements IOQLQuery unionResultSet.addResultSet(q, (CustomTableResultSet) unionResult);
}
}
+ else
+ {
+ // Create a dummy result to hold the query for redisplay later
+ if (unionResultSet != null)
+ {
+ unionResultSet.addResultSet(q, new ResultSet(unionQuery, new int[0]));
+ }
+ }
}
- return unionResultSet != null ? unionResultSet : unionIntResult;
+ return unionResultSet != null ? (unionResultSet.getRowCount() > 0 ? unionResultSet : null) : unionIntResult;
}
private Object doSubQuery(IProgressListener monitor) throws SnapshotException
@@ -1142,12 +1239,45 @@ public class OQLQueryImpl implements IOQLQuery OQLQueryImpl subQuery = new OQLQueryImpl(this.ctx, query.getFromClause().getSubSelect());
Object result = subQuery.internalExecute(monitor);
- if (result instanceof IResultTable || result instanceof IResultTree)
+ if (query.getFromClause().includeObjects() && !query.getFromClause().includeSubClasses())
{
- if (query.getFromClause().includeObjects() && !query.getFromClause().includeSubClasses())
+ if (result == null)
+ {
+ return null;
+ }
+ else if (result instanceof Iterable)
+ {
+ List<Object> r = new ArrayList<Object>();
+
+ for (Object obj : (Iterable<?>) result)
+ {
+ if (accept(obj, monitor))
+ r.add(obj);
+ }
+
+ return r.isEmpty() ? null : select(r, monitor);
+ }
+ else if (result.getClass().isArray())
+ {
+ List<Object> r = new ArrayList<Object>();
+
+ int length = Array.getLength(result);
+ for (int ii = 0; ii < length; ii++)
+ {
+ Object obj = Array.get(result, ii);
+ if (accept(obj, monitor))
+ r.add(obj);
+ }
+ return r.isEmpty() ? null : select(r, monitor);
+ }
+ else if (result instanceof IResultTable || result instanceof IResultTree)
{
return filterAndSelect((IStructuredResult)result, monitor);
}
+ else if (!(result instanceof IntResult))
+ {
+ return accept(result, monitor) ? select(result, monitor) : null;
+ }
}
if (!(result instanceof IntResult))
@@ -1693,31 +1823,7 @@ public class OQLQueryImpl implements IOQLQuery {
if (listener.isCanceled())
throw new IProgressListener.OperationCanceledException();
- Object row = irt instanceof IResultTable ? ((IResultTable)irt).getRow(ii) : elements.get(ii);
- Object rowobj;
- // Should single select items be wrapped?
- if (colCount > 1)
- {
- // Delay resolving columns until needed
- List<Object>l = new AbstractList<Object>() {
- @Override
- public Object get(int index)
- {
- return irt.getColumnValue(row, index);
- }
-
- @Override
- public int size()
- {
- return colCount;
- }
- };
- rowobj = l;
- }
- else
- {
- rowobj = irt.getColumnValue(row, 0);
- }
+ Object rowobj = new AbstractCustomTableResultSet.RowMap(irt, ii);
// Don't use any context object for the select
//IContextObject ic = irt.getContext(row);
//IObject o = ctx.getSnapshot().getObject(ic.getObjectId());
diff --git a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/PathExpression.java b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/PathExpression.java index e93f6ebd..7fbced6f 100644 --- a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/PathExpression.java +++ b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/PathExpression.java @@ -1,5 +1,5 @@ /*******************************************************************************
- * Copyright (c) 2008, 2015 SAP AG and IBM Corporation.
+ * Copyright (c) 2008, 2019 SAP AG and IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,6 +19,7 @@ import java.util.AbstractList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.parser.internal.Messages;
@@ -117,16 +118,30 @@ class PathExpression extends Expression {
boolean didFindProperty = false;
- BeanInfo info = Introspector.getBeanInfo(current.getClass());
- PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
-
- for (PropertyDescriptor descriptor : descriptors)
+ if (!attribute.isNative())
{
- if (attribute.getName().equals(descriptor.getName()))
+ // Used for table rows from sub-select
+ if (current instanceof Map<?,?>)
{
- current = descriptor.getReadMethod().invoke(current, (Object[]) null);
+ Map<?,?> map = (Map<?,?>)current;
+ current = map.get(attribute.getName());
didFindProperty = true;
- break;
+ }
+ }
+
+ if (!didFindProperty)
+ {
+ BeanInfo info = Introspector.getBeanInfo(current.getClass());
+ PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
+
+ for (PropertyDescriptor descriptor : descriptors)
+ {
+ if (attribute.getName().equals(descriptor.getName()))
+ {
+ current = descriptor.getReadMethod().invoke(current, (Object[]) null);
+ didFindProperty = true;
+ break;
+ }
}
}
diff --git a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/QueryExpression.java b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/QueryExpression.java index 2f5c9ecf..037201ec 100644 --- a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/QueryExpression.java +++ b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/compiler/QueryExpression.java @@ -71,6 +71,14 @@ public class QueryExpression extends Expression if (fromExpression != null && fromExpression.isContextDependent(ctx))
return true;
+ Query subSelect = query.getFromClause().getSubSelect();
+ if (subSelect != null)
+ {
+ QueryExpression qe = new QueryExpression(subSelect);
+ if (qe.isContextDependent(ctx))
+ return true;
+ }
+
if (query.getUnionQueries() != null)
{
for (Query union : query.getUnionQueries())
diff --git a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/OQLTest.java b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/OQLTest.java index d4805c73..90efe974 100644 --- a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/OQLTest.java +++ b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/OQLTest.java @@ -129,6 +129,93 @@ public class OQLTest }
@Test
+ public void testDistinct1() throws SnapshotException
+ {
+ Object result = execute("select distinct objects classof(s) from java.lang.String s");
+ assertThat("'SELECT distinct objects' must return a result of type int[]", result, instanceOf(int[].class));
+ int[] objectIds = (int[]) result;
+ assertThat("1 object of type java.lang.Class expected", objectIds.length, equalTo(1));
+ }
+
+ @Test
+ public void testDistinct2() throws SnapshotException
+ {
+ Object result = execute("select distinct classof(s) from java.lang.String s");
+ assertThat("'SELECT distinct' must return a result of type IResultTable", result, instanceOf(IResultTable.class));
+ IResultTable resulttable = (IResultTable) result;
+ assertThat("1 object of type java.lang.Class expected", resulttable.getRowCount(), equalTo(1));
+ checkGetOQL(resulttable);
+ }
+
+
+ @Test
+ public void testDistinct3() throws SnapshotException
+ {
+ Object result = execute("SELECT DISTINCT z FROM OBJECTS ( SELECT classof(s) FROM java.lang.String s ) z");
+ assertThat("'SELECT distinct' must return a result of type IResultTable", result, instanceOf(IResultTable.class));
+ IResultTable resulttable = (IResultTable) result;
+ assertThat("1 object of type java.lang.Class expected", resulttable.getRowCount(), equalTo(1));
+ checkGetOQL(resulttable);
+ }
+
+ @Test
+ public void testOperations1int() throws SnapshotException
+ {
+ Object result = execute("select * from objects ((1+2+3--2-2)*-4/-3)");
+ assertEquals(8.0, result);
+ }
+
+ @Test
+ public void testOperations1long() throws SnapshotException
+ {
+ Object result = execute("select * from objects ((1L+2L+3L--2L-2L)*-4L/-3L)");
+ assertEquals(8.0, result);
+ }
+
+ @Test
+ public void testOperations1double() throws SnapshotException
+ {
+ Object result = execute("select * from objects ((1.0+2.0+3.0--2.0-2.0)*-4.0/-3.0)");
+ assertEquals(8.0, result);
+ }
+
+ @Test
+ public void testOperations2int() throws SnapshotException
+ {
+ Object result = execute("select * from objects (1=1 AND 3<2 OR 4>3 AND 4>=4 AND 4 <= 4 AND 4 < 5)");
+ assertEquals(true, result);
+ }
+
+
+ @Test
+ public void testOperations2long() throws SnapshotException
+ {
+ Object result = execute("select * from objects (1L=1L AND 3L<2L OR 4L>3L AND 4L>=4L AND 4L <= 4L AND 4L < 5L)");
+ assertEquals(true, result);
+ }
+
+
+ @Test
+ public void testOperations2double() throws SnapshotException
+ {
+ Object result = execute("select * from objects (1.0=1.0 AND 3.0<2.0 OR 4.0>3.0 AND 4.0>=4.0 AND 4.0 <= 4.0 AND 4.0 < 5.0)");
+ assertEquals(true, result);
+ }
+
+ @Test
+ public void testOperations2date() throws SnapshotException
+ {
+ Object result = execute("select * from objects (" +
+ "${snapshot}.@snapshotInfo.@creationDate < ${snapshot}.@snapshotInfo.@creationDate OR " +
+ "${snapshot}.@snapshotInfo.@creationDate > ${snapshot}.@snapshotInfo.@creationDate OR " +
+ "${snapshot}.@snapshotInfo.@creationDate != ${snapshot}.@snapshotInfo.@creationDate OR " +
+ "${snapshot}.@snapshotInfo.@creationDate = ${snapshot}.@snapshotInfo.@creationDate AND " +
+ "${snapshot}.@snapshotInfo.@creationDate <= ${snapshot}.@snapshotInfo.@creationDate AND " +
+ "${snapshot}.@snapshotInfo.@creationDate >= ${snapshot}.@snapshotInfo.@creationDate)");
+ assertEquals(true, result);
+ }
+
+ @Test
public void testUnion() throws SnapshotException
{
int[] objectIds = (int[]) execute("select * from objects 0 union (select * from objects 1)");
@@ -287,6 +374,42 @@ public class OQLTest }
@Test
+ public void testUnionCommand10() throws SnapshotException
+ {
+ String oql = "SELECT s FROM missing s UNION (SELECT s FROM missing s ) UNION (SELECT s FROM java.lang.String s )";
+ IOQLQuery.Result r = (IOQLQuery.Result)execute(oql);
+ assertEquals(oql, r.getOQLQuery());
+ assertEquals(492, ((IResultTable)r).getRowCount());
+ checkGetOQL((IResultTable)r);
+ }
+
+ @Test
+ public void testUnionCommand11() throws SnapshotException
+ {
+ String oql = "SELECT s FROM java.lang.String[] s UNION (SELECT s FROM missing s ) UNION (SELECT s FROM java.lang.String s )";
+ IOQLQuery.Result r = (IOQLQuery.Result)execute(oql);
+ assertEquals(oql, r.getOQLQuery());
+ assertEquals(28 + 492, ((IResultTable)r).getRowCount());
+ checkGetOQL((IResultTable)r);
+ }
+
+ @Test
+ public void testUnionCommand12() throws SnapshotException
+ {
+ String oql = "SELECT * FROM missing UNION (SELECT * FROM missing ) UNION (SELECT * FROM java.lang.String )";
+ int r[] = (int[])execute(oql);
+ assertEquals(492, r.length);
+ }
+
+ @Test
+ public void testUnionCommand13() throws SnapshotException
+ {
+ String oql = "SELECT * FROM java.lang.String[] UNION (SELECT * FROM missing ) UNION (SELECT * FROM java.lang.String )";
+ int r[] = (int[])execute(oql);
+ assertEquals(28 + 492, r.length);
+ }
+
+ @Test
public void testFromPattern() throws SnapshotException
{
Object result = execute("select * from \"java.lang.*\"");
@@ -386,7 +509,7 @@ public class OQLTest objectIds = (int[]) execute("SELECT * FROM java.lang.String s WHERE s.count > 1000 OR s.value.@length > 1000");
assert objectIds.length == 3;
}
-
+
/**
* Check reads of attributes declared in subclasses
* @throws SnapshotException
@@ -397,7 +520,7 @@ public class OQLTest int[] objectIds = (int[]) execute("select * from instanceof java.util.Vector s where s.elementCount < 10");
assertEquals("Expected to read ", 11, objectIds.length);
}
-
+
/**
* Check reads of statics declared in classes
* @throws SnapshotException
@@ -810,7 +933,7 @@ public class OQLTest int res[] = (int[])execute("SELECT OBJECTS s.@GCRoots[1:3] FROM OBJECTS ${snapshot} s");
assertEquals(3, res.length);
}
-
+
@Test
public void testJavaArrayRange3() throws SnapshotException
{
@@ -859,7 +982,7 @@ public class OQLTest assertEquals("ABC123", val);
checkGetOQL(res);
}
-
+
@Test
public void testOQLunion1() {
StringBuilder sb = new StringBuilder();
@@ -941,7 +1064,7 @@ public class OQLTest /**
* Complex test to check that the second and third FROM clause
- * is not reevaluated each time - otherwise this will take a long time.
+ * is not reevaluated each time - otherwise this will take a long time.
* @throws SnapshotException
*/
@Test
@@ -954,9 +1077,9 @@ public class OQLTest @Test
public void testComplex4() throws SnapshotException {
- IResultTable irt = (IResultTable)execute("SELECT s AS HashMap, eval((SELECT t, t.getKey(), t.getValue() "
+ IResultTable irt = (IResultTable)execute("SELECT s AS HashMap, eval((SELECT t, t.getKey(), t.getValue() as value "
+ "FROM OBJECTS ( s[0:-1] ) t "
- + "WHERE (toString(t.getKey()) = \"META-INF\")))[0][2] AS \"Value for META-INF\" "
+ + "WHERE (toString(t.getKey()) = \"META-INF\")))[0].value AS \"Value for META-INF\" "
+ "FROM java.util.HashMap s "
+ "WHERE "
+ "((SELECT t FROM OBJECTS ( s[0:-1] ) t "
@@ -971,7 +1094,7 @@ public class OQLTest @Test
public void testComplex5() throws SnapshotException {
- IResultTable irt = (IResultTable)execute("SELECT v[0], v[1][0].getKey(), v[0][0:-1], v[1] "
+ IResultTable irt = (IResultTable)execute("SELECT v.t, v.get(\"t[0:-1]\")[0].getKey(), v.t[0:-1], v.get(\"t[0:-1]\") "
+ "FROM OBJECTS ( "
+ "SELECT t, t[0:-1] "
+ "FROM java.util.HashSet t "
@@ -984,7 +1107,7 @@ public class OQLTest @Test
public void testComplex5a() throws SnapshotException {
- IResultTable irt = (IResultTable)execute("SELECT v[0], v[1][0].getKey(), v[0][0:-1], v[1] "
+ IResultTable irt = (IResultTable)execute("SELECT v.t, v.get(\"t[0:-1]\")[0].getKey(), v.t[0:-1], v.get(\"t[0:-1]\") "
+ "FROM OBJECTS ( "
+ "SELECT t, t[0:-1] "
+ "FROM java.util.HashSet t ) v");
@@ -1002,12 +1125,12 @@ public class OQLTest @Test
public void testComplex5c() throws SnapshotException {
- IResultTable irt = (IResultTable)execute("SELECT v[0], v[1][0].getKey(), v[0][0:-1], v[1] "
+ IResultTable irt = (IResultTable)execute("SELECT v.t, v.get(\"t[0:-1]\")[0].getKey(), v.t[0:-1], v.get(\"t[0:-1]\") "
+ "FROM OBJECTS ( "
+ "SELECT t, t[0:-1] "
+ "FROM java.util.HashSet t ) v "
+ "UNION ("
- + "SELECT v[0], v[1][0].getKey(), v[0][0:-1], v[1] "
+ + "SELECT v.t, v.get(\"t[0:-1]\")[0].getKey(), v.t[0:-1], v.get(\"t[0:-1]\") "
+ "FROM OBJECTS "
+ "( SELECT t, t[0:-1] FROM java.util.Hashtable t ) v )");
assertEquals(11, irt.getRowCount());
@@ -1042,8 +1165,31 @@ public class OQLTest checkGetOQL(irt);
}
+ @Test
+ public void testComplex7() throws SnapshotException {
+ Object result = execute("select * from OBJECTS (SELECT * FROM OBJECTS ( SELECT s.table, s.@usedHeapSize, s[0:-1], s.@objectId, s.@usedHeapSize FROM java.util.HashMap s WHERE (s.table != null) ) z)");
+ assertNotNull(result);
+ }
+
+ /**
+ * Check select item is reevaluated as sub-select is context dependent
+ * @throws SnapshotException
+ */
+ @Test
+ public void testComplex8() throws SnapshotException {
+ int r1[] = (int[])execute("SELECT OBJECTS ( SELECT OBJECTS q.getKey() AS k FROM OBJECTS ( t[0:-1] ) q ) FROM java.util.HashMap t");
+ int r2[] = (int[])execute("SELECT OBJECTS (SELECT * FROM OBJECTS ( SELECT OBJECTS q.getKey() AS k FROM OBJECTS ( t[0:-1] ) q ) ) FROM java.util.HashMap t");
+ assertEquals("Context dependent subselect", r1.length, r2.length);
+ }
+
+ /**
+ * Check all getOQL() from contexts from the result are sensible.
+ * @param rt ResultTable
+ * @throws SnapshotException
+ */
void checkGetOQL(IResultTable rt) throws SnapshotException
{
+ // Check the default contextx
for (int i = 0; i < rt.getRowCount(); ++i)
{
IContextObject c = rt.getContext(rt.getRow(i));
@@ -1057,23 +1203,27 @@ public class OQLTest }
}
}
+ // check the other providers
for (ContextProvider p : rt.getResultMetaData().getContextProviders())
{
String l = p.getLabel();
for (int j = 0; j < rt.getColumns().length; ++j) {
if (l.equals(rt.getColumns()[j].getLabel()))
{
+ // Now check each row
for (int i = 0; i < rt.getRowCount(); ++i)
{
Object o = rt.getColumnValue(rt.getRow(i), j);
if (o instanceof IObject)
{
+ // SimpleObject
IObject io = (IObject)o;
IContextObject c = p.getContext(rt.getRow(i));
checkSingleObjectContext(io.getObjectId(), c);
}
else if (o instanceof Iterable && ((Iterable<?>)o).iterator().hasNext() && ((Iterable<?>)o).iterator().next() instanceof IObject)
{
+ // Iterable, look for objects
List<IObject>os = new ArrayList<IObject>();
for (Object o1 : (Iterable)o)
{
@@ -1099,6 +1249,16 @@ public class OQLTest }
assertTrue(found);
}
+ for (int ri : r)
+ {
+ boolean found = false;
+ for (IObject o1 : os)
+ {
+ if (ri == o1.getObjectId())
+ found = true;
+ }
+ assertTrue(found);
+ }
}
else if (res instanceof IResultTable)
{
@@ -1122,6 +1282,10 @@ public class OQLTest {
assertTrue(os2.contains(ox));
}
+ for (IObject ox : os2)
+ {
+ assertTrue(os.contains(ox));
+ }
}
}
}
@@ -1145,15 +1309,9 @@ public class OQLTest {
int r[] = (int[])res;
assertEquals(os.length, r.length);
- for (int o1 : os)
+ for (int i = 0; i < os.length; ++i)
{
- boolean found = false;
- for (int ri : r)
- {
- if (ri == o1)
- found = true;
- }
- assertTrue(found);
+ assertEquals("index="+i, os[i], r[i]);
}
}
else if (res instanceof IResultTable)
@@ -1229,7 +1387,7 @@ public class OQLTest IResultTable rt2 = (IResultTable)res;
assertEquals(1, rt2.getRowCount());
assertEquals(rt.getColumns().length, rt2.getColumns().length);
- for (int j = 0; j < rt.getColumns().length; ++j)
+ for (int j = 0; j < rt.getColumns().length; ++j)
{
Object o1 = rt.getColumnValue(rt.getRow(row), j);
Object o2 = rt2.getColumnValue(rt2.getRow(0), j);
@@ -1238,7 +1396,6 @@ public class OQLTest }
}
-
/**
* Test that null objects from a from clause don't cause problems
*/
@@ -1248,7 +1405,7 @@ public class OQLTest + " WHERE ((SELECT t FROM OBJECTS ( s.threads[0:-1] ) t WHERE t.name.toString().startsWith(\"R\")) != null)");
assertEquals(1, res.length);
}
-
+
/**
* Test reading static fields of a class
* @throws SnapshotException
@@ -1264,7 +1421,7 @@ public class OQLTest assertThat("Integer.MAX_VALUE", val, equalTo(Integer.MAX_VALUE));
checkGetOQL(table);
}
-
+
/**
* Test extracting objects from a collection
* @throws SnapshotException
@@ -1275,7 +1432,7 @@ public class OQLTest int objs[] = (int[])execute("select objects s[0:-1] from java.util.ArrayList s");
assertThat("Multiple objects expected", objs.length, greaterThanOrEqualTo(2));
}
-
+
/**
* Test extracting objects from a collection.
* Check we can read the last element from a collection.
@@ -1287,7 +1444,7 @@ public class OQLTest int objs[] = (int[])execute("select objects s[0:-1][-1:-1][0] from java.util.ArrayList s");
assertThat("Multiple objects expected", objs.length, greaterThanOrEqualTo(2));
}
-
+
// //////////////////////////////////////////////////////////////
// internal helper
// //////////////////////////////////////////////////////////////
|
