36 from cubicweb import dbapi, server |
36 from cubicweb import dbapi, server |
37 from cubicweb import BadConnectionId, UnknownEid, ConnectionError |
37 from cubicweb import BadConnectionId, UnknownEid, ConnectionError |
38 from cubicweb.cwconfig import register_persistent_options |
38 from cubicweb.cwconfig import register_persistent_options |
39 from cubicweb.server.sources import (AbstractSource, ConnectionWrapper, |
39 from cubicweb.server.sources import (AbstractSource, ConnectionWrapper, |
40 TimedCache, dbg_st_search, dbg_results) |
40 TimedCache, dbg_st_search, dbg_results) |
41 |
41 from cubicweb.server.msplanner import neged_relation |
42 |
42 |
43 def uidtype(union, col, etype, args): |
43 def uidtype(union, col, etype, args): |
44 select, col = union.locate_subquery(col, etype, args) |
44 select, col = union.locate_subquery(col, etype, args) |
45 return getattr(select.selection[col], 'uidtype', None) |
45 return getattr(select.selection[col], 'uidtype', None) |
46 |
46 |
474 if rql: |
474 if rql: |
475 return 'NOT (%s)' % rql |
475 return 'NOT (%s)' % rql |
476 return |
476 return |
477 |
477 |
478 def visit_exists(self, node): |
478 def visit_exists(self, node): |
479 return 'EXISTS(%s)' % node.children[0].accept(self) |
479 rql = node.children[0].accept(self) |
|
480 if rql: |
|
481 return 'EXISTS(%s)' % rql |
|
482 return |
480 |
483 |
481 def visit_relation(self, node): |
484 def visit_relation(self, node): |
482 try: |
485 try: |
483 if isinstance(node.children[0], Constant): |
486 if isinstance(node.children[0], Constant): |
484 # simplified rqlst, reintroduce eid relation |
487 # simplified rqlst, reintroduce eid relation |
485 try: |
488 try: |
486 restr, lhs = self.process_eid_const(node.children[0]) |
489 restr, lhs = self.process_eid_const(node.children[0]) |
487 except UnknownEid: |
490 except UnknownEid: |
488 # can safely skip not relation with an unsupported eid |
491 # can safely skip not relation with an unsupported eid |
489 if node.neged(strict=True): |
492 if neged_relation(node): |
490 return |
493 return |
491 raise |
494 raise |
492 else: |
495 else: |
493 lhs = node.children[0].accept(self) |
496 lhs = node.children[0].accept(self) |
494 restr = None |
497 restr = None |
495 except UnknownEid: |
498 except UnknownEid: |
496 # can safely skip not relation with an unsupported eid |
499 # can safely skip not relation with an unsupported eid |
497 if node.neged(strict=True): |
500 if neged_relation(node): |
498 return |
501 return |
499 # XXX what about optional relation or outer NOT EXISTS() |
502 # XXX what about optional relation or outer NOT EXISTS() |
500 raise |
503 raise |
501 if node.optional in ('left', 'both'): |
504 if node.optional in ('left', 'both'): |
502 lhs += '?' |
505 lhs += '?' |
509 self.current_etypes = node.children[0].variable.stinfo['possibletypes'] |
512 self.current_etypes = node.children[0].variable.stinfo['possibletypes'] |
510 try: |
513 try: |
511 rhs = node.children[1].accept(self) |
514 rhs = node.children[1].accept(self) |
512 except UnknownEid: |
515 except UnknownEid: |
513 # can safely skip not relation with an unsupported eid |
516 # can safely skip not relation with an unsupported eid |
514 if node.neged(strict=True): |
517 if neged_relation(node): |
515 return |
518 return |
516 # XXX what about optional relation or outer NOT EXISTS() |
519 # XXX what about optional relation or outer NOT EXISTS() |
517 raise |
520 raise |
518 except ReplaceByInOperator, ex: |
521 except ReplaceByInOperator, ex: |
519 rhs = 'IN (%s)' % ','.join(eid for eid in ex.eids) |
522 rhs = 'IN (%s)' % ','.join(eid for eid in ex.eids) |