@@ -2453,6 +2453,53 @@ def _filter_multilink_expression_fallback(self, proptree, expr):
24532453 # we have ids of the classname table
24542454 return ids .where ("_%s.id" % classname , self .db .arg )
24552455
2456+ def _filter_link_expression (self , proptree , v ):
2457+ """ Filter elements in the table that match the given expression
2458+ """
2459+ pln = proptree .parent .uniqname
2460+ prp = proptree .name
2461+ try :
2462+ opcodes = [int (x ) for x in v ]
2463+ if min (opcodes ) >= - 1 :
2464+ raise ValueError ()
2465+ expr = compile_expression (opcodes )
2466+ # NULL doesn't compare to NULL in SQL
2467+ # So not (x = '1') will *not* include NULL values for x
2468+ # That's why we need that and clause:
2469+ atom = "_%s._%s = %s and _%s._%s is not NULL" % (
2470+ pln , prp , self .db .arg , pln , prp )
2471+ atom_nil = "_%s._%s is NULL" % (pln , prp )
2472+ lambda_atom = lambda n : atom if n .x >= 0 else atom_nil
2473+ values = []
2474+ w = expr .generate (lambda_atom )
2475+ def collect_values (n ):
2476+ if n .x >= 0 :
2477+ values .append (n .x )
2478+ expr .visit (collect_values )
2479+ return w , values
2480+ except :
2481+ pass
2482+ # Fallback to original code
2483+ args = []
2484+ where = None
2485+ d = {}
2486+ for entry in v :
2487+ if entry == '-1' :
2488+ entry = None
2489+ d [entry ] = entry
2490+ l = []
2491+ if None in d or not d :
2492+ if None in d : del d [None ]
2493+ l .append ('_%s._%s is NULL' % (pln , prp ))
2494+ if d :
2495+ v = list (d )
2496+ s = ',' .join ([self .db .arg for x in v ])
2497+ l .append ('(_%s._%s in (%s))' % (pln , prp , s ))
2498+ args = v
2499+ if l :
2500+ where = '(' + ' or ' .join (l ) + ')'
2501+ return where , args
2502+
24562503 def _filter_multilink_expression (self , proptree , v ):
24572504 """ Filters out elements of the classname table that do not
24582505 match the given expression.
@@ -2678,22 +2725,10 @@ def _filter_sql (self, search_matches, filterspec, srt=[], grp=[], retr=0,
26782725 where .append ('_%s._%s=_%s.id' % (pln , k , ln ))
26792726 if p .has_values :
26802727 if isinstance (v , type ([])):
2681- d = {}
2682- for entry in v :
2683- if entry == '-1' :
2684- entry = None
2685- d [entry ] = entry
2686- l = []
2687- if None in d or not d :
2688- if None in d : del d [None ]
2689- l .append ('_%s._%s is NULL' % (pln , k ))
2690- if d :
2691- v = list (d )
2692- s = ',' .join ([a for x in v ])
2693- l .append ('(_%s._%s in (%s))' % (pln , k , s ))
2694- args = args + v
2695- if l :
2696- where .append ('(' + ' or ' .join (l ) + ')' )
2728+ w , arg = self ._filter_link_expression (p , v )
2729+ if w :
2730+ where .append (w )
2731+ args += arg
26972732 else :
26982733 if v in ('-1' , None ):
26992734 v = None
0 commit comments