preprocess Chgrp to different groups separately
further preprocessor unit tests
Empty the lookup caches before each preprocessor unit test.
complete preprocessor unit test work
Fix another +WS in spec.xml
Fix wrong return ID from findImproperIncomingLinks
Show GraphConstraintERR.constraints in library.py
Add ExtendedMetadata.getSQLJoin (See #11054)

In order to make use of `select distinct on (...)`, the
ome.services.graph package needs to be able to drop down
into raw SQL rather than HQL. Doing so, loses all of the
HQL dot notation, meaning it's necessary to lookup the
SQL-style joins for walking the graph.

This isn't a complete solution in that it doesn't take
joined subclasses into account, but works for the current
uses.
Add support for positional parameters to QueryBuilder

Use of direct SQL seemed to be returning odd results.
Positional params may or may not have helped with that
issue, but since they are implemented it doesn't hurt
to leave them. Named parameters should likely still be
preferred throughout the code base.
Permit 'select distinct on' raw SQL (See #11054, #9496)

Previously, only UPDATE and DELETE statements were allowed.
HQL, however, does not properly support `distinct on (...)`
and therefore it was necessary to include this workaround.
Refactor NULL handling into GraphStep (See #11054)

In preparation for NULLing UploadJob.versionInfo as a
workaround for SQL joined-subclass handling, the delete
step logic for nulling Pixels.relatedTo must be expanded
to also handle nulling versionInfo including during chgrp.
Refactor queryBackupIds for re-use by subclasses

The upcoming FilesetGraphSpec will need access to individual
parts of the queryBackupIds method. This is now been split up
into several protected methods for re-use.
Add FilesetGraphSpec to solve performance issues (Fix #11054)

"select distinct on (...)" is used to only load a /Fileset
once for an entire subgraph. To handle the variable intermediate
links, `-2` is inserted into the array of IDs, so that matching
in GraphTables completes appropriately.

/Filesets are now only handled from the contain types /Plate
and /Dataset.

NB: this is still not working because the super spec which
wraps the FilesetGraphSpec is not performing the proper
logic.
Remove CHGRP-VALIDATION EventLogs
Attempt to workaround missing Filesets
Revert "Attempt to workaround missing Filesets"

This reverts commit ab7184331855e37eec4b8e84aef929e86051ceb4.
Attempt to use synthetic paths e.g. /Dataset/Fileset

Since the dropped values between Dataset and Fileset seem
to be confusing the GraphTables logic (leading to duplicates
and similar), this change attempts to act as if the two
objects are actually related. Note: this does *not* require
SQL as the previous attempt did.
Move HQL distinct workaround for synthetics to base class

Since all the calls will need proper handling, move all logic
back to BaseGraphSpec.
Tweaking spec.xml for various tests
Extend BaseGraphSpec workaround for PDI, etc