CMIS Query with a "null predicate" containing a "multi-valued-column reference" throws exception

A CMIS Query with a “null predicate” containing a “multi-valued-column reference” throws an exception. A sample query that demonstrates the problem is listed below as is the exception stack trace. Please confirm this is a bug that I should record in JIRA.

SELECT cmis:objectId FROM cmis:document WHERE dc:subjects IS NOT NULL

Stack trace:

curl -u Administrator:Administrator "http://demo.nuxeo.com/nuxeo/atom/cmis/default/query?q=SELECT+cmis:objectId+FROM+cmis:document+WHERE+dc:subjects+IS+NOT+NULL&searchAllVersions=true&includeRelationships=none"
org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException: Failed to execute query: CMISQL: SELECT cmis:objectId FROM cmis:document WHERE dc:subjects IS NOT NULL: ERROR: missing FROM-clause entry for table "dc_subjects"
Position: 331
    at org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService.query(NuxeoCmisService.java:1342)
    ...
Caused by: org.nuxeo.ecm.core.api.ClientException: Failed to execute query: CMISQL: SELECT cmis:objectId FROM cmis:document WHERE dc:subjects IS NOT NULL: ERROR: missing FROM-clause entry for table "dc_subjects"
Position: 331
    at org.nuxeo.ecm.core.api.AbstractSession.queryAndFetch(AbstractSession.java:1672)
    at sun.reflect.GeneratedMethodAccessor286.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.nuxeo.ecm.core.api.TransactionalCoreSessionWrapper.invoke(TransactionalCoreSessionWrapper.java:136)
    at com.sun.proxy.$Proxy177.queryAndFetch(Unknown Source)
    at org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService.query(NuxeoCmisService.java:1295)
    ... 57 more
Caused by: org.nuxeo.ecm.core.query.QueryException: Invalid query: CMISQL: SELECT cmis:objectId FROM cmis:document WHERE dc:subjects IS NOT NULL
    at org.nuxeo.ecm.core.storage.sql.coremodel.SQLSession$SQLSessionQuery.executeAndFetch(SQLSession.java:613)
    at org.nuxeo.ecm.core.storage.sql.coremodel.SQLSession.queryAndFetch(SQLSession.java:527)
    at org.nuxeo.ecm.core.api.AbstractSession.queryAndFetch(AbstractSession.java:1667)
    ... 63 more
Caused by: org.nuxeo.ecm.core.storage.StorageException: Invalid query: CMISQL: SELECT cmis:objectId FROM cmis:document WHERE dc:subjects IS NOT NULL
    at org.nuxeo.ecm.core.storage.sql.jdbc.JDBCMapper.queryAndFetch(JDBCMapper.java:898)
    at org.nuxeo.ecm.core.storage.sql.SoftRefCachingMapper.queryAndFetch(SoftRefCachingMapper.java:107)
    at org.nuxeo.ecm.core.storage.sql.SessionImpl.queryAndFetch(SessionImpl.java:1209)
    at org.nuxeo.ecm.core.storage.sql.ra.ConnectionImpl.queryAndFetch(ConnectionImpl.java:354)
    at org.nuxeo.ecm.core.storage.sql.coremodel.SQLSession$SQLSessionQuery.executeAndFetch(SQLSession.java:610)
    ... 65 more
Caused by: org.postgresql.util.PSQLException: ERROR: missing FROM-clause entry for table "dc_subjects"
Position: 331
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:302)
    at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
    at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
    at org.nuxeo.ecm.core.storage.sql.jdbc.ResultSetQueryResult.<init>(ResultSetQueryResult.java:74)
    at org.nuxeo.ecm.core.storage.sql.jdbc.JDBCMapper.queryAndFetch(JDBCMapper.java:894)
    ... 69 more
0 votes

1 answers

4500 views

ANSWER



I believe it's a bug but on the other hand the current code is not intended to work with null predicates and multi-valued properties. I'm not sure we can find an efficient way to do that. Please open a JIRA anyway.

0 votes



rg1
See NXP-12642

WHERE clauses with (dc:subjects IS NULL OR dc:subjects NOT IN ('foo')) will likely be common. It seems reasonable to explicitly look for these types of multi-valued column ref OR clauses and optimize them with NOT EXISTS (SELECT 1 FROM … WHERE … IN …) sub-queries. Does this seem reasonable?

09/30/2013

Added a comment to NXP-12642.

Please discuss in the ticket the exact semantics you imagine for dc:subjects IS NULL OR ANY dc:subjects NOT IN (&apos;foo&apos;) because I'm not sure the spec matches your expectation. The CMIS 1.1 spec says (§2.1.14.2.4.3) that ANY dc:subjects NOT IN (&apos;foo&apos;) evaluates to TRUE if at least one subject is not 'foo'.

If you want something to be optimized into NOT EXISTS (SELECT 1 ... WHERE ... dc_subjects.item = &apos;foo&apos;) then it would be dc:subjects IS NULL OR NOT ANY dc:subjects IN (&apos;foo&apos;).

09/30/2013

rg1
Yes, thanks for the clarification.
09/30/2013