ddb icon indicating copy to clipboard operation
ddb copied to clipboard

Mapping of inet/cidr types to D types

Open aldem opened this issue 13 years ago • 9 comments

It seems that there is nothing in Phobos that can map to inet/cidr types (they have a bitmask). What do you think it might be - new type or simple string (as a starter)?

aldem avatar Apr 29 '11 16:04 aldem

I think we should add dedicated struct definitions for types that don't have one-to-one mapping in Phobos. Then we should make them convertible (by writing std.conv.toImpl() functions or casts) to more or less compatible Phobos types.

For example pg's interval type is currently mapped to Duration which doesn't hold months. I wanted to write PGInterval struct, subtype Duration and overload its operators so it could be added/subtracted to/from regular DateTime and SysTime.

So for inet or cird types, I think we should create structs PGInet and PGCidr and make them convertible to InternetAddress from std.socket.

The same approach should be taken for geometric types - PGPoint, PGCircle, PGLine, etc. In fact this is similar to Npgsql (http://npgsql.projects.postgresql.org/docs/manual/UserManual.html, see point 4).

pszturmaj avatar Apr 29 '11 16:04 pszturmaj

It seems quite reasonable.

I guess that most difficult would be to map numeric and decimal types, as Phobos' bigints don't have fractional part, AFAIK...

What could be done relatively easy, though, is conversion to strings - this way most functionality will be available to an application already.

aldem avatar Apr 29 '11 23:04 aldem

std.numeric has CustomFloat which I wanted to use for decimal/numeric mapping, but I don't know if it supports PostgreSQL's precisions.

pszturmaj avatar Apr 29 '11 23:04 pszturmaj

Well, according to documentation of std.numeric:

"Allows user code to define custom floating-point formats. These formats are for storage only; all operations on them are performed by first implicitly extracting them to real first."

So, even with 80 bits of precision, we still have floats, which means - no exact values, and the advantage of numeric/decimal is exactly this - exact values...

aldem avatar Apr 30 '11 00:04 aldem

I think you misunderstood CustomFloat documentation. We get exact values in CustomFloat, but any operations like adding or multiplying are performed using reals. So, it stores all the bits received from database and it loses precision only during math ops.

pszturmaj avatar Apr 30 '11 09:04 pszturmaj

Well, "any operation" is conversion to string too (according to implementation), and to do this, the number is converted to float first:

string toString() { return to!string(get!real); }

Looking into implementation, I've an impression that maximum precision is limited to 64 bits.

However, problem with exactness is not in precision, but in binary format itself, though - you simply cannot represent exactly any decimal value (say, 0.1) when you have binary (base 2) mantissa. You may take a look here for details: http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

That's why I think that converting numeric/decimal values to floats is bad idea. In .net, there is special "decimal" type, which is storing value in base 10, but we don't have this in D, unfortunately...

aldem avatar Apr 30 '11 11:04 aldem

My mistake. You are right. For now, following your suggestion we could map numeric/decimal to string. It seems as the only option right now.

But, if scale is set to 0, then numeric may be converted to BigInt. What do you think about subtyping BigInt to Decimal type, which will internally store and operate at full precision (using BigInt), but will parse and serialize numbers with their scales (fixed point).

pszturmaj avatar Apr 30 '11 12:04 pszturmaj

Idea of subtyping BigInt is not bad, though since BigInt is not a class but struct it cannot be easily subtyped. OTOH, simply for storage and formatting it should work - operations, if needed, may be added later.

aldem avatar Apr 30 '11 16:04 aldem

By writing 'subtyping' I meant wrapping BigInt into another stuct and aliasing it to 'this':

struct Decimal { BigInt base; alias base this;

// overrides

}

pszturmaj avatar May 01 '11 19:05 pszturmaj