Skip to content

Commit

Permalink
Add a newtype 'newtype'.
Browse files Browse the repository at this point in the history
I added a new type named newtype based on int8.
This type could be compared, sorted, and so on.
  • Loading branch information
shawn authored and shawn committed Apr 13, 2020
1 parent f1ac27b commit cb5ae3c
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/backend/bootstrap/bootstrap.c
Expand Up @@ -150,7 +150,9 @@ static const struct typinfo TypInfo[] = {
{"_char", 1002, CHAROID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
F_ARRAY_IN, F_ARRAY_OUT},
{"_aclitem", 1034, ACLITEMOID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
F_ARRAY_IN, F_ARRAY_OUT}
F_ARRAY_IN, F_ARRAY_OUT},
{"newtype", NEWTYPEOID, 0, 8, false, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
F_NEWTYPEIN, F_NEWTYPEOUT}
};

static const int n_types = sizeof(TypInfo) / sizeof(struct typinfo);
Expand Down
1 change: 1 addition & 0 deletions src/backend/utils/adt/Makefile
Expand Up @@ -63,6 +63,7 @@ OBJS = \
network_gist.o \
network_selfuncs.o \
network_spgist.o \
newtype.o \
numeric.o \
numutils.o \
oid.o \
Expand Down
180 changes: 180 additions & 0 deletions src/backend/utils/adt/newtype.c
@@ -0,0 +1,180 @@
/*-------------------------------------------------------------------------
*
* newtype.c
* Internal 64-bit integer operations
*
* Portions Copyright (c) 1996-2020, Shawn Wang
*
* IDENTIFICATION
* src/backend/utils/adt/newtype.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"

#include <ctype.h>
#include <limits.h>
#include <math.h>

#include "common/int.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "nodes/nodeFuncs.h"
#include "nodes/supportnodes.h"
#include "optimizer/optimizer.h"
#include "utils/builtins.h"
#include "utils/int8.h"


/***********************************************************************
**
** Routines for 64-bit integers.
**
***********************************************************************/

/* newtypein()
*/
Datum
newtypein(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
int64 result;

(void) scanint8(str, false, &result);
PG_RETURN_INT64(result);
}


/* newtypeout()
*/
Datum
newtypeout(PG_FUNCTION_ARGS)
{
int64 val = PG_GETARG_INT64(0);
char buf[MAXINT8LEN + 1];
char *result;

pg_lltoa(val, buf);
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
}

/*
* newtyperecv - converts external binary format to newtype
*/
Datum
newtyperecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);

PG_RETURN_INT64(pq_getmsgint64(buf));
}

/*
* int8send - converts newtype to binary format
*/
Datum
newtypesend(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
StringInfoData buf;

pq_begintypsend(&buf);
pq_sendint64(&buf, arg1);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

Datum
newtypeeq(PG_FUNCTION_ARGS)
{
int64 val1 = PG_GETARG_INT64(0);
int64 val2 = PG_GETARG_INT64(1);

PG_RETURN_BOOL(val1 == val2);
}

Datum
newtypene(PG_FUNCTION_ARGS)
{
int64 val1 = PG_GETARG_INT64(0);
int64 val2 = PG_GETARG_INT64(1);

PG_RETURN_BOOL(val1 != val2);
}

Datum
newtypelt(PG_FUNCTION_ARGS)
{
int64 val1 = PG_GETARG_INT64(0);
int64 val2 = PG_GETARG_INT64(1);

PG_RETURN_BOOL(val1 < val2);
}

Datum
newtypegt(PG_FUNCTION_ARGS)
{
int64 val1 = PG_GETARG_INT64(0);
int64 val2 = PG_GETARG_INT64(1);

PG_RETURN_BOOL(val1 > val2);
}

Datum
newtypele(PG_FUNCTION_ARGS)
{
int64 val1 = PG_GETARG_INT64(0);
int64 val2 = PG_GETARG_INT64(1);

PG_RETURN_BOOL(val1 <= val2);
}

Datum
newtypege(PG_FUNCTION_ARGS)
{
int64 val1 = PG_GETARG_INT64(0);
int64 val2 = PG_GETARG_INT64(1);

PG_RETURN_BOOL(val1 >= val2);
}

Datum
newtypelarger(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
int64 arg2 = PG_GETARG_INT64(1);
int64 result;

result = ((arg1 > arg2) ? arg1 : arg2);

PG_RETURN_INT64(result);
}

Datum
newtypesmaller(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
int64 arg2 = PG_GETARG_INT64(1);
int64 result;

result = ((arg1 < arg2) ? arg1 : arg2);

PG_RETURN_INT64(result);
}

Datum
btnewtypecmp(PG_FUNCTION_ARGS)
{
int64 b1 = PG_GETARG_INT64(0);
int64 b2 = PG_GETARG_INT64(1);
int32 result = 0;

if (b1 < b2)
result = -1;
else if (b1 > b2)
result = 1;
else
result = 0;

PG_RETURN_INT32(result);
}
13 changes: 13 additions & 0 deletions src/include/catalog/pg_amop.dat
Expand Up @@ -2437,4 +2437,17 @@
amoprighttype => 'point', amopstrategy => '7', amopopr => '@>(box,point)',
amopmethod => 'brin' },

# newtype

{ amopfamily => 'btree/newtype_ops', amoplefttype => 'newtype', amoprighttype => 'newtype',
amopstrategy => '1', amopopr => '<(newtype,newtype)', amopmethod => 'btree' },
{ amopfamily => 'btree/newtype_ops', amoplefttype => 'newtype', amoprighttype => 'newtype',
amopstrategy => '2', amopopr => '<=(newtype,newtype)', amopmethod => 'btree' },
{ amopfamily => 'btree/newtype_ops', amoplefttype => 'newtype', amoprighttype => 'newtype',
amopstrategy => '3', amopopr => '=(newtype,newtype)', amopmethod => 'btree' },
{ amopfamily => 'btree/newtype_ops', amoplefttype => 'newtype', amoprighttype => 'newtype',
amopstrategy => '4', amopopr => '>=(newtype,newtype)', amopmethod => 'btree' },
{ amopfamily => 'btree/newtype_ops', amoplefttype => 'newtype', amoprighttype => 'newtype',
amopstrategy => '5', amopopr => '>(newtype,newtype)', amopmethod => 'btree' },

]
3 changes: 3 additions & 0 deletions src/include/catalog/pg_amproc.dat
Expand Up @@ -1305,4 +1305,7 @@
{ amprocfamily => 'brin/box_inclusion_ops', amproclefttype => 'box',
amprocrighttype => 'box', amprocnum => '13', amproc => 'box_contain' },

{ amprocfamily => 'btree/newtype_ops', amproclefttype => 'newtype',
amprocrighttype => 'newtype', amprocnum => '1', amproc => 'btnewtypecmp' },

]
2 changes: 2 additions & 0 deletions src/include/catalog/pg_opclass.dat
Expand Up @@ -172,6 +172,8 @@
opcintype => 'cid' },
{ opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops',
opcintype => 'tid' },
{ opcmethod => 'btree', opcname => 'newtype_ops', opcfamily => 'btree/newtype_ops',
opcintype => 'newtype' },
{ opcmethod => 'hash', opcname => 'text_pattern_ops',
opcfamily => 'hash/text_pattern_ops', opcintype => 'text',
opcdefault => 'f' },
Expand Down
26 changes: 26 additions & 0 deletions src/include/catalog/pg_operator.dat
Expand Up @@ -3303,4 +3303,30 @@
oprresult => 'bool', oprcode => 'jsonb_path_match_opr(jsonb,jsonpath)',
oprrest => 'matchingsel', oprjoin => 'matchingjoinsel' },

{ oid => '568', oid_symbol => 'NEWTYPEEqualOperator', descr => 'equal',
oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'newtype',
oprright => 'newtype', oprresult => 'bool', oprcom => '=(newtype,newtype)',
oprnegate => '<>(newtype,newtype)', oprcode => 'newtypeeq', oprrest => 'eqsel',
oprjoin => 'eqjoinsel' },
{ oid => '569', descr => 'not equal',
oprname => '<>', oprleft => 'newtype', oprright => 'newtype', oprresult => 'bool',
oprcom => '<>(newtype,newtype)', oprnegate => '=(newtype,newtype)', oprcode => 'newtypene',
oprrest => 'neqsel', oprjoin => 'neqjoinsel' },
{ oid => '570', oid_symbol => 'NEWTYPELessOperator', descr => 'less than',
oprname => '<', oprleft => 'newtype', oprright => 'newtype', oprresult => 'bool',
oprcom => '>(newtype,newtype)', oprnegate => '>=(newtype,newtype)', oprcode => 'newtypelt',
oprrest => 'scalarltsel', oprjoin => 'scalarltjoinsel' },
{ oid => '571', descr => 'greater than',
oprname => '>', oprleft => 'newtype', oprright => 'newtype', oprresult => 'bool',
oprcom => '<(newtype,newtype)', oprnegate => '<=(newtype,newtype)', oprcode => 'newtypegt',
oprrest => 'scalargtsel', oprjoin => 'scalargtjoinsel' },
{ oid => '572', descr => 'less than or equal',
oprname => '<=', oprleft => 'newtype', oprright => 'newtype', oprresult => 'bool',
oprcom => '>=(newtype,newtype)', oprnegate => '>(newtype,newtype)', oprcode => 'newtypele',
oprrest => 'scalarlesel', oprjoin => 'scalarlejoinsel' },
{ oid => '573', descr => 'greater than or equal',
oprname => '>=', oprleft => 'newtype', oprright => 'newtype', oprresult => 'bool',
oprcom => '<=(newtype,newtype)', oprnegate => '<(newtype,newtype)', oprcode => 'newtypege',
oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' },

]
2 changes: 2 additions & 0 deletions src/include/catalog/pg_opfamily.dat
Expand Up @@ -226,5 +226,7 @@
opfmethod => 'spgist', opfname => 'box_ops' },
{ oid => '5008',
opfmethod => 'spgist', opfname => 'poly_ops' },
{ oid => '567',
opfmethod => 'btree', opfname => 'newtype_ops' },

]
43 changes: 43 additions & 0 deletions src/include/catalog/pg_proc.dat
Expand Up @@ -10859,4 +10859,47 @@
proname => 'is_normalized', prorettype => 'bool',
proargtypes => 'text text', prosrc => 'unicode_is_normalized' },

/*
* newtype
*/
{ oid => '560', descr => 'I/O',
proname => 'newtypein', prorettype => 'newtype', proargtypes => 'cstring',
prosrc => 'newtypein' },
{ oid => '561', descr => 'I/O',
proname => 'newtypeout', prorettype => 'cstring', proargtypes => 'newtype',
prosrc => 'newtypeout' },
{ oid => '562', descr => 'I/O',
proname => 'newtyperecv', prorettype => 'newtype', proargtypes => 'internal',
prosrc => 'newtyperecv' },
{ oid => '563', descr => 'I/O',
proname => 'newtypesend', prorettype => 'bytea', proargtypes => 'newtype',
prosrc => 'newtypesend' },
{ oid => '566', descr => 'less-equal-greater',
proname => 'btnewtypecmp', proleakproof => 't', prorettype => 'int4',
proargtypes => 'newtype newtype', prosrc => 'btnewtypecmp' },
{ oid => '574',
proname => 'newtypeeq', proleakproof => 't', prorettype => 'bool',
proargtypes => 'newtype newtype', prosrc => 'newtypeeq' },
{ oid => '575',
proname => 'newtypene', proleakproof => 't', prorettype => 'bool',
proargtypes => 'newtype newtype', prosrc => 'newtypene' },
{ oid => '576',
proname => 'newtypegt', proleakproof => 't', prorettype => 'bool',
proargtypes => 'newtype newtype', prosrc => 'newtypegt' },
{ oid => '577',
proname => 'newtypelt', proleakproof => 't', prorettype => 'bool',
proargtypes => 'newtype newtype', prosrc => 'newtypelt' },
{ oid => '578',
proname => 'newtypege', proleakproof => 't', prorettype => 'bool',
proargtypes => 'newtype newtype', prosrc => 'newtypege' },
{ oid => '579',
proname => 'newtypele', proleakproof => 't', prorettype => 'bool',
proargtypes => 'newtype newtype', prosrc => 'newtypele' },
{ oid => '582', descr => 'larger of two',
proname => 'newtypelarger', prorettype => 'newtype', proargtypes => 'newtype newtype',
prosrc => 'newtypelarger' },
{ oid => '583', descr => 'smaller of two',
proname => 'newtypesmaller', prorettype => 'newtype', proargtypes => 'newtype newtype',
prosrc => 'newtypesmaller' },

]
6 changes: 6 additions & 0 deletions src/include/catalog/pg_type.dat
Expand Up @@ -621,4 +621,10 @@
typoutput => 'anycompatiblerange_out', typreceive => '-', typsend => '-',
typalign => 'd', typstorage => 'x' },

{ oid => '564', array_type_oid => '565',
descr => '~18 digit integer, 8-byte storage',
typname => 'newtype', typlen => '8', typbyval => 't',
typcategory => 'N', typinput => 'newtypein', typoutput => 'newtypeout',
typreceive => 'newtyperecv', typsend => 'newtypesend', typalign => 'd' },

]

0 comments on commit cb5ae3c

Please sign in to comment.