Skip to content

Commit 5e7f90b

Browse files
df7cbmsdemlei
authored andcommitted
Implement = and <> on smoc
1 parent 62e9cb8 commit 5e7f90b

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

expected/moc.out

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,30 @@ SELECT '(0.78, 0.81)'::spoint <@ '7/123-456,1000-2000'::smoc;
4242
f
4343
(1 row)
4444

45+
SELECT '0/'::smoc = '1/'::smoc AS eq;
46+
eq
47+
----
48+
t
49+
(1 row)
50+
51+
SELECT '0/1,3,7'::smoc = '0/1,3,7' AS eq;
52+
eq
53+
----
54+
t
55+
(1 row)
56+
57+
SELECT '0/1,4,7'::smoc = '0/1,3,7' AS eq;
58+
eq
59+
----
60+
f
61+
(1 row)
62+
63+
SELECT '0/1,2,3'::smoc <> '0/1-3'::smoc AS neq;
64+
neq
65+
-----
66+
f
67+
(1 row)
68+
4569
SELECT 1 <@ (smoc('29/2-5,20-29,123,444,17-21,33-39,332-339,0-1'));
4670
?column?
4771
----------

moc.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PG_FUNCTION_INFO_V1(smoc_out);
99
PG_FUNCTION_INFO_V1(moc_debug);
1010
PG_FUNCTION_INFO_V1(set_smoc_output_type);
1111
PG_FUNCTION_INFO_V1(smoc_order);
12+
PG_FUNCTION_INFO_V1(smoc_eq);
13+
PG_FUNCTION_INFO_V1(smoc_neq);
1214

1315
PG_FUNCTION_INFO_V1(healpix_subset_smoc);
1416
PG_FUNCTION_INFO_V1(healpix_not_subset_smoc);
@@ -413,6 +415,55 @@ moc_debug(PG_FUNCTION_ARGS)
413415
PG_RETURN_TEXT_P(cstring_to_text(x));
414416
}
415417

418+
static bool
419+
smoc_eq_impl(Smoc* moc_a, Smoc* moc_b)
420+
{
421+
int32 a = moc_a->data_begin;
422+
int32 b = moc_b->data_begin;
423+
int32 entry_size = MOC_INTERVAL_SIZE;
424+
int32 moc_a_end = VARSIZE(moc_a) - VARHDRSZ;
425+
int32 moc_b_end = VARSIZE(moc_b) - VARHDRSZ;
426+
char* moc_a_base = MOC_BASE(moc_a);
427+
char* moc_b_base = MOC_BASE(moc_b);
428+
429+
if (moc_a->data_begin != moc_b->data_begin || moc_a_end != moc_b_end) /* this needs to be reconsidered if the MOC version is updated */
430+
return false;
431+
432+
if (moc_a->order != moc_b->order || moc_a->first != moc_b->first || moc_a->last != moc_b->last || moc_a->area != moc_b->area)
433+
return false;
434+
435+
for (int j = moc_a->data_begin; j < moc_a_end; j += entry_size) // iterate over both in parallel
436+
{
437+
// page bumps
438+
int32 mod = (j + entry_size) % PG_TOAST_PAGE_FRAGMENT;
439+
if (mod > 0 && mod < entry_size)
440+
j += entry_size - mod;
441+
moc_interval *x = MOC_INTERVAL(moc_a_base, j);
442+
moc_interval *y = MOC_INTERVAL(moc_b_base, j);
443+
444+
if (x->first != y->first || x->second != y->second)
445+
return false;
446+
}
447+
448+
return true;
449+
}
450+
451+
Datum
452+
smoc_eq(PG_FUNCTION_ARGS)
453+
{
454+
Smoc* moc_a = (Smoc *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
455+
Smoc* moc_b = (Smoc *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
456+
PG_RETURN_BOOL(smoc_eq_impl(moc_a, moc_b));
457+
}
458+
459+
Datum
460+
smoc_neq(PG_FUNCTION_ARGS)
461+
{
462+
Smoc* moc_a = (Smoc *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
463+
Smoc* moc_b = (Smoc *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
464+
PG_RETURN_BOOL(! smoc_eq_impl(moc_a, moc_b));
465+
}
466+
416467
static bool
417468
entry_equal(moc_tree_entry *a, hpint64 y)
418469
{

pgs_moc_ops.sql.in

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
CREATE FUNCTION smoc_eq (smoc, smoc)
2+
RETURNS boolean
3+
AS 'MODULE_PATHNAME'
4+
LANGUAGE C
5+
STRICT;
6+
7+
CREATE OPERATOR = (
8+
LEFTARG = smoc,
9+
RIGHTARG = smoc,
10+
PROCEDURE = smoc_eq,
11+
COMMUTATOR = '=',
12+
NEGATOR = '<>',
13+
RESTRICT = eqsel,
14+
JOIN = eqjoinsel
15+
);
16+
17+
CREATE FUNCTION smoc_neq (smoc, smoc)
18+
RETURNS boolean
19+
AS 'MODULE_PATHNAME'
20+
LANGUAGE C
21+
STRICT;
22+
23+
CREATE OPERATOR <> (
24+
LEFTARG = smoc,
25+
RIGHTARG = smoc,
26+
PROCEDURE = smoc_neq,
27+
COMMUTATOR = '<>',
28+
NEGATOR = '=',
29+
RESTRICT = neqsel,
30+
JOIN = neqjoinsel
31+
);
32+
133
CREATE FUNCTION smoc_union (smoc, smoc)
234
RETURNS smoc
335
AS 'MODULE_PATHNAME'

sql/moc.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ SELECT '0/0,1,2,3,7'::smoc; -- expected: '0/0-3,7'
99
SELECT '(0.78, 0.81)'::spoint <@ '7/123-456,10000-20000'::smoc;
1010
SELECT '(0.78, 0.81)'::spoint <@ '7/123-456,1000-2000'::smoc;
1111

12+
SELECT '0/'::smoc = '1/'::smoc AS eq;
13+
SELECT '0/1,3,7'::smoc = '0/1,3,7' AS eq;
14+
SELECT '0/1,4,7'::smoc = '0/1,3,7' AS eq;
15+
SELECT '0/1,2,3'::smoc <> '0/1-3'::smoc AS neq;
16+
1217
SELECT 1 <@ (smoc('29/2-5,20-29,123,444,17-21,33-39,332-339,0-1'));
1318
SELECT 1 <@ (smoc('29/2-5,20-29,123,444,17-21,33-39,332-339'));
1419
SELECT 2 <@ (smoc('29/2-5,20-29,123,444,17-21,33-39,332-339'));

0 commit comments

Comments
 (0)