@@ -40,10 +40,27 @@ RUM support functions
4040 Datum *rum_extract_value(Datum itemValue, int32 *nkeys, bool **nullFlags, Datum **addInfo, bool **nullFlagsAddInfo)
4141 Datum *rum_extract_query(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data,
4242 bool **nullFlags, int32 *searchMode)
43- boolconsistent (bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[],
43+ boolrum_consistent (bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[],
4444 bool *recheck, Datum queryKeys[], bool nullFlags[], Datum **addInfo, bool **nullFlagsAddInfo)
4545 int32 rum_compare_prefix(Datum a, Datum b,StrategyNumber n,void *addInfo)
4646 void rum_config(RumConfig *config)
47+
48+ bool rum_pre_consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[],
49+ bool *recheck, Datum queryKeys[], bool nullFlags[])
50+ Return value:
51+ false if index key value is not consistent with query
52+ true if key value MAYBE consistent and will be rechecked in rum_consistent function
53+ Parameters:
54+ check[] contains false, if element is not match any query element.
55+ if all elements in check[] equal to true, this function is not called
56+ if all elements in check[] equal to false, this function is not called
57+ StrategyNumber - the number of the strategy from the class operator
58+ query
59+ nkeys quantity of elements in check[]. If nkeys==0, this function is not called
60+ recheck - parameter is not used
61+ queryKeys[] - returned by rum_extract_query
62+ nullFlags[] - returned by rum_extract_query (or all false, if rum_extract_query did not return nullFlags)
63+
4764 double rum_ordering_distance(bool check[], ?StrategyNumber n, ?Datum query, int32 nkeys, ?Pointer extra_data[],
4865 ?bool *recheck, ?Datum queryKeys[], ?bool nullFlags[], Datum **addInfo, bool **nullFlagsAddInfo)
4966 Datum rum_join_pos(Datum, Datum)
@@ -228,39 +245,45 @@ rumanyarray_consistent(PG_FUNCTION_ARGS)
228245bool * recheck = (bool * )PG_GETARG_POINTER (5 );
229246
230247/* Datum *queryKeys = (Datum *) PG_GETARG_POINTER(6); */
231- bool * nullFlags = (bool * )PG_GETARG_POINTER (7 );
248+
249+ /* rumextract_anyarray_query does not return nullFlags, so RUM initializes all them by false */
250+ /* bool *nullFlags = (bool *) PG_GETARG_POINTER(7); */
232251
233252Datum * addInfo = (Datum * )PG_GETARG_POINTER (8 );
234- bool * addInfoIsNull = (bool * )PG_GETARG_POINTER (9 );
253+ /* rumextract_anyarray_query initializes all addInfoIsNull elements by false */
254+ /* bool *addInfoIsNull = (bool *) PG_GETARG_POINTER(9); */
235255
236256bool res ;
237257int32 i ;
238258
239259switch (strategy )
240260{
241261case RUM_OVERLAP_STRATEGY :
262+ /* at least one element in check[] is true, so result = true */
263+ * recheck = false;
264+ res = true;
242265/* result is not lossy */
243- * recheck = false;
266+ /* * recheck = false; */
244267/* must have a match for at least one non-null element */
245- res = false;
268+ /* res = false;
246269for (i = 0; i < nkeys; i++)
247270{
248271if (check[i] && !nullFlags[i])
249272{
250273res = true;
251274break;
252275}
253- }
276+ }*/
254277break ;
255278case RUM_CONTAINS_STRATEGY :
256- /* result is not lossy */
279+ /* result is not lossy */
257280* recheck = false;
258281
259282/* must have all elements in check[] true, and no nulls */
260283res = true;
261284for (i = 0 ;i < nkeys ;i ++ )
262285{
263- if (!check [i ]|| nullFlags [i ])
286+ if (!check [i ]/* || nullFlags[i] */ )
264287{
265288res = false;
266289break ;
@@ -272,19 +295,28 @@ rumanyarray_consistent(PG_FUNCTION_ARGS)
272295* recheck = true;
273296
274297/* query must have <= amount of elements than array */
298+ if (nkeys > 0 )
299+ {
300+ res = (DatumGetInt32 (addInfo [0 ]) <=nkeys );
301+ }else {
302+ /* empty arrays in query and index */
303+ * recheck = false;
304+ res = true;
305+ }
306+ /*
275307res = true;
276- for (i = 0 ;i < nkeys ;i ++ )
308+ for (i = 0; i < nkeys; i++)
277309{
278- if (!addInfoIsNull [i ]&& DatumGetInt32 (addInfo [i ])> nkeys )
310+ if ( !addInfoIsNull[i] && DatumGetInt32(addInfo[i]) > nkeys)
279311{
280312res = false;
281313break;
282314}
283- }
315+ } */
284316break ;
285317case RUM_EQUAL_STRATEGY :
286318/* we will need recheck */
287- * recheck = true;
319+ /* * recheck = true; */
288320
289321/*
290322 * Must have all elements in check[] true; no discrimination
@@ -293,6 +325,25 @@ rumanyarray_consistent(PG_FUNCTION_ARGS)
293325 *
294326 * Also, query and array must have equal amount of elements.
295327 */
328+ * recheck = true;
329+ res = true;
330+ if (nkeys > 0 )
331+ {
332+ if (DatumGetInt32 (addInfo [0 ])!= nkeys )
333+ {
334+ res = false;
335+ }else {
336+ for (i = 0 ;i < nkeys ;i ++ )
337+ {
338+ if (!check [i ])
339+ {
340+ res = false;
341+ break ;
342+ }
343+ }
344+ }
345+ }
346+ /*
296347res = true;
297348for (i = 0; i < nkeys; i++)
298349{
@@ -307,7 +358,7 @@ rumanyarray_consistent(PG_FUNCTION_ARGS)
307358res = false;
308359break;
309360}
310- }
361+ }*/
311362break ;
312363case RUM_SIMILAR_STRATEGY :
313364/* we won't need recheck */
@@ -317,48 +368,129 @@ rumanyarray_consistent(PG_FUNCTION_ARGS)
317368int32 intersection = 0 ,
318369nentries = -1 ;
319370SimpleArray sa ,sb ;
371+ float8 sml ;
320372
321373for (i = 0 ;i < nkeys ;i ++ )
322374if (check [i ])
323375intersection ++ ;
376+ if (intersection > 0 )
377+ {
378+ /* extract array's length from addInfo */
379+ nentries = DatumGetInt32 (addInfo [0 ]);
380+ /*for (i = 0; i < nkeys; i++)
381+ {
382+ if (!addInfoIsNull[i])
383+ {
384+ nentries = DatumGetInt32(addInfo[i]);
385+ break;
386+ }
387+ } */
388+
389+ /* there must be addInfo */
390+ Assert (nentries >=0 );
391+
392+ INIT_DUMMY_SIMPLE_ARRAY (& sa ,nentries );
393+ INIT_DUMMY_SIMPLE_ARRAY (& sb ,nkeys );
394+ sml = getSimilarityValue (& sa ,& sb ,intersection );
395+ }
396+ else
397+ {
398+ sml = 0.0 ;
399+ }
400+ res = (sml >=SmlLimit );
401+ }
402+ break ;
403+ default :
404+ elog (ERROR ,"rum_anyarray_consistent: unknown strategy number: %d" ,
405+ strategy );
406+ res = false;
407+ }
324408
325- if (intersection > 0 )
326- {
327- float8 sml ;
409+ PG_RETURN_BOOL (res );
410+ }
328411
329- /* extract array's length from addInfo */
330- for (i = 0 ;i < nkeys ;i ++ )
331- {
332- if (!addInfoIsNull [i ])
333- {
334- nentries = DatumGetInt32 (addInfo [i ]);
335- break ;
336- }
337- }
412+ PG_FUNCTION_INFO_V1 (rumanyarray_preconsistent );
413+ Datum
414+ rumanyarray_preconsistent (PG_FUNCTION_ARGS )
415+ {
416+ bool * check = (bool * )PG_GETARG_POINTER (0 );
417+ StrategyNumber strategy = PG_GETARG_UINT16 (1 );
418+ /* ArrayType *query = PG_GETARG_ARRAYTYPE_P(2); */
419+ int32 nkeys = PG_GETARG_INT32 (3 );
420+ /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
421+ /* bool *recheck = (bool *) PG_GETARG_POINTER(5); */
422+ /* Datum *queryKeys = (Datum *) PG_GETARG_POINTER(6); */
423+ /* bool *nullFlags = (bool *) PG_GETARG_POINTER(7); */
338424
339- /* there must be addInfo */
340- Assert ( nentries >= 0 ) ;
425+ bool res ;
426+ int32 i ;
341427
342- INIT_DUMMY_SIMPLE_ARRAY (& sa ,nentries );
343- INIT_DUMMY_SIMPLE_ARRAY (& sb ,nkeys );
344- sml = getSimilarityValue (& sa ,& sb ,intersection );
428+ switch (strategy )
429+ {
430+ case RUM_OVERLAP_STRATEGY :
431+ /*
432+ * at least one check[i]==true
433+ * preConsistent function is not called, if all check[i]==false
434+ */
435+ res = true;
436+ break ;
437+ case RUM_CONTAINS_STRATEGY :
438+ /*
439+ * at least one check[i]==false
440+ * preConsistent function is not called, if all check[i]==true
441+ */
442+ res = false;
443+ break ;
444+ case RUM_CONTAINED_STRATEGY :
445+ /* we will need recheck */
446+ res = true;
447+ break ;
448+ case RUM_EQUAL_STRATEGY :
449+ /*
450+ * at least one check[i]==false
451+ * preConsistent function is not called, if all check[i]==true
452+ */
453+ res = false;
454+ break ;
455+ case RUM_SIMILAR_STRATEGY :
456+ {
457+ int32 intersection = 0 ;
458+
459+ for (i = 0 ;i < nkeys ;i ++ )
460+ if (check [i ])
461+ intersection ++ ;
345462
346- res = (sml >=SmlLimit );
463+ switch (SmlType )
464+ {
465+ case AA_Cosine :
466+ /* intersection / sqrt(nkeys * intersection) */
467+ res = (sqrt (((double )intersection ) / (double )nkeys ) >=SmlLimit );
468+ break ;
469+ case AA_Jaccard :
470+ res = ((((double )intersection ) / (double )nkeys ) >=SmlLimit );
471+ break ;
472+ case AA_Overlap :
473+ /*
474+ * if intersection >= SmlLimit, so result = true
475+ * if intersection < SmlLimit, so result = false
476+ */
477+ res = (((double )intersection ) >=SmlLimit );
478+ break ;
479+ default :
480+ elog (ERROR ,"unknown similarity type" );
347481}
348- else
349- res = false;
350482}
351483break ;
352484default :
353- elog (ERROR ,"rum_anyarray_consistent: unknown strategy number: %d" ,
354- strategy );
485+ elog (ERROR ,"rum_anyarray_preconsistent: unknown strategy number: %d" ,strategy );
355486res = false;
356487}
357488
358489PG_RETURN_BOOL (res );
359490}
360491
361492
493+
362494PG_FUNCTION_INFO_V1 (rumanyarray_ordering );
363495/*
364496 * Similarity and distance
@@ -689,10 +821,10 @@ rumanyarray_consistent_with_position(PG_FUNCTION_ARGS)
689821/* ArrayType *query = PG_GETARG_ARRAYTYPE_P(2); */
690822int32 nkeys = PG_GETARG_INT32 (3 );
691823
692- /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ Datum * extra_data = ( Datum * ) PG_GETARG_POINTER ( 4 );
824+ /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
693825bool * recheck = (bool * )PG_GETARG_POINTER (5 );
694826
695- /* Datum *queryKeys = (Datum *) PG_GETARG_POINTER(6); */ Datum * queryKeys = ( Datum * ) PG_GETARG_POINTER ( 6 );
827+ /* Datum *queryKeys = (Datum *) PG_GETARG_POINTER(6); */
696828bool * nullFlags = (bool * )PG_GETARG_POINTER (7 );
697829
698830Datum * addInfo = (Datum * )PG_GETARG_POINTER (8 );