query_expression.hpp 138 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481
  1. /*************************************************************************
  2. *
  3. * Copyright 2016 Realm Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. **************************************************************************/
  18. /*
  19. This file lets you write queries in C++ syntax like: Expression* e = (first + 1 / second >= third + 12.3);
  20. Type conversion/promotion semantics is the same as in the C++ expressions, e.g float + int > double == float +
  21. (float)int > double.
  22. Grammar:
  23. -----------------------------------------------------------------------------------------------------------------------
  24. Expression: Subexpr2<T> Compare<Cond, T> Subexpr2<T>
  25. operator! Expression
  26. Subexpr2<T>: Value<T>
  27. Columns<T>
  28. Subexpr2<T> Operator<Oper<T> Subexpr2<T>
  29. power(Subexpr2<T>) // power(x) = x * x, as example of unary operator
  30. Value<T>: T
  31. Operator<Oper<T>>: +, -, *, /
  32. Compare<Cond, T>: ==, !=, >=, <=, >, <
  33. T: bool, int, int64_t, float, double, StringData
  34. Class diagram
  35. -----------------------------------------------------------------------------------------------------------------------
  36. Subexpr2
  37. void evaluate(size_t i, ValueBase* destination)
  38. Compare: public Subexpr2
  39. size_t find_first(size_t start, size_t end) // main method that executes query
  40. unique_ptr<Subexpr2> m_left; // left expression subtree
  41. unique_ptr<Subexpr2> m_right; // right expression subtree
  42. Operator: public Subexpr2
  43. void evaluate(size_t i, ValueBase* destination)
  44. unique_ptr<Subexpr2> m_left; // left expression subtree
  45. unique_ptr<Subexpr2> m_right; // right expression subtree
  46. Value<T>: public Subexpr2
  47. void evaluate(size_t i, ValueBase* destination)
  48. T m_v[8];
  49. Columns<T>: public Subexpr2
  50. void evaluate(size_t i, ValueBase* destination)
  51. SequentialGetter<T> sg; // class bound to a column, lets you read values in a fast way
  52. Table* m_table;
  53. class ColumnAccessor<>: public Columns<double>
  54. Call diagram:
  55. -----------------------------------------------------------------------------------------------------------------------
  56. Example of 'table.first > 34.6 + table.second':
  57. size_t Compare<Greater>::find_first()-------------+
  58. | |
  59. | |
  60. | |
  61. +--> Columns<float>::evaluate() +--------> Operator<Plus>::evaluate()
  62. | |
  63. Value<float>::evaluate() Columns<float>::evaluate()
  64. Operator, Value and Columns have an evaluate(size_t i, ValueBase* destination) method which returns a Value<T>
  65. containing 8 values representing table rows i...i + 7.
  66. So Value<T> contains 8 concecutive values and all operations are based on these chunks. This is
  67. to save overhead by virtual calls needed for evaluating a query that has been dynamically constructed at runtime.
  68. Memory allocation:
  69. -----------------------------------------------------------------------------------------------------------------------
  70. Subexpressions created by the end-user are stack allocated. They are cloned to the heap when passed to UnaryOperator,
  71. Operator, and Compare. Those types own the clones and deallocate them when destroyed.
  72. Caveats, notes and todos
  73. -----------------------------------------------------------------------------------------------------------------------
  74. * Perhaps disallow columns from two different tables in same expression
  75. * The name Columns (with s) an be confusing because we also have Column (without s)
  76. * We have Columns::m_table, Query::m_table and ColumnAccessorBase::m_table that point at the same thing, even with
  77. ColumnAccessor<> extending Columns. So m_table is redundant, but this is in order to keep class dependencies and
  78. entanglement low so that the design is flexible (if you perhaps later want a Columns class that is not dependent
  79. on ColumnAccessor)
  80. Nulls
  81. -----------------------------------------------------------------------------------------------------------------------
  82. First note that at array level, nulls are distinguished between non-null in different ways:
  83. String:
  84. m_data == 0 && m_size == 0
  85. Integer, Bool stored in ArrayIntNull:
  86. value == get(0) (entry 0 determins a magic value that represents nulls)
  87. Float/double:
  88. null::is_null(value) which tests if value bit-matches one specific bit pattern reserved for null
  89. The Columns class encapsulates all this into a simple class that, for any type T has
  90. evaluate(size_t index) that reads values from a column, taking nulls in count
  91. get(index)
  92. set(index)
  93. is_null(index)
  94. set_null(index)
  95. */
  96. #ifndef REALM_QUERY_EXPRESSION_HPP
  97. #define REALM_QUERY_EXPRESSION_HPP
  98. #include <realm/aggregate_ops.hpp>
  99. #include <realm/array_timestamp.hpp>
  100. #include <realm/array_binary.hpp>
  101. #include <realm/array_string.hpp>
  102. #include <realm/array_backlink.hpp>
  103. #include <realm/array_list.hpp>
  104. #include <realm/array_key.hpp>
  105. #include <realm/array_bool.hpp>
  106. #include <realm/array_fixed_bytes.hpp>
  107. #include <realm/column_integer.hpp>
  108. #include <realm/column_type_traits.hpp>
  109. #include <realm/dictionary.hpp>
  110. #include <realm/table.hpp>
  111. #include <realm/index_string.hpp>
  112. #include <realm/query.hpp>
  113. #include <realm/list.hpp>
  114. #include <realm/set.hpp>
  115. #include <realm/query_value.hpp>
  116. #include <realm/metrics/query_info.hpp>
  117. #include <realm/util/optional.hpp>
  118. #include <realm/util/serializer.hpp>
  119. #include <numeric>
  120. #include <algorithm>
  121. // Normally, if a next-generation-syntax condition is supported by the old query_engine.hpp, a query_engine node is
  122. // created because it's faster (by a factor of 5 - 10). Because many of our existing next-generation-syntax unit
  123. // unit tests are indeed simple enough to fallback to old query_engine, query_expression gets low test coverage. Undef
  124. // flag to get higher query_expression test coverage. This is a good idea to try out each time you develop on/modify
  125. // query_expression.
  126. #define REALM_OLDQUERY_FALLBACK 1
  127. namespace realm {
  128. template <class T>
  129. T minimum(T a, T b)
  130. {
  131. return a < b ? a : b;
  132. }
  133. template <class T>
  134. struct Plus {
  135. T operator()(T v1, T v2) const
  136. {
  137. return v1 + v2;
  138. }
  139. static std::string description()
  140. {
  141. return "+";
  142. }
  143. typedef T type;
  144. };
  145. template <class T>
  146. struct Minus {
  147. T operator()(T v1, T v2) const
  148. {
  149. return v1 - v2;
  150. }
  151. static std::string description()
  152. {
  153. return "-";
  154. }
  155. typedef T type;
  156. };
  157. template <class T>
  158. struct Div {
  159. T operator()(T v1, T v2) const
  160. {
  161. return v1 / v2;
  162. }
  163. static std::string description()
  164. {
  165. return "/";
  166. }
  167. typedef T type;
  168. };
  169. template <class T>
  170. struct Mul {
  171. T operator()(T v1, T v2) const
  172. {
  173. return v1 * v2;
  174. }
  175. static std::string description()
  176. {
  177. return "*";
  178. }
  179. typedef T type;
  180. };
  181. // Unary operator
  182. template <class T>
  183. struct Pow {
  184. T operator()(T v) const
  185. {
  186. return v * v;
  187. }
  188. static std::string description()
  189. {
  190. return "^";
  191. }
  192. typedef T type;
  193. };
  194. // Finds a common type for T1 and T2 according to C++ conversion/promotion in arithmetic (float + int => float, etc)
  195. template <class T1, class T2, bool T1_is_int = std::numeric_limits<T1>::is_integer || std::is_same_v<T1, null>,
  196. bool T2_is_int = std::numeric_limits<T2>::is_integer || std::is_same_v<T2, null>,
  197. bool T1_is_widest = (sizeof(T1) > sizeof(T2) || std::is_same_v<T2, null>)>
  198. struct Common;
  199. template <class T1, class T2, bool b>
  200. struct Common<T1, T2, b, b, true> {
  201. typedef T1 type;
  202. };
  203. template <class T1, class T2, bool b>
  204. struct Common<T1, T2, b, b, false> {
  205. typedef T2 type;
  206. };
  207. template <class T1, class T2, bool b>
  208. struct Common<T1, T2, false, true, b> {
  209. typedef T1 type;
  210. };
  211. template <class T1, class T2, bool b>
  212. struct Common<T1, T2, true, false, b> {
  213. typedef T2 type;
  214. };
  215. template <typename Operator>
  216. struct OperatorOptionalAdapter {
  217. util::Optional<typename Operator::type> operator()(const Mixed& left, const Mixed& right)
  218. {
  219. if (left.is_null() || right.is_null())
  220. return util::none;
  221. return Operator()(left.template export_to_type<typename Operator::type>(),
  222. right.template export_to_type<typename Operator::type>());
  223. }
  224. util::Optional<typename Operator::type> operator()(const Mixed& arg)
  225. {
  226. if (arg.is_null())
  227. return util::none;
  228. return Operator()(arg.template export_to_type<typename Operator::type>());
  229. }
  230. };
  231. class ValueBase {
  232. public:
  233. using ValueType = QueryValue;
  234. static const size_t chunk_size = 8;
  235. bool m_from_link_list = false;
  236. ValueBase() = default;
  237. ValueBase(const ValueType& init_val)
  238. {
  239. m_first[0] = init_val;
  240. }
  241. ~ValueBase()
  242. {
  243. dealloc();
  244. }
  245. ValueBase(const ValueBase& other)
  246. {
  247. *this = other;
  248. }
  249. ValueBase& operator=(const ValueBase& other)
  250. {
  251. m_from_link_list = other.m_from_link_list;
  252. set(other.begin(), other.end());
  253. return *this;
  254. }
  255. size_t size() const
  256. {
  257. return m_size;
  258. }
  259. void init(bool from_link_list, size_t nb_values)
  260. {
  261. m_from_link_list = from_link_list;
  262. resize(nb_values);
  263. }
  264. void init_for_links(bool only_unary_links, size_t size)
  265. {
  266. if (only_unary_links) {
  267. REALM_ASSERT(size <= 1);
  268. init(false, 1);
  269. set_null(0);
  270. }
  271. else {
  272. init(true, size);
  273. }
  274. }
  275. void set_null(size_t ndx)
  276. {
  277. m_first[ndx] = ValueType();
  278. }
  279. template <class T>
  280. void set(size_t ndx, const T& val)
  281. {
  282. if constexpr (std::is_same<T, float>::value || std::is_same<T, double>::value) {
  283. m_first[ndx] = null::is_null_float(val) ? ValueType() : ValueType(val);
  284. }
  285. else {
  286. m_first[ndx] = ValueType(val);
  287. }
  288. }
  289. template <class T>
  290. void set(T b, T e)
  291. {
  292. size_t sz = e - b;
  293. resize(sz);
  294. size_t i = 0;
  295. for (auto from = b; from != e; ++from) {
  296. set(i, *from);
  297. i++;
  298. }
  299. }
  300. ValueType& operator[](size_t n)
  301. {
  302. return m_first[n];
  303. }
  304. const ValueType& operator[](size_t n) const
  305. {
  306. return m_first[n];
  307. }
  308. const ValueType& get(size_t n) const
  309. {
  310. return m_first[n];
  311. }
  312. ValueType* begin()
  313. {
  314. return m_first;
  315. }
  316. const ValueType* begin() const
  317. {
  318. return m_first;
  319. }
  320. ValueType* end()
  321. {
  322. return m_first + m_size;
  323. }
  324. const ValueType* end() const
  325. {
  326. return m_first + m_size;
  327. }
  328. template <class TOperator>
  329. REALM_FORCEINLINE void fun(const ValueBase& left, const ValueBase& right)
  330. {
  331. OperatorOptionalAdapter<TOperator> o;
  332. if (!left.m_from_link_list && !right.m_from_link_list) {
  333. // Operate on values one-by-one (one value is one row; no links)
  334. size_t min = std::min(left.size(), right.size());
  335. init(false, min);
  336. for (size_t i = 0; i < min; i++) {
  337. set(i, o(left[i], right[i]));
  338. }
  339. }
  340. else if (left.m_from_link_list && right.m_from_link_list) {
  341. // FIXME: Many-to-many links not supported yet. Need to specify behaviour
  342. REALM_ASSERT_DEBUG(false);
  343. }
  344. else if (!left.m_from_link_list && right.m_from_link_list) {
  345. // Right values come from link. Left must come from single row.
  346. REALM_ASSERT_DEBUG(left.size() > 0);
  347. init(true, right.size());
  348. auto left_value = left[0];
  349. for (size_t i = 0; i < right.size(); i++) {
  350. set(i, o(left_value, right[i]));
  351. }
  352. }
  353. else if (left.m_from_link_list && !right.m_from_link_list) {
  354. // Same as above, but with left values coming from links
  355. REALM_ASSERT_DEBUG(right.size() > 0);
  356. init(true, left.size());
  357. auto right_value = right[0];
  358. for (size_t i = 0; i < left.size(); i++) {
  359. set(i, o(left[i], right_value));
  360. }
  361. }
  362. }
  363. template <class TOperator>
  364. REALM_FORCEINLINE void fun(const ValueBase& value)
  365. {
  366. init(value.m_from_link_list, value.size());
  367. OperatorOptionalAdapter<TOperator> o;
  368. for (size_t i = 0; i < value.size(); i++) {
  369. set(i, o(value[i]));
  370. }
  371. }
  372. // Given a TCond (==, !=, >, <, >=, <=) and two Value<T>, return index of first match
  373. template <class TCond>
  374. REALM_FORCEINLINE static size_t compare_const(const ValueType& left, ValueBase& right,
  375. ExpressionComparisonType comparison)
  376. {
  377. TCond c;
  378. const size_t sz = right.size();
  379. if (!right.m_from_link_list) {
  380. REALM_ASSERT_DEBUG(comparison ==
  381. ExpressionComparisonType::Any); // ALL/NONE not supported for non list types
  382. for (size_t m = 0; m < sz; m++) {
  383. if (c(left, right[m]))
  384. return m;
  385. }
  386. }
  387. else {
  388. for (size_t m = 0; m < sz; m++) {
  389. bool match = c(left, right[m]);
  390. if (match) {
  391. if (comparison == ExpressionComparisonType::Any) {
  392. return 0;
  393. }
  394. if (comparison == ExpressionComparisonType::None) {
  395. return not_found; // one matched
  396. }
  397. }
  398. else {
  399. if (comparison == ExpressionComparisonType::All) {
  400. return not_found;
  401. }
  402. }
  403. }
  404. if (comparison == ExpressionComparisonType::None || comparison == ExpressionComparisonType::All) {
  405. return 0; // either none or all
  406. }
  407. }
  408. return not_found;
  409. }
  410. template <class TCond>
  411. REALM_FORCEINLINE static size_t compare(const ValueBase& left, const ValueBase& right,
  412. ExpressionComparisonType left_cmp_type,
  413. ExpressionComparisonType right_cmp_type)
  414. {
  415. TCond c;
  416. if (!left.m_from_link_list && !right.m_from_link_list) {
  417. REALM_ASSERT_DEBUG(left_cmp_type ==
  418. ExpressionComparisonType::Any); // ALL/NONE not supported for non list types
  419. REALM_ASSERT_DEBUG(right_cmp_type ==
  420. ExpressionComparisonType::Any); // ALL/NONE not supported for non list types
  421. // Compare values one-by-one (one value is one row; no link lists)
  422. size_t min = minimum(left.size(), right.size());
  423. for (size_t m = 0; m < min; m++) {
  424. if (c(left[m], right[m]))
  425. return m;
  426. }
  427. }
  428. else if (left.m_from_link_list && right.m_from_link_list) {
  429. // FIXME: Many-to-many links not supported yet. Need to specify behaviour
  430. // knowing the comparison types means we can potentially support things such as:
  431. // ALL list.int > list.[FIRST].int
  432. // ANY list.int > ALL list2.int
  433. // NONE list.int > ANY list2.int
  434. REALM_ASSERT_DEBUG(false);
  435. }
  436. else if (!left.m_from_link_list && right.m_from_link_list) {
  437. // Right values come from link list. Left must come from single row. Semantics: Match if at least 1
  438. // linked-to-value fulfills the condition
  439. REALM_ASSERT_DEBUG(left.size() > 0);
  440. const size_t num_right_values = right.size();
  441. ValueType left_val = left[0];
  442. for (size_t r = 0; r < num_right_values; r++) {
  443. bool match = c(left_val, right[r]);
  444. if (match) {
  445. if (right_cmp_type == ExpressionComparisonType::Any) {
  446. return 0;
  447. }
  448. if (right_cmp_type == ExpressionComparisonType::None) {
  449. return not_found; // one matched
  450. }
  451. }
  452. else {
  453. if (right_cmp_type == ExpressionComparisonType::All) {
  454. return not_found;
  455. }
  456. }
  457. }
  458. if (right_cmp_type == ExpressionComparisonType::None || right_cmp_type == ExpressionComparisonType::All) {
  459. return 0; // either none or all
  460. }
  461. }
  462. else if (left.m_from_link_list && !right.m_from_link_list) {
  463. // Same as above, but with left values coming from link list.
  464. REALM_ASSERT_DEBUG(right.size() > 0);
  465. const size_t num_left_values = left.size();
  466. ValueType right_val = right[0];
  467. for (size_t l = 0; l < num_left_values; l++) {
  468. bool match = c(left[l], right_val);
  469. if (match) {
  470. if (left_cmp_type == ExpressionComparisonType::Any) {
  471. return 0;
  472. }
  473. if (left_cmp_type == ExpressionComparisonType::None) {
  474. return not_found; // one matched
  475. }
  476. }
  477. else {
  478. if (left_cmp_type == ExpressionComparisonType::All) {
  479. return not_found;
  480. }
  481. }
  482. }
  483. if (left_cmp_type == ExpressionComparisonType::None || left_cmp_type == ExpressionComparisonType::All) {
  484. return 0; // either none or all
  485. }
  486. }
  487. return not_found; // no match
  488. }
  489. private:
  490. // If true, all values in the class come from a link list of a single field in the parent table (m_table). If
  491. // false, then values come from successive rows of m_table (query operations are operated on in bulks for speed)
  492. static constexpr size_t prealloc = 8;
  493. QueryValue m_cache[prealloc];
  494. QueryValue* m_first = &m_cache[0];
  495. size_t m_size = 1;
  496. void resize(size_t size)
  497. {
  498. if (size == m_size)
  499. return;
  500. dealloc();
  501. m_size = size;
  502. if (m_size > 0) {
  503. if (m_size > prealloc)
  504. m_first = new QueryValue[m_size];
  505. else
  506. m_first = &m_cache[0];
  507. }
  508. }
  509. void dealloc()
  510. {
  511. if (m_first) {
  512. if (m_size > prealloc)
  513. delete[] m_first;
  514. m_first = nullptr;
  515. }
  516. }
  517. void fill(const QueryValue& val)
  518. {
  519. for (size_t i = 0; i < m_size; i++) {
  520. m_first[i] = val;
  521. }
  522. }
  523. };
  524. class Expression {
  525. public:
  526. Expression() {}
  527. virtual ~Expression() {}
  528. virtual double init()
  529. {
  530. return 50.0; // Default dT
  531. }
  532. virtual size_t find_first(size_t start, size_t end) const = 0;
  533. virtual void set_base_table(ConstTableRef table) = 0;
  534. virtual void set_cluster(const Cluster*) = 0;
  535. virtual void collect_dependencies(std::vector<TableKey>&) const {}
  536. virtual ConstTableRef get_base_table() const = 0;
  537. virtual std::string description(util::serializer::SerialisationState& state) const = 0;
  538. virtual std::unique_ptr<Expression> clone() const = 0;
  539. };
  540. template <typename T, typename... Args>
  541. std::unique_ptr<Expression> make_expression(Args&&... args)
  542. {
  543. return std::unique_ptr<Expression>(new T(std::forward<Args>(args)...));
  544. }
  545. class Subexpr {
  546. public:
  547. virtual ~Subexpr() {}
  548. virtual std::unique_ptr<Subexpr> clone() const = 0;
  549. // When the user constructs a query, it always "belongs" to one single base/parent table (regardless of
  550. // any links or not and regardless of any queries assembled with || or &&). When you do a Query::find(),
  551. // then Query::m_table is set to this table, and set_base_table() is called on all Columns and LinkMaps in
  552. // the query expression tree so that they can set/update their internals as required.
  553. //
  554. // During thread-handover of a Query, set_base_table() is also called to make objects point at the new table
  555. // instead of the old one from the old thread.
  556. virtual void set_base_table(ConstTableRef) {}
  557. virtual std::string description(util::serializer::SerialisationState& state) const = 0;
  558. virtual void set_cluster(const Cluster*) {}
  559. // Recursively fetch tables of columns in expression tree. Used when user first builds a stand-alone expression
  560. // and
  561. // binds it to a Query at a later time
  562. virtual ConstTableRef get_base_table() const
  563. {
  564. return nullptr;
  565. }
  566. virtual void collect_dependencies(std::vector<TableKey>&) const {}
  567. virtual bool has_constant_evaluation() const
  568. {
  569. return false;
  570. }
  571. virtual bool has_multiple_values() const
  572. {
  573. return false;
  574. }
  575. virtual bool has_search_index() const
  576. {
  577. return false;
  578. }
  579. virtual std::vector<ObjKey> find_all(Mixed) const
  580. {
  581. return {};
  582. }
  583. virtual DataType get_type() const = 0;
  584. virtual void evaluate(size_t index, ValueBase& destination) = 0;
  585. // This function supports SubColumnAggregate
  586. virtual void evaluate(ObjKey, ValueBase&)
  587. {
  588. REALM_ASSERT(false); // Unimplemented
  589. }
  590. virtual Mixed get_mixed()
  591. {
  592. return {};
  593. }
  594. virtual ExpressionComparisonType get_comparison_type() const
  595. {
  596. return ExpressionComparisonType::Any;
  597. }
  598. };
  599. template <typename T, typename... Args>
  600. std::unique_ptr<Subexpr> make_subexpr(Args&&... args)
  601. {
  602. return std::unique_ptr<Subexpr>(new T(std::forward<Args>(args)...));
  603. }
  604. template <class T>
  605. class Columns;
  606. template <class T>
  607. class Value;
  608. class ConstantMixedValue;
  609. template <class T>
  610. class Subexpr2;
  611. template <class oper, class TLeft = Subexpr, class TRight = Subexpr>
  612. class Operator;
  613. template <class oper, class TLeft = Subexpr>
  614. class UnaryOperator;
  615. template <class oper, class TLeft = Subexpr>
  616. class SizeOperator;
  617. template <class oper>
  618. class TypeOfValueOperator;
  619. template <class TCond>
  620. class Compare;
  621. template <bool has_links>
  622. class UnaryLinkCompare;
  623. class ColumnAccessorBase;
  624. // Handle cases where left side is a constant (int, float, int64_t, double, StringData)
  625. template <class Cond, class L, class R>
  626. Query create(L left, const Subexpr2<R>& right)
  627. {
  628. // Purpose of below code is to intercept the creation of a condition and test if it's supported by the old
  629. // query_engine.hpp which is faster. If it's supported, create a query_engine.hpp node, otherwise create a
  630. // query_expression.hpp node.
  631. //
  632. // This method intercepts only Value <cond> Subexpr2. Interception of Subexpr2 <cond> Subexpr is elsewhere.
  633. constexpr const bool supported_by_old_query_engine =
  634. (std::numeric_limits<L>::is_integer && std::numeric_limits<R>::is_integer) || std::is_same_v<R, Mixed> ||
  635. (std::is_same_v<L, R> &&
  636. realm::is_any_v<L, double, float, Timestamp, StringData, BinaryData, ObjectId, UUID>);
  637. if constexpr (REALM_OLDQUERY_FALLBACK && supported_by_old_query_engine) {
  638. const Columns<R>* column = dynamic_cast<const Columns<R>*>(&right);
  639. // TODO: recognize size operator expressions
  640. // auto size_operator = dynamic_cast<const SizeOperator<Size<StringData>, Subexpr>*>(&right);
  641. if (column && !column->links_exist()) {
  642. ConstTableRef t = column->get_base_table();
  643. Query q(t);
  644. if constexpr (std::is_same_v<Cond, Less>)
  645. q.greater(column->column_key(), static_cast<R>(left));
  646. else if constexpr (std::is_same_v<Cond, Greater>)
  647. q.less(column->column_key(), static_cast<R>(left));
  648. else if constexpr (std::is_same_v<Cond, Equal>)
  649. q.equal(column->column_key(), static_cast<R>(left));
  650. else if constexpr (std::is_same_v<Cond, NotEqual>)
  651. q.not_equal(column->column_key(), static_cast<R>(left));
  652. else if constexpr (std::is_same_v<Cond, LessEqual>)
  653. q.greater_equal(column->column_key(), static_cast<R>(left));
  654. else if constexpr (std::is_same_v<Cond, GreaterEqual>)
  655. q.less_equal(column->column_key(), static_cast<R>(left));
  656. else if constexpr (std::is_same_v<Cond, EqualIns>)
  657. q.equal(column->column_key(), left, false);
  658. else if constexpr (std::is_same_v<Cond, NotEqualIns>)
  659. q.not_equal(column->column_key(), left, false);
  660. else if constexpr (std::is_same_v<Cond, BeginsWith>)
  661. q.begins_with(column->column_key(), left);
  662. else if constexpr (std::is_same_v<Cond, BeginsWithIns>)
  663. q.begins_with(column->column_key(), left, false);
  664. else if constexpr (std::is_same_v<Cond, EndsWith>)
  665. q.ends_with(column->column_key(), left);
  666. else if constexpr (std::is_same_v<Cond, EndsWithIns>)
  667. q.ends_with(column->column_key(), left, false);
  668. else if constexpr (std::is_same_v<Cond, Contains>)
  669. q.contains(column->column_key(), left);
  670. else if constexpr (std::is_same_v<Cond, ContainsIns>)
  671. q.contains(column->column_key(), left, false);
  672. else if constexpr (std::is_same_v<Cond, Like>)
  673. q.like(column->column_key(), left);
  674. else if constexpr (std::is_same_v<Cond, LikeIns>)
  675. q.like(column->column_key(), left, false);
  676. else {
  677. // query_engine.hpp does not support this Cond. Please either add support for it in query_engine.hpp
  678. // or fallback to using use 'return new Compare<>' instead.
  679. REALM_ASSERT(false);
  680. }
  681. return q;
  682. }
  683. }
  684. // Return query_expression.hpp node
  685. if constexpr (std::is_same_v<L, TypeOfValue>) {
  686. return make_expression<Compare<Cond>>(make_subexpr<Value<TypeOfValue>>(left), right.clone());
  687. }
  688. else {
  689. return make_expression<Compare<Cond>>(make_subexpr<ConstantMixedValue>(left), right.clone());
  690. }
  691. }
  692. // All overloads where left-hand-side is Subexpr2<L>:
  693. //
  694. // left-hand-side operator right-hand-side
  695. // Subexpr2<L> +, -, *, /, <, >, ==, !=, <=, >= R, Subexpr2<R>
  696. //
  697. // For L = R = {int, int64_t, float, double, StringData, Timestamp}:
  698. template <class L, class R>
  699. class Overloads {
  700. typedef typename Common<L, R>::type CommonType;
  701. std::unique_ptr<Subexpr> clone_subexpr() const
  702. {
  703. return static_cast<const Subexpr2<L>&>(*this).clone();
  704. }
  705. public:
  706. // Arithmetic, right side constant
  707. Operator<Plus<CommonType>> operator+(R right) const
  708. {
  709. return {clone_subexpr(), make_subexpr<Value<R>>(right)};
  710. }
  711. Operator<Minus<CommonType>> operator-(R right) const
  712. {
  713. return {clone_subexpr(), make_subexpr<Value<R>>(right)};
  714. }
  715. Operator<Mul<CommonType>> operator*(R right) const
  716. {
  717. return {clone_subexpr(), make_subexpr<Value<R>>(right)};
  718. }
  719. Operator<Div<CommonType>> operator/(R right) const
  720. {
  721. return {clone_subexpr(), make_subexpr<Value<R>>(right)};
  722. }
  723. // Arithmetic, right side subexpression
  724. Operator<Plus<CommonType>> operator+(const Subexpr2<R>& right) const
  725. {
  726. return {clone_subexpr(), right.clone()};
  727. }
  728. Operator<Minus<CommonType>> operator-(const Subexpr2<R>& right) const
  729. {
  730. return {clone_subexpr(), right.clone()};
  731. }
  732. Operator<Mul<CommonType>> operator*(const Subexpr2<R>& right) const
  733. {
  734. return {clone_subexpr(), right.clone()};
  735. }
  736. Operator<Div<CommonType>> operator/(const Subexpr2<R>& right) const
  737. {
  738. return {clone_subexpr(), right.clone()};
  739. }
  740. // Compare, right side constant
  741. Query operator>(R right)
  742. {
  743. return create<Less>(right, static_cast<Subexpr2<L>&>(*this));
  744. }
  745. Query operator<(R right)
  746. {
  747. return create<Greater>(right, static_cast<Subexpr2<L>&>(*this));
  748. }
  749. Query operator>=(R right)
  750. {
  751. return create<LessEqual>(right, static_cast<Subexpr2<L>&>(*this));
  752. }
  753. Query operator<=(R right)
  754. {
  755. return create<GreaterEqual>(right, static_cast<Subexpr2<L>&>(*this));
  756. }
  757. Query operator==(R right)
  758. {
  759. return create<Equal>(right, static_cast<Subexpr2<L>&>(*this));
  760. }
  761. Query operator!=(R right)
  762. {
  763. return create<NotEqual>(right, static_cast<Subexpr2<L>&>(*this));
  764. }
  765. // Purpose of this method is to intercept the creation of a condition and test if it's supported by the old
  766. // query_engine.hpp which is faster. If it's supported, create a query_engine.hpp node, otherwise create a
  767. // query_expression.hpp node.
  768. //
  769. // This method intercepts Subexpr2 <cond> Subexpr2 only. Value <cond> Subexpr2 is intercepted elsewhere.
  770. template <class Cond>
  771. Query create2(const Subexpr2<R>& right)
  772. {
  773. #ifdef REALM_OLDQUERY_FALLBACK // if not defined, never fallback query_engine; always use query_expression
  774. // Test if expressions are of type Columns. Other possibilities are Value and Operator.
  775. const Columns<L>* left_col = dynamic_cast<const Columns<L>*>(static_cast<Subexpr2<L>*>(this));
  776. const Columns<R>* right_col = dynamic_cast<const Columns<R>*>(&right);
  777. // query_engine supports 'T-column <op> <T-column>' for T = {int64_t, float, double}, op = {<, >, ==, !=, <=,
  778. // >=},
  779. // but only if both columns are non-nullable, and aren't in linked tables.
  780. if (left_col && right_col) {
  781. ConstTableRef t = left_col->get_base_table();
  782. ConstTableRef t_right = right_col->get_base_table();
  783. REALM_ASSERT_DEBUG(t);
  784. REALM_ASSERT_DEBUG(t_right);
  785. // we only support multi column comparisons if they stem from the same table
  786. if (t->get_key() != t_right->get_key()) {
  787. throw std::runtime_error(util::format(
  788. "Comparison between two properties must be linked with a relationship or exist on the same "
  789. "Table (%1 and %2)",
  790. t->get_name(), t_right->get_name()));
  791. }
  792. if (!left_col->links_exist() && !right_col->links_exist()) {
  793. if constexpr (std::is_same_v<Cond, Less>)
  794. return Query(t).less(left_col->column_key(), right_col->column_key());
  795. if constexpr (std::is_same_v<Cond, Greater>)
  796. return Query(t).greater(left_col->column_key(), right_col->column_key());
  797. if constexpr (std::is_same_v<Cond, Equal>)
  798. return Query(t).equal(left_col->column_key(), right_col->column_key());
  799. if constexpr (std::is_same_v<Cond, NotEqual>)
  800. return Query(t).not_equal(left_col->column_key(), right_col->column_key());
  801. if constexpr (std::is_same_v<Cond, LessEqual>)
  802. return Query(t).less_equal(left_col->column_key(), right_col->column_key());
  803. if constexpr (std::is_same_v<Cond, GreaterEqual>)
  804. return Query(t).greater_equal(left_col->column_key(), right_col->column_key());
  805. }
  806. }
  807. #endif
  808. // Return query_expression.hpp node
  809. return make_expression<Compare<Cond>>(clone_subexpr(), right.clone());
  810. }
  811. // Compare, right side subexpression
  812. Query operator==(const Subexpr2<R>& right)
  813. {
  814. return create2<Equal>(right);
  815. }
  816. Query operator!=(const Subexpr2<R>& right)
  817. {
  818. return create2<NotEqual>(right);
  819. }
  820. Query operator>(const Subexpr2<R>& right)
  821. {
  822. return create2<Greater>(right);
  823. }
  824. Query operator<(const Subexpr2<R>& right)
  825. {
  826. return create2<Less>(right);
  827. }
  828. Query operator>=(const Subexpr2<R>& right)
  829. {
  830. return create2<GreaterEqual>(right);
  831. }
  832. Query operator<=(const Subexpr2<R>& right)
  833. {
  834. return create2<LessEqual>(right);
  835. }
  836. };
  837. // With this wrapper class we can define just 20 overloads inside Overloads<L, R> instead of 5 * 20 = 100. Todo: We
  838. // can
  839. // consider if it's simpler/better to remove this class completely and just list all 100 overloads manually anyway.
  840. template <class T>
  841. class Subexpr2 : public Subexpr,
  842. public Overloads<T, const char*>,
  843. public Overloads<T, int>,
  844. public Overloads<T, float>,
  845. public Overloads<T, double>,
  846. public Overloads<T, int64_t>,
  847. public Overloads<T, StringData>,
  848. public Overloads<T, bool>,
  849. public Overloads<T, Timestamp>,
  850. public Overloads<T, ObjectId>,
  851. public Overloads<T, Decimal128>,
  852. public Overloads<T, UUID>,
  853. public Overloads<T, Mixed>,
  854. public Overloads<T, null> {
  855. public:
  856. virtual ~Subexpr2() {}
  857. DataType get_type() const final
  858. {
  859. return ColumnTypeTraits<T>::id;
  860. }
  861. #define RLM_U2(t, o) using Overloads<T, t>::operator o;
  862. #define RLM_U(o) \
  863. RLM_U2(int, o) \
  864. RLM_U2(float, o) \
  865. RLM_U2(double, o) \
  866. RLM_U2(int64_t, o) \
  867. RLM_U2(StringData, o) \
  868. RLM_U2(bool, o) \
  869. RLM_U2(Timestamp, o) \
  870. RLM_U2(ObjectId, o) \
  871. RLM_U2(Decimal128, o) \
  872. RLM_U2(UUID, o) \
  873. RLM_U2(Mixed, o) \
  874. RLM_U2(null, o)
  875. RLM_U(+) RLM_U(-) RLM_U(*) RLM_U(/) RLM_U(>) RLM_U(<) RLM_U(==) RLM_U(!=) RLM_U(>=) RLM_U(<=)
  876. };
  877. // Subexpr2<Link> only provides equality comparisons. Their implementations can be found later in this file.
  878. template <>
  879. class Subexpr2<Link> : public Subexpr {
  880. public:
  881. DataType get_type() const
  882. {
  883. return type_Link;
  884. }
  885. };
  886. template <>
  887. class Subexpr2<StringData> : public Subexpr, public Overloads<StringData, StringData> {
  888. public:
  889. Query equal(StringData sd, bool case_sensitive = true);
  890. Query equal(const Subexpr2<StringData>& col, bool case_sensitive = true);
  891. Query not_equal(StringData sd, bool case_sensitive = true);
  892. Query not_equal(const Subexpr2<StringData>& col, bool case_sensitive = true);
  893. Query begins_with(StringData sd, bool case_sensitive = true);
  894. Query begins_with(const Subexpr2<StringData>& col, bool case_sensitive = true);
  895. Query ends_with(StringData sd, bool case_sensitive = true);
  896. Query ends_with(const Subexpr2<StringData>& col, bool case_sensitive = true);
  897. Query contains(StringData sd, bool case_sensitive = true);
  898. Query contains(const Subexpr2<StringData>& col, bool case_sensitive = true);
  899. Query like(StringData sd, bool case_sensitive = true);
  900. Query like(const Subexpr2<StringData>& col, bool case_sensitive = true);
  901. DataType get_type() const final
  902. {
  903. return type_String;
  904. }
  905. };
  906. template <>
  907. class Subexpr2<BinaryData> : public Subexpr, public Overloads<BinaryData, BinaryData> {
  908. public:
  909. Query equal(BinaryData sd, bool case_sensitive = true);
  910. Query equal(const Subexpr2<BinaryData>& col, bool case_sensitive = true);
  911. Query not_equal(BinaryData sd, bool case_sensitive = true);
  912. Query not_equal(const Subexpr2<BinaryData>& col, bool case_sensitive = true);
  913. Query begins_with(BinaryData sd, bool case_sensitive = true);
  914. Query begins_with(const Subexpr2<BinaryData>& col, bool case_sensitive = true);
  915. Query ends_with(BinaryData sd, bool case_sensitive = true);
  916. Query ends_with(const Subexpr2<BinaryData>& col, bool case_sensitive = true);
  917. Query contains(BinaryData sd, bool case_sensitive = true);
  918. Query contains(const Subexpr2<BinaryData>& col, bool case_sensitive = true);
  919. Query like(BinaryData sd, bool case_sensitive = true);
  920. Query like(const Subexpr2<BinaryData>& col, bool case_sensitive = true);
  921. DataType get_type() const final
  922. {
  923. return type_Binary;
  924. }
  925. };
  926. template <>
  927. class Subexpr2<Mixed> : public Subexpr,
  928. public Overloads<Mixed, Mixed>,
  929. public Overloads<Mixed, const char*>,
  930. public Overloads<Mixed, int>,
  931. public Overloads<Mixed, float>,
  932. public Overloads<Mixed, double>,
  933. public Overloads<Mixed, int64_t>,
  934. public Overloads<Mixed, StringData>,
  935. public Overloads<Mixed, bool>,
  936. public Overloads<Mixed, Timestamp>,
  937. public Overloads<Mixed, ObjectId>,
  938. public Overloads<Mixed, Decimal128>,
  939. public Overloads<Mixed, UUID>,
  940. public Overloads<Mixed, null> {
  941. public:
  942. Query equal(Mixed sd, bool case_sensitive = true);
  943. Query equal(const Subexpr2<Mixed>& col, bool case_sensitive = true);
  944. Query not_equal(Mixed sd, bool case_sensitive = true);
  945. Query not_equal(const Subexpr2<Mixed>& col, bool case_sensitive = true);
  946. Query begins_with(Mixed sd, bool case_sensitive = true);
  947. Query begins_with(const Subexpr2<Mixed>& col, bool case_sensitive = true);
  948. Query ends_with(Mixed sd, bool case_sensitive = true);
  949. Query ends_with(const Subexpr2<Mixed>& col, bool case_sensitive = true);
  950. Query contains(Mixed sd, bool case_sensitive = true);
  951. Query contains(const Subexpr2<Mixed>& col, bool case_sensitive = true);
  952. Query like(Mixed sd, bool case_sensitive = true);
  953. Query like(const Subexpr2<Mixed>& col, bool case_sensitive = true);
  954. DataType get_type() const final
  955. {
  956. return type_Mixed;
  957. }
  958. using T = Mixed; // used inside the following macros for operator overloads
  959. RLM_U(+) RLM_U(-) RLM_U(*) RLM_U(/) RLM_U(>) RLM_U(<) RLM_U(==) RLM_U(!=) RLM_U(>=) RLM_U(<=)
  960. };
  961. template <>
  962. class Subexpr2<TypeOfValue> : public Subexpr, public Overloads<TypeOfValue, TypeOfValue> {
  963. public:
  964. Query equal(TypeOfValue v);
  965. Query equal(const TypeOfValueOperator<Mixed>& col);
  966. Query not_equal(TypeOfValue v);
  967. Query not_equal(const TypeOfValueOperator<Mixed>& col);
  968. DataType get_type() const final
  969. {
  970. return type_TypeOfValue;
  971. }
  972. };
  973. struct TrueExpression : Expression {
  974. size_t find_first(size_t start, size_t end) const override
  975. {
  976. REALM_ASSERT(start <= end);
  977. if (start != end)
  978. return start;
  979. return realm::not_found;
  980. }
  981. void set_base_table(ConstTableRef) override {}
  982. void set_cluster(const Cluster*) override {}
  983. ConstTableRef get_base_table() const override
  984. {
  985. return nullptr;
  986. }
  987. std::string description(util::serializer::SerialisationState&) const override
  988. {
  989. return "TRUEPREDICATE";
  990. }
  991. std::unique_ptr<Expression> clone() const override
  992. {
  993. return std::unique_ptr<Expression>(new TrueExpression(*this));
  994. }
  995. };
  996. struct FalseExpression : Expression {
  997. size_t find_first(size_t, size_t) const override
  998. {
  999. return realm::not_found;
  1000. }
  1001. void set_base_table(ConstTableRef) override {}
  1002. void set_cluster(const Cluster*) override {}
  1003. std::string description(util::serializer::SerialisationState&) const override
  1004. {
  1005. return "FALSEPREDICATE";
  1006. }
  1007. ConstTableRef get_base_table() const override
  1008. {
  1009. return nullptr;
  1010. }
  1011. std::unique_ptr<Expression> clone() const override
  1012. {
  1013. return std::unique_ptr<Expression>(new FalseExpression(*this));
  1014. }
  1015. };
  1016. // Stores N values of type T. Can also exchange data with other ValueBase of different types
  1017. template <class T>
  1018. class Value : public ValueBase, public Subexpr2<T> {
  1019. public:
  1020. Value() = default;
  1021. Value(T init)
  1022. : ValueBase(QueryValue(init))
  1023. {
  1024. }
  1025. std::string description(util::serializer::SerialisationState&) const override
  1026. {
  1027. if (ValueBase::m_from_link_list) {
  1028. return util::serializer::print_value(util::to_string(ValueBase::size()) +
  1029. (ValueBase::size() == 1 ? " value" : " values"));
  1030. }
  1031. if (size() > 0) {
  1032. auto val = get(0);
  1033. if (val.is_null())
  1034. return "NULL";
  1035. else {
  1036. if constexpr (std::is_same_v<T, TypeOfValue>) {
  1037. return util::serializer::print_value(val.get_type_of_value());
  1038. }
  1039. else {
  1040. return util::serializer::print_value(val.template get<T>());
  1041. }
  1042. }
  1043. }
  1044. return "";
  1045. }
  1046. bool has_constant_evaluation() const override
  1047. {
  1048. return true;
  1049. }
  1050. Mixed get_mixed() override
  1051. {
  1052. return get(0);
  1053. }
  1054. void evaluate(size_t, ValueBase& destination) override
  1055. {
  1056. destination = *this;
  1057. }
  1058. std::unique_ptr<Subexpr> clone() const override
  1059. {
  1060. return make_subexpr<Value<T>>(*this);
  1061. }
  1062. };
  1063. class ConstantMixedValue : public Value<Mixed> {
  1064. public:
  1065. ConstantMixedValue(const Mixed& val)
  1066. : Value(val)
  1067. {
  1068. begin()->use_buffer(m_buffer);
  1069. }
  1070. std::unique_ptr<Subexpr> clone() const override
  1071. {
  1072. return std::unique_ptr<Subexpr>(new ConstantMixedValue(*this));
  1073. }
  1074. private:
  1075. ConstantMixedValue(const ConstantMixedValue& other)
  1076. : Value(other)
  1077. {
  1078. begin()->use_buffer(m_buffer);
  1079. }
  1080. std::string m_buffer;
  1081. };
  1082. class ConstantStringValue : public Value<StringData> {
  1083. public:
  1084. ConstantStringValue(const StringData& string)
  1085. : Value()
  1086. , m_string(string.is_null() ? util::none : util::make_optional(std::string(string)))
  1087. {
  1088. if (m_string)
  1089. set(0, *m_string);
  1090. }
  1091. std::unique_ptr<Subexpr> clone() const override
  1092. {
  1093. return std::unique_ptr<Subexpr>(new ConstantStringValue(*this));
  1094. }
  1095. private:
  1096. ConstantStringValue(const ConstantStringValue& other)
  1097. : Value()
  1098. , m_string(other.m_string)
  1099. {
  1100. if (m_string)
  1101. set(0, *m_string);
  1102. }
  1103. util::Optional<std::string> m_string;
  1104. };
  1105. class ConstantBinaryValue : public Value<BinaryData> {
  1106. public:
  1107. ConstantBinaryValue(const BinaryData& bin)
  1108. : Value()
  1109. , m_buffer(bin)
  1110. {
  1111. if (m_buffer.data())
  1112. set(0, BinaryData(m_buffer.data(), m_buffer.size()));
  1113. }
  1114. std::unique_ptr<Subexpr> clone() const override
  1115. {
  1116. return std::unique_ptr<Subexpr>(new ConstantBinaryValue(*this));
  1117. }
  1118. private:
  1119. ConstantBinaryValue(const ConstantBinaryValue& other)
  1120. : Value()
  1121. , m_buffer(other.m_buffer)
  1122. {
  1123. if (m_buffer.data())
  1124. set(0, BinaryData(m_buffer.data(), m_buffer.size()));
  1125. }
  1126. OwnedBinaryData m_buffer;
  1127. };
  1128. // All overloads where left-hand-side is L:
  1129. //
  1130. // left-hand-side operator right-hand-side
  1131. // L +, -, *, /, <, >, ==, !=, <=, >= Subexpr2<R>
  1132. //
  1133. // For L = R = {int, int64_t, float, double, Timestamp, ObjectId, Decimal128}:
  1134. // Compare numeric values
  1135. template <class R>
  1136. Query operator>(double left, const Subexpr2<R>& right)
  1137. {
  1138. return create<Greater>(left, right);
  1139. }
  1140. template <class R>
  1141. Query operator>(float left, const Subexpr2<R>& right)
  1142. {
  1143. return create<Greater>(left, right);
  1144. }
  1145. template <class R>
  1146. Query operator>(int left, const Subexpr2<R>& right)
  1147. {
  1148. return create<Greater>(left, right);
  1149. }
  1150. template <class R>
  1151. Query operator>(int64_t left, const Subexpr2<R>& right)
  1152. {
  1153. return create<Greater>(left, right);
  1154. }
  1155. template <class R>
  1156. Query operator>(Timestamp left, const Subexpr2<R>& right)
  1157. {
  1158. return create<Greater>(left, right);
  1159. }
  1160. template <class R>
  1161. Query operator>(ObjectId left, const Subexpr2<R>& right)
  1162. {
  1163. return create<Greater>(left, right);
  1164. }
  1165. template <class R>
  1166. Query operator>(Decimal128 left, const Subexpr2<R>& right)
  1167. {
  1168. return create<Greater>(left, right);
  1169. }
  1170. template <class R>
  1171. Query operator<(double left, const Subexpr2<R>& right)
  1172. {
  1173. return create<Less>(left, right);
  1174. }
  1175. template <class R>
  1176. Query operator<(float left, const Subexpr2<R>& right)
  1177. {
  1178. return create<Less>(left, right);
  1179. }
  1180. template <class R>
  1181. Query operator<(int left, const Subexpr2<R>& right)
  1182. {
  1183. return create<Less>(left, right);
  1184. }
  1185. template <class R>
  1186. Query operator<(int64_t left, const Subexpr2<R>& right)
  1187. {
  1188. return create<Less>(left, right);
  1189. }
  1190. template <class R>
  1191. Query operator<(Timestamp left, const Subexpr2<R>& right)
  1192. {
  1193. return create<Less>(left, right);
  1194. }
  1195. template <class R>
  1196. Query operator<(ObjectId left, const Subexpr2<R>& right)
  1197. {
  1198. return create<Less>(left, right);
  1199. }
  1200. template <class R>
  1201. Query operator<(Decimal128 left, const Subexpr2<R>& right)
  1202. {
  1203. return create<Less>(left, right);
  1204. }
  1205. template <class R>
  1206. Query operator==(double left, const Subexpr2<R>& right)
  1207. {
  1208. return create<Equal>(left, right);
  1209. }
  1210. template <class R>
  1211. Query operator==(float left, const Subexpr2<R>& right)
  1212. {
  1213. return create<Equal>(left, right);
  1214. }
  1215. template <class R>
  1216. Query operator==(int left, const Subexpr2<R>& right)
  1217. {
  1218. return create<Equal>(left, right);
  1219. }
  1220. template <class R>
  1221. Query operator==(int64_t left, const Subexpr2<R>& right)
  1222. {
  1223. return create<Equal>(left, right);
  1224. }
  1225. template <class R>
  1226. Query operator==(Timestamp left, const Subexpr2<R>& right)
  1227. {
  1228. return create<Equal>(left, right);
  1229. }
  1230. template <class R>
  1231. Query operator==(ObjectId left, const Subexpr2<R>& right)
  1232. {
  1233. return create<Equal>(left, right);
  1234. }
  1235. template <class R>
  1236. Query operator==(Decimal128 left, const Subexpr2<R>& right)
  1237. {
  1238. return create<Equal>(left, right);
  1239. }
  1240. template <class R>
  1241. Query operator==(bool left, const Subexpr2<R>& right)
  1242. {
  1243. return create<Equal>(left, right);
  1244. }
  1245. template <class R>
  1246. Query operator==(UUID left, const Subexpr2<R>& right)
  1247. {
  1248. return create<Equal>(left, right);
  1249. }
  1250. template <class R>
  1251. Query operator>=(double left, const Subexpr2<R>& right)
  1252. {
  1253. return create<GreaterEqual>(left, right);
  1254. }
  1255. template <class R>
  1256. Query operator>=(float left, const Subexpr2<R>& right)
  1257. {
  1258. return create<GreaterEqual>(left, right);
  1259. }
  1260. template <class R>
  1261. Query operator>=(int left, const Subexpr2<R>& right)
  1262. {
  1263. return create<GreaterEqual>(left, right);
  1264. }
  1265. template <class R>
  1266. Query operator>=(int64_t left, const Subexpr2<R>& right)
  1267. {
  1268. return create<GreaterEqual>(left, right);
  1269. }
  1270. template <class R>
  1271. Query operator>=(Timestamp left, const Subexpr2<R>& right)
  1272. {
  1273. return create<GreaterEqual>(left, right);
  1274. }
  1275. template <class R>
  1276. Query operator>=(ObjectId left, const Subexpr2<R>& right)
  1277. {
  1278. return create<GreaterEqual>(left, right);
  1279. }
  1280. template <class R>
  1281. Query operator>=(Decimal128 left, const Subexpr2<R>& right)
  1282. {
  1283. return create<GreaterEqual>(left, right);
  1284. }
  1285. template <class R>
  1286. Query operator<=(double left, const Subexpr2<R>& right)
  1287. {
  1288. return create<LessEqual>(left, right);
  1289. }
  1290. template <class R>
  1291. Query operator<=(float left, const Subexpr2<R>& right)
  1292. {
  1293. return create<LessEqual>(left, right);
  1294. }
  1295. template <class R>
  1296. Query operator<=(int left, const Subexpr2<R>& right)
  1297. {
  1298. return create<LessEqual>(left, right);
  1299. }
  1300. template <class R>
  1301. Query operator<=(int64_t left, const Subexpr2<R>& right)
  1302. {
  1303. return create<LessEqual>(left, right);
  1304. }
  1305. template <class R>
  1306. Query operator<=(Timestamp left, const Subexpr2<R>& right)
  1307. {
  1308. return create<LessEqual>(left, right);
  1309. }
  1310. template <class R>
  1311. Query operator<=(ObjectId left, const Subexpr2<R>& right)
  1312. {
  1313. return create<LessEqual>(left, right);
  1314. }
  1315. template <class R>
  1316. Query operator<=(Decimal128 left, const Subexpr2<R>& right)
  1317. {
  1318. return create<LessEqual>(left, right);
  1319. }
  1320. template <class R>
  1321. Query operator!=(double left, const Subexpr2<R>& right)
  1322. {
  1323. return create<NotEqual>(left, right);
  1324. }
  1325. template <class R>
  1326. Query operator!=(float left, const Subexpr2<R>& right)
  1327. {
  1328. return create<NotEqual>(left, right);
  1329. }
  1330. template <class R>
  1331. Query operator!=(int left, const Subexpr2<R>& right)
  1332. {
  1333. return create<NotEqual>(left, right);
  1334. }
  1335. template <class R>
  1336. Query operator!=(int64_t left, const Subexpr2<R>& right)
  1337. {
  1338. return create<NotEqual>(left, right);
  1339. }
  1340. template <class R>
  1341. Query operator!=(Timestamp left, const Subexpr2<R>& right)
  1342. {
  1343. return create<NotEqual>(left, right);
  1344. }
  1345. template <class R>
  1346. Query operator!=(ObjectId left, const Subexpr2<R>& right)
  1347. {
  1348. return create<NotEqual>(left, right);
  1349. }
  1350. template <class R>
  1351. Query operator!=(Decimal128 left, const Subexpr2<R>& right)
  1352. {
  1353. return create<NotEqual>(left, right);
  1354. }
  1355. template <class R>
  1356. Query operator!=(bool left, const Subexpr2<R>& right)
  1357. {
  1358. return create<NotEqual>(left, right);
  1359. }
  1360. template <class R>
  1361. Query operator!=(UUID left, const Subexpr2<R>& right)
  1362. {
  1363. return create<NotEqual>(left, right);
  1364. }
  1365. // Arithmetic
  1366. template <class R>
  1367. Operator<Plus<typename Common<R, double>::type>> operator+(double left, const Subexpr2<R>& right)
  1368. {
  1369. return {make_subexpr<Value<double>>(left), right.clone()};
  1370. }
  1371. template <class R>
  1372. Operator<Plus<typename Common<R, float>::type>> operator+(float left, const Subexpr2<R>& right)
  1373. {
  1374. return {make_subexpr<Value<float>>(left), right.clone()};
  1375. }
  1376. template <class R>
  1377. Operator<Plus<typename Common<R, int>::type>> operator+(int left, const Subexpr2<R>& right)
  1378. {
  1379. return {make_subexpr<Value<int>>(left), right.clone()};
  1380. }
  1381. template <class R>
  1382. Operator<Plus<typename Common<R, int64_t>::type>> operator+(int64_t left, const Subexpr2<R>& right)
  1383. {
  1384. return {make_subexpr<Value<int64_t>>(left), right.clone()};
  1385. }
  1386. template <class R>
  1387. Operator<Minus<typename Common<R, double>::type>> operator-(double left, const Subexpr2<R>& right)
  1388. {
  1389. return {make_subexpr<Value<double>>(left), right.clone()};
  1390. }
  1391. template <class R>
  1392. Operator<Minus<typename Common<R, float>::type>> operator-(float left, const Subexpr2<R>& right)
  1393. {
  1394. return {make_subexpr<Value<float>>(left), right.clone()};
  1395. }
  1396. template <class R>
  1397. Operator<Minus<typename Common<R, int>::type>> operator-(int left, const Subexpr2<R>& right)
  1398. {
  1399. return {make_subexpr<Value<int>>(left), right.clone()};
  1400. }
  1401. template <class R>
  1402. Operator<Minus<typename Common<R, int64_t>::type>> operator-(int64_t left, const Subexpr2<R>& right)
  1403. {
  1404. return {make_subexpr<Value<int64_t>>(left), right.clone()};
  1405. }
  1406. template <class R>
  1407. Operator<Mul<typename Common<R, double>::type>> operator*(double left, const Subexpr2<R>& right)
  1408. {
  1409. return {make_subexpr<Value<double>>(left), right.clone()};
  1410. }
  1411. template <class R>
  1412. Operator<Mul<typename Common<R, float>::type>> operator*(float left, const Subexpr2<R>& right)
  1413. {
  1414. return {make_subexpr<Value<float>>(left), right.clone()};
  1415. }
  1416. template <class R>
  1417. Operator<Mul<typename Common<R, int>::type>> operator*(int left, const Subexpr2<R>& right)
  1418. {
  1419. return {make_subexpr<Value<int>>(left), right.clone()};
  1420. }
  1421. template <class R>
  1422. Operator<Mul<typename Common<R, int64_t>::type>> operator*(int64_t left, const Subexpr2<R>& right)
  1423. {
  1424. return {make_subexpr<Value<int64_t>>(left), right.clone()};
  1425. }
  1426. template <class R>
  1427. Operator<Div<typename Common<R, double>::type>> operator/(double left, const Subexpr2<R>& right)
  1428. {
  1429. return {make_subexpr<Value<double>>(left), right.clone()};
  1430. }
  1431. template <class R>
  1432. Operator<Div<typename Common<R, float>::type>> operator/(float left, const Subexpr2<R>& right)
  1433. {
  1434. return {make_subexpr<Value<float>>(left), right.clone()};
  1435. }
  1436. template <class R>
  1437. Operator<Div<typename Common<R, int>::type>> operator/(int left, const Subexpr2<R>& right)
  1438. {
  1439. return {make_subexpr<Value<int>>(left), right.clone()};
  1440. }
  1441. template <class R>
  1442. Operator<Div<typename Common<R, int64_t>::type>> operator/(int64_t left, const Subexpr2<R>& right)
  1443. {
  1444. return {make_subexpr<Value<int64_t>>(left), right.clone()};
  1445. }
  1446. // Unary operators
  1447. template <class T>
  1448. UnaryOperator<Pow<T>> power(const Subexpr2<T>& left)
  1449. {
  1450. return {left.clone()};
  1451. }
  1452. // Classes used for LinkMap (see below).
  1453. struct LinkMapFunction {
  1454. // Your consume() method is given key within the linked-to table as argument, and you must return whether or
  1455. // not you want the LinkMapFunction to exit (return false) or continue (return true) harvesting the link tree
  1456. // for the current main table object (it will be a link tree if you have multiple type_LinkList columns
  1457. // in a link()->link() query.
  1458. virtual bool consume(ObjKey) = 0;
  1459. };
  1460. struct FindNullLinks : public LinkMapFunction {
  1461. bool consume(ObjKey) override
  1462. {
  1463. m_has_link = true;
  1464. return false; // we've found a key, so this can't be a null-link, so exit link harvesting
  1465. }
  1466. bool m_has_link = false;
  1467. };
  1468. struct MakeLinkVector : public LinkMapFunction {
  1469. MakeLinkVector(std::vector<ObjKey>& result)
  1470. : m_links(result)
  1471. {
  1472. }
  1473. bool consume(ObjKey key) override
  1474. {
  1475. m_links.push_back(key);
  1476. return true; // continue evaluation
  1477. }
  1478. std::vector<ObjKey>& m_links;
  1479. };
  1480. struct UnaryLinkResult : public LinkMapFunction {
  1481. bool consume(ObjKey key) override
  1482. {
  1483. m_result = key;
  1484. return false; // exit search, only one result ever expected
  1485. }
  1486. ObjKey m_result;
  1487. };
  1488. struct CountLinks : public LinkMapFunction {
  1489. bool consume(ObjKey) override
  1490. {
  1491. m_link_count++;
  1492. return true;
  1493. }
  1494. size_t result() const
  1495. {
  1496. return m_link_count;
  1497. }
  1498. size_t m_link_count = 0;
  1499. };
  1500. struct CountBacklinks : public LinkMapFunction {
  1501. CountBacklinks(ConstTableRef t)
  1502. : m_table(t)
  1503. {
  1504. }
  1505. bool consume(ObjKey key) override
  1506. {
  1507. m_link_count += m_table.unchecked_ptr()->get_object(key).get_backlink_count();
  1508. return true;
  1509. }
  1510. size_t result() const
  1511. {
  1512. return m_link_count;
  1513. }
  1514. ConstTableRef m_table;
  1515. size_t m_link_count = 0;
  1516. };
  1517. /*
  1518. The LinkMap and LinkMapFunction classes are used for query conditions on links themselves (contrary to conditions on
  1519. the value payload they point at).
  1520. MapLink::map_links() takes a row index of the link array as argument and follows any link chain stated in the query
  1521. (through the link()->link() methods) until the final payload table is reached, and then applies LinkMapFunction on
  1522. the linked-to key(s).
  1523. If all link columns are type_Link, then LinkMapFunction is only invoked for a single key. If one or more
  1524. columns are type_LinkList, then it may result in multiple keys.
  1525. The reason we use this map pattern is that we can exit the link-tree-traversal as early as possible, e.g. when we've
  1526. found the first link that points to key '5'. Other solutions could be a std::vector<ColKey> harvest_all_links(), or an
  1527. iterator pattern. First solution can't exit, second solution requires internal state.
  1528. */
  1529. class LinkMap {
  1530. public:
  1531. LinkMap() = default;
  1532. LinkMap(ConstTableRef table, std::vector<ColKey> columns)
  1533. : m_link_column_keys(std::move(columns))
  1534. {
  1535. set_base_table(table);
  1536. }
  1537. LinkMap(LinkMap const& other)
  1538. {
  1539. m_link_column_keys = other.m_link_column_keys;
  1540. m_tables = other.m_tables;
  1541. m_link_types = other.m_link_types;
  1542. m_only_unary_links = other.m_only_unary_links;
  1543. }
  1544. size_t get_nb_hops() const
  1545. {
  1546. return m_link_column_keys.size();
  1547. }
  1548. bool has_links() const
  1549. {
  1550. return m_link_column_keys.size() > 0;
  1551. }
  1552. ColKey get_first_column_key() const
  1553. {
  1554. REALM_ASSERT(has_links());
  1555. return m_link_column_keys[0];
  1556. }
  1557. void set_base_table(ConstTableRef table);
  1558. void set_cluster(const Cluster* cluster)
  1559. {
  1560. Allocator& alloc = get_base_table()->get_alloc();
  1561. m_array_ptr = nullptr;
  1562. switch (m_link_types[0]) {
  1563. case col_type_Link:
  1564. if (m_link_column_keys[0].is_dictionary()) {
  1565. m_array_ptr = LeafPtr(new (&m_storage.m_dict) ArrayInteger(alloc));
  1566. }
  1567. else {
  1568. m_array_ptr = LeafPtr(new (&m_storage.m_list) ArrayKey(alloc));
  1569. }
  1570. break;
  1571. case col_type_LinkList:
  1572. m_array_ptr = LeafPtr(new (&m_storage.m_linklist) ArrayList(alloc));
  1573. break;
  1574. case col_type_BackLink:
  1575. m_array_ptr = LeafPtr(new (&m_storage.m_backlink) ArrayBacklink(alloc));
  1576. break;
  1577. default:
  1578. break;
  1579. }
  1580. // m_tables[0]->report_invalid_key(m_link_column_keys[0]);
  1581. cluster->init_leaf(m_link_column_keys[0], m_array_ptr.get());
  1582. m_leaf_ptr = m_array_ptr.get();
  1583. }
  1584. void collect_dependencies(std::vector<TableKey>& tables) const;
  1585. virtual std::string description(util::serializer::SerialisationState& state) const;
  1586. ObjKey get_unary_link_or_not_found(size_t index) const
  1587. {
  1588. REALM_ASSERT(m_only_unary_links);
  1589. UnaryLinkResult res;
  1590. map_links(index, res);
  1591. return res.m_result;
  1592. }
  1593. std::vector<ObjKey> get_links(size_t index) const
  1594. {
  1595. std::vector<ObjKey> res;
  1596. get_links(index, res);
  1597. return res;
  1598. }
  1599. std::vector<ObjKey> get_origin_ndxs(ObjKey key, size_t column = 0) const;
  1600. size_t count_links(size_t row) const
  1601. {
  1602. CountLinks counter;
  1603. map_links(row, counter);
  1604. return counter.result();
  1605. }
  1606. size_t count_all_backlinks(size_t row) const
  1607. {
  1608. CountBacklinks counter(get_target_table());
  1609. map_links(row, counter);
  1610. return counter.result();
  1611. }
  1612. void map_links(size_t row, LinkMapFunction& lm) const
  1613. {
  1614. map_links(0, row, lm);
  1615. }
  1616. bool only_unary_links() const
  1617. {
  1618. return m_only_unary_links;
  1619. }
  1620. ConstTableRef get_base_table() const
  1621. {
  1622. return m_tables.empty() ? nullptr : m_tables[0];
  1623. }
  1624. ConstTableRef get_target_table() const
  1625. {
  1626. REALM_ASSERT(!m_tables.empty());
  1627. return m_tables.back();
  1628. }
  1629. bool links_exist() const
  1630. {
  1631. return !m_link_column_keys.empty();
  1632. }
  1633. private:
  1634. void map_links(size_t column, ObjKey key, LinkMapFunction& lm) const;
  1635. void map_links(size_t column, size_t row, LinkMapFunction& lm) const;
  1636. void get_links(size_t row, std::vector<ObjKey>& result) const
  1637. {
  1638. MakeLinkVector mlv = MakeLinkVector(result);
  1639. map_links(row, mlv);
  1640. }
  1641. mutable std::vector<ColKey> m_link_column_keys;
  1642. std::vector<ColumnType> m_link_types;
  1643. std::vector<ConstTableRef> m_tables;
  1644. bool m_only_unary_links = true;
  1645. // Leaf cache
  1646. using LeafPtr = std::unique_ptr<ArrayPayload, PlacementDelete>;
  1647. union Storage {
  1648. typename std::aligned_storage<sizeof(ArrayKey), alignof(ArrayKey)>::type m_list;
  1649. typename std::aligned_storage<sizeof(ArrayInteger), alignof(ArrayKey)>::type m_dict;
  1650. typename std::aligned_storage<sizeof(ArrayList), alignof(ArrayList)>::type m_linklist;
  1651. typename std::aligned_storage<sizeof(ArrayList), alignof(ArrayList)>::type m_backlink;
  1652. };
  1653. Storage m_storage;
  1654. LeafPtr m_array_ptr;
  1655. const ArrayPayload* m_leaf_ptr = nullptr;
  1656. template <class>
  1657. friend Query compare(const Subexpr2<Link>&, const Obj&);
  1658. };
  1659. template <class T>
  1660. Value<T> make_value_for_link(bool only_unary_links, size_t size)
  1661. {
  1662. Value<T> value;
  1663. if (only_unary_links) {
  1664. REALM_ASSERT(size <= 1);
  1665. value.init(false, 1);
  1666. value.m_storage.set_null(0);
  1667. }
  1668. else {
  1669. value.init(true, size);
  1670. }
  1671. return value;
  1672. }
  1673. // This class can be used as untyped base for expressions that handle object properties
  1674. class ObjPropertyBase {
  1675. public:
  1676. ObjPropertyBase(ColKey column, ConstTableRef table, std::vector<ColKey> links, ExpressionComparisonType type)
  1677. : m_link_map(table, std::move(links))
  1678. , m_column_key(column)
  1679. , m_comparison_type(type)
  1680. {
  1681. }
  1682. ObjPropertyBase(const ObjPropertyBase& other)
  1683. : m_link_map(other.m_link_map)
  1684. , m_column_key(other.m_column_key)
  1685. , m_comparison_type(other.m_comparison_type)
  1686. {
  1687. }
  1688. ObjPropertyBase(ColKey column, const LinkMap& link_map, ExpressionComparisonType type)
  1689. : m_link_map(link_map)
  1690. , m_column_key(column)
  1691. , m_comparison_type(type)
  1692. {
  1693. }
  1694. bool links_exist() const
  1695. {
  1696. return m_link_map.has_links();
  1697. }
  1698. bool only_unary_links() const
  1699. {
  1700. return m_link_map.only_unary_links();
  1701. }
  1702. bool is_nullable() const
  1703. {
  1704. return m_column_key.get_attrs().test(col_attr_Nullable);
  1705. }
  1706. LinkMap get_link_map() const
  1707. {
  1708. return m_link_map;
  1709. }
  1710. ColKey column_key() const noexcept
  1711. {
  1712. return m_column_key;
  1713. }
  1714. protected:
  1715. LinkMap m_link_map;
  1716. // Column index of payload column of m_table
  1717. mutable ColKey m_column_key;
  1718. ExpressionComparisonType m_comparison_type; // Any, All, None
  1719. };
  1720. // Combines Subexpr2<T> and ObjPropertyBase
  1721. // Implements virtual functions defined in Expression/Subexpr
  1722. template <class T>
  1723. class ObjPropertyExpr : public Subexpr2<T>, public ObjPropertyBase {
  1724. public:
  1725. using ObjPropertyBase::ObjPropertyBase;
  1726. bool has_multiple_values() const override
  1727. {
  1728. return m_link_map.has_links() && !m_link_map.only_unary_links();
  1729. }
  1730. ConstTableRef get_base_table() const final
  1731. {
  1732. return m_link_map.get_base_table();
  1733. }
  1734. void set_base_table(ConstTableRef table) final
  1735. {
  1736. if (table != get_base_table()) {
  1737. m_link_map.set_base_table(table);
  1738. }
  1739. }
  1740. bool has_search_index() const final
  1741. {
  1742. auto target_table = m_link_map.get_target_table();
  1743. return target_table->get_primary_key_column() == m_column_key || target_table->has_search_index(m_column_key);
  1744. }
  1745. std::vector<ObjKey> find_all(Mixed value) const final
  1746. {
  1747. std::vector<ObjKey> ret;
  1748. std::vector<ObjKey> result;
  1749. if (value.is_null() && !m_column_key.is_nullable()) {
  1750. return ret;
  1751. }
  1752. if (m_link_map.get_target_table()->get_primary_key_column() == m_column_key) {
  1753. // Only one object with a given key would be possible
  1754. if (auto k = m_link_map.get_target_table()->find_primary_key(value))
  1755. result.push_back(k);
  1756. }
  1757. else {
  1758. StringIndex* index = m_link_map.get_target_table()->get_search_index(m_column_key);
  1759. REALM_ASSERT(index);
  1760. if (value.is_null()) {
  1761. index->find_all(result, realm::null{});
  1762. }
  1763. else {
  1764. T val = value.get<T>();
  1765. index->find_all(result, val);
  1766. }
  1767. }
  1768. for (ObjKey k : result) {
  1769. auto ndxs = m_link_map.get_origin_ndxs(k);
  1770. ret.insert(ret.end(), ndxs.begin(), ndxs.end());
  1771. }
  1772. return ret;
  1773. }
  1774. void collect_dependencies(std::vector<TableKey>& tables) const final
  1775. {
  1776. m_link_map.collect_dependencies(tables);
  1777. }
  1778. virtual std::string description(util::serializer::SerialisationState& state) const override
  1779. {
  1780. return state.describe_expression_type(m_comparison_type) + state.describe_columns(m_link_map, m_column_key);
  1781. }
  1782. virtual ExpressionComparisonType get_comparison_type() const final
  1783. {
  1784. return m_comparison_type;
  1785. }
  1786. std::unique_ptr<Subexpr> clone() const override
  1787. {
  1788. return make_subexpr<Columns<T>>(static_cast<const Columns<T>&>(*this));
  1789. }
  1790. };
  1791. // If we add a new Realm type T and quickly want Query support for it, then simply inherit from it like
  1792. // `template <> class Columns<T> : public SimpleQuerySupport<T>` and you're done. Any operators of the set
  1793. // { ==, >=, <=, !=, >, < } that are supported by T will be supported by the "query expression syntax"
  1794. // automatically. NOTE: This method of Query support will be slow because it goes through Table::get<T>.
  1795. // To get faster Query support, either add SequentialGetter support (faster) or create a query_engine.hpp
  1796. // node for it (super fast).
  1797. template <class T>
  1798. class SimpleQuerySupport : public ObjPropertyExpr<T> {
  1799. public:
  1800. using ObjPropertyExpr<T>::links_exist;
  1801. SimpleQuerySupport(ColKey column, ConstTableRef table, std::vector<ColKey> links = {},
  1802. ExpressionComparisonType type = ExpressionComparisonType::Any)
  1803. : ObjPropertyExpr<T>(column, table, std::move(links), type)
  1804. {
  1805. }
  1806. void set_cluster(const Cluster* cluster) override
  1807. {
  1808. m_array_ptr = nullptr;
  1809. m_leaf_ptr = nullptr;
  1810. if (links_exist()) {
  1811. m_link_map.set_cluster(cluster);
  1812. }
  1813. else {
  1814. // Create new Leaf
  1815. m_array_ptr = LeafPtr(new (&m_leaf_cache_storage) LeafType(m_link_map.get_base_table()->get_alloc()));
  1816. cluster->init_leaf(m_column_key, m_array_ptr.get());
  1817. m_leaf_ptr = m_array_ptr.get();
  1818. }
  1819. }
  1820. void evaluate(size_t index, ValueBase& destination) override
  1821. {
  1822. if (links_exist()) {
  1823. REALM_ASSERT(m_leaf_ptr == nullptr);
  1824. if (m_link_map.only_unary_links()) {
  1825. REALM_ASSERT(destination.size() == 1);
  1826. REALM_ASSERT(!destination.m_from_link_list);
  1827. destination.set_null(0);
  1828. auto link_translation_key = this->m_link_map.get_unary_link_or_not_found(index);
  1829. if (link_translation_key) {
  1830. const Obj obj = m_link_map.get_target_table()->get_object(link_translation_key);
  1831. if constexpr (realm::is_any_v<T, ObjectId, UUID>) {
  1832. auto opt_val = obj.get<util::Optional<T>>(m_column_key);
  1833. if (opt_val) {
  1834. destination.set(0, *opt_val);
  1835. }
  1836. else {
  1837. destination.set_null(0);
  1838. }
  1839. }
  1840. else {
  1841. destination.set(0, obj.get<T>(m_column_key));
  1842. }
  1843. }
  1844. }
  1845. else {
  1846. std::vector<ObjKey> links = m_link_map.get_links(index);
  1847. destination.init(true, links.size());
  1848. for (size_t t = 0; t < links.size(); t++) {
  1849. const Obj obj = m_link_map.get_target_table()->get_object(links[t]);
  1850. if constexpr (realm::is_any_v<T, ObjectId, UUID>) {
  1851. auto opt_val = obj.get<util::Optional<T>>(m_column_key);
  1852. if (opt_val) {
  1853. destination.set(t, *opt_val);
  1854. }
  1855. else {
  1856. destination.set_null(t);
  1857. }
  1858. }
  1859. else {
  1860. destination.set(t, obj.get<T>(m_column_key));
  1861. }
  1862. }
  1863. }
  1864. }
  1865. else {
  1866. // Not a link column
  1867. REALM_ASSERT(m_leaf_ptr != nullptr);
  1868. REALM_ASSERT(destination.size() == 1);
  1869. REALM_ASSERT(!destination.m_from_link_list);
  1870. if (m_leaf_ptr->is_null(index)) {
  1871. destination.set_null(0);
  1872. }
  1873. else {
  1874. destination.set(0, m_leaf_ptr->get(index));
  1875. }
  1876. }
  1877. }
  1878. void evaluate(ObjKey key, ValueBase& destination) override
  1879. {
  1880. Value<T>& d = static_cast<Value<T>&>(destination);
  1881. d.set(0, m_link_map.get_target_table()->get_object(key).template get<T>(m_column_key));
  1882. }
  1883. SimpleQuerySupport(const SimpleQuerySupport& other)
  1884. : ObjPropertyExpr<T>(other)
  1885. {
  1886. }
  1887. SizeOperator<T> size()
  1888. {
  1889. return SizeOperator<T>(this->clone());
  1890. }
  1891. TypeOfValueOperator<T> type_of_value()
  1892. {
  1893. return TypeOfValueOperator<T>(this->clone());
  1894. }
  1895. private:
  1896. using ObjPropertyExpr<T>::m_link_map;
  1897. using ObjPropertyExpr<T>::m_column_key;
  1898. // Leaf cache
  1899. using LeafType = typename ColumnTypeTraits<T>::cluster_leaf_type;
  1900. using LeafCacheStorage = typename std::aligned_storage<sizeof(LeafType), alignof(LeafType)>::type;
  1901. using LeafPtr = std::unique_ptr<LeafType, PlacementDelete>;
  1902. LeafCacheStorage m_leaf_cache_storage;
  1903. LeafPtr m_array_ptr;
  1904. LeafType* m_leaf_ptr = nullptr;
  1905. };
  1906. template <>
  1907. class Columns<Timestamp> : public SimpleQuerySupport<Timestamp> {
  1908. using SimpleQuerySupport::SimpleQuerySupport;
  1909. };
  1910. template <>
  1911. class Columns<BinaryData> : public SimpleQuerySupport<BinaryData> {
  1912. using SimpleQuerySupport::SimpleQuerySupport;
  1913. };
  1914. template <>
  1915. class Columns<ObjectId> : public SimpleQuerySupport<ObjectId> {
  1916. using SimpleQuerySupport::SimpleQuerySupport;
  1917. };
  1918. template <>
  1919. class Columns<Decimal128> : public SimpleQuerySupport<Decimal128> {
  1920. using SimpleQuerySupport::SimpleQuerySupport;
  1921. };
  1922. template <>
  1923. class Columns<Mixed> : public SimpleQuerySupport<Mixed> {
  1924. using SimpleQuerySupport::SimpleQuerySupport;
  1925. };
  1926. template <>
  1927. class Columns<UUID> : public SimpleQuerySupport<UUID> {
  1928. using SimpleQuerySupport::SimpleQuerySupport;
  1929. };
  1930. template <>
  1931. class Columns<StringData> : public SimpleQuerySupport<StringData> {
  1932. public:
  1933. Columns(ColKey column, ConstTableRef table, std::vector<ColKey> links = {},
  1934. ExpressionComparisonType type = ExpressionComparisonType::Any)
  1935. : SimpleQuerySupport(column, table, links, type)
  1936. {
  1937. }
  1938. Columns(Columns const& other)
  1939. : SimpleQuerySupport(other)
  1940. {
  1941. }
  1942. Columns(Columns&& other) noexcept
  1943. : SimpleQuerySupport(other)
  1944. {
  1945. }
  1946. using SimpleQuerySupport::size;
  1947. };
  1948. template <class T, class S, class I>
  1949. inline std::enable_if_t<!realm::is_any_v<T, StringData, realm::null, const char*, std::string>, Query>
  1950. string_compare(const Subexpr2<StringData>& left, T right, bool)
  1951. {
  1952. return make_expression<Compare<Equal>>(right.clone(), left.clone());
  1953. }
  1954. template <class T, class S, class I>
  1955. inline std::enable_if_t<realm::is_any_v<T, StringData, realm::null, const char*, std::string>, Query>
  1956. string_compare(const Subexpr2<StringData>& left, T right, bool case_sensitive)
  1957. {
  1958. StringData sd(right);
  1959. if (case_sensitive)
  1960. return create<S>(sd, left);
  1961. else
  1962. return create<I>(sd, left);
  1963. }
  1964. template <class S, class I>
  1965. Query string_compare(const Subexpr2<StringData>& left, const Subexpr2<StringData>& right, bool case_sensitive)
  1966. {
  1967. if (case_sensitive)
  1968. return make_expression<Compare<S>>(right.clone(), left.clone());
  1969. else
  1970. return make_expression<Compare<I>>(right.clone(), left.clone());
  1971. }
  1972. template <class T, class S, class I>
  1973. Query binary_compare(const Subexpr2<BinaryData>& left, T right, bool case_sensitive)
  1974. {
  1975. BinaryData data(right);
  1976. if (case_sensitive)
  1977. return create<S>(data, left);
  1978. else
  1979. return create<I>(data, left);
  1980. }
  1981. template <class S, class I>
  1982. Query binary_compare(const Subexpr2<BinaryData>& left, const Subexpr2<BinaryData>& right, bool case_sensitive)
  1983. {
  1984. if (case_sensitive)
  1985. return make_expression<Compare<S>>(right.clone(), left.clone());
  1986. else
  1987. return make_expression<Compare<I>>(right.clone(), left.clone());
  1988. }
  1989. template <class T, class S, class I>
  1990. Query mixed_compare(const Subexpr2<Mixed>& left, T right, bool case_sensitive)
  1991. {
  1992. Mixed data(right);
  1993. if (case_sensitive)
  1994. return create<S>(data, left);
  1995. else
  1996. return create<I>(data, left);
  1997. }
  1998. template <class S, class I>
  1999. Query mixed_compare(const Subexpr2<Mixed>& left, const Subexpr2<Mixed>& right, bool case_sensitive)
  2000. {
  2001. if (case_sensitive)
  2002. return make_expression<Compare<S>>(right.clone(), left.clone());
  2003. else
  2004. return make_expression<Compare<I>>(right.clone(), left.clone());
  2005. }
  2006. // Columns<String> == Columns<String>
  2007. inline Query operator==(const Columns<StringData>& left, const Columns<StringData>& right)
  2008. {
  2009. return string_compare<Equal, EqualIns>(left, right, true);
  2010. }
  2011. // Columns<String> != Columns<String>
  2012. inline Query operator!=(const Columns<StringData>& left, const Columns<StringData>& right)
  2013. {
  2014. return string_compare<NotEqual, NotEqualIns>(left, right, true);
  2015. }
  2016. // String == Columns<String>
  2017. template <class T>
  2018. Query operator==(T left, const Columns<StringData>& right)
  2019. {
  2020. return operator==(right, left);
  2021. }
  2022. // String != Columns<String>
  2023. template <class T>
  2024. Query operator!=(T left, const Columns<StringData>& right)
  2025. {
  2026. return operator!=(right, left);
  2027. }
  2028. // Columns<String> == String
  2029. template <class T>
  2030. Query operator==(const Columns<StringData>& left, T right)
  2031. {
  2032. return string_compare<T, Equal, EqualIns>(left, right, true);
  2033. }
  2034. // Columns<String> != String
  2035. template <class T>
  2036. Query operator!=(const Columns<StringData>& left, T right)
  2037. {
  2038. return string_compare<T, NotEqual, NotEqualIns>(left, right, true);
  2039. }
  2040. inline Query operator==(const Columns<BinaryData>& left, BinaryData right)
  2041. {
  2042. return create<Equal>(right, left);
  2043. }
  2044. inline Query operator==(BinaryData left, const Columns<BinaryData>& right)
  2045. {
  2046. return create<Equal>(left, right);
  2047. }
  2048. inline Query operator!=(const Columns<BinaryData>& left, BinaryData right)
  2049. {
  2050. return create<NotEqual>(right, left);
  2051. }
  2052. inline Query operator!=(BinaryData left, const Columns<BinaryData>& right)
  2053. {
  2054. return create<NotEqual>(left, right);
  2055. }
  2056. inline Query operator==(const Columns<BinaryData>& left, realm::null)
  2057. {
  2058. return create<Equal>(BinaryData(), left);
  2059. }
  2060. inline Query operator==(realm::null, const Columns<BinaryData>& right)
  2061. {
  2062. return create<Equal>(BinaryData(), right);
  2063. }
  2064. inline Query operator!=(const Columns<BinaryData>& left, realm::null)
  2065. {
  2066. return create<NotEqual>(BinaryData(), left);
  2067. }
  2068. inline Query operator!=(realm::null, const Columns<BinaryData>& right)
  2069. {
  2070. return create<NotEqual>(BinaryData(), right);
  2071. }
  2072. // This class is intended to perform queries on the *pointers* of links, contrary to performing queries on *payload*
  2073. // in linked-to tables. Queries can be "find first link that points at row X" or "find first null-link". Currently
  2074. // only "find first null link" and "find first non-null link" is supported. More will be added later. When we add
  2075. // more, I propose to remove the <bool has_links> template argument from this class and instead template it by
  2076. // a criteria-class (like the FindNullLinks class below in find_first()) in some generalized fashion.
  2077. template <bool has_links>
  2078. class UnaryLinkCompare : public Expression {
  2079. public:
  2080. UnaryLinkCompare(const LinkMap& lm)
  2081. : m_link_map(lm)
  2082. {
  2083. }
  2084. void set_base_table(ConstTableRef table) override
  2085. {
  2086. m_link_map.set_base_table(table);
  2087. }
  2088. void set_cluster(const Cluster* cluster) override
  2089. {
  2090. m_link_map.set_cluster(cluster);
  2091. }
  2092. void collect_dependencies(std::vector<TableKey>& tables) const override
  2093. {
  2094. m_link_map.collect_dependencies(tables);
  2095. }
  2096. // Return main table of query (table on which table->where()... is invoked). Note that this is not the same as
  2097. // any linked-to payload tables
  2098. ConstTableRef get_base_table() const override
  2099. {
  2100. return m_link_map.get_base_table();
  2101. }
  2102. size_t find_first(size_t start, size_t end) const override
  2103. {
  2104. for (; start < end;) {
  2105. FindNullLinks fnl;
  2106. m_link_map.map_links(start, fnl);
  2107. if (fnl.m_has_link == has_links)
  2108. return start;
  2109. start++;
  2110. }
  2111. return not_found;
  2112. }
  2113. virtual std::string description(util::serializer::SerialisationState& state) const override
  2114. {
  2115. return state.describe_columns(m_link_map, ColKey()) + (has_links ? " != NULL" : " == NULL");
  2116. }
  2117. std::unique_ptr<Expression> clone() const override
  2118. {
  2119. return std::unique_ptr<Expression>(new UnaryLinkCompare(*this));
  2120. }
  2121. private:
  2122. UnaryLinkCompare(const UnaryLinkCompare& other)
  2123. : Expression(other)
  2124. , m_link_map(other.m_link_map)
  2125. {
  2126. }
  2127. mutable LinkMap m_link_map;
  2128. };
  2129. class LinkCount : public Subexpr2<Int> {
  2130. public:
  2131. LinkCount(const LinkMap& link_map)
  2132. : m_link_map(link_map)
  2133. {
  2134. }
  2135. LinkCount(LinkCount const& other)
  2136. : Subexpr2<Int>(other)
  2137. , m_link_map(other.m_link_map)
  2138. {
  2139. }
  2140. std::unique_ptr<Subexpr> clone() const override
  2141. {
  2142. return make_subexpr<LinkCount>(*this);
  2143. }
  2144. ConstTableRef get_base_table() const override
  2145. {
  2146. return m_link_map.get_base_table();
  2147. }
  2148. void set_base_table(ConstTableRef table) override
  2149. {
  2150. m_link_map.set_base_table(table);
  2151. }
  2152. void set_cluster(const Cluster* cluster) override
  2153. {
  2154. m_link_map.set_cluster(cluster);
  2155. }
  2156. void collect_dependencies(std::vector<TableKey>& tables) const override
  2157. {
  2158. m_link_map.collect_dependencies(tables);
  2159. }
  2160. void evaluate(size_t index, ValueBase& destination) override
  2161. {
  2162. size_t count = m_link_map.count_links(index);
  2163. destination = Value<int64_t>(count);
  2164. }
  2165. virtual std::string description(util::serializer::SerialisationState& state) const override
  2166. {
  2167. return state.describe_columns(m_link_map, ColKey()) + util::serializer::value_separator + "@count";
  2168. }
  2169. private:
  2170. LinkMap m_link_map;
  2171. };
  2172. // Gives a count of all backlinks across all columns for the specified row.
  2173. // The unused template parameter is a hack to avoid a circular dependency between table.hpp and query_expression.hpp.
  2174. template <class>
  2175. class BacklinkCount : public Subexpr2<Int> {
  2176. public:
  2177. BacklinkCount(const LinkMap& link_map)
  2178. : m_link_map(link_map)
  2179. {
  2180. }
  2181. BacklinkCount(LinkMap&& link_map)
  2182. : m_link_map(std::move(link_map))
  2183. {
  2184. }
  2185. BacklinkCount(ConstTableRef table, std::vector<ColKey> links = {})
  2186. : m_link_map(table, std::move(links))
  2187. {
  2188. }
  2189. BacklinkCount(BacklinkCount const& other)
  2190. : Subexpr2<Int>(other)
  2191. , m_link_map(other.m_link_map)
  2192. {
  2193. }
  2194. std::unique_ptr<Subexpr> clone() const override
  2195. {
  2196. return make_subexpr<BacklinkCount<Int>>(*this);
  2197. }
  2198. ConstTableRef get_base_table() const override
  2199. {
  2200. return m_link_map.get_base_table();
  2201. }
  2202. void set_base_table(ConstTableRef table) override
  2203. {
  2204. m_link_map.set_base_table(table);
  2205. }
  2206. void set_cluster(const Cluster* cluster) override
  2207. {
  2208. if (m_link_map.has_links()) {
  2209. m_link_map.set_cluster(cluster);
  2210. }
  2211. else {
  2212. m_keys = cluster->get_key_array();
  2213. m_offset = cluster->get_offset();
  2214. }
  2215. }
  2216. void collect_dependencies(std::vector<TableKey>& tables) const override
  2217. {
  2218. m_link_map.collect_dependencies(tables);
  2219. }
  2220. void evaluate(size_t index, ValueBase& destination) override
  2221. {
  2222. size_t count;
  2223. if (m_link_map.has_links()) {
  2224. count = m_link_map.count_all_backlinks(index);
  2225. }
  2226. else {
  2227. ObjKey key(m_keys->get(index) + m_offset);
  2228. const Obj obj = m_link_map.get_base_table()->get_object(key);
  2229. count = obj.get_backlink_count();
  2230. }
  2231. destination = Value<int64_t>(count);
  2232. }
  2233. virtual std::string description(util::serializer::SerialisationState& state) const override
  2234. {
  2235. std::string s;
  2236. if (m_link_map.links_exist()) {
  2237. s += state.describe_columns(m_link_map, ColKey()) + util::serializer::value_separator;
  2238. }
  2239. s += "@links.@count";
  2240. return s;
  2241. }
  2242. private:
  2243. const ClusterKeyArray* m_keys = nullptr;
  2244. uint64_t m_offset = 0;
  2245. LinkMap m_link_map;
  2246. };
  2247. template <class T, class TExpr>
  2248. class SizeOperator : public Subexpr2<Int> {
  2249. public:
  2250. SizeOperator(std::unique_ptr<TExpr> left)
  2251. : m_expr(std::move(left))
  2252. {
  2253. }
  2254. SizeOperator(const SizeOperator& other)
  2255. : m_expr(other.m_expr->clone())
  2256. {
  2257. }
  2258. // See comment in base class
  2259. void set_base_table(ConstTableRef table) override
  2260. {
  2261. m_expr->set_base_table(table);
  2262. }
  2263. void set_cluster(const Cluster* cluster) override
  2264. {
  2265. m_expr->set_cluster(cluster);
  2266. }
  2267. // Recursively fetch tables of columns in expression tree. Used when user first builds a stand-alone expression
  2268. // and binds it to a Query at a later time
  2269. ConstTableRef get_base_table() const override
  2270. {
  2271. return m_expr->get_base_table();
  2272. }
  2273. // destination = operator(left)
  2274. void evaluate(size_t index, ValueBase& destination) override
  2275. {
  2276. Value<T> v;
  2277. m_expr->evaluate(index, v);
  2278. size_t sz = v.size();
  2279. destination.init(v.m_from_link_list, sz);
  2280. for (size_t i = 0; i < sz; i++) {
  2281. auto elem = v[i].template get<T>();
  2282. if constexpr (std::is_same_v<T, int64_t>) {
  2283. // This is the size of a list
  2284. destination.set(i, elem);
  2285. }
  2286. else {
  2287. if (!elem) {
  2288. destination.set_null(i);
  2289. }
  2290. else {
  2291. destination.set(i, int64_t(elem.size()));
  2292. }
  2293. }
  2294. }
  2295. }
  2296. std::string description(util::serializer::SerialisationState& state) const override
  2297. {
  2298. if (m_expr) {
  2299. return m_expr->description(state) + util::serializer::value_separator + "@size";
  2300. }
  2301. return "@size";
  2302. }
  2303. std::unique_ptr<Subexpr> clone() const override
  2304. {
  2305. return std::unique_ptr<Subexpr>(new SizeOperator(*this));
  2306. }
  2307. private:
  2308. std::unique_ptr<TExpr> m_expr;
  2309. };
  2310. template <class T>
  2311. class TypeOfValueOperator : public Subexpr2<TypeOfValue> {
  2312. public:
  2313. TypeOfValueOperator(std::unique_ptr<Subexpr> left)
  2314. : m_expr(std::move(left))
  2315. {
  2316. }
  2317. TypeOfValueOperator(const TypeOfValueOperator& other)
  2318. : m_expr(other.m_expr->clone())
  2319. {
  2320. }
  2321. ExpressionComparisonType get_comparison_type() const override
  2322. {
  2323. return m_expr->get_comparison_type();
  2324. }
  2325. // See comment in base class
  2326. void set_base_table(ConstTableRef table) override
  2327. {
  2328. m_expr->set_base_table(table);
  2329. }
  2330. void set_cluster(const Cluster* cluster) override
  2331. {
  2332. m_expr->set_cluster(cluster);
  2333. }
  2334. // Recursively fetch tables of columns in expression tree. Used when user first builds a stand-alone expression
  2335. // and binds it to a Query at a later time
  2336. ConstTableRef get_base_table() const override
  2337. {
  2338. return m_expr->get_base_table();
  2339. }
  2340. // destination = operator(left)
  2341. void evaluate(size_t index, ValueBase& destination) override
  2342. {
  2343. Value<T> v;
  2344. m_expr->evaluate(index, v);
  2345. size_t sz = v.size();
  2346. destination.init(v.m_from_link_list, sz);
  2347. for (size_t i = 0; i < sz; i++) {
  2348. auto elem = v[i].template get<T>();
  2349. destination.set(i, TypeOfValue(elem));
  2350. }
  2351. }
  2352. std::string description(util::serializer::SerialisationState& state) const override
  2353. {
  2354. if (m_expr) {
  2355. return m_expr->description(state) + util::serializer::value_separator + "@type";
  2356. }
  2357. return "@type";
  2358. }
  2359. std::unique_ptr<Subexpr> clone() const override
  2360. {
  2361. return std::unique_ptr<Subexpr>(new TypeOfValueOperator(*this));
  2362. }
  2363. private:
  2364. std::unique_ptr<Subexpr> m_expr;
  2365. };
  2366. class KeyValue : public Subexpr2<Link> {
  2367. public:
  2368. KeyValue(ObjKey key)
  2369. : m_key(key)
  2370. {
  2371. }
  2372. void set_base_table(ConstTableRef) override {}
  2373. ConstTableRef get_base_table() const override
  2374. {
  2375. return nullptr;
  2376. }
  2377. void evaluate(size_t, ValueBase& destination) override
  2378. {
  2379. destination = Value<ObjKey>(m_key);
  2380. }
  2381. virtual std::string description(util::serializer::SerialisationState&) const override
  2382. {
  2383. return util::serializer::print_value(m_key);
  2384. }
  2385. std::unique_ptr<Subexpr> clone() const override
  2386. {
  2387. return std::unique_ptr<Subexpr>(new KeyValue(*this));
  2388. }
  2389. private:
  2390. KeyValue(const KeyValue& source)
  2391. : m_key(source.m_key)
  2392. {
  2393. }
  2394. ObjKey m_key;
  2395. };
  2396. template <typename T>
  2397. class SubColumns;
  2398. // This is for LinkList and BackLink too since they're declared as typedefs of Link.
  2399. template <>
  2400. class Columns<Link> : public Subexpr2<Link> {
  2401. public:
  2402. Columns(const Columns& other)
  2403. : Subexpr2<Link>(other)
  2404. , m_link_map(other.m_link_map)
  2405. , m_comparison_type(other.m_comparison_type)
  2406. , m_is_list(other.m_is_list)
  2407. {
  2408. }
  2409. Query is_null()
  2410. {
  2411. if (m_link_map.get_nb_hops() > 1)
  2412. throw util::runtime_error("Combining link() and is_null() is currently not supported");
  2413. // Todo, it may be useful to support the above, but we would need to figure out an intuitive behaviour
  2414. return make_expression<UnaryLinkCompare<false>>(m_link_map);
  2415. }
  2416. Query is_not_null()
  2417. {
  2418. if (m_link_map.get_nb_hops() > 1)
  2419. throw util::runtime_error("Combining link() and is_not_null() is currently not supported");
  2420. // Todo, it may be useful to support the above, but we would need to figure out an intuitive behaviour
  2421. return make_expression<UnaryLinkCompare<true>>(m_link_map);
  2422. }
  2423. LinkCount count() const
  2424. {
  2425. return LinkCount(m_link_map);
  2426. }
  2427. template <class T>
  2428. BacklinkCount<T> backlink_count() const
  2429. {
  2430. return BacklinkCount<T>(m_link_map);
  2431. }
  2432. template <typename C>
  2433. SubColumns<C> column(ColKey column_key) const
  2434. {
  2435. // no need to pass along m_comparison_type because the only operations supported from
  2436. // the subsequent SubColumns are aggregate operations such as sum, min, max, avg where
  2437. // having
  2438. REALM_ASSERT_DEBUG(m_comparison_type == ExpressionComparisonType::Any);
  2439. return SubColumns<C>(Columns<C>(column_key, m_link_map.get_target_table()), m_link_map);
  2440. }
  2441. const LinkMap& link_map() const
  2442. {
  2443. return m_link_map;
  2444. }
  2445. DataType get_type() const override
  2446. {
  2447. return type_Link;
  2448. }
  2449. bool has_multiple_values() const override
  2450. {
  2451. return m_is_list || !m_link_map.only_unary_links();
  2452. }
  2453. ConstTableRef get_base_table() const override
  2454. {
  2455. return m_link_map.get_base_table();
  2456. }
  2457. void set_base_table(ConstTableRef table) override
  2458. {
  2459. m_link_map.set_base_table(table);
  2460. }
  2461. void set_cluster(const Cluster* cluster) override
  2462. {
  2463. REALM_ASSERT(m_link_map.has_links());
  2464. m_link_map.set_cluster(cluster);
  2465. }
  2466. void collect_dependencies(std::vector<TableKey>& tables) const override
  2467. {
  2468. m_link_map.collect_dependencies(tables);
  2469. }
  2470. std::string description(util::serializer::SerialisationState& state) const override
  2471. {
  2472. return state.describe_expression_type(m_comparison_type) + state.describe_columns(m_link_map, ColKey());
  2473. }
  2474. virtual ExpressionComparisonType get_comparison_type() const override
  2475. {
  2476. return m_comparison_type;
  2477. }
  2478. std::unique_ptr<Subexpr> clone() const override
  2479. {
  2480. return std::unique_ptr<Subexpr>(new Columns<Link>(*this));
  2481. }
  2482. void evaluate(size_t index, ValueBase& destination) override;
  2483. private:
  2484. LinkMap m_link_map;
  2485. ExpressionComparisonType m_comparison_type;
  2486. bool m_is_list;
  2487. friend class Table;
  2488. friend class LinkChain;
  2489. Columns(ColKey column_key, ConstTableRef table, const std::vector<ColKey>& links = {},
  2490. ExpressionComparisonType type = ExpressionComparisonType::Any)
  2491. : m_link_map(table, links)
  2492. , m_comparison_type(type)
  2493. , m_is_list(column_key.is_list())
  2494. {
  2495. }
  2496. };
  2497. template <typename T>
  2498. class ListColumns;
  2499. template <typename T, typename Operation>
  2500. class CollectionColumnAggregate;
  2501. namespace aggregate_operations {
  2502. template <typename T>
  2503. class Minimum;
  2504. template <typename T>
  2505. class Maximum;
  2506. template <typename T>
  2507. class Sum;
  2508. template <typename T>
  2509. class Average;
  2510. } // namespace aggregate_operations
  2511. class ColumnListBase {
  2512. public:
  2513. ColumnListBase(ColKey column_key, ConstTableRef table, const std::vector<ColKey>& links,
  2514. ExpressionComparisonType type = ExpressionComparisonType::Any)
  2515. : m_column_key(column_key)
  2516. , m_link_map(table, links)
  2517. , m_comparison_type(type)
  2518. {
  2519. }
  2520. ColumnListBase(const ColumnListBase& other)
  2521. : m_column_key(other.m_column_key)
  2522. , m_link_map(other.m_link_map)
  2523. , m_comparison_type(other.m_comparison_type)
  2524. {
  2525. }
  2526. void set_cluster(const Cluster* cluster);
  2527. void get_lists(size_t index, Value<int64_t>& destination, size_t nb_elements);
  2528. std::string description(util::serializer::SerialisationState& state) const
  2529. {
  2530. return state.describe_expression_type(m_comparison_type) + state.describe_columns(m_link_map, m_column_key);
  2531. }
  2532. bool links_exist() const
  2533. {
  2534. return m_link_map.has_links();
  2535. }
  2536. virtual SizeOperator<int64_t> size() = 0;
  2537. virtual std::unique_ptr<Subexpr> get_element_length() = 0;
  2538. virtual std::unique_ptr<Subexpr> max_of() = 0;
  2539. virtual std::unique_ptr<Subexpr> min_of() = 0;
  2540. virtual std::unique_ptr<Subexpr> sum_of() = 0;
  2541. virtual std::unique_ptr<Subexpr> avg_of() = 0;
  2542. mutable ColKey m_column_key;
  2543. LinkMap m_link_map;
  2544. // Leaf cache
  2545. using LeafCacheStorage = typename std::aligned_storage<sizeof(ArrayInteger), alignof(Array)>::type;
  2546. using LeafPtr = std::unique_ptr<ArrayInteger, PlacementDelete>;
  2547. LeafCacheStorage m_leaf_cache_storage;
  2548. LeafPtr m_array_ptr;
  2549. ArrayInteger* m_leaf_ptr = nullptr;
  2550. ExpressionComparisonType m_comparison_type = ExpressionComparisonType::Any;
  2551. };
  2552. template <typename>
  2553. class ColumnListSize;
  2554. template <typename T>
  2555. class ColumnListElementLength;
  2556. template <typename T>
  2557. class ColumnsCollection : public Subexpr2<T>, public ColumnListBase {
  2558. public:
  2559. ColumnsCollection(ColKey column_key, ConstTableRef table, const std::vector<ColKey>& links = {},
  2560. ExpressionComparisonType type = ExpressionComparisonType::Any)
  2561. : ColumnListBase(column_key, table, links, type)
  2562. , m_is_nullable_storage(this->m_column_key.get_attrs().test(col_attr_Nullable))
  2563. {
  2564. }
  2565. ColumnsCollection(const ColumnsCollection& other)
  2566. : Subexpr2<T>(other)
  2567. , ColumnListBase(other)
  2568. , m_is_nullable_storage(this->m_column_key.get_attrs().test(col_attr_Nullable))
  2569. {
  2570. }
  2571. bool has_multiple_values() const override
  2572. {
  2573. return true;
  2574. }
  2575. ConstTableRef get_base_table() const final
  2576. {
  2577. return m_link_map.get_base_table();
  2578. }
  2579. Allocator& get_alloc() const
  2580. {
  2581. return m_link_map.get_target_table()->get_alloc();
  2582. }
  2583. void set_base_table(ConstTableRef table) final
  2584. {
  2585. m_link_map.set_base_table(table);
  2586. }
  2587. void set_cluster(const Cluster* cluster) final
  2588. {
  2589. ColumnListBase::set_cluster(cluster);
  2590. }
  2591. void collect_dependencies(std::vector<TableKey>& tables) const final
  2592. {
  2593. m_link_map.collect_dependencies(tables);
  2594. }
  2595. void evaluate(size_t index, ValueBase& destination) override
  2596. {
  2597. if constexpr (realm::is_any_v<T, ObjectId, Int, Bool, UUID>) {
  2598. if (m_is_nullable_storage) {
  2599. evaluate<util::Optional<T>>(index, destination);
  2600. return;
  2601. }
  2602. }
  2603. evaluate<T>(index, destination);
  2604. }
  2605. std::string description(util::serializer::SerialisationState& state) const override
  2606. {
  2607. return ColumnListBase::description(state);
  2608. }
  2609. ExpressionComparisonType get_comparison_type() const final
  2610. {
  2611. return ColumnListBase::m_comparison_type;
  2612. }
  2613. SizeOperator<int64_t> size() override;
  2614. ColumnListElementLength<T> element_lengths() const
  2615. {
  2616. return {*this};
  2617. }
  2618. TypeOfValueOperator<T> type_of_value()
  2619. {
  2620. return TypeOfValueOperator<T>(this->clone());
  2621. }
  2622. CollectionColumnAggregate<T, aggregate_operations::Minimum<T>> min() const
  2623. {
  2624. return {*this};
  2625. }
  2626. CollectionColumnAggregate<T, aggregate_operations::Maximum<T>> max() const
  2627. {
  2628. return {*this};
  2629. }
  2630. CollectionColumnAggregate<T, aggregate_operations::Sum<T>> sum() const
  2631. {
  2632. return {*this};
  2633. }
  2634. CollectionColumnAggregate<T, aggregate_operations::Average<T>> average() const
  2635. {
  2636. return {*this};
  2637. }
  2638. std::unique_ptr<Subexpr> max_of() override
  2639. {
  2640. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128, Mixed>) {
  2641. return max().clone();
  2642. }
  2643. else {
  2644. return {};
  2645. }
  2646. }
  2647. std::unique_ptr<Subexpr> min_of() override
  2648. {
  2649. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128, Mixed>) {
  2650. return min().clone();
  2651. }
  2652. else {
  2653. return {};
  2654. }
  2655. }
  2656. std::unique_ptr<Subexpr> sum_of() override
  2657. {
  2658. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128, Mixed>) {
  2659. return sum().clone();
  2660. }
  2661. else {
  2662. return {};
  2663. }
  2664. }
  2665. std::unique_ptr<Subexpr> avg_of() override
  2666. {
  2667. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128, Mixed>) {
  2668. return average().clone();
  2669. }
  2670. else {
  2671. return {};
  2672. }
  2673. }
  2674. std::unique_ptr<Subexpr> get_element_length() override
  2675. {
  2676. if constexpr (realm::is_any_v<T, StringData, BinaryData, Mixed>) {
  2677. return element_lengths().clone();
  2678. }
  2679. else {
  2680. return {};
  2681. }
  2682. }
  2683. std::unique_ptr<Subexpr> clone() const override
  2684. {
  2685. return std::unique_ptr<Subexpr>(new ColumnsCollection(*this));
  2686. }
  2687. const bool m_is_nullable_storage;
  2688. private:
  2689. template <typename StorageType>
  2690. void evaluate(size_t index, ValueBase& destination)
  2691. {
  2692. Allocator& alloc = get_alloc();
  2693. Value<int64_t> list_refs;
  2694. get_lists(index, list_refs, 1);
  2695. const bool is_from_list = true;
  2696. std::vector<StorageType> values;
  2697. for (auto&& i : list_refs) {
  2698. ref_type list_ref = to_ref(i.get_int());
  2699. if (list_ref) {
  2700. BPlusTree<StorageType> list(alloc);
  2701. list.init_from_ref(list_ref);
  2702. size_t s = list.size();
  2703. for (size_t j = 0; j < s; j++) {
  2704. values.push_back(list.get(j));
  2705. }
  2706. }
  2707. }
  2708. destination.init(is_from_list, values.size());
  2709. destination.set(values.begin(), values.end());
  2710. }
  2711. };
  2712. template <typename T>
  2713. class Columns<Lst<T>> : public ColumnsCollection<T> {
  2714. public:
  2715. using ColumnsCollection<T>::ColumnsCollection;
  2716. std::unique_ptr<Subexpr> clone() const override
  2717. {
  2718. return make_subexpr<Columns<Lst<T>>>(*this);
  2719. }
  2720. friend class Table;
  2721. friend class LinkChain;
  2722. };
  2723. template <typename T>
  2724. class Columns<Set<T>> : public ColumnsCollection<T> {
  2725. public:
  2726. using ColumnsCollection<T>::ColumnsCollection;
  2727. std::unique_ptr<Subexpr> clone() const override
  2728. {
  2729. return make_subexpr<Columns<Set<T>>>(*this);
  2730. }
  2731. };
  2732. template <>
  2733. class Columns<LnkLst> : public Columns<Lst<ObjKey>> {
  2734. public:
  2735. using Columns<Lst<ObjKey>>::Columns;
  2736. std::unique_ptr<Subexpr> clone() const override
  2737. {
  2738. return make_subexpr<Columns<LnkLst>>(*this);
  2739. }
  2740. };
  2741. template <>
  2742. class Columns<LnkSet> : public Columns<Set<ObjKey>> {
  2743. public:
  2744. using Columns<Set<ObjKey>>::Columns;
  2745. std::unique_ptr<Subexpr> clone() const override
  2746. {
  2747. return make_subexpr<Columns<LnkSet>>(*this);
  2748. }
  2749. };
  2750. // Returns the keys
  2751. class ColumnDictionaryKeys;
  2752. // Returns the values of a given key
  2753. class ColumnDictionaryKey;
  2754. // Returns the values
  2755. template <>
  2756. class Columns<Dictionary> : public ColumnsCollection<Mixed> {
  2757. public:
  2758. Columns(ColKey column, ConstTableRef table, std::vector<ColKey> links = {},
  2759. ExpressionComparisonType type = ExpressionComparisonType::Any)
  2760. : ColumnsCollection<Mixed>(column, table, std::move(links), type)
  2761. {
  2762. m_key_type = m_link_map.get_target_table()->get_dictionary_key_type(column);
  2763. }
  2764. DataType get_key_type() const
  2765. {
  2766. return m_key_type;
  2767. }
  2768. ColumnDictionaryKey key(const Mixed& key_value);
  2769. ColumnDictionaryKeys keys();
  2770. SizeOperator<int64_t> size() override;
  2771. std::unique_ptr<Subexpr> get_element_length() override
  2772. {
  2773. // Not supported for Dictionary
  2774. return {};
  2775. }
  2776. void evaluate(size_t index, ValueBase& destination) override;
  2777. std::unique_ptr<Subexpr> clone() const override
  2778. {
  2779. return make_subexpr<Columns<Dictionary>>(*this);
  2780. }
  2781. Columns(Columns const& other)
  2782. : ColumnsCollection<Mixed>(other)
  2783. , m_key_type(other.m_key_type)
  2784. {
  2785. }
  2786. protected:
  2787. DataType m_key_type;
  2788. };
  2789. class ColumnDictionaryKey : public Columns<Dictionary> {
  2790. public:
  2791. ColumnDictionaryKey(Mixed key_value, const Columns<Dictionary>& dict)
  2792. : Columns<Dictionary>(dict)
  2793. {
  2794. init_key(key_value);
  2795. }
  2796. ColumnDictionaryKey& property(const std::string& prop)
  2797. {
  2798. m_prop_list.push_back(prop);
  2799. return *this;
  2800. }
  2801. void evaluate(size_t index, ValueBase& destination) override;
  2802. std::string description(util::serializer::SerialisationState& state) const override
  2803. {
  2804. std::ostringstream ostr;
  2805. ostr << m_key;
  2806. return ColumnListBase::description(state) + '[' + ostr.str() + ']';
  2807. }
  2808. std::unique_ptr<Subexpr> clone() const override
  2809. {
  2810. return std::unique_ptr<Subexpr>(new ColumnDictionaryKey(*this));
  2811. }
  2812. ColumnDictionaryKey(ColumnDictionaryKey const& other)
  2813. : Columns<Dictionary>(other)
  2814. , m_prop_list(other.m_prop_list)
  2815. , m_objkey(other.m_objkey)
  2816. {
  2817. init_key(other.m_key);
  2818. }
  2819. private:
  2820. Mixed m_key;
  2821. std::string m_buffer;
  2822. std::vector<std::string> m_prop_list;
  2823. ObjKey m_objkey;
  2824. void init_key(Mixed key_value);
  2825. };
  2826. // Returns the keys
  2827. class ColumnDictionaryKeys : public Subexpr2<StringData> {
  2828. public:
  2829. ColumnDictionaryKeys(const Columns<Dictionary>& dict)
  2830. : m_key_type(dict.get_key_type())
  2831. , m_column_key(dict.m_column_key)
  2832. , m_link_map(dict.m_link_map)
  2833. , m_comparison_type(dict.get_comparison_type())
  2834. {
  2835. REALM_ASSERT(m_key_type == type_String);
  2836. }
  2837. ConstTableRef get_base_table() const final
  2838. {
  2839. return m_link_map.get_base_table();
  2840. }
  2841. void set_base_table(ConstTableRef table) final
  2842. {
  2843. m_link_map.set_base_table(table);
  2844. }
  2845. void collect_dependencies(std::vector<TableKey>& tables) const final
  2846. {
  2847. m_link_map.collect_dependencies(tables);
  2848. }
  2849. ExpressionComparisonType get_comparison_type() const final
  2850. {
  2851. return m_comparison_type;
  2852. }
  2853. void set_cluster(const Cluster* cluster) override;
  2854. void evaluate(size_t index, ValueBase& destination) override;
  2855. std::string description(util::serializer::SerialisationState& state) const override
  2856. {
  2857. return state.describe_expression_type(m_comparison_type) + state.describe_columns(m_link_map, m_column_key) +
  2858. ".@keys";
  2859. }
  2860. std::unique_ptr<Subexpr> clone() const override
  2861. {
  2862. return std::unique_ptr<Subexpr>(new ColumnDictionaryKeys(*this));
  2863. }
  2864. ColumnDictionaryKeys(const ColumnDictionaryKeys& other)
  2865. : m_key_type(other.m_key_type)
  2866. , m_column_key(other.m_column_key)
  2867. , m_link_map(other.m_link_map)
  2868. , m_comparison_type(other.m_comparison_type)
  2869. {
  2870. }
  2871. private:
  2872. DataType m_key_type;
  2873. ColKey m_column_key;
  2874. LinkMap m_link_map;
  2875. ExpressionComparisonType m_comparison_type = ExpressionComparisonType::Any;
  2876. // Leaf cache
  2877. using LeafCacheStorage = typename std::aligned_storage<sizeof(ArrayInteger), alignof(Array)>::type;
  2878. using LeafPtr = std::unique_ptr<ArrayInteger, PlacementDelete>;
  2879. LeafCacheStorage m_leaf_cache_storage;
  2880. LeafPtr m_array_ptr;
  2881. ArrayInteger* m_leaf_ptr = nullptr;
  2882. };
  2883. template <typename T>
  2884. class ColumnListSize : public ColumnsCollection<T> {
  2885. public:
  2886. ColumnListSize(const ColumnsCollection<T>& other)
  2887. : ColumnsCollection<T>(other)
  2888. {
  2889. }
  2890. void evaluate(size_t index, ValueBase& destination) override
  2891. {
  2892. if constexpr (realm::is_any_v<T, ObjectId, Int, Bool, UUID>) {
  2893. if (this->m_is_nullable_storage) {
  2894. evaluate<util::Optional<T>>(index, destination);
  2895. return;
  2896. }
  2897. }
  2898. evaluate<T>(index, destination);
  2899. }
  2900. std::unique_ptr<Subexpr> clone() const override
  2901. {
  2902. return std::unique_ptr<Subexpr>(new ColumnListSize<T>(*this));
  2903. }
  2904. private:
  2905. template <typename StorageType>
  2906. void evaluate(size_t index, ValueBase& destination)
  2907. {
  2908. Allocator& alloc = ColumnsCollection<T>::get_alloc();
  2909. Value<int64_t> list_refs;
  2910. this->get_lists(index, list_refs, 1);
  2911. destination.init(list_refs.m_from_link_list, list_refs.size());
  2912. for (size_t i = 0; i < list_refs.size(); i++) {
  2913. ref_type list_ref = to_ref(list_refs[i].get_int());
  2914. if (list_ref) {
  2915. BPlusTree<StorageType> list(alloc);
  2916. list.init_from_ref(list_ref);
  2917. size_t s = list.size();
  2918. destination.set(i, int64_t(s));
  2919. }
  2920. else {
  2921. destination.set(i, 0);
  2922. }
  2923. }
  2924. }
  2925. };
  2926. template <typename T>
  2927. class ColumnListElementLength : public Subexpr2<Int> {
  2928. public:
  2929. ColumnListElementLength(const ColumnsCollection<T>& source)
  2930. : m_list(source)
  2931. {
  2932. }
  2933. bool has_multiple_values() const override
  2934. {
  2935. return true;
  2936. }
  2937. void evaluate(size_t index, ValueBase& destination) override
  2938. {
  2939. Allocator& alloc = m_list.get_alloc();
  2940. Value<int64_t> list_refs;
  2941. m_list.get_lists(index, list_refs, 1);
  2942. std::vector<Int> sizes;
  2943. for (size_t i = 0; i < list_refs.size(); i++) {
  2944. ref_type list_ref = to_ref(list_refs[i].get_int());
  2945. if (list_ref) {
  2946. BPlusTree<T> list(alloc);
  2947. list.init_from_ref(list_ref);
  2948. const size_t list_size = list.size();
  2949. sizes.reserve(sizes.size() + list_size);
  2950. for (size_t j = 0; j < list_size; j++) {
  2951. if constexpr (std::is_same_v<T, Mixed>) {
  2952. Mixed v = list.get(j);
  2953. if (!v.is_null()) {
  2954. if (v.get_type() == type_String) {
  2955. sizes.push_back(v.get_string().size());
  2956. }
  2957. else if (v.get_type() == type_Binary) {
  2958. sizes.push_back(v.get_binary().size());
  2959. }
  2960. }
  2961. }
  2962. else {
  2963. sizes.push_back(list.get(j).size());
  2964. }
  2965. }
  2966. }
  2967. }
  2968. constexpr bool is_from_list = true;
  2969. destination.init(is_from_list, sizes.size());
  2970. destination.set(sizes.begin(), sizes.end());
  2971. }
  2972. ConstTableRef get_base_table() const override
  2973. {
  2974. return m_list.get_base_table();
  2975. }
  2976. void set_base_table(ConstTableRef table) override
  2977. {
  2978. m_list.set_base_table(table);
  2979. }
  2980. void set_cluster(const Cluster* cluster) override
  2981. {
  2982. m_list.set_cluster(cluster);
  2983. }
  2984. void collect_dependencies(std::vector<TableKey>& tables) const override
  2985. {
  2986. m_list.collect_dependencies(tables);
  2987. }
  2988. std::unique_ptr<Subexpr> clone() const override
  2989. {
  2990. return std::unique_ptr<Subexpr>(new ColumnListElementLength<T>(*this));
  2991. }
  2992. std::string description(util::serializer::SerialisationState& state) const override
  2993. {
  2994. return m_list.description(state) + util::serializer::value_separator + "length";
  2995. }
  2996. virtual ExpressionComparisonType get_comparison_type() const override
  2997. {
  2998. return m_list.get_comparison_type();
  2999. }
  3000. private:
  3001. ColumnsCollection<T> m_list;
  3002. };
  3003. template <typename T>
  3004. SizeOperator<int64_t> ColumnsCollection<T>::size()
  3005. {
  3006. std::unique_ptr<Subexpr> ptr(new ColumnListSize<T>(*this));
  3007. return SizeOperator<int64_t>(std::move(ptr));
  3008. }
  3009. template <typename T, typename Operation>
  3010. class CollectionColumnAggregate : public Subexpr2<decltype(Operation().result())> {
  3011. public:
  3012. CollectionColumnAggregate(ColumnsCollection<T> column)
  3013. : m_columns_collection(std::move(column))
  3014. {
  3015. if (m_columns_collection.m_column_key.is_dictionary()) {
  3016. m_dictionary_key_type = m_columns_collection.m_link_map.get_target_table()->get_dictionary_key_type(
  3017. m_columns_collection.m_column_key);
  3018. }
  3019. }
  3020. CollectionColumnAggregate(const CollectionColumnAggregate& other)
  3021. : m_columns_collection(other.m_columns_collection)
  3022. , m_dictionary_key_type(other.m_dictionary_key_type)
  3023. {
  3024. }
  3025. std::unique_ptr<Subexpr> clone() const override
  3026. {
  3027. return make_subexpr<CollectionColumnAggregate>(*this);
  3028. }
  3029. ConstTableRef get_base_table() const override
  3030. {
  3031. return m_columns_collection.get_base_table();
  3032. }
  3033. void set_base_table(ConstTableRef table) override
  3034. {
  3035. m_columns_collection.set_base_table(table);
  3036. }
  3037. void set_cluster(const Cluster* cluster) override
  3038. {
  3039. m_columns_collection.set_cluster(cluster);
  3040. }
  3041. void collect_dependencies(std::vector<TableKey>& tables) const override
  3042. {
  3043. m_columns_collection.collect_dependencies(tables);
  3044. }
  3045. void evaluate(size_t index, ValueBase& destination) override
  3046. {
  3047. if (m_dictionary_key_type) {
  3048. if (m_columns_collection.links_exist()) {
  3049. std::vector<ObjKey> links = m_columns_collection.m_link_map.get_links(index);
  3050. auto sz = links.size();
  3051. destination.init_for_links(m_columns_collection.m_link_map.only_unary_links(), sz);
  3052. for (size_t t = 0; t < sz; t++) {
  3053. const Obj obj = m_columns_collection.m_link_map.get_target_table()->get_object(links[t]);
  3054. auto dict = obj.get_dictionary(m_columns_collection.m_column_key);
  3055. if (dict.size() > 0) {
  3056. destination.set(t, do_dictionary_agg(*dict.m_clusters));
  3057. }
  3058. else {
  3059. set_value_for_empty_dictionary(destination, t);
  3060. }
  3061. }
  3062. }
  3063. else {
  3064. if (m_columns_collection.m_leaf_ptr->get(index)) {
  3065. Allocator& alloc = m_columns_collection.get_base_table()->get_alloc();
  3066. DictionaryClusterTree dict_cluster(static_cast<Array*>(m_columns_collection.m_leaf_ptr),
  3067. *m_dictionary_key_type, alloc, index);
  3068. dict_cluster.init_from_parent();
  3069. destination.set(0, do_dictionary_agg(dict_cluster));
  3070. }
  3071. else {
  3072. set_value_for_empty_dictionary(destination, 0);
  3073. }
  3074. }
  3075. }
  3076. else {
  3077. Allocator& alloc = m_columns_collection.get_alloc();
  3078. Value<int64_t> list_refs;
  3079. m_columns_collection.get_lists(index, list_refs, 1);
  3080. size_t sz = list_refs.size();
  3081. REALM_ASSERT_DEBUG(sz > 0 || list_refs.m_from_link_list);
  3082. // The result is an aggregate value for each table
  3083. destination.init_for_links(!list_refs.m_from_link_list, sz);
  3084. for (size_t i = 0; i < list_refs.size(); i++) {
  3085. auto list_ref = to_ref(list_refs[i].get_int());
  3086. Operation op;
  3087. if (list_ref) {
  3088. if constexpr (realm::is_any_v<T, ObjectId, Int, Bool, UUID>) {
  3089. if (m_columns_collection.m_is_nullable_storage) {
  3090. accumulate<util::Optional<T>>(op, alloc, list_ref);
  3091. }
  3092. else {
  3093. accumulate<T>(op, alloc, list_ref);
  3094. }
  3095. }
  3096. else {
  3097. accumulate<T>(op, alloc, list_ref);
  3098. }
  3099. }
  3100. if (op.is_null()) {
  3101. destination.set_null(i);
  3102. }
  3103. else {
  3104. destination.set(i, op.result());
  3105. }
  3106. }
  3107. }
  3108. }
  3109. virtual std::string description(util::serializer::SerialisationState& state) const override
  3110. {
  3111. return m_columns_collection.description(state) + util::serializer::value_separator + Operation::description();
  3112. }
  3113. private:
  3114. template <typename StorageType>
  3115. void accumulate(Operation& op, Allocator& alloc, ref_type list_ref)
  3116. {
  3117. BPlusTree<StorageType> list(alloc);
  3118. list.init_from_ref(list_ref);
  3119. size_t s = list.size();
  3120. for (unsigned j = 0; j < s; j++) {
  3121. auto v = list.get(j);
  3122. if (!value_is_null(v)) {
  3123. if constexpr (std::is_same_v<StorageType, util::Optional<T>>) {
  3124. op.accumulate(*v);
  3125. }
  3126. else {
  3127. op.accumulate(v);
  3128. }
  3129. }
  3130. }
  3131. }
  3132. Mixed do_dictionary_agg(const DictionaryClusterTree& dict_cluster)
  3133. {
  3134. if constexpr (std::is_same_v<Operation, aggregate_operations::Maximum<Mixed>>) {
  3135. return dict_cluster.max();
  3136. }
  3137. else if constexpr (std::is_same_v<Operation, aggregate_operations::Minimum<Mixed>>) {
  3138. return dict_cluster.min();
  3139. }
  3140. else if constexpr (std::is_same_v<Operation, aggregate_operations::Average<Mixed>>) {
  3141. return dict_cluster.avg();
  3142. }
  3143. else if constexpr (std::is_same_v<Operation, aggregate_operations::Sum<Mixed>>) {
  3144. return dict_cluster.sum();
  3145. }
  3146. REALM_UNREACHABLE();
  3147. }
  3148. inline void set_value_for_empty_dictionary(ValueBase& destination, size_t ndx)
  3149. {
  3150. if constexpr (std::is_same_v<Operation, aggregate_operations::Sum<Mixed>>) {
  3151. destination.set(ndx, 0); // the sum of nothing is zero
  3152. }
  3153. else {
  3154. destination.set_null(ndx);
  3155. }
  3156. }
  3157. ColumnsCollection<T> m_columns_collection;
  3158. util::Optional<DataType> m_dictionary_key_type;
  3159. };
  3160. template <class Operator>
  3161. Query compare(const Subexpr2<Link>& left, const Obj& obj)
  3162. {
  3163. static_assert(std::is_same_v<Operator, Equal> || std::is_same_v<Operator, NotEqual>,
  3164. "Links can only be compared for equality.");
  3165. const Columns<Link>* column = dynamic_cast<const Columns<Link>*>(&left);
  3166. if (column) {
  3167. const LinkMap& link_map = column->link_map();
  3168. REALM_ASSERT(link_map.get_target_table()->get_key() == obj.get_table()->get_key());
  3169. #ifdef REALM_OLDQUERY_FALLBACK
  3170. if (link_map.get_nb_hops() == 1) {
  3171. // We can fall back to Query::links_to for != and == operations on links
  3172. if (link_map.m_link_types[0] == col_type_Link || (link_map.m_link_types[0] == col_type_LinkList)) {
  3173. ConstTableRef t = column->get_base_table();
  3174. Query query(t);
  3175. if (std::is_same_v<Operator, Equal>) {
  3176. return query.equal(link_map.m_link_column_keys[0], obj.get_link());
  3177. }
  3178. else {
  3179. return query.not_equal(link_map.m_link_column_keys[0], obj.get_link());
  3180. }
  3181. }
  3182. }
  3183. #endif
  3184. }
  3185. return make_expression<Compare<Operator>>(left.clone(), make_subexpr<KeyValue>(obj.get_key()));
  3186. }
  3187. inline Query operator==(const Subexpr2<Link>& left, const Obj& row)
  3188. {
  3189. return compare<Equal>(left, row);
  3190. }
  3191. inline Query operator!=(const Subexpr2<Link>& left, const Obj& row)
  3192. {
  3193. return compare<NotEqual>(left, row);
  3194. }
  3195. inline Query operator==(const Obj& row, const Subexpr2<Link>& right)
  3196. {
  3197. return compare<Equal>(right, row);
  3198. }
  3199. inline Query operator!=(const Obj& row, const Subexpr2<Link>& right)
  3200. {
  3201. return compare<NotEqual>(right, row);
  3202. }
  3203. template <class Operator>
  3204. Query compare(const Subexpr2<Link>& left, null)
  3205. {
  3206. static_assert(std::is_same_v<Operator, Equal> || std::is_same_v<Operator, NotEqual>,
  3207. "Links can only be compared for equality.");
  3208. return make_expression<Compare<Operator>>(left.clone(), make_subexpr<KeyValue>(ObjKey{}));
  3209. }
  3210. inline Query operator==(const Subexpr2<Link>& left, null)
  3211. {
  3212. return compare<Equal>(left, null());
  3213. }
  3214. inline Query operator!=(const Subexpr2<Link>& left, null)
  3215. {
  3216. return compare<NotEqual>(left, null());
  3217. }
  3218. inline Query operator==(null, const Subexpr2<Link>& right)
  3219. {
  3220. return compare<Equal>(right, null());
  3221. }
  3222. inline Query operator!=(null, const Subexpr2<Link>& right)
  3223. {
  3224. return compare<NotEqual>(right, null());
  3225. }
  3226. inline Query operator==(const Subexpr2<Link>& left, const Subexpr2<Link>& right)
  3227. {
  3228. return make_expression<Compare<Equal>>(left.clone(), right.clone());
  3229. }
  3230. inline Query operator!=(const Subexpr2<Link>& left, const Subexpr2<Link>& right)
  3231. {
  3232. return make_expression<Compare<NotEqual>>(left.clone(), right.clone());
  3233. }
  3234. template <class T>
  3235. class Columns : public ObjPropertyExpr<T> {
  3236. public:
  3237. using LeafType = typename ColumnTypeTraits<T>::cluster_leaf_type;
  3238. using ObjPropertyExpr<T>::links_exist;
  3239. using ObjPropertyBase::is_nullable;
  3240. Columns(ColKey column, ConstTableRef table, std::vector<ColKey> links = {},
  3241. ExpressionComparisonType type = ExpressionComparisonType::Any)
  3242. : ObjPropertyExpr<T>(column, table, std::move(links), type)
  3243. {
  3244. }
  3245. Columns(const Columns& other)
  3246. : ObjPropertyExpr<T>(other)
  3247. {
  3248. }
  3249. void set_cluster(const Cluster* cluster) override
  3250. {
  3251. m_array_ptr = nullptr;
  3252. m_leaf_ptr = nullptr;
  3253. if (links_exist()) {
  3254. m_link_map.set_cluster(cluster);
  3255. }
  3256. else {
  3257. // Create new Leaf
  3258. m_array_ptr = LeafPtr(new (&m_leaf_cache_storage) LeafType(this->get_base_table()->get_alloc()));
  3259. cluster->init_leaf(m_column_key, m_array_ptr.get());
  3260. m_leaf_ptr = m_array_ptr.get();
  3261. }
  3262. }
  3263. template <class LeafType2 = LeafType>
  3264. void evaluate_internal(size_t index, ValueBase& destination)
  3265. {
  3266. using U = typename LeafType2::value_type;
  3267. if (links_exist()) {
  3268. REALM_ASSERT(m_leaf_ptr == nullptr);
  3269. if (m_link_map.only_unary_links()) {
  3270. destination.init(false, 1);
  3271. destination.set_null(0);
  3272. if (auto link_translation_key = m_link_map.get_unary_link_or_not_found(index)) {
  3273. const Obj obj = m_link_map.get_target_table()->get_object(link_translation_key);
  3274. if (!obj.is_null(m_column_key))
  3275. destination.set(0, obj.get<U>(m_column_key));
  3276. }
  3277. }
  3278. else {
  3279. // LinkList with more than 0 values. Create Value with payload for all fields
  3280. std::vector<ObjKey> links = m_link_map.get_links(index);
  3281. destination.init_for_links(m_link_map.only_unary_links(), links.size());
  3282. for (size_t t = 0; t < links.size(); t++) {
  3283. const Obj obj = m_link_map.get_target_table()->get_object(links[t]);
  3284. if (obj.is_null(m_column_key))
  3285. destination.set_null(t);
  3286. else
  3287. destination.set(t, obj.get<U>(m_column_key));
  3288. }
  3289. }
  3290. }
  3291. else {
  3292. REALM_ASSERT(m_leaf_ptr != nullptr);
  3293. auto leaf = static_cast<const LeafType2*>(m_leaf_ptr);
  3294. // Not a Link column
  3295. size_t colsize = leaf->size();
  3296. // Now load `ValueBase::chunk_size` rows from from the leaf into m_storage. If it's an integer
  3297. // leaf, then it contains the method get_chunk() which copies these values in a super fast way (first
  3298. // case of the `if` below. Otherwise, copy the values one by one in a for-loop (the `else` case).
  3299. if constexpr (std::is_same_v<U, int64_t>) {
  3300. if (index + ValueBase::chunk_size <= colsize) {
  3301. // If you want to modify 'chunk_size' then update Array::get_chunk()
  3302. REALM_ASSERT_3(ValueBase::chunk_size, ==, 8);
  3303. auto leaf_2 = static_cast<const Array*>(leaf);
  3304. int64_t res[ValueBase::chunk_size];
  3305. leaf_2->get_chunk(index, res);
  3306. destination.set(res, res + ValueBase::chunk_size);
  3307. return;
  3308. }
  3309. }
  3310. size_t rows = colsize - index;
  3311. if (rows > ValueBase::chunk_size)
  3312. rows = ValueBase::chunk_size;
  3313. destination.init(false, rows);
  3314. for (size_t t = 0; t < rows; t++) {
  3315. if (leaf->is_null(index + t)) {
  3316. destination.set_null(t);
  3317. }
  3318. else {
  3319. destination.set(t, leaf->get(index + t));
  3320. }
  3321. }
  3322. }
  3323. }
  3324. virtual std::string description(util::serializer::SerialisationState& state) const override
  3325. {
  3326. return state.describe_expression_type(this->m_comparison_type) +
  3327. state.describe_columns(m_link_map, m_column_key);
  3328. }
  3329. // Load values from Column into destination
  3330. void evaluate(size_t index, ValueBase& destination) override
  3331. {
  3332. if (is_nullable() && std::is_same_v<typename LeafType::value_type, int64_t>) {
  3333. evaluate_internal<ArrayIntNull>(index, destination);
  3334. }
  3335. else if (is_nullable() && std::is_same_v<typename LeafType::value_type, bool>) {
  3336. evaluate_internal<ArrayBoolNull>(index, destination);
  3337. }
  3338. else {
  3339. evaluate_internal<LeafType>(index, destination);
  3340. }
  3341. }
  3342. void evaluate(ObjKey key, ValueBase& destination) override
  3343. {
  3344. destination.init(false, 1);
  3345. auto table = m_link_map.get_target_table();
  3346. auto obj = table.unchecked_ptr()->get_object(key);
  3347. if (is_nullable() && std::is_same_v<typename LeafType::value_type, int64_t>) {
  3348. destination.set(0, obj.template get<util::Optional<int64_t>>(m_column_key));
  3349. }
  3350. else if (is_nullable() && std::is_same_v<typename LeafType::value_type, bool>) {
  3351. destination.set(0, obj.template get<util::Optional<bool>>(m_column_key));
  3352. }
  3353. else {
  3354. destination.set(0, obj.template get<T>(m_column_key));
  3355. }
  3356. }
  3357. private:
  3358. using ObjPropertyExpr<T>::m_link_map;
  3359. using ObjPropertyExpr<T>::m_column_key;
  3360. // Leaf cache
  3361. using LeafCacheStorage = typename std::aligned_storage<sizeof(LeafType), alignof(LeafType)>::type;
  3362. using LeafPtr = std::unique_ptr<ArrayPayload, PlacementDelete>;
  3363. LeafCacheStorage m_leaf_cache_storage;
  3364. LeafPtr m_array_ptr;
  3365. const ArrayPayload* m_leaf_ptr = nullptr;
  3366. };
  3367. template <typename T, typename Operation>
  3368. class SubColumnAggregate;
  3369. // Defines a uniform interface for aggregation methods.
  3370. class SubColumnBase {
  3371. public:
  3372. virtual std::unique_ptr<Subexpr> max_of() = 0;
  3373. virtual std::unique_ptr<Subexpr> min_of() = 0;
  3374. virtual std::unique_ptr<Subexpr> sum_of() = 0;
  3375. virtual std::unique_ptr<Subexpr> avg_of() = 0;
  3376. };
  3377. template <typename T>
  3378. class SubColumns : public Subexpr, public SubColumnBase {
  3379. public:
  3380. SubColumns(Columns<T>&& column, const LinkMap& link_map)
  3381. : m_column(std::move(column))
  3382. , m_link_map(link_map)
  3383. {
  3384. }
  3385. DataType get_type() const final
  3386. {
  3387. return ColumnTypeTraits<T>::id;
  3388. }
  3389. std::unique_ptr<Subexpr> clone() const override
  3390. {
  3391. return make_subexpr<SubColumns<T>>(*this);
  3392. }
  3393. ConstTableRef get_base_table() const override
  3394. {
  3395. return m_link_map.get_base_table();
  3396. }
  3397. void set_base_table(ConstTableRef table) override
  3398. {
  3399. m_link_map.set_base_table(table);
  3400. m_column.set_base_table(m_link_map.get_target_table());
  3401. }
  3402. void collect_dependencies(std::vector<TableKey>& tables) const override
  3403. {
  3404. m_link_map.collect_dependencies(tables);
  3405. }
  3406. void evaluate(size_t, ValueBase&) override
  3407. {
  3408. // SubColumns can only be used in an expression in conjunction with its aggregate methods.
  3409. REALM_ASSERT(false);
  3410. }
  3411. virtual std::string description(util::serializer::SerialisationState&) const override
  3412. {
  3413. return ""; // by itself there are no conditions, see SubColumnAggregate
  3414. }
  3415. SubColumnAggregate<T, aggregate_operations::Minimum<T>> min() const
  3416. {
  3417. return {m_column, m_link_map};
  3418. }
  3419. SubColumnAggregate<T, aggregate_operations::Maximum<T>> max() const
  3420. {
  3421. return {m_column, m_link_map};
  3422. }
  3423. SubColumnAggregate<T, aggregate_operations::Sum<T>> sum() const
  3424. {
  3425. return {m_column, m_link_map};
  3426. }
  3427. SubColumnAggregate<T, aggregate_operations::Average<T>> average() const
  3428. {
  3429. return {m_column, m_link_map};
  3430. }
  3431. std::unique_ptr<Subexpr> max_of() override
  3432. {
  3433. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128, Timestamp>) {
  3434. return max().clone();
  3435. }
  3436. else {
  3437. return {};
  3438. }
  3439. }
  3440. std::unique_ptr<Subexpr> min_of() override
  3441. {
  3442. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128, Timestamp>) {
  3443. return min().clone();
  3444. }
  3445. else {
  3446. return {};
  3447. }
  3448. }
  3449. std::unique_ptr<Subexpr> sum_of() override
  3450. {
  3451. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128>) {
  3452. return sum().clone();
  3453. }
  3454. else {
  3455. return {};
  3456. }
  3457. }
  3458. std::unique_ptr<Subexpr> avg_of() override
  3459. {
  3460. if constexpr (realm::is_any_v<T, Int, Float, Double, Decimal128>) {
  3461. return average().clone();
  3462. }
  3463. else {
  3464. return {};
  3465. }
  3466. }
  3467. private:
  3468. Columns<T> m_column;
  3469. LinkMap m_link_map;
  3470. };
  3471. template <typename T, typename Operation>
  3472. class SubColumnAggregate : public Subexpr2<decltype(Operation().result())> {
  3473. public:
  3474. SubColumnAggregate(const Columns<T>& column, const LinkMap& link_map)
  3475. : m_column(column)
  3476. , m_link_map(link_map)
  3477. {
  3478. }
  3479. SubColumnAggregate(SubColumnAggregate const& other)
  3480. : m_column(other.m_column)
  3481. , m_link_map(other.m_link_map)
  3482. {
  3483. }
  3484. std::unique_ptr<Subexpr> clone() const override
  3485. {
  3486. return make_subexpr<SubColumnAggregate>(*this);
  3487. }
  3488. ConstTableRef get_base_table() const override
  3489. {
  3490. return m_link_map.get_base_table();
  3491. }
  3492. void set_base_table(ConstTableRef table) override
  3493. {
  3494. m_link_map.set_base_table(table);
  3495. m_column.set_base_table(m_link_map.get_target_table());
  3496. }
  3497. void set_cluster(const Cluster* cluster) override
  3498. {
  3499. m_link_map.set_cluster(cluster);
  3500. }
  3501. void collect_dependencies(std::vector<TableKey>& tables) const override
  3502. {
  3503. m_link_map.collect_dependencies(tables);
  3504. }
  3505. void evaluate(size_t index, ValueBase& destination) override
  3506. {
  3507. std::vector<ObjKey> keys = m_link_map.get_links(index);
  3508. std::sort(keys.begin(), keys.end());
  3509. Operation op;
  3510. for (auto key : keys) {
  3511. Value<T> value;
  3512. m_column.evaluate(key, value);
  3513. size_t value_index = 0;
  3514. if (!value[value_index].is_null()) {
  3515. op.accumulate(value[value_index].template get<T>());
  3516. }
  3517. }
  3518. if (op.is_null()) {
  3519. destination.set_null(0);
  3520. }
  3521. else {
  3522. destination.set(0, op.result());
  3523. }
  3524. }
  3525. virtual std::string description(util::serializer::SerialisationState& state) const override
  3526. {
  3527. util::serializer::SerialisationState empty_state(state.class_prefix);
  3528. return state.describe_columns(m_link_map, ColKey()) + util::serializer::value_separator +
  3529. Operation::description() + util::serializer::value_separator + m_column.description(empty_state);
  3530. }
  3531. private:
  3532. Columns<T> m_column;
  3533. LinkMap m_link_map;
  3534. };
  3535. class SubQueryCount : public Subexpr2<Int> {
  3536. public:
  3537. SubQueryCount(const Query& q, const LinkMap& link_map)
  3538. : m_query(q)
  3539. , m_link_map(link_map)
  3540. {
  3541. REALM_ASSERT(q.produces_results_in_table_order());
  3542. REALM_ASSERT(m_query.get_table() == m_link_map.get_target_table());
  3543. }
  3544. ConstTableRef get_base_table() const override
  3545. {
  3546. return m_link_map.get_base_table();
  3547. }
  3548. void set_base_table(ConstTableRef table) override
  3549. {
  3550. m_link_map.set_base_table(table);
  3551. m_query.set_table(m_link_map.get_target_table().cast_away_const());
  3552. }
  3553. void set_cluster(const Cluster* cluster) override
  3554. {
  3555. m_link_map.set_cluster(cluster);
  3556. }
  3557. void collect_dependencies(std::vector<TableKey>& tables) const override
  3558. {
  3559. m_link_map.collect_dependencies(tables);
  3560. }
  3561. void evaluate(size_t index, ValueBase& destination) override
  3562. {
  3563. std::vector<ObjKey> links = m_link_map.get_links(index);
  3564. // std::sort(links.begin(), links.end());
  3565. m_query.init();
  3566. size_t count = std::accumulate(links.begin(), links.end(), size_t(0), [this](size_t running_count, ObjKey k) {
  3567. const Obj obj = m_link_map.get_target_table()->get_object(k);
  3568. return running_count + m_query.eval_object(obj);
  3569. });
  3570. destination = Value<int64_t>(count);
  3571. }
  3572. virtual std::string description(util::serializer::SerialisationState& state) const override
  3573. {
  3574. REALM_ASSERT(m_link_map.get_base_table() != nullptr);
  3575. std::string target = state.describe_columns(m_link_map, ColKey());
  3576. std::string var_name = state.get_variable_name(m_link_map.get_base_table());
  3577. state.subquery_prefix_list.push_back(var_name);
  3578. std::string desc = "SUBQUERY(" + target + ", " + var_name + ", " + m_query.get_description(state) + ")" +
  3579. util::serializer::value_separator + "@count";
  3580. state.subquery_prefix_list.pop_back();
  3581. return desc;
  3582. }
  3583. std::unique_ptr<Subexpr> clone() const override
  3584. {
  3585. return make_subexpr<SubQueryCount>(*this);
  3586. }
  3587. private:
  3588. Query m_query;
  3589. LinkMap m_link_map;
  3590. };
  3591. // The unused template parameter is a hack to avoid a circular dependency between table.hpp and query_expression.hpp.
  3592. template <class>
  3593. class SubQuery {
  3594. public:
  3595. SubQuery(Columns<Link> link_column, Query query)
  3596. : m_query(std::move(query))
  3597. , m_link_map(link_column.link_map())
  3598. {
  3599. REALM_ASSERT(m_link_map.get_target_table() == m_query.get_table());
  3600. }
  3601. SubQueryCount count() const
  3602. {
  3603. return SubQueryCount(m_query, m_link_map);
  3604. }
  3605. private:
  3606. Query m_query;
  3607. LinkMap m_link_map;
  3608. };
  3609. template <class oper, class TLeft>
  3610. class UnaryOperator : public Subexpr2<typename oper::type> {
  3611. public:
  3612. UnaryOperator(std::unique_ptr<TLeft> left)
  3613. : m_left(std::move(left))
  3614. {
  3615. }
  3616. UnaryOperator(const UnaryOperator& other)
  3617. : m_left(other.m_left->clone())
  3618. {
  3619. }
  3620. UnaryOperator& operator=(const UnaryOperator& other)
  3621. {
  3622. if (this != &other) {
  3623. m_left = other.m_left->clone();
  3624. }
  3625. return *this;
  3626. }
  3627. UnaryOperator(UnaryOperator&&) noexcept = default;
  3628. UnaryOperator& operator=(UnaryOperator&&) noexcept = default;
  3629. // See comment in base class
  3630. void set_base_table(ConstTableRef table) override
  3631. {
  3632. m_left->set_base_table(table);
  3633. }
  3634. void set_cluster(const Cluster* cluster) override
  3635. {
  3636. m_left->set_cluster(cluster);
  3637. }
  3638. void collect_dependencies(std::vector<TableKey>& tables) const override
  3639. {
  3640. m_left->collect_dependencies(tables);
  3641. }
  3642. // Recursively fetch tables of columns in expression tree. Used when user first builds a stand-alone expression
  3643. // and binds it to a Query at a later time
  3644. ConstTableRef get_base_table() const override
  3645. {
  3646. return m_left->get_base_table();
  3647. }
  3648. // destination = operator(left)
  3649. void evaluate(size_t index, ValueBase& destination) override
  3650. {
  3651. Value<T> result;
  3652. Value<T> left;
  3653. m_left->evaluate(index, left);
  3654. result.template fun<oper>(left);
  3655. destination = result;
  3656. }
  3657. virtual std::string description(util::serializer::SerialisationState& state) const override
  3658. {
  3659. if (m_left) {
  3660. return m_left->description(state);
  3661. }
  3662. return "";
  3663. }
  3664. std::unique_ptr<Subexpr> clone() const override
  3665. {
  3666. return make_subexpr<UnaryOperator>(*this);
  3667. }
  3668. private:
  3669. typedef typename oper::type T;
  3670. std::unique_ptr<TLeft> m_left;
  3671. };
  3672. template <class oper, class TLeft, class TRight>
  3673. class Operator : public Subexpr2<typename oper::type> {
  3674. public:
  3675. Operator(std::unique_ptr<TLeft> left, std::unique_ptr<TRight> right)
  3676. : m_left(std::move(left))
  3677. , m_right(std::move(right))
  3678. {
  3679. }
  3680. Operator(const Operator& other)
  3681. : m_left(other.m_left->clone())
  3682. , m_right(other.m_right->clone())
  3683. {
  3684. }
  3685. Operator& operator=(const Operator& other)
  3686. {
  3687. if (this != &other) {
  3688. m_left = other.m_left->clone();
  3689. m_right = other.m_right->clone();
  3690. }
  3691. return *this;
  3692. }
  3693. Operator(Operator&&) noexcept = default;
  3694. Operator& operator=(Operator&&) noexcept = default;
  3695. // See comment in base class
  3696. void set_base_table(ConstTableRef table) override
  3697. {
  3698. m_left->set_base_table(table);
  3699. m_right->set_base_table(table);
  3700. }
  3701. void set_cluster(const Cluster* cluster) override
  3702. {
  3703. m_left->set_cluster(cluster);
  3704. m_right->set_cluster(cluster);
  3705. }
  3706. // Recursively fetch tables of columns in expression tree. Used when user first builds a stand-alone expression
  3707. // and
  3708. // binds it to a Query at a later time
  3709. ConstTableRef get_base_table() const override
  3710. {
  3711. ConstTableRef l = m_left->get_base_table();
  3712. ConstTableRef r = m_right->get_base_table();
  3713. // Queries do not support multiple different tables; all tables must be the same.
  3714. REALM_ASSERT(l == nullptr || r == nullptr || l == r);
  3715. // nullptr pointer means expression which isn't yet associated with any table, or is a Value<T>
  3716. return bool(l) ? l : r;
  3717. }
  3718. // destination = operator(left, right)
  3719. void evaluate(size_t index, ValueBase& destination) override
  3720. {
  3721. Value<T> result;
  3722. Value<T> left;
  3723. Value<T> right;
  3724. m_left->evaluate(index, left);
  3725. m_right->evaluate(index, right);
  3726. result.template fun<oper>(left, right);
  3727. destination = result;
  3728. }
  3729. virtual std::string description(util::serializer::SerialisationState& state) const override
  3730. {
  3731. std::string s;
  3732. if (m_left) {
  3733. s += m_left->description(state);
  3734. }
  3735. s += (" " + oper::description() + " ");
  3736. if (m_right) {
  3737. s += m_right->description(state);
  3738. }
  3739. return s;
  3740. }
  3741. std::unique_ptr<Subexpr> clone() const override
  3742. {
  3743. return make_subexpr<Operator>(*this);
  3744. }
  3745. private:
  3746. typedef typename oper::type T;
  3747. std::unique_ptr<TLeft> m_left;
  3748. std::unique_ptr<TRight> m_right;
  3749. };
  3750. template <class TCond>
  3751. class Compare : public Expression {
  3752. public:
  3753. Compare(std::unique_ptr<Subexpr> left, std::unique_ptr<Subexpr> right)
  3754. : m_left(std::move(left))
  3755. , m_right(std::move(right))
  3756. {
  3757. m_left_is_const = m_left->has_constant_evaluation();
  3758. if (m_left_is_const) {
  3759. m_left_value = m_left->get_mixed();
  3760. }
  3761. }
  3762. // See comment in base class
  3763. void set_base_table(ConstTableRef table) override
  3764. {
  3765. m_left->set_base_table(table);
  3766. m_right->set_base_table(table);
  3767. }
  3768. void set_cluster(const Cluster* cluster) override
  3769. {
  3770. if (m_has_matches) {
  3771. m_cluster = cluster;
  3772. }
  3773. else {
  3774. m_left->set_cluster(cluster);
  3775. m_right->set_cluster(cluster);
  3776. }
  3777. }
  3778. double init() override
  3779. {
  3780. double dT = m_left_is_const ? 10.0 : 50.0;
  3781. if (std::is_same_v<TCond, Equal> && m_left_is_const && m_right->has_search_index() &&
  3782. m_right->get_comparison_type() == ExpressionComparisonType::Any) {
  3783. if (m_left_value.is_null()) {
  3784. const ObjPropertyBase* prop = dynamic_cast<const ObjPropertyBase*>(m_right.get());
  3785. // when checking for null across links, null links are considered matches,
  3786. // so we must compute the slow matching even if there is an index.
  3787. if (!prop || prop->links_exist()) {
  3788. return dT;
  3789. }
  3790. else {
  3791. m_matches = m_right->find_all(Mixed());
  3792. }
  3793. }
  3794. else {
  3795. if (m_right->get_type() != m_left_value.get_type()) {
  3796. // If the type we are looking for is not the same type as the target
  3797. // column, we cannot use the index
  3798. return dT;
  3799. }
  3800. m_matches = m_right->find_all(m_left_value);
  3801. }
  3802. // Sort
  3803. std::sort(m_matches.begin(), m_matches.end());
  3804. // Remove all duplicates
  3805. m_matches.erase(std::unique(m_matches.begin(), m_matches.end()), m_matches.end());
  3806. m_has_matches = true;
  3807. m_index_get = 0;
  3808. m_index_end = m_matches.size();
  3809. dT = 0;
  3810. }
  3811. return dT;
  3812. }
  3813. // Recursively fetch tables of columns in expression tree. Used when user first builds a stand-alone expression
  3814. // and binds it to a Query at a later time
  3815. ConstTableRef get_base_table() const override
  3816. {
  3817. ConstTableRef l = m_left->get_base_table();
  3818. ConstTableRef r = m_right->get_base_table();
  3819. // All main tables in each subexpression of a query (table.columns() or table.link()) must be the same.
  3820. REALM_ASSERT(l == nullptr || r == nullptr || l == r);
  3821. // nullptr pointer means expression which isn't yet associated with any table, or is a Value<T>
  3822. return (l) ? l : r;
  3823. }
  3824. void collect_dependencies(std::vector<TableKey>& tables) const override
  3825. {
  3826. m_left->collect_dependencies(tables);
  3827. m_right->collect_dependencies(tables);
  3828. }
  3829. size_t find_first(size_t start, size_t end) const override
  3830. {
  3831. if (m_has_matches) {
  3832. if (m_index_end == 0 || start >= end)
  3833. return not_found;
  3834. ObjKey first_key = m_cluster->get_real_key(start);
  3835. ObjKey actual_key;
  3836. // Sequential lookup optimization: when the query isn't constrained
  3837. // to a LnkLst we'll get find_first() requests in ascending order,
  3838. // so we can do a simple linear scan.
  3839. if (m_index_get < m_index_end && m_matches[m_index_get] <= first_key) {
  3840. actual_key = m_matches[m_index_get];
  3841. // skip through keys which are in "earlier" leafs than the one selected by start..end:
  3842. while (first_key > actual_key) {
  3843. m_index_get++;
  3844. if (m_index_get == m_index_end)
  3845. return not_found;
  3846. actual_key = m_matches[m_index_get];
  3847. }
  3848. }
  3849. // Otherwise if we get requests out of order we have to do a more
  3850. // expensive binary search
  3851. else {
  3852. auto it = std::lower_bound(m_matches.begin(), m_matches.end(), first_key);
  3853. if (it == m_matches.end())
  3854. return not_found;
  3855. actual_key = *it;
  3856. }
  3857. // if actual key is bigger than last key, it is not in this leaf
  3858. ObjKey last_key = start + 1 == end ? first_key : m_cluster->get_real_key(end - 1);
  3859. if (actual_key > last_key)
  3860. return not_found;
  3861. // key is known to be in this leaf, so find key whithin leaf keys
  3862. return m_cluster->lower_bound_key(ObjKey(actual_key.value - m_cluster->get_offset()));
  3863. }
  3864. size_t match;
  3865. ValueBase right;
  3866. const ExpressionComparisonType right_cmp_type = m_right->get_comparison_type();
  3867. if (m_left_is_const) {
  3868. for (; start < end;) {
  3869. m_right->evaluate(start, right);
  3870. match = ValueBase::compare_const<TCond>(m_left_value, right, right_cmp_type);
  3871. if (match != not_found && match + start < end)
  3872. return start + match;
  3873. size_t rows = right.m_from_link_list ? 1 : right.size();
  3874. start += rows;
  3875. }
  3876. }
  3877. else {
  3878. ValueBase left;
  3879. const ExpressionComparisonType left_cmp_type = m_left->get_comparison_type();
  3880. for (; start < end;) {
  3881. m_left->evaluate(start, left);
  3882. m_right->evaluate(start, right);
  3883. match = ValueBase::template compare<TCond>(left, right, left_cmp_type, right_cmp_type);
  3884. if (match != not_found && match + start < end)
  3885. return start + match;
  3886. size_t rows =
  3887. (left.m_from_link_list || right.m_from_link_list) ? 1 : minimum(right.size(), left.size());
  3888. start += rows;
  3889. }
  3890. }
  3891. return not_found; // no match
  3892. }
  3893. virtual std::string description(util::serializer::SerialisationState& state) const override
  3894. {
  3895. if (realm::is_any_v<TCond, BeginsWith, BeginsWithIns, EndsWith, EndsWithIns, Contains, ContainsIns, Like,
  3896. LikeIns>) {
  3897. // these string conditions have the arguments reversed but the order is important
  3898. // operations ==, and != can be reversed because the produce the same results both ways
  3899. return util::serializer::print_value(m_right->description(state) + " " + TCond::description() + " " +
  3900. m_left->description(state));
  3901. }
  3902. return util::serializer::print_value(m_left->description(state) + " " + TCond::description() + " " +
  3903. m_right->description(state));
  3904. }
  3905. std::unique_ptr<Expression> clone() const override
  3906. {
  3907. return std::unique_ptr<Expression>(new Compare(*this));
  3908. }
  3909. private:
  3910. Compare(const Compare& other)
  3911. : m_left(other.m_left->clone())
  3912. , m_right(other.m_right->clone())
  3913. , m_left_is_const(other.m_left_is_const)
  3914. {
  3915. if (m_left_is_const) {
  3916. m_left_value = m_left->get_mixed();
  3917. }
  3918. }
  3919. std::unique_ptr<Subexpr> m_left;
  3920. std::unique_ptr<Subexpr> m_right;
  3921. const Cluster* m_cluster;
  3922. bool m_left_is_const;
  3923. QueryValue m_left_value;
  3924. bool m_has_matches = false;
  3925. std::vector<ObjKey> m_matches;
  3926. mutable size_t m_index_get = 0;
  3927. size_t m_index_end = 0;
  3928. };
  3929. } // namespace realm
  3930. #endif // REALM_QUERY_EXPRESSION_HPP