Idea and realization by Sergey Koposov, Sternberg Astronomical Institute, Moscow University. General formulation and testing by Oleg Bartunov, Sternberg Astronomical Institute, Moscow University.


The paper about concept and idea behind Q3C scheme is available from ADASS proceedings, 2005. Users of Q3C are kindly asked to cite it in publications (or other types of presentation).

The URL of the paper:


PostgreSQL version 8.1 and later, and ability to install contribution module.


Compilation should be simple, just



  • q3c_ang2ipix – converts spatial coordinates (ra,dec) to the ipix value
  • q3c_join – spatial cross-match on the sphere
  • q3c_ellipse_join – spatial cross-match with ellipse error area
  • q3c_radial_query – radial query
  • q3c_poly_query – queries in polygonal regions


Suppose, you have table with spatial coordinates - ra and dec columns. Important notice - q3c uses ra in degrees, so it might be need to use ra*15 everywhere !

  • You need to load q3c functions into your database:
psql your_db < q3c.sql
  • Create the spatial index:
# CREATE INDEX q3c_mytable_idx ON mytable (q3c_ang2ipix(ra,dec)); 
  • For better performance you may want cluster the table on that index, i.e. physically order the data on the disk according to the index, which greatly improves sequential access If the data already ordered by some spherical zones or something similar, the clustering step could be ommited.
# CLUSTER q3c_mytable_idx ON my_table;
  • Analyze your table:
# ANALYZE my_table;
Radial query (cone search)
To perform the query around ra0=2 and dec0=3 with radius0=1 from the table mytable you can do:
# select * from mytable where q3c_radial_query(ra, dec, 2, 3, 1);
The polygonal query
The query of the objects which lie inside the region bounded by the polygon on the sphere. To query the objects in the polygon ((0,0),(2,0),(2,1),(0,1)) ) (this is the spherical polygon with following vertices: (ra=0, dec=0) ; (ra=2, dec=0); (ra=2, dec=1); (ra=0, dec=1)):
# SELECT * FROM mytable WHERE q3c_poly_query(ra, dec, '{0, 0, 2, 0, 2, 1, 0, 1}');
The join example
Assuming that we have a huge table "table2" with created ipix index and with ra and dec columns and the smaller one "table1" with ra and dec columns. If we want now to join "table1" with "table2" with error circle with the size 0.001 degrees, we do:
# SELECT * from table1 as a , table2 as b where q3c_join(a.ra, a.dec, b.ra, b.dec, 0.001);

If every object in the table1 have his own error circle (like with X-ray data for example) (suppose that the radius of that circle is the column "err"), then you can run the query:

# SELECT * from table1 as a , table2 as b where q3c_join(a.ra, a.dec, b.ra, b.dec, a.err);
The positional cross-match of the tables with the ellipse error-area
(for example if you want to find all the objects from one catalogue which lies inside the bodies of the galaxies from the second catalogue) The example: It is possible to do the join when the error area of each record of the catalogue is an ellipse. Then you can do the query like this
# SELECT * FROM table1 AS a, table2 AS b WHERE q3c_ellipse_join(a.ra, a.dec, b.ra, b.dec, a.maj_ax, a.axis_ratio, a.PA);

where axis_ratio is the column with axis ratio of the ellipses and PA is the column with the positional angles of them, and maj_ax is the column with major axises of those ellipses.

This work is partially supported by Russian Foundation for Basic Research.