diff options
| author | Andrew Johnson | 2019-11-28 11:28:37 +0000 |
|---|---|---|
| committer | Andrew Johnson | 2019-11-28 11:28:37 +0000 |
| commit | 6281f921952bbc2b7b2e250dace8271e7767c7b1 (patch) | |
| tree | e375427cb126843dab32d69017c53c2c7727e0a3 | |
| parent | b483e85d3c58fc1c07ff4c523c58e7a1d79a0e81 (diff) | |
| download | org.eclipse.mat-6281f921952bbc2b7b2e250dace8271e7767c7b1.tar.gz org.eclipse.mat-6281f921952bbc2b7b2e250dace8271e7767c7b1.tar.xz org.eclipse.mat-6281f921952bbc2b7b2e250dace8271e7767c7b1.zip | |
552879: OQL enhancements for sub-selects, maps, context providers
Improve getOQL for context menus
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=552879
Change-Id: If11978dce7878ccb4d2b82c6e409787a7af279aa
4 files changed, 489 insertions, 84 deletions
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/snapshot/OQL.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/snapshot/OQL.java index 2552dc2f..65513ac5 100644 --- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/snapshot/OQL.java +++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/snapshot/OQL.java @@ -167,7 +167,7 @@ public final class OQL int end = query.length();
while (query.charAt(end - 1) == ')')
{
- int start = query.lastIndexOf(" UNION ("); //$NON-NLS-1$
+ int start = query.lastIndexOf(" UNION (", end - 1); //$NON-NLS-1$
if (start == -1)
break;
if (union(query, start + 8, end - 1, other))
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 1243cb98..a88d73bd 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 @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
@@ -102,6 +103,10 @@ public class OQLQueryImpl implements IOQLQuery return newrows;
}
+ /**
+ * A table holding the result of a query.
+ *
+ */
private static abstract class AbstractCustomTableResultSet extends AbstractList<AbstractCustomTableResultSet.RowMap> implements CustomTableResultSet
{
/**
@@ -113,14 +118,20 @@ public class OQLQueryImpl implements IOQLQuery IResultTable irtb;
IResultTree irtr;
int index;
+ int subindex;
public RowMap(IStructuredResult irt, int index)
{
+ this(irt, index, -1);
+ }
+ public RowMap(IStructuredResult irt, int index, int subindex)
+ {
this.isr = irt;
if (isr instanceof IResultTable)
this.irtb = (IResultTable)irt;
if (isr instanceof IResultTree)
this.irtr = (IResultTree)irt;
this.index = index;
+ this.subindex = subindex;
}
@Override
@@ -308,7 +319,23 @@ public class OQLQueryImpl implements IOQLQuery {
Object o = getColumnValue(row, columnIndex);
int objectId = getObjectId(o);
- if (objectId != -1)
+ boolean goodContext = false;
+ if (objectId == -1 && !(o instanceof Iterable<?> || o instanceof int[]))
+ {
+ IContextObject cx = AbstractCustomTableResultSet.this.getContext(row);
+ if (cx != null)
+ {
+ int selectId = cx.getObjectId();
+ if (selectId != -1)
+ goodContext = true;
+ else if (cx instanceof IContextObjectSet)
+ {
+ if (((IContextObjectSet)cx).getOQL() != null)
+ goodContext = true;
+ }
+ }
+ }
+ if (objectId != -1 || goodContext)
{
return new IContextObjectSet() {
@@ -322,8 +349,10 @@ public class OQLQueryImpl implements IOQLQuery @Override
public int[] getObjectIds()
{
-
- return new int[] {objectId};
+ if (objectId != -1)
+ return new int[] {objectId};
+ else
+ return new int[0];
}
@Override
@@ -341,9 +370,30 @@ public class OQLQueryImpl implements IOQLQuery {
int selectId = cx.getObjectId();
if (selectId != -1)
- return "SELECT "+column.toString()+" FROM OBJECTS " + selectId+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ return "SELECT " + column.toString() + " FROM OBJECTS " + selectId + alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ else if (cx instanceof IContextObjectSet)
+ {
+ IContextObjectSet cs = (IContextObjectSet)cx;
+ String oqlsource = cs.getOQL();
+ if (oqlsource != null)
+ {
+ try
+ {
+ OQLQueryImpl q2 = new OQLQueryImpl(oqlsource);
+ q2.query.getSelectClause().setSelectList(Collections.emptyList());
+ String oqlsource2 = q2.query.toString();
+ return "SELECT "+column.toString()+" FROM OBJECTS (" + oqlsource2+") "+alias2; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ catch (OQLParseException e)
+ {
+ }
+ }
+ }
}
- return OQL.forObjectId(objectId);
+ if (objectId != -1)
+ return OQL.forObjectId(objectId);
+ else
+ return OQLforSubject("*", o, ""); //$NON-NLS-1$ //$NON-NLS-2$
}
};
}
@@ -401,7 +451,29 @@ public class OQLQueryImpl implements IOQLQuery Query.SelectItem column = query.getSelectClause().getSelectList().get(columnIndex);
int selectId = getObjectId();
if (selectId != -1)
- return "SELECT "+column.toString()+" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ return "SELECT "+column.toString()+" FROM OBJECTS " + selectId + alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ else
+ {
+ IContextObject cx = AbstractCustomTableResultSet.this.getContext(row);
+ if (cx instanceof IContextObjectSet)
+ {
+ IContextObjectSet cs = (IContextObjectSet)cx;
+ String oqlsource = cs.getOQL();
+ if (oqlsource != null)
+ {
+ try
+ {
+ OQLQueryImpl q2 = new OQLQueryImpl(oqlsource);
+ q2.query.getSelectClause().setSelectList(Collections.emptyList());
+ String oqlsource2 = q2.query.toString();
+ return "SELECT " + column.toString() + " FROM OBJECTS (" + oqlsource2 + ") " + alias2; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ catch (OQLParseException e)
+ {
+ }
+ }
+ }
+ }
return OQL.forObjectIds(getObjectIds());
}
};
@@ -443,7 +515,8 @@ public class OQLQueryImpl implements IOQLQuery }
/**
- * Result from a select with select list where the from clause returned a list or array of objects.
+ * Result from a select with select list where the from clause returned a list or array of non-heap objects.
+ * Each row is backed by a non-heap object.
*/
private static class ObjectResultSet extends AbstractCustomTableResultSet implements CustomTableResultSet
{
@@ -539,9 +612,17 @@ public class OQLQueryImpl implements IOQLQuery if (!(objects[index] instanceof ValueHolder))
resolve(index);
- int objectId = getObjectId(((ValueHolder) objects[index]).subject);
- if (objectId != -1)
+ Object subject = ((ValueHolder) objects[index]).subject;
+ int objectId = getObjectId(subject);
+ if (objectId != -1 || subject == null || subject instanceof Character || subject instanceof Integer
+ || subject instanceof Long || subject instanceof Float || subject instanceof Double
+ || subject instanceof Boolean || subject instanceof String || subject instanceof AbstractCustomTableResultSet.RowMap)
{
+ if (objectId == -1)
+ {
+ if (OQLforSubject("*", subject, "") == null) //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
return new IContextObjectSet()
{
public int getObjectId()
@@ -551,7 +632,10 @@ public class OQLQueryImpl implements IOQLQuery public int[] getObjectIds()
{
- return new int[] {getObjectId()};
+ if (getObjectId() != -1)
+ return new int[] {getObjectId()};
+ else
+ return new int[0];
}
public String getOQL()
@@ -571,7 +655,17 @@ public class OQLQueryImpl implements IOQLQuery sc2.setSelectList(sc.getSelectList());
sc = sc2;
}
- return "SELECT "+sc.toString() +" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+
+ String from;
+ if (getObjectId() != -1)
+ from = String.valueOf(getObjectId());
+ else
+ {
+ // OQL literals (not Byte or Short)
+ String oql = OQLforSubject("*", subject, alias2); //$NON-NLS-1$
+ from = "(" + oql + ")";//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return "SELECT "+sc.toString() +" FROM OBJECTS " + from + alias2; //$NON-NLS-1$ //$NON-NLS-2$
}
};
}
@@ -600,6 +694,7 @@ public class OQLQueryImpl implements IOQLQuery /**
* Result from a select with select list where the from clause returned an array of object IDs.
+ * Each row is backed by a heap object, so will appear in the inspector view.
*/
private static class ResultSet extends AbstractCustomTableResultSet implements CustomTableResultSet
{
@@ -717,7 +812,7 @@ public class OQLQueryImpl implements IOQLQuery sc2.setSelectList(sc.getSelectList());
sc = sc2;
}
- return "SELECT "+sc.toString() +" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ return "SELECT " + sc.toString() + " FROM OBJECTS " + getObjectId() + alias2; //$NON-NLS-1$ //$NON-NLS-2$
}
};
}
@@ -748,6 +843,78 @@ public class OQLQueryImpl implements IOQLQuery return new Column(name, type).noTotals();
}
+ public static String OQLLiteral(Object subject)
+ {
+ // OQL literals (not Byte or Short)
+ if (subject instanceof Character)
+ return "'" + subject + "'"; //$NON-NLS-1$ //$NON-NLS-2$
+ else if (subject instanceof String)
+ return "\"" + subject + "\""; //$NON-NLS-1$ //$NON-NLS-2$
+ else if (subject instanceof Boolean || subject instanceof Integer
+ || subject instanceof Float || subject instanceof Double || subject == null)
+ return String.valueOf(subject);
+ else if (subject instanceof Long)
+ return Long.toHexString((Long) subject) + "L)"; //$NON-NLS-1$
+ else if (subject instanceof IObject)
+ return "${snapshot}.getObject(" + Integer.toString(((IObject) subject).getObjectId()) + ")"; //$NON-NLS-1$//$NON-NLS-2$
+ else
+ return null;
+ }
+
+ public static String OQLforSubject(String select, Object subject, String alias)
+ {
+ String from;
+ // OQL literals (not Byte or Short)
+ String literal = OQLLiteral(subject);
+ if (literal != null)
+ from = "(" + literal + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ else if (subject instanceof AbstractCustomTableResultSet.RowMap)
+ {
+ AbstractCustomTableResultSet.RowMap rm = ( AbstractCustomTableResultSet.RowMap)subject;
+ StringBuilder buf = new StringBuilder();
+ for (Map.Entry<String,Object> e : rm.entrySet())
+ {
+ Object val = e.getValue();
+ String v1;
+ if (val == null)
+ {
+ // "null" doesn't work
+ v1 = "toString(\"\").toCharArray()[0:-1]"; //$NON-NLS-1$
+ }
+ else
+ {
+ v1 = OQLLiteral(val);
+ }
+ if (v1 == null)
+ {
+ v1 = OQLforSubject("*", val, ""); //$NON-NLS-1$ //$NON-NLS-2$
+ if (v1 == null)
+ return null;
+ v1 = "(" + v1 + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (buf.length() == 0)
+ buf.append("SELECT "); //$NON-NLS-1$
+ else
+ buf.append(", "); //$NON-NLS-1$
+ buf.append(v1).append(" AS "); //$NON-NLS-1$
+ String name = e.getKey();
+ boolean quote = !name.matches("[A-Za-z$_][A-Za-z0-9$_]*"); //$NON-NLS-1$
+ if (quote)
+ buf.append('"');
+ buf.append(name);
+ if (quote)
+ buf.append('"');
+ }
+ buf.append(" FROM OBJECTS (null)").append(alias); //$NON-NLS-1$
+ from = buf.toString();
+ if (select.equals("*")) //$NON-NLS-1$
+ return from;
+ }
+ else
+ return null;
+ return "SELECT " + select + " FROM OBJECTS " + from + alias; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
private static class UnionResultSet extends AbstractCustomTableResultSet implements Result, IResultTable
{
private static class ValueHolder
@@ -844,7 +1011,23 @@ public class OQLQueryImpl implements IOQLQuery {
Object o = getColumnValue(row, columnIndex);
int objectId = getObjectId(o);
- if (objectId != -1)
+ boolean goodContext = false;
+ if (objectId == -1 && !(o instanceof Iterable<?> || o instanceof int[]))
+ {
+ IContextObject cx = UnionResultSet.this.getContext(row);
+ if (cx != null)
+ {
+ int selectId = cx.getObjectId();
+ if (selectId != -1)
+ goodContext = true;
+ else if (cx instanceof IContextObjectSet)
+ {
+ if (((IContextObjectSet)cx).getOQL() != null)
+ goodContext = true;
+ }
+ }
+ }
+ if (objectId != -1 || goodContext)
{
return new IContextObjectSet() {
@@ -857,8 +1040,10 @@ public class OQLQueryImpl implements IOQLQuery @Override
public int[] getObjectIds()
{
-
- return new int[] {objectId};
+ if (objectId != -1)
+ return new int[] {objectId};
+ else
+ return new int[0];
}
@Override
@@ -877,14 +1062,34 @@ public class OQLQueryImpl implements IOQLQuery int selectId = cx.getObjectId();
if (selectId != -1)
return "SELECT "+column.toString()+" FROM OBJECTS " + selectId+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ else if (cx instanceof IContextObjectSet)
+ {
+ IContextObjectSet cs = (IContextObjectSet)cx;
+ String oqlsource = cs.getOQL();
+ if (oqlsource != null)
+ {
+ try
+ {
+ OQLQueryImpl q2 = new OQLQueryImpl(oqlsource);
+ q2.query.getSelectClause().setSelectList(Collections.emptyList());
+ String oqlsource2 = q2.query.toString();
+ return "SELECT "+column.toString()+" FROM OBJECTS (" + oqlsource2+") "+alias2; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ catch (OQLParseException e)
+ {
+ }
+ }
+ }
}
- return OQL.forObjectId(getObjectId());
+ if (objectId != -1)
+ return OQL.forObjectId(objectId);
+ else
+ return OQLforSubject("*", o, ""); //$NON-NLS-1$ //$NON-NLS-2$
}
};
}
else if (o instanceof Iterable<?> || o instanceof int[])
{
- Iterable<?>l = (Iterable<?>)o;
return new IContextObjectSet() {
@Override
@@ -910,12 +1115,16 @@ public class OQLQueryImpl implements IOQLQuery return (int[])o;
}
ArrayInt ai = new ArrayInt();
- for (Object o : l)
+ if (o instanceof Iterable<?>)
{
- int objectId = UnionResultSet.getObjectId(o);
- if (objectId != -1)
+ Iterable<?>l = (Iterable<?>)o;
+ for (Object o : l)
{
- ai.add(objectId);
+ int objectId = UnionResultSet.getObjectId(o);
+ if (objectId != -1)
+ {
+ ai.add(objectId);
+ }
}
}
return ai.toArray();
@@ -934,6 +1143,28 @@ public class OQLQueryImpl implements IOQLQuery int selectId = getObjectId();
if (selectId != -1)
return "SELECT "+column.toString()+" FROM OBJECTS " + selectId+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ else
+ {
+ IContextObject cx = UnionResultSet.this.getContext(row);
+ if (cx instanceof IContextObjectSet)
+ {
+ IContextObjectSet cs = (IContextObjectSet)cx;
+ String oqlsource = cs.getOQL();
+ if (oqlsource != null)
+ {
+ try
+ {
+ OQLQueryImpl q2 = new OQLQueryImpl(oqlsource);
+ q2.query.getSelectClause().setSelectList(Collections.emptyList());
+ String oqlsource2 = q2.query.toString();
+ return "SELECT " + column.toString() + " FROM OBJECTS (" + oqlsource2 + ") " + alias2; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ catch (OQLParseException e)
+ {
+ }
+ }
+ }
+ }
return OQL.forObjectIds(getObjectIds());
}
};
@@ -2045,7 +2276,7 @@ public class OQLQueryImpl implements IOQLQuery for (int i = 0; i < maxlen; ++i)
{
int ix = i;
- AbstractCustomTableResultSet.RowMap rm2 = new AbstractCustomTableResultSet.RowMap(result, rowobj.index) {
+ AbstractCustomTableResultSet.RowMap rm2 = new AbstractCustomTableResultSet.RowMap(result, rowobj.index, i) {
public Object get(Object key)
{
Object v = rowobj.get(key);
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 c1abb3f6..963319ca 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 @@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -33,6 +34,8 @@ import java.util.List; import java.util.Set;
import org.eclipse.mat.SnapshotException;
+import org.eclipse.mat.collect.ArrayInt;
+import org.eclipse.mat.collect.IteratorInt;
import org.eclipse.mat.query.ContextProvider;
import org.eclipse.mat.query.IContextObject;
import org.eclipse.mat.query.IContextObjectSet;
@@ -1135,6 +1138,22 @@ public class OQLTest assertEquals("select s from 1,2,3 s UNION (select t from 17,23 t)", sb.toString());
}
+ @Test
+ public void testOQLunion7() throws SnapshotException {
+ String dump = TestSnapshots.SUN_JDK6_18_32BIT;
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT a.t.s.value FROM OBJECTS (SELECT * FROM OBJECTS ( SELECT (SELECT ${snapshot}.getObject(2839) AS s FROM OBJECTS ( null ) ) AS t FROM OBJECTS ( null ) a ) a ) a");
+ OQL.union(sb, "SELECT a.t.s.value FROM OBJECTS (SELECT * FROM OBJECTS ( SELECT (SELECT ${snapshot}.getObject(2896) AS s FROM OBJECTS ( null ) ) AS t FROM OBJECTS ( null ) a ) a ) a");
+ OQL.union(sb, "SELECT a.t.s.value FROM OBJECTS (SELECT * FROM OBJECTS ( SELECT (SELECT ${snapshot}.getObject(2796) AS s FROM OBJECTS ( null ) ) AS t FROM OBJECTS ( null ) a ) a ) a");
+ String s1 = sb.toString();
+ assertThat(s1, containsString("2839"));
+ assertThat(s1, containsString("2896"));
+ assertThat(s1, containsString("2796"));
+ IResultTable irt = (IResultTable)execute(s1, dump);
+ assertThat(irt.getRowCount(), equalTo(3));
+ checkGetOQL(irt, dump);
+ }
+
/**
* Complex test to check that the second FROM clause is reevaluated.
* @throws SnapshotException
@@ -1306,23 +1325,117 @@ public class OQLTest }
@Test
+ public void testComplex11() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT 'c', \"String\", 1, 1234567890123456789L, 1.23456, 1.23456F, 1.23456789, 1.23456789D, true, false, null FROM OBJECTS 0");
+ assertThat(irt.getRowCount(), equalTo(1));
+ assertThat(irt.getColumns().length, equalTo(11));
+ Object row = irt.getRow(0);
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testComplex12() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT 'c' as a, \"String\" as b, 1 as c, 1234567890123456789L as d, 1.23456 as e, 1.23456F as f, 1.23456789 as g, 1.23456789D as h, true as i, false as j, null as k FROM OBJECTS 0");
+ assertThat(irt.getRowCount(), equalTo(1));
+ assertThat(irt.getColumns().length, equalTo(11));
+ Object row = irt.getRow(0);
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testComplex13() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT z.a,z.b,z.c,z.d,z.e,z.f,z.g,z.h,z.i,z.j,z.k FROM OBJECTS ("
+ + "SELECT 'c' as a, \"String\" as b, 1 as c, 1234567890123456789L as d, 1.23456 as e, 1.23456F as f, 1.23456789 as g, 1.23456789D as h, true as i, false as j, null as k FROM OBJECTS 0"
+ + ") z");
+ assertThat(irt.getRowCount(), equalTo(1));
+ assertThat(irt.getColumns().length, equalTo(11));
+ Object row = irt.getRow(0);
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testComplex14() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT "
+ + "(SELECT * FROM OBJECTS ('c')) as a, "
+ + "(SELECT * FROM OBJECTS (\"String\")) as b, "
+ + "(SELECT * FROM OBJECTS (1)) as c, "
+ + "(SELECT * FROM OBJECTS (1234567890123456789L)) as d, "
+ + "(SELECT * FROM OBJECTS (1.23456)) as e, "
+ + "(SELECT * FROM OBJECTS (1.23456F)) as f, "
+ + "(SELECT * FROM OBJECTS (1.23456789)) as g, "
+ + "(SELECT * FROM OBJECTS (1.23456789D)) as h, "
+ + "(SELECT * FROM OBJECTS (true)) as i, "
+ + "(SELECT * FROM OBJECTS (false)) as j, "
+ + "(SELECT * FROM OBJECTS (null)) as k"
+ + " FROM OBJECTS 0");
+ assertThat(irt.getRowCount(), equalTo(1));
+ assertThat(irt.getColumns().length, equalTo(11));
+ Object row = irt.getRow(0);
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testComplex15() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT a.t.s.value, a, outbounds(a.t.s.value) "
+ + "FROM OBJECTS ( "
+ + "SELECT "
+ + "(SELECT s FROM java.lang.String s ) AS t "
+ + "FROM OBJECTS ( \"A\" ) ) a");
+ assertThat(irt.getColumns().length, equalTo(3));
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testComplex16() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT a.t.s.value, a, outbounds(a.t.s.value) "
+ + "FROM OBJECTS ( "
+ + "SELECT "
+ + "(SELECT s FROM java.lang.String s ) AS t "
+ + "FROM OBJECTS ( \"A\" ) ) a "
+ + "UNION ("
+ + "SELECT a.t.s.value, a, outbounds(a.t.s.value) "
+ + "FROM OBJECTS ( "
+ + "SELECT "
+ + "(SELECT s FROM java.lang.String s ) AS t "
+ + "FROM OBJECTS ( \"A\" ) ) a )");
+ assertThat(irt.getColumns().length, equalTo(3));
+ checkGetOQL(irt);
+ }
+
+ /**
+ * check a column holding objects and ints
+ */
+ @Test
+ public void testComplex17() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT v, v.i.value FROM OBJECTS ( SELECT i FROM java.lang.String i UNION ( SELECT i FROM java.lang.Integer i ) ) v");
+ assertThat(irt.getColumns().length, equalTo(2));
+ checkGetOQL(irt);
+ }
+
+ /**
+ * Cross Join.
+ * Integer and Boolean
+ * takes too long with Integer and Long
+ * @throws SnapshotException
+ */
+ @Test
public void testCrossJoin() throws SnapshotException {
String dump = TestSnapshots.SUN_JDK6_18_32BIT;
int ints[] = (int[])execute("SELECT * from java.lang.Integer", dump);
assertNotNull(ints);
- int longs[] = (int[])execute("SELECT * from java.lang.Long", dump);
- assertNotNull(longs);
- IResultTable irt = (IResultTable)execute("SELECT z.i AS Integer, z.i.value AS \"Integer value\", z.lv.l AS Long, z.lv.l.value as \"Long value\" \r\n" +
- "FROM OBJECTS ( SELECT i, (SELECT l FROM java.lang.Long l ) AS lv FROM java.lang.Integer i ) z", dump);
- assertThat(irt.getRowCount(), equalTo(ints.length * longs.length));
+ int bools[] = (int[])execute("SELECT * from java.lang.Boolean", dump);
+ assertNotNull(bools);
+ IResultTable irt = (IResultTable)execute("SELECT z.i AS Integer, z.i.value AS \"Integer value\", z.lv.l AS Boolean, z.lv.l.value as \"Boolean value\" \r\n" +
+ "FROM OBJECTS ( SELECT i, (SELECT l FROM java.lang.Boolean l ) AS lv FROM java.lang.Integer i ) z", dump);
+ assertThat(irt.getRowCount(), equalTo(ints.length * bools.length));
for (int i = 0; i < irt.getRowCount(); ++i) {
Object row = irt.getRow(i);
Object iv1 = irt.getColumnValue(row, 1);
assertThat(iv1, instanceOf(Integer.class));
Object iv2 = irt.getColumnValue(row, 3);
- assertThat(iv2, instanceOf(Long.class));
+ assertThat(iv2, instanceOf(Boolean.class));
}
- checkGetOQL(irt);
+ checkGetOQL(irt, dump);
}
@Test
@@ -1344,7 +1457,7 @@ public class OQLTest if (iv2 != null)
assertThat((long)(Integer)iv1, equalTo(iv2));
}
- checkGetOQL(irt);
+ checkGetOQL(irt, dump);
}
@Test
@@ -1366,7 +1479,7 @@ public class OQLTest assertThat(iv2, instanceOf(Long.class));
assertThat((long)(Integer)iv1, equalTo(iv2));
}
- checkGetOQL(irt);
+ checkGetOQL(irt, dump);
}
@Test
@@ -1388,7 +1501,7 @@ public class OQLTest assertThat(iv2, instanceOf(Long.class));
assertThat((long)(Integer)iv1, equalTo(iv2));
}
- checkGetOQL(irt);
+ checkGetOQL(irt, dump);
}
@Test
@@ -1410,7 +1523,7 @@ public class OQLTest if (iv1 != null)
assertThat((long)(Integer)iv1, equalTo(iv2));
}
- checkGetOQL(irt);
+ checkGetOQL(irt, dump);
}
@Test
@@ -1437,7 +1550,7 @@ public class OQLTest if (iv1 != null && iv2 != null)
assertThat((long)(Integer)iv1, equalTo(iv2));
}
- checkGetOQL(irt);
+ checkGetOQL(irt, dump);
}
/**
@@ -1447,17 +1560,28 @@ public class OQLTest */
void checkGetOQL(IResultTable rt) throws SnapshotException
{
+ checkGetOQL(rt, TestSnapshots.SUN_JDK5_64BIT);
+ }
+
+ /**
+ * Check all getOQL() from contexts from the result are sensible.
+ * @param rt ResultTable
+ * @param dump the snapshot to test against
+ * @throws SnapshotException
+ */
+ void checkGetOQL(IResultTable rt, String dump) throws SnapshotException
+ {
// Check the default contextx
for (int i = 0; i < rt.getRowCount(); ++i)
{
IContextObject c = rt.getContext(rt.getRow(i));
- checkDefaultContext(rt, i, c);
+ checkDefaultContext(rt, i, c, dump);
for (ContextProvider p : rt.getResultMetaData().getContextProviders())
{
if (p.getLabel().startsWith("SELECT ... ")) {
// Default provider as metadata provider
c = p.getContext(rt.getRow(i));
- checkDefaultContext(rt, i, c);
+ checkDefaultContext(rt, i, c, dump);
}
}
}
@@ -1477,72 +1601,107 @@ public class OQLTest // SimpleObject
IObject io = (IObject)o;
IContextObject c = p.getContext(rt.getRow(i));
- checkSingleObjectContext(io.getObjectId(), c);
+ checkSingleObjectContext(io.getObjectId(), c, dump);
}
- else if (o instanceof Iterable && ((Iterable<?>)o).iterator().hasNext() && ((Iterable<?>)o).iterator().next() instanceof IObject)
+ else if (o instanceof Iterable && ((Iterable<?>)o).iterator().hasNext() && ((Iterable<?>)o).iterator().next() instanceof IObject || o instanceof int[])
{
// Iterable, look for objects
- List<IObject>os = new ArrayList<IObject>();
- for (Object o1 : (Iterable)o)
+ List<IObject> os = new ArrayList<IObject>();
+ ArrayInt ai = new ArrayInt();
+ if (o instanceof Iterable<?>)
{
- if (o1 instanceof IObject)
- os.add((IObject)o1);
+ for (Object o1 : (Iterable<?>)o)
+ {
+ if (o1 instanceof IObject)
+ {
+ ai.add(((IObject)o1).getObjectId());
+ os.add((IObject)o1);
+ }
+ }
+ }
+ else
+ {
+ int oa[] = (int[])o;
+ for (int o1 : oa)
+ {
+ ai.add(o1);
+ }
}
IContextObject c = p.getContext(rt.getRow(i));
- assertTrue(c instanceof IContextObjectSet);
+ assertThat("row="+i+" col="+j, c, instanceOf(IContextObjectSet.class));
IContextObjectSet cs = (IContextObjectSet)c;
+ int []csobjs = cs.getObjectIds();
+ assertThat("row="+i+" col="+j, csobjs, equalTo(ai.toArray()));
String oql = cs.getOQL();
- Object res = execute(oql);
+ Object res = execute(oql, dump);
if (res instanceof int[])
{
int r[] = (int[])res;
- assertEquals(os.size(), r.length);
- for (IObject o1 : os)
+ assertEquals("row="+i+" col="+j, ai.size(), r.length);
+ for (IteratorInt it = ai.iterator(); it.hasNext(); )
{
+ int o1 = it.next();
boolean found = false;
for (int ri : r)
{
- if (ri == o1.getObjectId())
+ if (ri == o1)
found = true;
}
- assertTrue(found);
+ assertTrue("row="+i+" col="+j, found);
}
for (int ri : r)
{
boolean found = false;
- for (IObject o1 : os)
+ for (IteratorInt it = ai.iterator(); it.hasNext(); )
{
- if (ri == o1.getObjectId())
+ int o1 = it.next();
+ if (ri == o1)
found = true;
}
- assertTrue(found);
+ assertTrue("row="+i+" col="+j, found);
}
}
else if (res instanceof IResultTable)
{
IResultTable rt2 = (IResultTable)res;
- assertEquals(1, rt2.getRowCount());
- assertEquals(1, rt2.getColumns().length);
+ assertEquals("row="+i+" col="+j, 1, rt2.getRowCount());
+ assertEquals("row="+i+" col="+j, 1, rt2.getColumns().length);
List<IObject>os2 = new ArrayList<IObject>();
+ ArrayInt ai2 = new ArrayInt();
for (int r = 0; r < rt2.getRowCount(); ++r)
{
Object o2 = rt2.getColumnValue(rt2.getRow(r), 0);
- assertTrue(""+o2, o2 instanceof Iterable);
- for (Object o3 : (Iterable)o2)
+ if (o2 instanceof int[])
+ {
+ ai2.addAll((int[])o2);
+ }
+ else
{
- assertTrue(""+o3, o3 instanceof IObject);
- IObject io2 = (IObject)o3;
- assertTrue(os.contains(io2));
- os2.add(io2);
+ assertThat(o2, instanceOf(Iterable.class));
+ for (Object o3 : (Iterable<?>)o2)
+ {
+ assertThat(o3, instanceOf(IObject.class));
+ IObject io2 = (IObject)o3;
+ assertTrue("row="+i+" col="+j, os.contains(io2));
+ os2.add(io2);
+ ai2.add(io2.getObjectId());
+ }
}
}
- for (IObject ox : os)
+ if (ai2.isEmpty())
{
- assertTrue(os2.contains(ox));
+ for (IObject ox : os)
+ {
+ assertTrue(os2.contains(ox));
+ }
+ for (IObject ox : os2)
+ {
+ assertTrue(os.contains(ox));
+ }
}
- for (IObject ox : os2)
+ else
{
- assertTrue(os.contains(ox));
+ assertThat(ai.toArray(), equalTo(ai2.toArray()));
}
}
}
@@ -1552,17 +1711,17 @@ public class OQLTest }
}
- private void checkDefaultContext(IResultTable rt, int row, IContextObject c) throws SnapshotException
+ private void checkDefaultContext(IResultTable rt, int row, IContextObject c, String dump) throws SnapshotException
{
if (c instanceof IContextObjectSet)
{
IContextObjectSet cs = (IContextObjectSet)c;
if (cs.getObjectIds().length == 1)
- checkSingleObjectContext(rt, row, cs.getObjectIds()[0], c);
+ checkSingleObjectContext(rt, row, cs.getObjectIds()[0], c, dump);
else {
int os[] = cs.getObjectIds();
String oql = cs.getOQL();
- Object res = execute(oql);
+ Object res = execute(oql, dump);
if (res instanceof int[])
{
int r[] = (int[])res;
@@ -1575,23 +1734,23 @@ public class OQLTest else if (res instanceof IResultTable)
{
IResultTable rt2 = (IResultTable)res;
- assertEquals(1, rt2.getRowCount());
- assertEquals(rt.getColumns().length, rt2.getColumns().length);
+ assertEquals("row="+row+" oql="+oql, 1, rt2.getRowCount());
+ assertEquals("row="+row+" oql="+oql, rt.getColumns().length, rt2.getColumns().length);
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);
- assertEquals("row="+row+" col="+j, o1, o2);
+ assertThat("row="+row+" col="+j+" oql="+oql, o1, equalTo(o2));
}
IContextObject ic = rt2.getContext(rt2.getRow(0));
- assertTrue(ic instanceof IContextObjectSet);
+ assertThat("row="+row+" oql="+oql, ic, instanceOf(IContextObjectSet.class));
IContextObjectSet ics = (IContextObjectSet)ic;
- assertEquals(oql, ics.getOQL());
- assertEquals(cs.getObjectId(), ics.getObjectId());
- assertEquals(os.length, ics.getObjectIds().length);
+ assertEquals("row="+row, oql, ics.getOQL());
+ assertEquals("row="+row+" oql="+oql ,cs.getObjectId(), ics.getObjectId());
+ assertEquals("row="+row+" oql="+oql, os.length, ics.getObjectIds().length);
for (int ix = 0; ix < os.length; ++ix)
{
- assertEquals(os[ix], ics.getObjectIds()[ix]);
+ assertEquals("row="+row+" oql="+oql, os[ix], ics.getObjectIds()[ix]);
}
}
}
@@ -1601,15 +1760,15 @@ public class OQLTest }
}
- private void checkSingleObjectContext(int ioid, IContextObject c) throws SnapshotException
+ private void checkSingleObjectContext(int ioid, IContextObject c, String dump) throws SnapshotException
{
- assertTrue(c instanceof IContextObjectSet);
+ assertThat(c, instanceOf(IContextObjectSet.class));
IContextObjectSet cs = (IContextObjectSet)c;
assertEquals(ioid, cs.getObjectId());
assertEquals(1, cs.getObjectIds().length);
assertEquals(ioid, cs.getObjectIds()[0]);
String oql = cs.getOQL();
- Object res = execute(oql);
+ Object res = execute(oql, dump);
if (res instanceof int[])
{
int r[] = (int[])res;
@@ -1622,18 +1781,18 @@ public class OQLTest assertEquals(1, rt2.getRowCount());
assertEquals(1, rt2.getColumns().length);
Object o2 = rt2.getColumnValue(rt2.getRow(0), 0);
- assertTrue(o2 instanceof IObject);
+ assertThat(o2, instanceOf(IObject.class));
IObject io2 = (IObject)o2;
assertEquals(ioid, io2.getObjectId());
}
}
- private void checkSingleObjectContext(IResultTable rt, int row, int ioid, IContextObject c) throws SnapshotException
+ private void checkSingleObjectContext(IResultTable rt, int row, int ioid, IContextObject c, String dump) throws SnapshotException
{
- assertTrue(c instanceof IContextObjectSet);
+ assertThat(c, instanceOf(IContextObjectSet.class));
IContextObjectSet cs = (IContextObjectSet)c;
String oql = cs.getOQL();
- Object res = execute(oql);
+ Object res = execute(oql, dump);
if (res instanceof int[])
{
int r[] = (int[])res;
@@ -1742,7 +1901,7 @@ public class OQLTest }
private Object execute(String oql, String snapshotName) throws SnapshotException
- {
+ {
try
{
ISnapshot snapshot = TestSnapshots.getSnapshot(snapshotName, false);
diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/util/QueryContextMenu.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/util/QueryContextMenu.java index 645c5b7d..9656232f 100644 --- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/util/QueryContextMenu.java +++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/util/QueryContextMenu.java @@ -115,6 +115,7 @@ public class QueryContextMenu String label = null;
+ boolean shownSystem = false;
// context calculation
for (ContextProvider p : contextProvider)
{
@@ -157,11 +158,17 @@ public class QueryContextMenu if (!menuContext.isEmpty())
queryMenu(menu, menuContext, label);
- systemMenu(menu, control);
+ if (!menuContext.isEmpty())
+ {
+ systemMenu(menu, control);
+ shownSystem = true;
+ }
if (!menuContext.isEmpty())
customMenu(menu, menuContext, p, label);
}
+ if (!shownSystem)
+ systemMenu(manager, control);
}
private String getLabel(IStructuredSelection selection)
@@ -750,7 +757,15 @@ public class QueryContextMenu String menuName = QueryRegistry.instance().getRootCategory().resolve(qd.getCategory()).getName();
PopupMenu menu2 = menu.getChildMenu(menuName);
if (menu2 != null)
+ {
menu = menu2;
+ }
+ else
+ {
+ menu2 = new PopupMenu(menuName);
+ menu.add(menu2);
+ menu = menu2;
+ }
}
Action copySelectionAction = new Action()
|
