Changeset: e7e309a77c0e for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e7e309a77c0e
Modified Files:
        clients/Tests/exports.stable.out
        common/stream/stream.c
        common/stream/stream.h
        gdk/gdk_batop.c
        gdk/gdk_select.c
        monetdb5/mal/mal_import.c
        monetdb5/modules/mal/tokenizer.c
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_scenario.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
Branch: default
Log Message:

Merge with Oct2014 branch.


diffs (truncated from 977 to 300 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -2835,6 +2835,7 @@ stream *file_rstream(FILE *fp, const cha
 stream *file_wastream(FILE *fp, const char *name);
 stream *file_wstream(FILE *fp, const char *name);
 FILE *getFile(stream *s);
+size_t getFileSize(stream *s);
 stream *iconv_rstream(stream *ss, const char *charset, const char *name);
 stream *iconv_wstream(stream *ss, const char *charset, const char *name);
 int isa_block_stream(stream *s);
diff --git a/common/stream/stream.c b/common/stream/stream.c
--- a/common/stream/stream.c
+++ b/common/stream/stream.c
@@ -71,8 +71,16 @@
 #include <stdarg.h>            /* va_alist.. */
 #include <assert.h>
 
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 #ifdef HAVE_NETDB_H
-# include <sys/types.h>
 # include <netinet/in_systm.h>
 # include <netinet/in.h>
 # include <netinet/ip.h>
@@ -577,7 +585,7 @@ file_read(stream *s, void *buf, size_t e
                return -1;
        }
 
-       if (!feof(fp)) {
+       if (elmsize && cnt && !feof(fp)) {
                if (ferror(fp) ||
                    ((rc = fread(buf, elmsize, cnt, fp)) == 0 &&
                     ferror(fp))) {
@@ -724,6 +732,18 @@ getFile(stream *s)
        return (FILE *) s->stream_data.p;
 }
 
+size_t
+getFileSize(stream *s)
+{
+       if (s->read == file_read) {
+               struct stat stb;
+
+               fstat(fileno((FILE *) s->stream_data.p), &stb);
+               return (size_t) stb.st_size;
+       }
+       return 0;               /* unknown */
+}
+
 static stream *
 open_stream(const char *filename, const char *flags)
 {
@@ -781,7 +801,7 @@ stream_gzread(stream *s, void *buf, size
                return -1;
        }
 
-       if (!gzeof(fp)) {
+       if (size && !gzeof(fp)) {
                size = gzread(fp, buf, size);
                if (gzerror(fp, &err) != NULL && err < 0) {
                        s->errnr = MNSTR_READ_ERROR;
@@ -1003,6 +1023,8 @@ stream_bzread(stream *s, void *buf, size
                s->errnr = MNSTR_READ_ERROR;
                return -1;
        }
+       if (size == 0)
+               return 0;
        size = BZ2_bzRead(&err, bzp->b, buf, size);
        if (err == BZ_STREAM_END) {
                /* end of stream, but not necessarily end of file: get
@@ -1450,20 +1472,23 @@ static ssize_t
 curl_read(stream *s, void *buf, size_t elmsize, size_t cnt)
 {
        struct curl_data *c = (struct curl_data *) s->stream_data.p;
-       size_t size;
+       size_t size = cnt * elmsize;
 
        if (c == NULL) {
                s->errnr = MNSTR_READ_ERROR;
                return -1;
        }
 
+       if (size == 0)
+               return 0;
        if (c->usesize - c->offset >= elmsize || !c->running) {
                /* there is at least one element's worth of data
                 * available, or we have reached the end: return as
                 * much as we have, but no more than requested */
-               if (cnt * elmsize > c->usesize - c->offset)
+               if (size > c->usesize - c->offset) {
                        cnt = (c->usesize - c->offset) / elmsize;
-               size = cnt * elmsize;
+                       size = cnt * elmsize;
+               }
                memcpy(buf, c->buffer + c->offset, size);
                c->offset += size;
                if (c->offset == c->usesize)
@@ -1645,6 +1670,8 @@ socket_read(stream *s, void *buf, size_t
        if (s->errnr || size == 0)
                return -1;
 
+       if (size == 0)
+               return 0;
        do {
                errno = 0;
 #ifdef NATIVE_WIN32
@@ -1910,6 +1937,8 @@ udp_read(stream *s, void *buf, size_t el
        if (s->errnr || udp == NULL)
                return -1;
 
+       if (size == 0)
+               return 0;
        errno = 0;
        if ((res = recvfrom(udp->s, buf,
 #ifdef NATIVE_WIN32
@@ -2255,6 +2284,8 @@ ic_read(stream *s, void *buf, size_t elm
        inbytesleft = ic->buflen;
        outbuf = (char *) buf;
        outbytesleft = elmsize * cnt;
+       if (outbytesleft == 0)
+               return 0;
        while (outbytesleft > 0 && !ic->eof) {
                if (ic->buflen == sizeof(ic->buffer)) {
                        /* ridiculously long multibyte sequence, return error */
@@ -2560,7 +2591,7 @@ buffer_read(stream *s, void *buf, size_t
 
        b = (buffer *) s->stream_data.p;
        assert(b);
-       if (b && b->pos + size <= b->len) {
+       if (size && b && b->pos + size <= b->len) {
                memcpy(buf, b->buf + b->pos, size);
                b->pos += size;
                return (ssize_t) (size / elmsize);
@@ -2946,7 +2977,7 @@ bs_read(stream *ss, void *buf, size_t el
         * empty read */
        if (todo > 0 && cnt == 0)
                s->nr = 0;
-       return (ssize_t) (cnt / elmsize);
+       return (ssize_t) (elmsize > 0 ? cnt / elmsize : 0);
 }
 
 static void
diff --git a/common/stream/stream.h b/common/stream/stream.h
--- a/common/stream/stream.h
+++ b/common/stream/stream.h
@@ -192,6 +192,7 @@ stream_export stream *file_rastream(FILE
 stream_export stream *file_wastream(FILE *fp, const char *name);
 
 stream_export FILE *getFile(stream *s);
+stream_export size_t getFileSize(stream *s);
 
 stream_export stream *iconv_rstream(stream *ss, const char *charset, const 
char *name);
 stream_export stream *iconv_wstream(stream *ss, const char *charset, const 
char *name);
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -1897,6 +1897,21 @@ BATcount_no_nil(BAT *b)
        return cnt;
 }
 
+static BAT *
+newdensecand(oid first, oid last)
+{
+       BAT *bn;
+
+       if ((bn = BATnew(TYPE_void, TYPE_void, 0, TRANSIENT)) == NULL)
+               return NULL;
+       if (last < first)
+               first = last = 0; /* empty range */
+       BATsetcount(bn, last - first + 1);
+       BATseqbase(bn, 0);
+       BATseqbase(BATmirror(bn), first);
+       return bn;
+}
+
 /* merge two candidate lists and produce a new one
  *
  * candidate lists are VOID-headed BATs with an OID tail which is
@@ -1926,10 +1941,10 @@ BATmergecand(BAT *a, BAT *b)
        assert(b->T->nonil);
 
        /* we can return a if b is empty (and v.v.) */
-       if ( BATcount(a) == 0){
+       if (BATcount(a) == 0) {
                return BATcopy(b, b->htype, b->ttype, 0, TRANSIENT);
        }
-       if ( BATcount(b) == 0){
+       if (BATcount(b) == 0) {
                return BATcopy(a, a->htype, a->ttype, 0, TRANSIENT);
        }
        /* we can return a if a fully covers b (and v.v) */
@@ -1941,11 +1956,24 @@ BATmergecand(BAT *a, BAT *b)
        bl = *(oid*) BUNtail(bi, BUNlast(b) - 1);
        ad = (af + BATcount(a) - 1 == al); /* i.e., dense */
        bd = (bf + BATcount(b) - 1 == bl); /* i.e., dense */
+       if (ad && bd) {
+               /* both are dense */
+               if (af <= bf && bf <= al + 1) {
+                       /* partial overlap starting with a, or b is
+                        * smack bang after a */
+                       return newdensecand(af, al < bl ? bl : al);
+               }
+               if (bf <= af && af <= bl + 1) {
+                       /* partial overlap starting with b, or a is
+                        * smack bang after b */
+                       return newdensecand(bf, al < bl ? bl : al);
+               }
+       }
        if (ad && af <= bf && al >= bl) {
-               return BATcopy(a, a->htype, a->ttype, 0, TRANSIENT);
+               return newdensecand(af, al);
        }
        if (bd && bf <= af && bl >= al) {
-               return BATcopy(b, b->htype, b->ttype, 0, TRANSIENT);
+               return newdensecand(bf, bl);
        }
 
        bn = BATnew(TYPE_void, TYPE_oid, BATcount(a) + BATcount(b), TRANSIENT);
@@ -2010,11 +2038,22 @@ BATmergecand(BAT *a, BAT *b)
        /* properties */
        BATsetcount(bn, (BUN) (p - (oid *) Tloc(bn, BUNfirst(bn))));
        BATseqbase(bn, 0);
-       bn->trevsorted = 0;
+       bn->trevsorted = BATcount(bn) <= 1;
        bn->tsorted = 1;
        bn->tkey = 1;
        bn->T->nil = 0;
        bn->T->nonil = 1;
+       af = * (const oid *) Tloc(bn, BUNfirst(bn));
+       if (af + BATcount(bn) - 1 == *(const oid *) Tloc(bn, BUNlast(bn) - 1)) {
+               /* new bat is in fact dense, replace by void column */
+               bn->tseqbase = af;
+               bn->tdense = 1;
+               HEAPfree(&bn->T->heap);
+               bn->ttype = TYPE_void;
+               bn->tvarsized = 1;
+               bn->T->width = 0;
+               bn->T->shift = 0;
+       }
        return bn;
 }
 
@@ -2028,7 +2067,9 @@ BATintersectcand(BAT *a, BAT *b)
 {
        BAT *bn;
        const oid *ap, *bp, *ape, *bpe;
-       oid *p, i;
+       oid *p;
+       oid af, al, bf, bl;
+       BATiter ai, bi;
 
        BATcheck(a, "BATintersectcand");
        BATcheck(b, "BATintersectcand");
@@ -2044,30 +2085,19 @@ BATintersectcand(BAT *a, BAT *b)
        assert(b->T->nonil);
 
        if (BATcount(a) == 0 || BATcount(b) == 0) {
-               bn = BATnew(TYPE_void, TYPE_void, 0, TRANSIENT);
-               if (bn) {
-                       BATseqbase(bn, 0);
-                       BATseqbase(BATmirror(bn), 0);
-               }
-               return bn;
+               return newdensecand(0, 0);
        }
 
-       if (a->ttype == TYPE_void && b->ttype == TYPE_void) {
+       ai = bat_iterator(a);
+       bi = bat_iterator(b);
+       af = *(oid*) BUNtail(ai, BUNfirst(a));
+       bf = *(oid*) BUNtail(bi, BUNfirst(b));
+       al = *(oid*) BUNtail(ai, BUNlast(a) - 1);
+       bl = *(oid*) BUNtail(bi, BUNlast(b) - 1);
+
+       if ((af + BATcount(a) - 1 == al) && (bf + BATcount(b) - 1 == bl)) {
                /* both lists are VOID */
-               bn = BATnew(TYPE_void, TYPE_void, 0, TRANSIENT);
-               if (bn == NULL)
-                       return NULL;
-               i = MAX(a->tseqbase, b->tseqbase);
-               if (a->tseqbase + BATcount(a) <= b->tseqbase ||
-                   b->tseqbase + BATcount(b) <= a->tseqbase) {
-                       /* no overlap */
-                       BATsetcount(bn, 0);
-               } else {
-                       BATsetcount(bn, MIN(a->tseqbase + BATcount(a) - i,
-                                           b->tseqbase + BATcount(b) - i));
-               }
-               BATseqbase(BATmirror(bn), i);
-               return bn;
+               return newdensecand(MAX(af, bf), MIN(al, bl));
        }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to