Started adding comparison functions
This commit is contained in:
parent
339fac17d2
commit
25d23b90d3
|
@ -76,12 +76,11 @@ extern "C" {
|
|||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_in);
|
||||
|
||||
PGDLLEXPORT
|
||||
Datum
|
||||
phone_number_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_in(PG_FUNCTION_ARGS) {
|
||||
const char *number_str = PG_GETARG_CSTRING(0);
|
||||
|
||||
//TODO: use international format instead.
|
||||
ShortPhoneNumber* number = parsePhoneNumber(number_str, "US");
|
||||
if(number) {
|
||||
PG_RETURN_POINTER(number);
|
||||
|
@ -92,10 +91,8 @@ extern "C" {
|
|||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(parse_phone_number);
|
||||
|
||||
PGDLLEXPORT
|
||||
Datum
|
||||
parse_phone_number(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PGDLLEXPORT Datum
|
||||
parse_phone_number(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const text* number_text = PG_GETARG_TEXT_P(0);
|
||||
const text* country_text = PG_GETARG_TEXT_P(1);
|
||||
|
@ -112,7 +109,7 @@ extern "C" {
|
|||
} else {
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
} catch(std::bad_alloc e) {
|
||||
} catch(std::bad_alloc& e) {
|
||||
reportOutOfMemory();
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
|
@ -121,10 +118,8 @@ extern "C" {
|
|||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_out);
|
||||
|
||||
PGDLLEXPORT
|
||||
Datum
|
||||
phone_number_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_out(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* short_number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
PhoneNumber number = *short_number;
|
||||
|
@ -154,8 +149,7 @@ extern "C" {
|
|||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_recv);
|
||||
|
||||
PGDLLEXPORT
|
||||
Datum
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_recv(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
|
||||
|
@ -176,8 +170,7 @@ extern "C" {
|
|||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_send);
|
||||
|
||||
PGDLLEXPORT
|
||||
Datum
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_send(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber *number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
|
@ -194,4 +187,101 @@ extern "C" {
|
|||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_equal);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(*number1 == *number2);
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_not_equal);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_not_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(*number1 != *number2);
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_less(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) < 0);
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less_or_equal);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_less_or_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) <= 0);
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_greater(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) > 0);
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater_or_equal);
|
||||
|
||||
PGDLLEXPORT Datum
|
||||
phone_number_greater_or_equal(PG_FUNCTION_ARGS) {
|
||||
try {
|
||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(number1->compare_fast(*number2) >= 0);
|
||||
} catch(std::exception& e) {
|
||||
reportGenericError(e);
|
||||
}
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
CREATE TYPE phone_number;
|
||||
|
||||
--Basic function definitions
|
||||
|
||||
CREATE FUNCTION phone_number_in(cstring) RETURNS phone_number
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_in';
|
||||
|
@ -29,9 +31,111 @@ CREATE TYPE phone_number (
|
|||
STORAGE = plain
|
||||
);
|
||||
|
||||
--Cast definitions
|
||||
|
||||
CREATE CAST (phone_number AS text)
|
||||
WITH INOUT;
|
||||
|
||||
--Operator definitions
|
||||
|
||||
CREATE FUNCTION phone_number_equal(phone_number, phone_number) RETURNS bool
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_equal';
|
||||
|
||||
CREATE OPERATOR = (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_equal,
|
||||
commutator = =,
|
||||
negator = <>,
|
||||
restrict = eqsel,
|
||||
join = eqjoinsel,
|
||||
hashes = true,
|
||||
merges = true
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_not_equal(phone_number, phone_number) RETURNS bool
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_not_equal';
|
||||
|
||||
CREATE OPERATOR <> (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_not_equal,
|
||||
commutator = <>,
|
||||
negator = =,
|
||||
restrict = neqsel,
|
||||
join = neqjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_less(phone_number, phone_number) RETURNS bool
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_less';
|
||||
|
||||
CREATE OPERATOR < (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_less,
|
||||
commutator = >,
|
||||
negator = >=,
|
||||
restrict = scalarltsel,
|
||||
join = scalarltjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_less_or_equal(phone_number, phone_number) RETURNS bool
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_less_or_equal';
|
||||
|
||||
CREATE OPERATOR <= (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_less_or_equal,
|
||||
commutator = >=,
|
||||
negator = >,
|
||||
restrict = scalarltsel,
|
||||
join = scalarltjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_greater(phone_number, phone_number) RETURNS bool
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_greater';
|
||||
|
||||
CREATE OPERATOR > (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_greater,
|
||||
commutator = >,
|
||||
negator = <=,
|
||||
restrict = scalargtsel,
|
||||
join = scalargtjoinsel
|
||||
);
|
||||
|
||||
CREATE FUNCTION phone_number_greater_or_equal(phone_number, phone_number) RETURNS bool
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'phone_number_greater_or_equal';
|
||||
|
||||
CREATE OPERATOR >= (
|
||||
leftarg = phone_number,
|
||||
rightarg = phone_number,
|
||||
procedure = phone_number_greater_or_equal,
|
||||
commutator = >=,
|
||||
negator = <,
|
||||
restrict = scalargtsel,
|
||||
join = scalargtjoinsel
|
||||
);
|
||||
|
||||
|
||||
CREATE OPERATOR CLASS phone_number_ops
|
||||
DEFAULT FOR TYPE phone_number USING btree AS
|
||||
OPERATOR 1 <,
|
||||
OPERATOR 2 <=,
|
||||
OPERATOR 3 =,
|
||||
OPERATOR 4 >=,
|
||||
OPERATOR 5 >,
|
||||
FUNCTION 1 phone_number_cmp(phone_number, phone_number);
|
||||
|
||||
--General functions
|
||||
|
||||
CREATE FUNCTION parse_phone_number(text, text) RETURNS phone_number
|
||||
LANGUAGE c IMMUTABLE STRICT
|
||||
AS 'pg_libphonenumber', 'parse_phone_number';
|
||||
|
|
|
@ -41,3 +41,4 @@ ShortPhoneNumber::operator PhoneNumber() const {
|
|||
number.set_number_of_leading_zeros(leading_zeros);
|
||||
return number;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,27 +18,50 @@ class ShortPhoneNumber {
|
|||
public:
|
||||
enum : size_t {
|
||||
MAX_COUNTRY_CODE = 999,
|
||||
MAX_LEADING_ZEROS = 15,
|
||||
//15 digits
|
||||
MAX_NATIONAL_NUMBER = 999999999999999,
|
||||
MAX_LEADING_ZEROS = 15,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
COUNTRY_CODE_BITS = 10,
|
||||
NATIONAL_NUMBER_BITS = 50,
|
||||
LEADING_ZEROS_BITS = 4,
|
||||
NATIONAL_NUMBER_BITS = 50,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
COUNTRY_CODE_OFFSET = 0,
|
||||
NATIONAL_NUMBER_OFFSET = COUNTRY_CODE_OFFSET + COUNTRY_CODE_BITS,
|
||||
LEADING_ZEROS_OFFSET = NATIONAL_NUMBER_OFFSET + NATIONAL_NUMBER_BITS,
|
||||
LEADING_ZEROS_OFFSET = COUNTRY_CODE_OFFSET + COUNTRY_CODE_BITS,
|
||||
NATIONAL_NUMBER_OFFSET = LEADING_ZEROS_OFFSET + LEADING_ZEROS_BITS,
|
||||
};
|
||||
|
||||
ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number);
|
||||
|
||||
bool operator == (const ShortPhoneNumber other) const {
|
||||
return this->_data == other._data;
|
||||
}
|
||||
|
||||
bool operator != (const ShortPhoneNumber other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
operator i18n::phonenumbers::PhoneNumber() const;
|
||||
|
||||
/*
|
||||
* Compares to another PhoneNumber using a fast collation heuristic
|
||||
*
|
||||
* May not produce intuitive results for numbers with the same
|
||||
* country code but different lengths
|
||||
*
|
||||
* Returns:
|
||||
* - <0 (if a < b)
|
||||
* - 0 (if a == b)
|
||||
* - >0 (if a > b)
|
||||
*/
|
||||
google::protobuf::int64 compare_fast(ShortPhoneNumber other) const {
|
||||
return other._data - this->_data;
|
||||
}
|
||||
|
||||
google::protobuf::uint32 country_code() const {
|
||||
return getMasked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue