All Projects → begriffs → Pg_rational

begriffs / Pg_rational

Licence: mit
Precise fractional arithmetic for PostgreSQL

Labels

Projects that are alternatives of or similar to Pg rational

Pg2go
PostgreSQL script that generates Go struct definitions for all tables in a database
Stars: ✭ 116 (-30.95%)
Mutual labels:  plpgsql
Subzero Starter Kit
Starter Kit and tooling for authoring GraphQL/REST API backends with subZero
Stars: ✭ 136 (-19.05%)
Mutual labels:  plpgsql
Cisl
Columnstore Indexes Scripts Library
Stars: ✭ 155 (-7.74%)
Mutual labels:  plpgsql
Sqlite Parser
An ANTLR4 grammar for SQLite statements.
Stars: ✭ 119 (-29.17%)
Mutual labels:  plpgsql
Ccap
open source and transparent cryptocurrency analysis platform
Stars: ✭ 128 (-23.81%)
Mutual labels:  plpgsql
Postgresql Event Sourcing
postgresql event sourcing
Stars: ✭ 146 (-13.1%)
Mutual labels:  plpgsql
Vocabulary V5.0
PALLAS: Build process for OMOP Standardized Vocabularies. Currently not available as independent release. Therefore, do not clone or try to replicate. It is work in progress and not ready for replication.
Stars: ✭ 114 (-32.14%)
Mutual labels:  plpgsql
Postgresdbsamples
Sample databases for postgres
Stars: ✭ 161 (-4.17%)
Mutual labels:  plpgsql
Pg jobmon
PostgreSQL extension which provides persistent logging within transactions and functions.
Stars: ✭ 128 (-23.81%)
Mutual labels:  plpgsql
Chicago Atlas
View citywide information about health trends and take action near you to improve your own health.
Stars: ✭ 152 (-9.52%)
Mutual labels:  plpgsql
Mytap
MySQL Unit Testing Suite
Stars: ✭ 118 (-29.76%)
Mutual labels:  plpgsql
Temporal tables
Stars: ✭ 126 (-25%)
Mutual labels:  plpgsql
Opm Core
Central module of the OPM suite
Stars: ✭ 148 (-11.9%)
Mutual labels:  plpgsql
Pg Auth
A complete authentication system built in Postgres using schemas and functions
Stars: ✭ 117 (-30.36%)
Mutual labels:  plpgsql
Pghero.sql
Postgres insights made easy
Stars: ✭ 155 (-7.74%)
Mutual labels:  plpgsql
Scaledger
A double-entry accounting database with a typed GraphQL API
Stars: ✭ 115 (-31.55%)
Mutual labels:  plpgsql
Hierarchy Data Closure Table
This is a mysql and postgresql store procedure and trigger implementation of closure table in RDBMS about hierarchy data model.
Stars: ✭ 135 (-19.64%)
Mutual labels:  plpgsql
Docker Compose
一些基础服务的docker-compose配置文件,方便在一台新电脑上快速开始工作
Stars: ✭ 163 (-2.98%)
Mutual labels:  plpgsql
Wikipedia Mirror
🌐 Guide and tools to run a full offline mirror of Wikipedia.org with three different approaches: Nginx caching proxy, Kimix + ZIM dump, and MediaWiki/XOWA + XML dump
Stars: ✭ 160 (-4.76%)
Mutual labels:  plpgsql
Adventureworks For Postgres
Set up the AdventureWorks sample database for use with Postgres
Stars: ✭ 148 (-11.9%)
Mutual labels:  plpgsql

Precise fractions for PostgreSQL

build:

An efficient custom type. Perfect for exact arithmetic or user-specified table row ordering. Holds values as big as an integer, with matching precision in the denominator.

Features

  • Stores fractions in exactly 64 bits (same size as float)
  • Written in C for high performance
  • Detects and halts arithmetic overflow for correctness
  • Uses native CPU instructions for fast overflow detection
  • Defers GCD calculation until requested or absolutely required
  • Supports btree and hash indices
  • Implements Stern-Brocot trees for finding intermediate points
  • Coercion from integer/bigint/tuple
  • Custom aggregate

Motivation

See my blog post about User-Defined Order in SQL.

Usage

Basics

-- fractions are precise
-- this would not work with a float type
select 1::rational / 3 * 3 = 1;
-- => t

-- provides the usual operations, e.g.
select '1/3'::rational + '2/7';
-- => 13/21

-- helper "ratt' type to coerce from tuples
select 1 + (i,i+1)::ratt from generate_series(1,5) as i;
-- => 3/2, 5/3, 7/4, 9/5, 11/6

-- simplify if desired
select rational_simplify('36/12');
-- => 3/1

-- convert float to rational
select 0.263157894737::float::rational;
-- => 5/19

-- convert rational to float
select '-1/2'::rational::float;
-- => -0.5

Reorder items without renumbering surrounding items.

create sequence todos_seq;

create table todos (
  prio rational unique
    default nextval('todos_seq'),
  what text not null
);

insert into todos (what) values
  ('install extension'),
  ('read about it'),
  ('try it'),
  ('profit?');

select * from todos order by prio asc;
/*
┌──────┬───────────────────┐
│ prio │       what        │
├──────┼───────────────────┤
│ 1/1  │ install extension │
│ 2/1  │ read about it     │
│ 3/1  │ try it            │
│ 4/1  │ profit?           │
└──────┴───────────────────┘
*/

-- put "try" between "install" and "read"
update todos
set prio = rational_intermediate(1,2)
where prio = 3;

select * from todos order by prio asc;
/*
┌──────┬───────────────────┐
│ prio │       what        │
├──────┼───────────────────┤
│ 1/1  │ install extension │
│ 3/2  │ try it            │
│ 2/1  │ read about it     │
│ 4/1  │ profit?           │
└──────┴───────────────────┘
*/

-- put "read" back between "install" and "try"
update todos
set prio = rational_intermediate(1,'3/2')
where prio = 2;

select * from todos order by prio asc;
/*
┌──────┬───────────────────┐
│ prio │       what        │
├──────┼───────────────────┤
│ 1/1  │ install extension │
│ 4/3  │ read about it     │
│ 3/2  │ try it            │
│ 4/1  │ profit?           │
└──────┴───────────────────┘
*/

This extension uses Stern-Brocot trees to find efficient intermediate points as fractions in lowest terms. It can continue to split deeper between fractions as much as any practical application requires.

Using floats, on the other hand, and picking the midpoints between adjacent values runs out of space rapidly (you only need 50-odd inserts at the wrong spot to start hitting problems).

Installation

Clone this repo, go inside and simply run:

make
sudo make install

Then, in your database:

create extension pg_rational;

Caveats

The rational_intermediate function is super fast on typical intervals, but the narrower the range between arguments the longer it takes. We may want to add a max search depth parameter to prevent malicious values from hogging the server.

Thanks

This is my first PostgreSQL extension, and these resources were helpful in learning to write it.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].