@@ -576,51 +576,65 @@ smoc_overlap_neg(PG_FUNCTION_ARGS)
576576
577577/* check if moc_a is a subset of moc_b */
578578static bool
579- smoc_subset_impl (Smoc * moc_a , Smoc * moc_b )
579+ smoc_subset_impl (Datum a , Datum b )
580580{
581- int32 a = moc_a -> data_begin ;
582- int32 b = moc_b -> data_begin ;
583- int32 moc_a_end = VARSIZE (moc_a )- VARHDRSZ ;
584- int32 moc_b_end = VARSIZE (moc_b )- VARHDRSZ ;
585- char * moc_a_base = MOC_BASE (moc_a );
586- char * moc_b_base = MOC_BASE (moc_b );
581+ Smoc * moc_a = (Smoc * )PG_DETOAST_DATUM_SLICE (a ,0 ,MOC_HEADER_PAGE );
582+ Smoc * moc_b = (Smoc * )PG_DETOAST_DATUM_SLICE (b ,0 ,MOC_HEADER_PAGE );
583+ int32 i = moc_a -> data_begin ;
584+ int32 j = moc_b -> data_begin ;
585+ int32 moc_a_end ;
586+ int32 moc_b_end ;
587+ char * moc_a_base ;
588+ char * moc_b_base ;
587589
588590// an empty moc is subset of all mocs
589591if (moc_a -> area == 0 )
590592return true;
591- // and empty moc cannot have any other subsets than the empty one
592- if (moc_b -> area == 0 )
593+ // b is the whole sky
594+ if (moc_b -> area == MOC_AREA_ALL_SKY )
595+ return true;
596+ // a cannot be larger than b
597+ if (moc_a -> area > moc_b -> area )
593598return false;
594599
595600// quick exit if the mocs do not overlap at all
596601if (moc_a -> first >=moc_b -> last || moc_a -> last <=moc_b -> first )
597602return false;
598603
599- while (a < moc_a_end )// iterate over a
604+ // get full moc
605+ moc_a = (Smoc * )PG_DETOAST_DATUM (a );
606+ moc_b = (Smoc * )PG_DETOAST_DATUM (b );
607+
608+ moc_a_end = VARSIZE (moc_a )- VARHDRSZ ;
609+ moc_b_end = VARSIZE (moc_b )- VARHDRSZ ;
610+ moc_a_base = MOC_BASE (moc_a );
611+ moc_b_base = MOC_BASE (moc_b );
612+
613+ while (i < moc_a_end )// iterate over a
600614{
601615int32 mod ;
602616moc_interval * x ;
603617moc_interval * y ;
604618
605619// end of b reached while there's still 'a' intervals
606- if (b >=moc_b_end )
620+ if (j >=moc_b_end )
607621return false;
608622
609623// page bumps
610- mod = (a + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
624+ mod = (i + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
611625if (mod > 0 && mod < MOC_INTERVAL_SIZE )
612- a += MOC_INTERVAL_SIZE - mod ;
613- x = MOC_INTERVAL (moc_a_base ,a );
626+ i += MOC_INTERVAL_SIZE - mod ;
627+ x = MOC_INTERVAL (moc_a_base ,i );
614628
615- mod = (b + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
629+ mod = (j + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
616630if (mod > 0 && mod < MOC_INTERVAL_SIZE )
617- b += MOC_INTERVAL_SIZE - mod ;
618- y = MOC_INTERVAL (moc_b_base ,b );
631+ j += MOC_INTERVAL_SIZE - mod ;
632+ y = MOC_INTERVAL (moc_b_base ,j );
619633
620634// advance b until as long as we are before the 'a' interval
621635if (y -> second <=x -> first )
622636{
623- b += MOC_INTERVAL_SIZE ;
637+ j += MOC_INTERVAL_SIZE ;
624638continue ;
625639}
626640
@@ -633,13 +647,13 @@ smoc_subset_impl(Smoc* moc_a, Smoc* moc_b)
633647// advance interval that has the lowest end
634648if (x -> second == y -> second )
635649{
636- a += MOC_INTERVAL_SIZE ;
637- b += MOC_INTERVAL_SIZE ;
650+ i += MOC_INTERVAL_SIZE ;
651+ j += MOC_INTERVAL_SIZE ;
638652}
639653else if (x -> second <=y -> second )
640- a += MOC_INTERVAL_SIZE ;
654+ i += MOC_INTERVAL_SIZE ;
641655else
642- b += MOC_INTERVAL_SIZE ;
656+ j += MOC_INTERVAL_SIZE ;
643657// TODO: we could walk the tree structure to find the next interesting interval
644658}
645659
@@ -649,33 +663,33 @@ smoc_subset_impl(Smoc* moc_a, Smoc* moc_b)
649663Datum
650664smoc_subset_smoc (PG_FUNCTION_ARGS )
651665{
652- Smoc * moc_a = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (0 ) );
653- Smoc * moc_b = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (1 ) );
654- PG_RETURN_BOOL (smoc_subset_impl (moc_a , moc_b ));
666+ Datum a = PG_GETARG_DATUM (0 );
667+ Datum b = PG_GETARG_DATUM (1 );
668+ PG_RETURN_BOOL (smoc_subset_impl (a , b ));
655669}
656670
657671Datum
658672smoc_subset_smoc_neg (PG_FUNCTION_ARGS )
659673{
660- Smoc * moc_a = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (0 ) );
661- Smoc * moc_b = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (1 ) );
662- PG_RETURN_BOOL (!smoc_subset_impl (moc_a , moc_b ));
674+ Datum a = PG_GETARG_DATUM (0 );
675+ Datum b = PG_GETARG_DATUM (1 );
676+ PG_RETURN_BOOL (!smoc_subset_impl (a , b ));
663677}
664678
665679Datum
666680smoc_superset_smoc (PG_FUNCTION_ARGS )
667681{
668- Smoc * moc_a = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (0 ) );
669- Smoc * moc_b = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (1 ) );
670- PG_RETURN_BOOL (smoc_subset_impl (moc_b , moc_a ));
682+ Datum a = PG_GETARG_DATUM (0 );
683+ Datum b = PG_GETARG_DATUM (1 );
684+ PG_RETURN_BOOL (smoc_subset_impl (b , a ));
671685}
672686
673687Datum
674688smoc_superset_smoc_neg (PG_FUNCTION_ARGS )
675689{
676- Smoc * moc_a = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (0 ) );
677- Smoc * moc_b = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (1 ) );
678- PG_RETURN_BOOL (!smoc_subset_impl (moc_b , moc_a ));
690+ Datum a = PG_GETARG_DATUM (0 );
691+ Datum b = PG_GETARG_DATUM (1 );
692+ PG_RETURN_BOOL (!smoc_subset_impl (b , a ));
679693}
680694
681695static bool