El lunes, 21 de enero de 2013 22:47:41 UTC+1, Massimo Di Pierro escribió: > > Now I understand the problem. You want to pass an expression where a value > is expected. I do not believe we can support this. INSTR does not solve the > problem because it would not be correct to looks for substrings. In fact > paper.authors may contain '|12|13|' and it would incorrectly return that > author '2' is one of authors because it is a substring. >
ok, but we can use CONCAT to append and prepend '|', that's more standard that instr. > > You have to do it in two steps: > > person = db(db.person.name='....').select().first() > papers = db.paper.authors.contains(person.id).select() > But it's not a one-time query. I'm working in something like appadmin, tweaking smart_query and SQLFORM.grid to help the user build compund querys. I'd rather normalize the database. BTW, I will come later with some ideas/questions. Thanks again > > Massimo > > > On Jan 21, 2013, at 3:33 PM, pablo....@uam.es <javascript:> wrote: > > > > El lunes, 21 de enero de 2013 18:56:07 UTC+1, Massimo Di Pierro escribió: >> >> Before we attempt to fix this. It works for me as it is with sqlite. Why >> does doesn't it wirk with mysql? MySQL has a LIKE operator. Wat error do >> you get? > > > execution of: > > db(db.paper.authors.contains(person.id))._select() > > gives: > > "SELECT person.id, paper.id, paper.title, paper.authors FROM person, > paper WHERE (paper.authors LIKE '%|person.id|%');" > > which I think tries to find those papers whose "authors" field contains > the literal "person.id", instead of the pairs (paper,person) such that > the person is one of the authors of the paper. > > With the modification I wrote before, it gets converted into: > > 'SELECT person.id, paper.id, paper.title, paper.authors FROM person, > paper WHERE INSTR(paper.authors, person.id);' > > with a different meaning. > > I can see why using the INSTR operator on MySQL may be better but do we >> know it is faster? >> > > I haven't made any speed test, I'd go for anything that works in sqlite > and mysql/mariadb. > > Thanks for your attention! > > >> >> Massimo >> >> On Monday, 21 January 2013 08:55:40 UTC-6, pablo....@uam.es wrote: >>> >>> Hello: >>> I was getting incorrect SQL from statements like: >>> >>> db(db.paper.authors.contains(person.id)).select() >>> >>> where >>> >>> db.define_table('paper', >>> Field('title'), >>> Field('authors', 'list:reference person'), >>> ) >>> >>> >>> so I rewrote dal.MySQLAdapter.CONTAINS from: >>> >>> def CONTAINS(self, first, second): >>> if first.type in ('string', 'text'): >>> key = '%'+str(second).replace('%','%%')+'%' >>> elif first.type.startswith('list:'): >>> key = >>> '%|'+str(second).replace('|','||').replace('%','%%')+'|%' >>> return '(%s LIKE %s)' % >>> (self.expand(first),self.expand(key,'string')) >>> >>> into: >>> >>> def CONTAINS(self, first, second): >>> if first.type in ('string', 'text'): >>> key = '%'+str(second).replace('%','%%')+'%' >>> elif first.type.startswith('list:reference'): >>> return 'INSTR(%s, %s)'%(first, str(second)) >>> elif first.type.startswith('list:'): >>> key = >>> '%|'+str(second).replace('|','||').replace('%','%%')+'|%' >>> return '(%s LIKE %s)' % >>> (self.expand(first),self.expand(key,'string')) >>> >>> now the above query works, but that's in MySQL, not SQLite, which >>> apparently does not have a INSTR operation, despite the fact that it is >>> advertised! >>> >>> https://www.sqlite.org/lang_corefunc.html >>> >>> Can anybody think of a solution that works in more databases >>> >> > --