@@ -495,39 +495,60 @@ smoc_neq(PG_FUNCTION_ARGS)
495495}
496496
497497static bool
498- smoc_overlap_impl (Smoc * moc_a , Smoc * moc_b )
498+ smoc_overlap_impl (Datum a , Datum b )
499499{
500- int32 a = moc_a -> data_begin ;
501- int32 b = moc_b -> data_begin ;
502- int32 moc_a_end = VARSIZE (moc_a )- VARHDRSZ ;
503- int32 moc_b_end = VARSIZE (moc_b )- VARHDRSZ ;
504- char * moc_a_base = MOC_BASE (moc_a );
505- char * moc_b_base = MOC_BASE (moc_b );
500+ Smoc * moc_a = (Smoc * )PG_DETOAST_DATUM_SLICE (a ,0 ,MOC_HEADER_PAGE );
501+ Smoc * moc_b = (Smoc * )PG_DETOAST_DATUM_SLICE (b ,0 ,MOC_HEADER_PAGE );
502+ int32 i = moc_a -> data_begin ;
503+ int32 j = moc_b -> data_begin ;
504+ int32 moc_a_end ;
505+ int32 moc_b_end ;
506+ char * moc_a_base ;
507+ char * moc_b_base ;
506508
507- while (a < moc_a_end && b < moc_b_end )// iterate over both in parallel
509+ // empty mocs do not overlap
510+ if (moc_a -> area == 0 || moc_b -> area == 0 )
511+ return false;
512+ // quick exit if the mocs do not overlap at all
513+ if (moc_a -> first >=moc_b -> last || moc_a -> last <=moc_b -> first )
514+ return false;
515+ // all-sky mocs overlap everything
516+ if (moc_a -> area == MOC_AREA_ALL_SKY || moc_b -> area == MOC_AREA_ALL_SKY )
517+ return true;
518+
519+ // get full moc
520+ moc_a = (Smoc * )PG_DETOAST_DATUM (a );
521+ moc_b = (Smoc * )PG_DETOAST_DATUM (b );
522+
523+ moc_a_end = VARSIZE (moc_a )- VARHDRSZ ;
524+ moc_b_end = VARSIZE (moc_b )- VARHDRSZ ;
525+ moc_a_base = MOC_BASE (moc_a );
526+ moc_b_base = MOC_BASE (moc_b );
527+
528+ while (i < moc_a_end && j < moc_b_end )// iterate over both in parallel
508529{
509530moc_interval * x ;
510531moc_interval * y ;
511532
512533// page bumps
513- int32 mod = (a + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
534+ int32 mod = (i + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
514535if (mod > 0 && mod < MOC_INTERVAL_SIZE )
515- a += MOC_INTERVAL_SIZE - mod ;
516- x = MOC_INTERVAL (moc_a_base ,a );
536+ i += MOC_INTERVAL_SIZE - mod ;
537+ x = MOC_INTERVAL (moc_a_base ,i );
517538
518- mod = (b + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
539+ mod = (j + MOC_INTERVAL_SIZE ) %PG_TOAST_PAGE_FRAGMENT ;
519540if (mod > 0 && mod < MOC_INTERVAL_SIZE )
520- b += MOC_INTERVAL_SIZE - mod ;
521- y = MOC_INTERVAL (moc_b_base ,b );
541+ j += MOC_INTERVAL_SIZE - mod ;
542+ y = MOC_INTERVAL (moc_b_base ,j );
522543
523544if (x -> second <=y -> first )// a entirely left of b, advance a
524545{
525- a += MOC_INTERVAL_SIZE ;
546+ i += MOC_INTERVAL_SIZE ;
526547continue ;
527548}
528549if (y -> second <=x -> first )// b entirely left of a, advance b
529550{
530- b += MOC_INTERVAL_SIZE ;
551+ j += MOC_INTERVAL_SIZE ;
531552continue ;
532553}
533554
@@ -540,17 +561,17 @@ smoc_overlap_impl(Smoc* moc_a, Smoc* moc_b)
540561Datum
541562smoc_overlap (PG_FUNCTION_ARGS )
542563{
543- Smoc * moc_a = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (0 ) );
544- Smoc * moc_b = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (1 ) );
545- PG_RETURN_BOOL (smoc_overlap_impl (moc_a , moc_b ));
564+ Datum a = PG_GETARG_DATUM (0 );
565+ Datum b = PG_GETARG_DATUM (1 );
566+ PG_RETURN_BOOL (smoc_overlap_impl (a , b ));
546567}
547568
548569Datum
549570smoc_overlap_neg (PG_FUNCTION_ARGS )
550571{
551- Smoc * moc_a = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (0 ) );
552- Smoc * moc_b = ( Smoc * ) PG_DETOAST_DATUM ( PG_GETARG_DATUM (1 ) );
553- PG_RETURN_BOOL (!smoc_overlap_impl (moc_a , moc_b ));
572+ Datum a = PG_GETARG_DATUM (0 );
573+ Datum b = PG_GETARG_DATUM (1 );
574+ PG_RETURN_BOOL (!smoc_overlap_impl (a , b ));
554575}
555576
556577/* check if moc_a is a subset of moc_b */