Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMIS queries involving comparisons to empty strings fail #423

Open
Googulator opened this issue May 10, 2023 · 0 comments
Open

CMIS queries involving comparisons to empty strings fail #423

Googulator opened this issue May 10, 2023 · 0 comments

Comments

@Googulator
Copy link

Googulator commented May 10, 2023

On Alfresco Search Services v2.0.7, the following CMIS query (tested via the CMIS 1.1 browser binding) fails with HTTP 500:
SELECT cmis:objectId FROM cmis:document WHERE cmis:name = '' AND CONTAINS('(TEXT:* OR NOT TEXT:*)')

The CONTAINS() at the end is effectively a no-op, but it prevents executing the query as TMDQ. With it removed, the query is performed directly from the database, and it succeeds:

SELECT cmis:objectId FROM cmis:document WHERE cmis:name = ''
This correctly returns object IDs for documents with an empty name.

The failing query produces this stack trace in the Search Services container log:

2023-05-10 13:11:40.306 ERROR (qtp455538610-17) [ x:alfresco] o.a.s.s.HttpSolrCall null:org.alfresco.repo.search.impl.querymodel.QueryModelException: 04100015 No query time mapping for property cmis:name, it should not be allowed in predicates
at org.alfresco.repo.search.impl.querymodel.impl.lucene.functions.LuceneLike.addComponent(LuceneLike.java:78)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneFunctionalConstraint.addComponent(LuceneFunctionalConstraint.java:63)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneConjunction.addComponent(LuceneConjunction.java:71)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQuery.buildQuery(LuceneQuery.java:110)
at org.alfresco.solr.AlfrescoSolrDataModel.getCMISQuery(AlfrescoSolrDataModel.java:1570)
at org.alfresco.solr.query.CmisQParserPlugin$CmisQParser.parse(CmisQParserPlugin.java:191)
at org.apache.solr.search.QParser.getQuery(QParser.java:168)
at org.apache.solr.handler.component.QueryComponent.prepare(QueryComponent.java:161)
at org.apache.solr.handler.component.AlfrescoSearchHandler.handleRequestBody(AlfrescoSearchHandler.java:348)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:173)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:2477)
at org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:723)
at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:529)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:361)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:305)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:513)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:539)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:333)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.base/java.lang.Thread.run(Thread.java:833)

An IS NULL query works (but has a different issue, where it interacts wrongly with LEFT JOINs), and so does any comparison string other than the empty string.

Rewriting the empty string comparison as a CONTAINS() also works fine:
SELECT cmis:objectId FROM cmis:document WHERE CONTAINS('=cmis:name:""') AND CONTAINS('(TEXT:* OR NOT TEXT:*)')

Using an IN query with a list containing the empty string, a different stack trace is printed:
SELECT cmis:objectId FROM cmis:document WHERE cmis:name IN ('', 'test') AND CONTAINS('(TEXT:* OR NOT TEXT:*)')

2023-05-10 13:23:22.267 ERROR (qtp455538610-22) [ x:alfresco] o.a.s.s.HttpSolrCall null:java.lang.NullPointerException: Query must not be null
at java.base/java.util.Objects.requireNonNull(Objects.java:233)
at org.apache.lucene.search.BooleanClause.(BooleanClause.java:60)
at org.apache.lucene.search.BooleanQuery$Builder.add(BooleanQuery.java:138)
at org.alfresco.solr.query.Lucene4QueryParserAdaptor$Lucene4QueryParserExpressionAdaptor.addOptional(Lucene4QueryParserAdaptor.java:338)
at org.alfresco.solr.query.Lucene4QueryParserAdaptor$Lucene4QueryParserExpressionAdaptor.addOptional(Lucene4QueryParserAdaptor.java:310)
at org.alfresco.opencmis.mapping.BaseLuceneBuilder.buildLuceneIn(BaseLuceneBuilder.java:82)
at org.alfresco.opencmis.search.CmisFunctionEvaluationContext.buildLuceneIn(CmisFunctionEvaluationContext.java:326)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.functions.LuceneIn.addComponent(LuceneIn.java:81)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneFunctionalConstraint.addComponent(LuceneFunctionalConstraint.java:63)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneConjunction.addComponent(LuceneConjunction.java:71)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQuery.buildQuery(LuceneQuery.java:110)
at org.alfresco.solr.AlfrescoSolrDataModel.getCMISQuery(AlfrescoSolrDataModel.java:1570)
at org.alfresco.solr.query.CmisQParserPlugin$CmisQParser.parse(CmisQParserPlugin.java:191)
at org.apache.solr.search.QParser.getQuery(QParser.java:168)
at org.apache.solr.handler.component.QueryComponent.prepare(QueryComponent.java:161)
at org.apache.solr.handler.component.AlfrescoSearchHandler.handleRequestBody(AlfrescoSearchHandler.java:348)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:173)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:2477)
at org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:723)
at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:529)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:361)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:305)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:513)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:539)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:333)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.base/java.lang.Thread.run(Thread.java:833)

The issue is not unique to cmis:name, or the cmis: pseudo-namespace, but also occurs with properties from aspects:
SELECT A.cmis:objectId FROM cmis:document A JOIN cm:titled B ON A.cmis:objectId = B.cmis:objectId WHERE B.cm:title = '' AND CONTAINS(A, '(TEXT:* OR NOT TEXT:*)')

2023-05-10 13:27:43.042 ERROR (qtp455538610-16) [ x:alfresco] o.a.s.s.HttpSolrCall null:org.alfresco.repo.search.impl.querymodel.QueryModelException: 04100016 No query time mapping for property cm:title, it should not be allowed in predicates
at org.alfresco.repo.search.impl.querymodel.impl.lucene.functions.LuceneEquals.addComponent(LuceneEquals.java:71)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneFunctionalConstraint.addComponent(LuceneFunctionalConstraint.java:63)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneConjunction.addComponent(LuceneConjunction.java:71)
at org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQuery.buildQuery(LuceneQuery.java:110)
at org.alfresco.solr.AlfrescoSolrDataModel.getCMISQuery(AlfrescoSolrDataModel.java:1570)
at org.alfresco.solr.query.CmisQParserPlugin$CmisQParser.parse(CmisQParserPlugin.java:191)
at org.apache.solr.search.QParser.getQuery(QParser.java:168)
at org.apache.solr.handler.component.QueryComponent.prepare(QueryComponent.java:161)
at org.apache.solr.handler.component.AlfrescoSearchHandler.handleRequestBody(AlfrescoSearchHandler.java:348)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:173)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:2477)
at org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:723)
at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:529)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:361)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:305)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:513)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:539)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:333)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.base/java.lang.Thread.run(Thread.java:833)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant