Skip to content

Commit

Permalink
Merge branch 'selectivity'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Koposov committed May 30, 2019
2 parents dd5eaf1 + 38c82cc commit 14fd0ec
Show file tree
Hide file tree
Showing 5 changed files with 1,031 additions and 2 deletions.
102 changes: 102 additions & 0 deletions q3c.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#if PG_VERSION_NUM >= 90300
#include "access/tupmacs.h"
#endif
#include "nodes/relation.h"
#include "utils/selfuncs.h"



/* For PostgreSQL versions >= 8.2 */
Expand All @@ -46,6 +49,8 @@ PG_MODULE_MAGIC;

#include "common.h"

extern Node *estimate_expression_value(PlannerInfo *root, Node *node);

/* Postgres functions */
Datum pgq3c_ang2ipix(PG_FUNCTION_ARGS);
Datum pgq3c_ang2ipix_real(PG_FUNCTION_ARGS);
Expand All @@ -66,6 +71,103 @@ Datum pgq3c_poly_query_it(PG_FUNCTION_ARGS);
Datum pgq3c_in_ellipse(PG_FUNCTION_ARGS);
Datum pgq3c_in_poly(PG_FUNCTION_ARGS);
Datum pgq3c_get_version(PG_FUNCTION_ARGS);
Datum pgq3c_sel(PG_FUNCTION_ARGS);
Datum pgq3c_seljoin(PG_FUNCTION_ARGS);
Datum pgq3c_seloper(PG_FUNCTION_ARGS);


/* Dummy function that implements the selectivity operator */
PG_FUNCTION_INFO_V1(pgq3c_seloper);
Datum pgq3c_seloper(PG_FUNCTION_ARGS)
{
PG_RETURN_BOOL(true);
}

/* The actual selectivity function, it returns the ratio of the
* search circle to the whole sky area
*/
PG_FUNCTION_INFO_V1(pgq3c_sel);
Datum pgq3c_sel(PG_FUNCTION_ARGS)
{
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
List *args = (List *) PG_GETARG_POINTER(2);
int varRelid = PG_GETARG_INT32(3);
Node *left;
Node *other;
VariableStatData vardata;
Datum radDatum;
bool isnull;
double rad;
double ratio;

/* this needs more protections against crazy inputs */
if (list_length(args) != 2) { elog(ERROR, "Wrong inputs to selectivity function");}
left = (Node *) linitial(args);

examine_variable(root, left, varRelid, &vardata);
other = estimate_expression_value(root, vardata.var);
radDatum = ((Const *) other)->constvalue;
isnull = ((Const *) other)->constisnull;
/* We shouldn't be really getting null inputs here */
if (!isnull)
{
rad = DatumGetFloat8(radDatum);
}
else
{
rad = 0;
}
ratio = 3.14 * rad * rad/41252. ; /* pi*r^2/whole_sky_area */

/* clamp at 0, 1*/
CLAMP_PROBABILITY(ratio);

//elog(WARNING, "HERE0.... %e", ratio);

PG_RETURN_FLOAT8(ratio);
}


PG_FUNCTION_INFO_V1(pgq3c_seljoin);
Datum pgq3c_seljoin(PG_FUNCTION_ARGS)
{
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
List *args = (List *) PG_GETARG_POINTER(2);
int varRelid = 0;
/* Because there is no varrelid in the join selectivity call
* I just set it to zero */
Node *left;
Node *other;
VariableStatData vardata;
Datum radDatum;
bool isnull;
double rad;
double ratio;

/* this needs more protections against crazy inputs */
if (list_length(args) != 2) { elog(ERROR, "Wrong inputs to selectivity function");}
left = (Node *) linitial(args);

examine_variable(root, left, varRelid, &vardata);
other = estimate_expression_value(root, vardata.var);
radDatum = ((Const *) other)->constvalue;
isnull = ((Const *) other)->constisnull;
/* We shouldn't be really getting null inputs here */
if (!isnull)
{
rad = DatumGetFloat8(radDatum);
}
else
{
rad = 0;
}
ratio = 3.14 * rad * rad/41252. ; /* pi*r^2/whole_sky_area */

/* clamp at 0, 1*/
CLAMP_PROBABILITY(ratio);

PG_RETURN_FLOAT8(ratio);
}


PG_FUNCTION_INFO_V1(pgq3c_get_version);
Expand Down
2 changes: 1 addition & 1 deletion q3c.control
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
comment = 'q3c sky indexing plugin'
default_version = '1.6.0'
default_version = '1.7.0'
module_pathname = '$libdir/q3c'
121 changes: 121 additions & 0 deletions scripts/q3c--1.6.0--1.7.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
\echo Use "CREATE EXTENSION q3c" to load this file. \quit

-- A dummy type used in the selectivity operator
create type q3c_type as (ra double precision, dec double precision,
ra1 double precision, dec1 double precision);


-- A dummy operator function (always returns true)
CREATE OR REPLACE FUNCTION q3c_seloper(double precision, q3c_type)
RETURNS bool
AS 'MODULE_PATHNAME', 'pgq3c_seloper'
LANGUAGE C STRICT IMMUTABLE COST 1000;

-- A selectivity function for the q3c operator
CREATE OR REPLACE FUNCTION q3c_sel(internal, oid, internal, int4)
RETURNS float8
AS 'MODULE_PATHNAME', 'pgq3c_sel'
LANGUAGE C IMMUTABLE STRICT ;

-- A selectivity function for the q3c operator
CREATE OR REPLACE FUNCTION q3c_seljoin(internal, oid, internal, int2, internal)
RETURNS float8
AS 'MODULE_PATHNAME', 'pgq3c_seljoin'
LANGUAGE C IMMUTABLE STRICT ;


-- distance operator with correct selectivity
CREATE OPERATOR ==<<>>== (
LEFTARG = double precision,
RIGHTARG = q3c_type,
PROCEDURE = q3c_seloper,
RESTRICT = q3c_sel,
JOIN = q3c_seljoin
);

DROP FUNCTION q3c_radial_query(bigint,
double precision, double precision,
double precision, double precision, double precision);

DROP FUNCTION q3c_join(double precision, double precision,
double precision, double precision,
bigint, double precision);


CREATE OR REPLACE FUNCTION q3c_join(leftra double precision, leftdec double precision,
rightra double precision, rightdec double precision,
radius double precision)
RETURNS boolean AS
'
SELECT (((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,0))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,1))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,2))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,3))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,4))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,5))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,6))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,7)))))
AND q3c_sindist($1,$2,$3,$4)<POW(SIN(RADIANS($5)/2),2)
AND ($5::double precision ==<<>>== ($1,$2,$3,$4)::q3c_type)
' LANGUAGE SQL IMMUTABLE;


CREATE OR REPLACE FUNCTION q3c_join(leftra double precision, leftdec double precision,
rightra real, rightdec real,
radius double precision)
RETURNS boolean AS
'
SELECT (((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,0))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,1))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,2))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,3))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,4))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,5))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_nearby_it($1,$2,$5,6))) AND (q3c_ang2ipix($3,$4)<=(q3c_nearby_it($1,$2,$5,7)))))
AND q3c_sindist($1,$2,$3,$4)<POW(SIN(RADIANS($5)/2),2)
AND ($5::double precision ==<<>>== ($1,$2,$3,$4)::q3c_type)
' LANGUAGE SQL IMMUTABLE;



CREATE OR REPLACE FUNCTION q3c_join_pm(
left_ra double precision, -- 1
left_dec double precision, -- 2
left_pmra double precision, -- 3
left_pmdec double precision, -- 4
left_epoch double precision, -- 5
right_ra double precision, -- 6
right_dec double precision, -- 7
right_epoch double precision, -- 8
max_epoch_delta double precision, --9
radius double precision -- 10
)

RETURNS boolean AS
'
SELECT (
((q3c_ang2ipix($6,$7) >= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,0)) AND
(q3c_ang2ipix($6,$7) <= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,1)))
OR
((q3c_ang2ipix($6,$7) >= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,2)) AND
(q3c_ang2ipix($6,$7) <= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,3)))
OR
((q3c_ang2ipix($6,$7) >= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,4)) AND
(q3c_ang2ipix($6,$7) <= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,5)))
OR
((q3c_ang2ipix($6,$7) >= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,6)) AND
(q3c_ang2ipix($6,$7) <= q3c_nearby_pm_it($1,$2,$3,$4,$9,$10,7))))
AND q3c_sindist_pm($1,$2,$3,$4,$5,$6,$7,$8)<POW(SIN(RADIANS($10)/2),2)
AND ($10::double precision ==<<>>== ($1,$2,$6,$7)::q3c_type)
' LANGUAGE SQL IMMUTABLE;
-- not strict


CREATE OR REPLACE FUNCTION q3c_ellipse_join(leftra double precision, leftdec double precision,
rightra double precision, rightdec double precision,
majoraxis double precision, axisratio double precision,
pa double precision)
RETURNS boolean AS
'
SELECT (((q3c_ang2ipix($3,$4)>=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,0))) AND (q3c_ang2ipix($3,$4)<=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,1))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,2))) AND (q3c_ang2ipix($3,$4)<=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,3))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,4))) AND (q3c_ang2ipix($3,$4)<=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,5))))
OR ((q3c_ang2ipix($3,$4)>=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,6))) AND (q3c_ang2ipix($3,$4)<=(q3c_ellipse_nearby_it($1,$2,$5,$6,$7,7)))))
AND q3c_in_ellipse($3,$4,$1,$2,$5,$6,$7)
AND ($5::double precision ==<<>>== ($1,$2,$3,$4)::q3c_type)
' LANGUAGE SQL IMMUTABLE;

2 changes: 1 addition & 1 deletion scripts/q3c--1.6.0.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
\echo Use "CREATE EXTENSION pair" to load this file. \quit
\echo Use "CREATE EXTENSION q3c" to load this file. \quit


CREATE OR REPLACE FUNCTION q3c_version()
Expand Down
Loading

0 comments on commit 14fd0ec

Please sign in to comment.