Changeset: 119bbf9daf84 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/119bbf9daf84 Modified Files: sql/backends/monet5/rel_bin.c Branch: returning Log Message:
merge with default diffs (truncated from 1623 to 300 lines): diff --git a/gdk/CMakeLists.txt b/gdk/CMakeLists.txt --- a/gdk/CMakeLists.txt +++ b/gdk/CMakeLists.txt @@ -64,6 +64,7 @@ target_sources(bat gdk_string.c gdk_qsort.c gdk_qsort_impl.h + gdk_rsort.c gdk_storage.c gdk_bat.c gdk_delta.c gdk_delta.h diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c --- a/gdk/gdk_batop.c +++ b/gdk/gdk_batop.c @@ -2269,6 +2269,29 @@ do_sort(void *restrict h, void *restrict { if (n <= 1) /* trivially sorted */ return GDK_SUCCEED; + switch (tpe) { + case TYPE_bte: + case TYPE_sht: + case TYPE_int: + case TYPE_lng: +#ifdef HAVE_HGE + case TYPE_hge: +#endif + case TYPE_date: + case TYPE_daytime: + case TYPE_timestamp: + assert(base == NULL); + if (nilslast == reverse && (stable || n > 100)) + return GDKrsort(h, t, n, hs, ts, reverse, false); + break; + case TYPE_uuid: + assert(base == NULL); + if (nilslast == reverse && (stable || n > 100)) + return GDKrsort(h, t, n, hs, ts, reverse, true); + break; + default: + break; + } if (stable) { if (reverse) return GDKssort_rev(h, t, base, n, hs, ts, tpe); diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -2429,6 +2429,8 @@ do_flush_range_cleanup(logger *lg) logged_range *frange = lg->flush_ranges; logged_range *first = frange; + if (frange == NULL) + return NULL; while (frange->next) { if (ATOMIC_GET(&frange->refcount) > 1) break; @@ -2532,6 +2534,7 @@ log_create(int debug, const char *fn, co }; lg->current = &dummy; if (log_open_output(lg) != GDK_SUCCEED) { + lg->current = NULL; log_destroy(lg); return NULL; } diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h --- a/gdk/gdk_private.h +++ b/gdk/gdk_private.h @@ -151,6 +151,9 @@ gdk_return GDKremovedir(int farmid, cons gdk_return GDKsave(int farmid, const char *nme, const char *ext, void *buf, size_t size, storage_t mode, bool dosync) __attribute__((__warn_unused_result__)) __attribute__((__visibility__("hidden"))); +gdk_return GDKrsort(void *restrict h, void *restrict t, size_t n, size_t hs, size_t ts, bool reverse, bool isuuid) + __attribute__((__warn_unused_result__)) + __attribute__((__visibility__("hidden"))); gdk_return GDKssort_rev(void *restrict h, void *restrict t, const void *restrict base, size_t n, int hs, int ts, int tpe) __attribute__((__warn_unused_result__)) __attribute__((__visibility__("hidden"))); diff --git a/gdk/gdk_rsort.c b/gdk/gdk_rsort.c new file mode 100644 --- /dev/null +++ b/gdk/gdk_rsort.c @@ -0,0 +1,171 @@ +/* + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2024 MonetDB Foundation; + * Copyright August 2008 - 2023 MonetDB B.V.; + * Copyright 1997 - July 2008 CWI. + */ + +#include "monetdb_config.h" +#include "gdk.h" +#include "gdk_private.h" + +#define RADIX 8 /* one char at a time */ +#define NBUCKETS (1 << RADIX) + +gdk_return +GDKrsort(void *restrict h, void *restrict t, size_t n, size_t hs, size_t ts, bool reverse, bool isuuid) +{ + size_t *counts = GDKmalloc(hs * NBUCKETS * sizeof(size_t)); + size_t pos[NBUCKETS]; + uint8_t *h1 = h; + uint8_t *h2; + uint8_t *t1 = NULL; + uint8_t *t2 = NULL; + Heap tmph, tmpt; + + if (counts == NULL) + return GDK_FAIL; + + tmph = tmpt = (Heap) { + .farmid = 1, + }; + + snprintf(tmph.filename, sizeof(tmph.filename), "%s%crsort%zuh", + TEMPDIR_NAME, DIR_SEP, (size_t) MT_getpid()); + if (HEAPalloc(&tmph, n, hs) != GDK_SUCCEED) { + GDKfree(counts); + return GDK_FAIL; + } + h2 = (uint8_t *) tmph.base; + + if (t) { + snprintf(tmpt.filename, sizeof(tmpt.filename), "%s%crsort%zut", + TEMPDIR_NAME, DIR_SEP, (size_t) MT_getpid()); + if (HEAPalloc(&tmpt, n, ts) != GDK_SUCCEED) { + GDKfree(counts); + HEAPfree(&tmph, true); + return GDK_FAIL; + } + t1 = t; + t2 = (uint8_t *) tmpt.base; + } else { + ts = 0; + } + + memset(counts, 0, hs * NBUCKETS * sizeof(size_t)); +#ifndef WORDS_BIGENDIAN + if (isuuid /* UUID, treat like big-endian */) +#endif + for (size_t i = 0, o = 0; i < n; i++, o += hs) { + for (size_t j = 0, k = hs - 1; j < hs; j++, k--) { + uint8_t v = h1[o + k]; + counts[(j << RADIX) + v]++; + } + } +#ifndef WORDS_BIGENDIAN + else + for (size_t i = 0, o = 0; i < n; i++, o += hs) { + for (size_t j = 0; j < hs; j++) { + uint8_t v = h1[o + j]; + counts[(j << RADIX) + v]++; + } + } +#endif + /* When sorting in ascending order, the negative numbers occupy + * the second half of the buckets in the last iteration; when + * sorting in descending order, the negative numbers occupy the + * first half. In either case, at the end we need to put the + * second half first and the first half after. */ + size_t negpos = 0; + for (size_t j = 0, b = 0, k = hs - 1; j < hs; j++, b += NBUCKETS, k--) { + size_t nb = counts[b] > 0; + if (reverse) { + pos[NBUCKETS - 1] = 0; + for (size_t i = NBUCKETS - 1; i > 0; i--) { + pos[i - 1] = pos[i] + counts[b + i]; + nb += counts[b + i] > 0; + } + } else { + pos[0] = 0; + for (size_t i = 1; i < NBUCKETS; i++) { + pos[i] = pos[i - 1] + counts[b + i - 1]; + nb += counts[b + i] > 0; + } + } + /* we're only interested in the position in the last + * iteration */ + negpos = pos[NBUCKETS / 2 - reverse]; + if (nb == 1) { + /* no need to reshuffle data for this iteration: + * everything is in the same bucket */ + continue; + } + /* note, this loop changes the pos array */ +#ifndef WORDS_BIGENDIAN + if (isuuid /* UUID, treat like big-endian */) +#endif + for (size_t i = 0, ho = 0, to = 0; i < n; i++, ho += hs, to += ts) { + uint8_t v = h1[ho + k]; + if (t) + memcpy(t2 + ts * pos[v], t1 + to, ts); + memcpy(h2 + hs * pos[v]++, h1 + ho, hs); + } +#ifndef WORDS_BIGENDIAN + else + for (size_t i = 0, ho = 0, to = 0; i < n; i++, ho += hs, to += ts) { + uint8_t v = h1[ho + j]; + if (t) + memcpy(t2 + ts * pos[v], t1 + to, ts); + memcpy(h2 + hs * pos[v]++, h1 + ho, hs); + } +#endif + uint8_t *t = h1; + h1 = h2; + h2 = t; + t = t1; + t1 = t2; + t2 = t; + } + GDKfree(counts); + + if (h1 != (uint8_t *) h) { + /* we need to copy the data back to the correct heap */ + if (isuuid) { + /* no negative values in uuid, so no shuffling */ + memcpy(h2, h1, n * hs); + if (t) + memcpy(t2, t1, n * ts); + } else { + /* copy the negative integers to the start, copy positive after */ + if (negpos < n) { + memcpy(h2, h1 + hs * negpos, (n - negpos) * hs); + if (t) + memcpy(t2, t1 + ts * negpos, (n - negpos) * ts); + } + if (negpos > 0) { + memcpy(h2 + hs * (n - negpos), h1, negpos * hs); + if (t) + memcpy(t2 + ts * (n - negpos), t1, negpos * ts); + } + } + } else if (negpos > 0 && negpos < n && !isuuid) { + /* copy the negative integers to the start, copy positive after */ + memcpy(h2, h1 + hs * negpos, (n - negpos) * hs); + memcpy(h2 + hs * (n - negpos), h1, negpos * hs); + memcpy(h, h2, n * hs); + if (t) { + memcpy(t2, t1 + ts * negpos, (n - negpos) * ts); + memcpy(t2 + ts * (n - negpos), t1, negpos * ts); + memcpy(t, t2, n * ts); + } + } /* else, everything is already in the correct place */ + HEAPfree(&tmph, true); + if (t) + HEAPfree(&tmpt, true); + return GDK_SUCCEED; +} diff --git a/sql/ChangeLog-Archive b/sql/ChangeLog-Archive --- a/sql/ChangeLog-Archive +++ b/sql/ChangeLog-Archive @@ -48,6 +48,13 @@ are no longer accepted in the ANALYZE statement. - The ANALYZE statement can now be used in procedures, functions and triggers. +* Thu Apr 23 2024 Yunus Koning <yunus.kon...@monetdbsolutions.com> - 11.51.1-20240812 +- Added support for CHECK constraints in CREATE TABLE and ALTER TABLE + ADD CONSTRAINT statements. Columns and tables can have multiple CHECK + constraints provided their names are unique within the schema of the table. + The syntax is: [ CONSTRAINT a_name ] CHECK ( boolean_expression ). + When no constraint name is specified, a constraint name will be generated. + * Wed Apr 10 2024 Lucas Pereira <lucas.pere...@monetdbsolutions.com> - 11.51.1-20240812 - Make schema renaming more permissive. A schema can be renamed if it does not contain objects that are a dependency for objects outside diff --git a/sql/backends/monet5/UDF/pyapi3/convert_loops.h b/sql/backends/monet5/UDF/pyapi3/convert_loops.h --- a/sql/backends/monet5/UDF/pyapi3/convert_loops.h +++ b/sql/backends/monet5/UDF/pyapi3/convert_loops.h @@ -339,7 +339,7 @@ convert_and_append(BAT* b, const char* t break; \ case NPY_UNICODE: \ NP_COL_BAT_LOOP_FUNC(bat, mtpe, unicode_to_##mtpe, \ - Py_UNICODE, index); \ + wchar_t, index); \ break; \ case NPY_OBJECT: \ NP_COL_BAT_LOOP_FUNC(bat, mtpe, pyobject_to_##mtpe, \ @@ -440,7 +440,7 @@ convert_and_append(BAT* b, const char* t } else { \ utf32_to_utf8( \ 0, ret->memory_size / 4, utf8_string, \ - (const Py_UNICODE \ + (const wchar_t \ *)(&data[(index_offset * ret->count + iu) * \ ret->memory_size])); \ if (convert_and_append(b, utf8_string, false) != GDK_SUCCEED) { \ diff --git a/sql/backends/monet5/UDF/pyapi3/type_conversion.h b/sql/backends/monet5/UDF/pyapi3/type_conversion.h --- a/sql/backends/monet5/UDF/pyapi3/type_conversion.h +++ b/sql/backends/monet5/UDF/pyapi3/type_conversion.h @@ -35,7 +35,7 @@ int hge_to_string(char *str, hge); //! Converts a base-10 string to a hge value str str_to_hge(const char *ptr, size_t maxsize, hge *value); //! Converts a base-10 utf32-encoded string to a hge value -str unicode_to_hge(Py_UNICODE *utf32, size_t maxsize, hge *value); +str unicode_to_hge(wchar_t *utf32, size_t maxsize, hge *value); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org