Changeset: 031e14da4e02 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/031e14da4e02
Modified Files:
        clients/Tests/MAL-signatures-hge.test
        clients/Tests/MAL-signatures.test
        gdk/gdk_atoms.c
        gdk/gdk_calc_convert.c
        monetdb5/modules/atoms/inet-46.c
Branch: default
Log Message:

Implemented conversion between inet4 and inet6 (both ways) in BATconvert.


diffs (truncated from 385 to 300 lines):

diff --git a/clients/Tests/MAL-signatures-hge.test 
b/clients/Tests/MAL-signatures-hge.test
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -29160,6 +29160,11 @@ INETinet42inet4_bulk
 (empty)
 batcalc
 inet4
+command batcalc.inet4(X_0:bat[:inet6], X_1:bat[:oid]):bat[:inet4]
+INETinet62inet4_bulk
+Coerce an inet6 to an inet4
+batcalc
+inet4
 command batcalc.inet4(X_0:bat[:str], X_1:bat[:oid]):bat[:inet4]
 INETstr2inet4_bulk
 Coerce a string to an inet4, validating its format
@@ -44150,6 +44155,11 @@ INETinet42inet4
 (empty)
 calc
 inet4
+command calc.inet4(X_0:inet6):inet4
+INETinet62inet4
+Coerce an inet6 to an inet4
+calc
+inet4
 command calc.inet4(X_0:str):inet4
 INETstr2inet4
 Coerce a string to an inet4, validating its format
diff --git a/clients/Tests/MAL-signatures.test 
b/clients/Tests/MAL-signatures.test
--- a/clients/Tests/MAL-signatures.test
+++ b/clients/Tests/MAL-signatures.test
@@ -20585,6 +20585,11 @@ INETinet42inet4_bulk
 (empty)
 batcalc
 inet4
+command batcalc.inet4(X_0:bat[:inet6], X_1:bat[:oid]):bat[:inet4]
+INETinet62inet4_bulk
+Coerce an inet6 to an inet4
+batcalc
+inet4
 command batcalc.inet4(X_0:bat[:str], X_1:bat[:oid]):bat[:inet4]
 INETstr2inet4_bulk
 Coerce a string to an inet4, validating its format
@@ -32810,6 +32815,11 @@ INETinet42inet4
 (empty)
 calc
 inet4
+command calc.inet4(X_0:inet6):inet4
+INETinet62inet4
+Coerce an inet6 to an inet4
+calc
+inet4
 command calc.inet4(X_0:str):inet4
 INETstr2inet4
 Coerce a string to an inet4, validating its format
diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c
--- a/gdk/gdk_atoms.c
+++ b/gdk/gdk_atoms.c
@@ -1674,19 +1674,19 @@ INET6toString(str *retval, size_t *len, 
                *len = 40;
        }
        /* find longest stretch of zeroes */
-       int rl = 0;
-       int rl1 = -1;
-       int mrl = 0;
-       int mrl1 = -1;
+       int rl = 0;             /* length of current stretch of zeros */
+       int rl1 = -1;           /* start of current stretch of zeros */
+       int mrl = 0;            /* length of longest stretch of zeros */
+       int mrl1 = -1;          /* start of longest stretch of zeros */
        for (int i = 0; i < 8; i++) {
                if (value->oct[i] == 0) {
                        if (rl++ == 0)
                                rl1 = i;
-               } else if (rl > 1 && rl > mrl) {
-                       mrl = rl;
-                       mrl1 = rl1;
-                       rl = 0;
                } else {
+                       if (rl > 1 && rl > mrl) {
+                               mrl = rl;
+                               mrl1 = rl1;
+                       }
                        rl = 0;
                }
        }
@@ -1698,6 +1698,7 @@ INET6toString(str *retval, size_t *len, 
                mrl1 = 8;
        int pos = 0;
        if (mrl1 == 0 && mrl == 5 && value->oct[5] == 0xFFFF) {
+               /* IPv4 address disguised as IPv6 */
                pos += snprintf(*retval + pos, *len - pos,
                                "::%x:%d.%d.%d.%d",
                                value->oct[5], value->oct[6] >> 8,
diff --git a/gdk/gdk_calc_convert.c b/gdk/gdk_calc_convert.c
--- a/gdk/gdk_calc_convert.c
+++ b/gdk/gdk_calc_convert.c
@@ -978,6 +978,120 @@ convert_void_any(oid seq, BAT *bn,
 }
 
 static BUN
+convert_inet6_inet4(const inet6 *src, inet4 *restrict dst,
+                   struct canditer *restrict ci,
+                   oid candoff)
+{
+       BUN i, nils = 0;
+       oid x;
+       QryCtx *qry_ctx = MT_thread_get_qry_ctx();
+
+       if (ci->tpe == cand_dense) {
+               TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
+                       x = canditer_next_dense(ci) - candoff;
+                       if (is_inet6_nil(src[x])) {
+                               dst[i] = inet4_nil;
+                               nils++;
+                       } else if (src[x].oct[0] == 0 &&
+                                  src[x].oct[1] == 0 &&
+                                  src[x].oct[2] == 0 &&
+                                  src[x].oct[3] == 0 &&
+                                  src[x].oct[4] == 0 &&
+                                  src[x].oct[5] == 0xFFFF &&
+                                  (src[x].oct[6] != 0 || src[x].oct[7] != 0)) {
+                               dst[i] = (inet4) {
+                                       .quad[0] = src[x].oct[6] >> 8,
+                                       .quad[1] = src[x].oct[6] & 0xFF,
+                                       .quad[2] = src[x].oct[7] >> 8,
+                                       .quad[3] = src[x].oct[7] & 0xFF,
+                               };
+                       } else {
+                               char buf[40], *s = buf;
+                               size_t l = sizeof(buf);
+                               BATatoms[TYPE_inet6].atomToStr(&s, &l, &src[x], 
false);
+                               assert(buf == s);
+                               GDKerror("22003!overflow in conversion of %s to 
inet4.\n", buf);
+                               return BUN_NONE;
+                       }
+               }
+               TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
+       } else {
+               TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
+                       x = canditer_next(ci) - candoff;
+                       if (is_inet6_nil(src[x])) {
+                               dst[i] = inet4_nil;
+                               nils++;
+                       } else if (src[x].oct[0] == 0 &&
+                                  src[x].oct[1] == 0 &&
+                                  src[x].oct[2] == 0 &&
+                                  src[x].oct[3] == 0 &&
+                                  src[x].oct[4] == 0 &&
+                                  src[x].oct[5] == 0xFFFF &&
+                                  (src[x].oct[6] != 0 || src[x].oct[7] != 0)) {
+                               dst[i] = (inet4) {
+                                       .quad[0] = src[x].oct[6] >> 8,
+                                       .quad[1] = src[x].oct[6] & 0xFF,
+                                       .quad[2] = src[x].oct[7] >> 8,
+                                       .quad[3] = src[x].oct[7] & 0xFF,
+                               };
+                       } else {
+                               char buf[40], *s = buf;
+                               size_t l = sizeof(buf);
+                               BATatoms[TYPE_inet6].atomToStr(&s, &l, &src[x], 
false);
+                               assert(buf == s);
+                               GDKerror("22003!overflow in conversion of %s to 
inet4.\n", buf);
+                               return BUN_NONE;
+                       }
+               }
+               TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
+       }
+       return nils;
+}
+
+static BUN
+convert_inet4_inet6(const inet4 *src, inet6 *restrict dst,
+                   struct canditer *restrict ci,
+                   oid candoff)
+{
+       BUN i, nils = 0;
+       oid x;
+       QryCtx *qry_ctx = MT_thread_get_qry_ctx();
+
+       if (ci->tpe == cand_dense) {
+               TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
+                       x = canditer_next_dense(ci) - candoff;
+                       if (is_inet4_nil(src[x])) {
+                               dst[i] = inet6_nil;
+                               nils++;
+                       } else {
+                               dst[i] = (inet6) {
+                                       .oct[5] = 0xffff,
+                                       .oct[6] = (src[x].quad[0] << 8) | 
src[x].quad[1],
+                                       .oct[7] = (src[x].quad[2] << 8) | 
src[x].quad[3],
+                               };
+                       }
+               }
+               TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
+       } else {
+               TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
+                       x = canditer_next(ci) - candoff;
+                       if (is_inet4_nil(src[x])) {
+                               dst[i] = inet6_nil;
+                               nils++;
+                       } else {
+                               dst[i] = (inet6) {
+                                       .oct[5] = 0xffff,
+                                       .oct[6] = (src[x].quad[0] << 8) | 
src[x].quad[1],
+                                       .oct[7] = (src[x].quad[2] << 8) | 
src[x].quad[3],
+                               };
+                       }
+               }
+               TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
+       }
+       return nils;
+}
+
+static BUN
 convert_typeswitchloop(const void *src, int stp, void *restrict dst, int dtp,
                       struct canditer *restrict ci,
                       oid candoff, bool *reduce,
@@ -1406,6 +1520,22 @@ convert_typeswitchloop(const void *src, 
                default:
                        return BUN_NONE + 1;
                }
+       case TYPE_inet4:
+               switch (ATOMbasetype(dtp)) {
+               case TYPE_inet6:
+                       *reduce = false;
+                       return convert_inet4_inet6(src, dst, ci, candoff);
+               default:
+                       return BUN_NONE + 1;
+               }
+       case TYPE_inet6:
+               switch (ATOMbasetype(dtp)) {
+               case TYPE_inet4:
+                       *reduce = false;
+                       return convert_inet6_inet4(src, dst, ci, candoff);
+               default:
+                       return BUN_NONE + 1;
+               }
        default:
                return BUN_NONE + 1;
        }
diff --git a/monetdb5/modules/atoms/inet-46.c b/monetdb5/modules/atoms/inet-46.c
--- a/monetdb5/modules/atoms/inet-46.c
+++ b/monetdb5/modules/atoms/inet-46.c
@@ -563,6 +563,8 @@ INETinet62str(char **ret, const inet6 *v
 static str
 INETinet42inet6(inet6 *ret, const inet4 *s)
 {
+       /* could use VALconvert like the function below, but this has less
+        * overhead */
        if (is_inet4_nil(*s))
                *ret = inet6_nil;
        else
@@ -574,6 +576,18 @@ INETinet42inet6(inet6 *ret, const inet4 
        return MAL_SUCCEED;
 }
 
+static str
+INETinet62inet4(inet4 *ret, const inet6 *s)
+{
+       ValRecord val;
+       VALinit(&val, TYPE_inet6, s);
+       if (VALconvert(TYPE_inet4, &val) == NULL)
+               throw(MAL, "inet46.inet4",
+                         SQLSTATE(22003) "overflow in conversion to inet4");
+       *ret = val.val.ip4val;
+       return MAL_SUCCEED;
+}
+
 static bte
 inet6containsinet6(const inet6 *ip1, const sht *msk1, const inet6 *ip2, const 
sht *msk2, bool strict, bool symmetric)
 {
@@ -672,13 +686,7 @@ static str
 INETinet42inet6_bulk(bat *ret, const bat *bid, const bat *sid)
 {
        BAT *b = NULL, *s = NULL, *dst = NULL;
-       inet4 *restrict bv;
-       inet6 *restrict dv;
        str msg = NULL;
-       struct canditer ci;
-       oid off;
-       bool nils = false;
-       BATiter bi;
 
        if (sid && !is_bat_nil(*sid)) {
                if ((s = BATdescriptor(*sid)) == NULL) {
@@ -695,55 +703,48 @@ INETinet42inet6_bulk(bat *ret, const bat
                                                          SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
                goto bailout;
        }
-       off = b->hseqbase;
-       canditer_init(&ci, b, s);
-       if (!(dst = COLnew(ci.hseq, TYPE_inet6, ci.ncand, TRANSIENT))) {
+       if ((dst = BATconvert(b, s, TYPE_inet6, 0, 0, 0)) == NULL) {
                msg = createException(SQL, "batcalc.inet6",
                                                          SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
                goto bailout;
        }
+       *ret = dst->batCacheid;
+       BBPkeepref(dst);
 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to