Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Johnson2019-11-18 16:46:20 +0000
committerAndrew Johnson2019-11-18 16:46:20 +0000
commit05fb6aa5ca9af3f8e7d25fe4517ef5bf76d75941 (patch)
tree1a0710b2ae2fcd7a6a3ec1c456b5567df512d01f
parentcca4cae44ab5e6d6a6b4ca1ba8b2bbfa968b12d0 (diff)
downloadorg.eclipse.mat-05fb6aa5ca9af3f8e7d25fe4517ef5bf76d75941.tar.gz
org.eclipse.mat-05fb6aa5ca9af3f8e7d25fe4517ef5bf76d75941.tar.xz
org.eclipse.mat-05fb6aa5ca9af3f8e7d25fe4517ef5bf76d75941.zip
552879: OQL enhancements for sub-selects, maps, context providers
Bug fixes and flattening sub-select arrays Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=552879 Change-Id: I99ee24fec6fe26730cf57b04c08f4c1a99f3ca8a
-rw-r--r--plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/oql/OQLQueryImpl.java107
-rw-r--r--plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/OQLTest.java132
2 files changed, 223 insertions, 16 deletions
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 46495331..34b03d1c 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
@@ -39,6 +39,7 @@ import org.eclipse.mat.parser.internal.oql.compiler.EvaluationContext;
import org.eclipse.mat.parser.internal.oql.compiler.Expression;
import org.eclipse.mat.parser.internal.oql.compiler.Query;
import org.eclipse.mat.parser.internal.oql.compiler.Query.FromClause;
+import org.eclipse.mat.parser.internal.oql.compiler.Query.SelectClause;
import org.eclipse.mat.parser.internal.oql.compiler.Query.SelectItem;
import org.eclipse.mat.parser.internal.oql.parser.OQLParser;
import org.eclipse.mat.parser.internal.oql.parser.ParseException;
@@ -199,11 +200,11 @@ public class OQLQueryImpl implements IOQLQuery
public boolean equals(Object o)
{
- if (!(o instanceof Entry<?,?>))
+ if ((o instanceof Entry<?,?>))
{
Entry<?,?>ox = (Entry<?,?>)o;
- return Objects.equals(getKey(), ox.getKey()) &&
- Objects.equals(getValue(), ox.getValue());
+ return Objects.equals(getKey(), ox.getKey()) &&
+ Objects.equals(getValue(), ox.getValue());
}
{
return false;
@@ -532,7 +533,16 @@ public class OQLQueryImpl implements IOQLQuery
alias2 = ""; //$NON-NLS-1$
else
alias2 = " "+alias; //$NON-NLS-1$
- return "SELECT "+source.query.getSelectClause().toString() +" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ SelectClause sc = source.query.getSelectClause();
+ if (sc.isRetainedSet())
+ {
+ // Remove asRetainedSet() as we just have a single object here
+ SelectClause sc2 = new SelectClause();
+ sc2.setAsObjects(sc.isAsObjects());
+ sc2.setSelectList(sc.getSelectList());
+ sc = sc2;
+ }
+ return "SELECT "+sc.toString() +" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
}
};
}
@@ -665,7 +675,16 @@ public class OQLQueryImpl implements IOQLQuery
alias2 = ""; //$NON-NLS-1$
else
alias2 = " "+alias; //$NON-NLS-1$
- return "SELECT "+source.query.getSelectClause().toString() +" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
+ SelectClause sc = source.query.getSelectClause();
+ if (sc.isRetainedSet())
+ {
+ // Remove asRetainedSet() as we just have a single object here
+ SelectClause sc2 = new SelectClause();
+ sc2.setAsObjects(sc.isAsObjects());
+ sc2.setSelectList(sc.getSelectList());
+ sc = sc2;
+ }
+ return "SELECT "+sc.toString() +" FROM OBJECTS " + getObjectId()+alias2; //$NON-NLS-1$ //$NON-NLS-2$
}
};
}
@@ -1306,6 +1325,13 @@ public class OQLQueryImpl implements IOQLQuery
{
return null;
}
+ else if (result instanceof AbstractCustomTableResultSet)
+ {
+ /*
+ * Experiment - flatten sub-select containing selects in select items
+ */
+ return filterAndSelect((AbstractCustomTableResultSet)result, monitor);
+ }
else if (result instanceof Iterable)
{
List<Object> r = new ArrayList<Object>();
@@ -1920,6 +1946,77 @@ public class OQLQueryImpl implements IOQLQuery
return r.isEmpty() ? null : select(r, listener);
}
+ private Object filterAndSelect(AbstractCustomTableResultSet result, IProgressListener listener) throws SnapshotException
+ {
+ List<Object> r = new ArrayList<Object>();
+ for (AbstractCustomTableResultSet.RowMap rowobj : result)
+ {
+ if (listener.isCanceled())
+ throw new IProgressListener.OperationCanceledException();
+
+ /*
+ * Possible flatten
+ */
+ int maxlen = -1;
+ for (Object v : rowobj.values())
+ {
+ if (v instanceof List)
+ {
+ int ll = ((List<?>)v).size();
+ if (ll > maxlen)
+ maxlen = ll;
+ }
+ else if (v !=null && v.getClass().isArray())
+ {
+ int ll = Array.getLength(v);
+ if (ll > maxlen)
+ maxlen = ll;
+ }
+ }
+
+ if (maxlen >= 0)
+ {
+ // Create a row even if the list/array is empty, will be replaced with null
+ if (maxlen == 0)
+ maxlen = 1;
+ for (int i = 0; i < maxlen; ++i)
+ {
+ int ix = i;
+ AbstractCustomTableResultSet.RowMap rm2 = new AbstractCustomTableResultSet.RowMap(result, rowobj.index) {
+ public Object get(Object key)
+ {
+ Object v = rowobj.get(key);
+ if (v instanceof List)
+ {
+ if (ix >= ((List<?>)v).size())
+ return null;
+ return ((List<?>)v).get(ix);
+ }
+ else if (v != null && v.getClass().isArray())
+ {
+ if (ix >= Array.getLength(v))
+ return null;
+ return Array.get(v, ix);
+ }
+ else
+ {
+ return v;
+ }
+ }
+ };
+ if (accept(rm2, listener))
+ r.add(rm2);
+ }
+ }
+ else
+ {
+ if (accept(rowobj, listener))
+ r.add(rowobj);
+ }
+ }
+ return r.isEmpty() ? null : select(r, listener);
+ }
+
private Object select(Object object, IProgressListener listener) throws SnapshotException
{
Query.SelectClause select = query.getSelectClause();
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 7b3fea1e..817acabc 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
@@ -13,6 +13,7 @@
package org.eclipse.mat.tests.snapshot;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertArrayEquals;
@@ -110,10 +111,32 @@ public class OQLTest
}
@Test
- public void testSelectRetained() throws SnapshotException
+ public void testSelectRetained1() throws SnapshotException
{
int[] objectIds = (int[]) execute("select as retained set * from java.lang.String");
- assert objectIds.length == 963 : "963 objects expected";
+ assertThat("963 objects expected", objectIds.length, equalTo(963));
+ }
+
+ @Test
+ public void testSelectRetained2() throws SnapshotException
+ {
+ int[] objectIds = (int[]) execute("SELECT AS RETAINED SET * FROM OBJECTS ( SELECT * FROM java.lang.String ) s ");
+ assertThat("963 objects expected", objectIds.length, equalTo(963));
+ }
+
+ @Test
+ public void testSelectRetained3() throws SnapshotException
+ {
+ int[] objectIds = (int[]) execute("SELECT AS RETAINED SET OBJECTS s FROM OBJECTS ( SELECT * FROM java.lang.String ) s ");
+ assertThat("963 objects expected", objectIds.length, equalTo(963));
+ }
+
+ @Test
+ public void testSelectRetained4() throws SnapshotException
+ {
+ IResultTable resulttable = (IResultTable)execute("SELECT AS RETAINED SET s FROM OBJECTS ( SELECT * FROM java.lang.String ) s ");
+ assertThat("963 objects expected", resulttable.getRowCount(), equalTo(963));
+ checkGetOQL(resulttable);
}
@Test
@@ -437,6 +460,73 @@ public class OQLTest
}
@Test
+ public void testFromByName1() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT s, snapshot FROM OBJECTS ${snapshot}.getClassesByName(\"java.lang.Class\",false).iterator().next().getObjectIds() s WHERE ${snapshot}.isClass(s)");
+ ISnapshot sn = (ISnapshot)irt.getColumnValue(0, 1);
+ assertThat(irt.getRowCount(), equalTo(sn.getSnapshotInfo().getNumberOfClasses()));
+ }
+
+ @Test
+ public void testFromByName2() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT t FROM ("
+ + "SELECT OBJECTS s FROM OBJECTS ${snapshot}.getClassesByName(\"java.lang.Class\",false).iterator().next().getObjectIds() s WHERE ${snapshot}.isClass(s)"
+ + ") t");
+ IObject o = (IObject)irt.getColumnValue(0, 0);
+ assertThat(irt.getRowCount(), equalTo(o.getSnapshot().getSnapshotInfo().getNumberOfObjects()));
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testFromByName3() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT t,snapshot FROM ( eval(("
+ + "SELECT OBJECTS s FROM OBJECTS ${snapshot}.getClassesByName(\"java.lang.Class\",false).iterator().next().getObjectIds() s WHERE ${snapshot}.isClass(s)"
+ + "))"
+ + ") t");
+ IObject o = (IObject)irt.getColumnValue(0, 0);
+ assertThat(irt.getRowCount(), equalTo(o.getSnapshot().getSnapshotInfo().getNumberOfObjects()));
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testFromByName4() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT s,snapshot FROM OBJECTS ${snapshot}.getClassesByName(\"java.lang.Object\",true).toArray() s WHERE ${snapshot}.isClass(s.@objectId)");
+ ISnapshot sn = (ISnapshot)irt.getColumnValue(0, 1);
+ assertThat(irt.getRowCount(), equalTo(sn.getSnapshotInfo().getNumberOfClasses()));
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testFromByName5() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT s, snapshot FROM ${snapshot}.getClassesByName(\"java.lang.Object\",true).toArray() s WHERE ${snapshot}.isClass(s.@objectId)");
+ ISnapshot sn = (ISnapshot)irt.getColumnValue(0, 1);
+ assertThat(irt.getRowCount(), equalTo(sn.getSnapshotInfo().getNumberOfClasses()));
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testFromByName6() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT s, snapshot FROM INSTANCEOF ${snapshot}.getClassesByName(\"java.lang.Object\",false).toArray() s WHERE ${snapshot}.isClass(s.@objectId)");
+ ISnapshot sn = (ISnapshot)irt.getColumnValue(0, 1);
+ assertThat(irt.getRowCount(), equalTo(sn.getSnapshotInfo().getNumberOfClasses()));
+ checkGetOQL(irt);
+ }
+
+ @Test
+ public void testFromByName7() throws SnapshotException
+ {
+ IResultTable irt = (IResultTable)execute("SELECT AS RETAINED SET s, snapshot FROM ${snapshot}.getClassesByName(\"java.lang.Class\",false) s");
+ ISnapshot sn = (ISnapshot)irt.getColumnValue(0, 1);
+ assertThat(irt.getRowCount(), greaterThan(sn.getSnapshotInfo().getNumberOfClasses()));
+ checkGetOQL(irt);
+ }
+
+ @Test
public void testFromSubSelect() throws SnapshotException
{
String oql = "SELECT * FROM ( SELECT * " //
@@ -1097,11 +1187,14 @@ public class OQLTest
public void testComplex5() throws SnapshotException {
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 ( "
+ + "eval((" // Avoid auto-flattening
+ "SELECT t, t[0:-1] "
+ "FROM java.util.HashSet t "
+ "UNION "
+ "( SELECT s, s[0:-1] "
- + "FROM java.util.Hashtable s ) ) v ");
+ + "FROM java.util.Hashtable s ) )"
+ + "))"
+ + " v ");
assertEquals(11, irt.getRowCount());
checkGetOQL(irt);
}
@@ -1110,8 +1203,11 @@ public class OQLTest
public void testComplex5a() throws SnapshotException {
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 ( "
+ + "eval((" // Avoid auto-flattening
+ "SELECT t, t[0:-1] "
- + "FROM java.util.HashSet t ) v");
+ + "FROM java.util.HashSet t )"
+ + "))"
+ + " v");
assertEquals(5, irt.getRowCount());
checkGetOQL(irt);
}
@@ -1128,12 +1224,18 @@ public class OQLTest
public void testComplex5c() throws SnapshotException {
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 ( "
+ + "eval((" // Avoid auto-flattening
+ "SELECT t, t[0:-1] "
- + "FROM java.util.HashSet t ) v "
+ + "FROM java.util.HashSet t )"
+ + "))"
+ + " v "
+ "UNION ("
+ "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 )");
+ + "FROM OBJECTS ("
+ + "eval((" // Avoid auto-flattening
+ + "SELECT t, t[0:-1] FROM java.util.Hashtable t )"
+ + "))"
+ + " v )");
assertEquals(11, irt.getRowCount());
checkGetOQL(irt);
}
@@ -1191,6 +1293,14 @@ public class OQLTest
checkGetOQL(irt);
}
+ @Test
+ public void testComplex10() throws SnapshotException {
+ IResultTable irt = (IResultTable)execute("SELECT z.map AS Map, z.kv.key AS Key, z.kv.value AS Value FROM OBJECTS ( SELECT h AS map, (SELECT e.getKey() AS key, e.getValue() AS value FROM OBJECTS ${h}[0:-1] e ) AS kv FROM java.util.HashMap h ) z WHERE (z.kv.key != null)");
+ assertThat(irt.getRowCount(), greaterThan(0));
+ assertThat(irt.getColumns().length, equalTo(3));
+ checkGetOQL(irt);
+ }
+
/**
* Check all getOQL() from contexts from the result are sensible.
* @param rt ResultTable
@@ -1388,14 +1498,14 @@ public class OQLTest
if (res instanceof int[])
{
int r[] = (int[])res;
- assertEquals(1, r.length);
- assertEquals(ioid, r[0]);
+ assertEquals(oql, 1, r.length);
+ assertEquals(oql, ioid, r[0]);
}
else if (res instanceof IResultTable)
{
IResultTable rt2 = (IResultTable)res;
- assertEquals(1, rt2.getRowCount());
- assertEquals(rt.getColumns().length, rt2.getColumns().length);
+ assertEquals(oql, 1, rt2.getRowCount());
+ assertEquals(oql, rt.getColumns().length, rt2.getColumns().length);
for (int j = 0; j < rt.getColumns().length; ++j)
{
Object o1 = rt.getColumnValue(rt.getRow(row), j);

Back to the top