Changeset: 69bd2b94e5cb for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/69bd2b94e5cb
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/server/rel_schema.c
        sql/storage/bat/bat_storage.c
Branch: default
Log Message:

Merge with Aug2024 branch.


diffs (truncated from 601 to 300 lines):

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/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 <[email protected]> - 
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 <[email protected]> - 
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);
 //! Converts a PyObject to a hge value
 str pyobject_to_hge(PyObject **ptr, size_t maxsize, hge *value);
 //! Create a PyLongObject from a hge integer
@@ -52,21 +52,21 @@ str pyobject_to_blob(PyObject **ptr, siz
 
 str pyobject_to_date(PyObject **ptr, size_t maxsize, date *value);
 str str_to_date(const char *ptr, size_t maxsize, date *value);
-str unicode_to_date(Py_UNICODE *ptr, size_t maxsize, date *value);
+str unicode_to_date(wchar_t *ptr, size_t maxsize, date *value);
 
 str pyobject_to_daytime(PyObject **ptr, size_t maxsize, daytime *value);
 str str_to_daytime(const char *ptr, size_t maxsize, daytime *value);
-str unicode_to_daytime(Py_UNICODE *ptr, size_t maxsize, daytime *value);
+str unicode_to_daytime(wchar_t *ptr, size_t maxsize, daytime *value);
 
 str pyobject_to_timestamp(PyObject **ptr, size_t maxsize, timestamp *value);
 str str_to_timestamp(const char *ptr, size_t maxsize, timestamp *value);
-str unicode_to_timestamp(Py_UNICODE *ptr, size_t maxsize, timestamp *value);
+str unicode_to_timestamp(wchar_t *ptr, size_t maxsize, timestamp *value);
 
 
 //using macros, create a number of str_to_<type>, unicode_to_<type> and 
pyobject_to_<type> functions (we are Java now)
 #define CONVERSION_FUNCTION_HEADER_FACTORY(tpe)          \
     str str_to_##tpe(const char *ptr, size_t maxsize, tpe *value);          \
-    str unicode_to_##tpe(Py_UNICODE *ptr, size_t maxsize, tpe *value);         
         \
+    str unicode_to_##tpe(wchar_t *ptr, size_t maxsize, tpe *value);            
      \
     str pyobject_to_##tpe(PyObject **ptr, size_t maxsize, tpe *value);
 
 CONVERSION_FUNCTION_HEADER_FACTORY(bte)
diff --git a/sql/backends/monet5/UDF/pyapi3/type_conversion3.c 
b/sql/backends/monet5/UDF/pyapi3/type_conversion3.c
--- a/sql/backends/monet5/UDF/pyapi3/type_conversion3.c
+++ b/sql/backends/monet5/UDF/pyapi3/type_conversion3.c
@@ -296,7 +296,7 @@ str str_to_date(const char *ptr, size_t 
        return GDKstrdup("Implicit conversion of string to date is not 
allowed.");
 }
 
-str unicode_to_date(Py_UNICODE *ptr, size_t maxsize, date *value)
+str unicode_to_date(wchar_t *ptr, size_t maxsize, date *value)
 {
        (void)ptr;
        (void)maxsize;
@@ -314,7 +314,7 @@ str str_to_daytime(const char *ptr, size
        return GDKstrdup("Implicit conversion of string to daytime is not 
allowed.");
 }
 
-str unicode_to_daytime(Py_UNICODE *ptr, size_t maxsize, daytime *value)
+str unicode_to_daytime(wchar_t *ptr, size_t maxsize, daytime *value)
 {
        (void)ptr;
        (void)maxsize;
@@ -332,7 +332,7 @@ str str_to_timestamp(const char *ptr, si
        return GDKstrdup("Implicit conversion of string to timestamp is not 
allowed.");
 }
 
-str unicode_to_timestamp(Py_UNICODE *ptr, size_t maxsize, timestamp *value)
+str unicode_to_timestamp(wchar_t *ptr, size_t maxsize, timestamp *value)
 {
        (void)ptr;
        (void)maxsize;
@@ -444,7 +444,7 @@ str pyobject_to_##type(PyObject **pyobj,
 
 #define CONVERSION_FUNCTION_FACTORY(tpe, inttpe)                               
                \
        STRING_TO_NUMBER_FACTORY(tpe)                                           
                                \
-       str unicode_to_##tpe(Py_UNICODE *ptr, size_t maxsize, tpe *value)   \
+       str unicode_to_##tpe(wchar_t *ptr, size_t maxsize, tpe *value)   \
        {                                                                       
                                                                \
                char utf8[1024];                                                
                                                \
        if (maxsize == 0)                                                       
                                                \
diff --git a/sql/backends/monet5/UDF/pyapi3/unicode.h 
b/sql/backends/monet5/UDF/pyapi3/unicode.h
--- a/sql/backends/monet5/UDF/pyapi3/unicode.h
+++ b/sql/backends/monet5/UDF/pyapi3/unicode.h
@@ -34,7 +34,7 @@
    ascii-encoded and to false otherwise
 */
 int utf8_strlen(const char *utf8_str, bool *ascii);
-size_t utf32_strlen(const Py_UNICODE *utf32_str);
+size_t utf32_strlen(const wchar_t *utf32_str);
 
 //! Returns the length in bytes of a single utf8 character [1,2,3 or 4] based 
on
 //! the signature of the first byte, returns -1 if the character is not a valid
@@ -56,13 +56,13 @@ int utf8_length(unsigned char utf8_char)
        utf32: An array of utf32 characters
 */
 bool utf32_to_utf8(size_t offset, size_t size, char *utf8_storage,
-                                  const Py_UNICODE *utf32);
+                                  const wchar_t *utf32);
 
 bool ucs2_to_utf8(size_t offset, size_t size, char *utf8_storage,
-                                 const Py_UNICODE *ucs2);
+                                 const wchar_t *ucs2);
 
 bool unicode_to_utf8(size_t offset, size_t size, char *utf8_storage,
-                                        const Py_UNICODE *unicode);
+                                        const wchar_t *unicode);
 //! Converts a utf8 string to a utf32 string, returns TRUE on success and FALSE
 //! on failure
 /* Arguments:
@@ -73,7 +73,7 @@ bool unicode_to_utf8(size_t offset, size
    string in. To ensure the utf32 string fits this has to be [size] bytes.
        utf8: An array of utf8 characters
 */
-bool utf8_to_utf32(size_t offset, size_t size, Py_UNICODE *utf32_storage,
+bool utf8_to_utf32(size_t offset, size_t size, wchar_t *utf32_storage,
                                   const unsigned char *utf8);
 
 //! Converts a single utf8 char to a single utf32 char, returns the size of the
@@ -84,7 +84,7 @@ bool utf8_to_utf32(size_t offset, size_t
        offset:
        utf8_char:
 */
-int utf8_char_to_utf32_char(size_t position, Py_UNICODE *utf32_storage,
+int utf8_char_to_utf32_char(size_t position, wchar_t *utf32_storage,
                                                        int offset, const 
unsigned char *utf8_char);
 
 //! Converts a single utf32 char to a single utf8 char, returns the size of the
diff --git a/sql/backends/monet5/UDF/pyapi3/unicode3.c 
b/sql/backends/monet5/UDF/pyapi3/unicode3.c
--- a/sql/backends/monet5/UDF/pyapi3/unicode3.c
+++ b/sql/backends/monet5/UDF/pyapi3/unicode3.c
@@ -36,7 +36,7 @@ int utf8_strlen(const char *utf8_str, bo
        return utf8_char_count;
 }
 
-size_t utf32_strlen(const Py_UNICODE *utf32_str)
+size_t utf32_strlen(const wchar_t *utf32_str)
 {
        size_t i = 0;
        while (utf32_str[i] != 0)
@@ -102,7 +102,7 @@ int utf32_char_to_utf8_char(size_t posit
 }
 
 bool ucs2_to_utf8(size_t offset, size_t size, char *utf8_storage,
-                                 const Py_UNICODE *ucs2)
+                                 const wchar_t *ucs2)
 {
        size_t i = 0;
        int position = 0;
@@ -123,7 +123,7 @@ bool ucs2_to_utf8(size_t offset, size_t 
 }
 
 bool utf32_to_utf8(size_t offset, size_t size, char *utf8_storage,
-                                  const Py_UNICODE *utf32_input)
+                                  const wchar_t *utf32_input)
 {
        size_t i = 0;
        int position = 0;
@@ -147,16 +147,16 @@ bool utf32_to_utf8(size_t offset, size_t
 }
 
 bool unicode_to_utf8(size_t offset, size_t size, char *utf8_storage,
-                                        const Py_UNICODE *unicode)
+                                        const wchar_t *unicode)
 {
-#if Py_UNICODE_SIZE == 2
+#if SIZEOF_WCHAR_T == 2
        return ucs2_to_utf8(offset, size, utf8_storage, unicode);
 #else
        return utf32_to_utf8(offset, size, utf8_storage, unicode);
 #endif
 }
 
-int utf8_char_to_utf32_char(size_t position, Py_UNICODE *utf32_storage,
+int utf8_char_to_utf32_char(size_t position, wchar_t *utf32_storage,
                                                        int offset, const 
unsigned char *utf8_char)
 {
        unsigned char bytes[4];
@@ -178,7 +178,7 @@ int utf8_char_to_utf32_char(size_t posit
                return -1; // invalid utf8 character, the maximum value of the 
first
                                   // byte is 0xf7
 
-#if Py_UNICODE_SIZE == 2
+#if SIZEOF_WCHAR_T == 2
        if (utf8_size > 2) {
                // utf-8 character out of range on a UCS2 python compilation
                return -1;
@@ -227,7 +227,7 @@ int utf8_char_to_utf32_char(size_t posit
        }
 }
 
-bool utf8_to_utf32(size_t offset, size_t size, Py_UNICODE *utf32_storage,
+bool utf8_to_utf32(size_t offset, size_t size, wchar_t *utf32_storage,
                                   const unsigned char *utf8)
 {
        size_t i = 0;
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -5189,7 +5189,7 @@ sql_insert_check(backend *be, sql_key *k
        sql_subfunc *cnt = sql_bind_func(sql, "sys", "count", 
sql_bind_localtype("void"), NULL, F_AGGR, true, true);
        s = stmt_uselect(be, column(be, s), stmt_bool(be, 0), cmp_equal, NULL, 
0, 1);
        s = stmt_aggr(be, s, NULL, NULL, cnt, 1, 0, 1);
-       char *msg = sa_message(sql->sa, SQLSTATE(40002) "UPDATE: CHECK 
constraint violated: %s", key->base.name);
+       char *msg = sa_message(sql->sa, SQLSTATE(40002) "INSERT INTO: CHECK 
constraint violated: %s", key->base.name);
        (void)stmt_exception(be, s, msg, 00001);
 }
 
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -466,8 +466,8 @@ column_constraint_type(sql_query *query,
                        return res;
                }
                char* check = NULL;
+               sql_rel* check_rel = NULL;
                if (kt == ckey) {
-                       sql_rel* check_rel = NULL;
                        if ((check_rel = create_check_plan(query, s, t)) == 
NULL) {
                                return -3;
                        }
@@ -484,6 +484,32 @@ column_constraint_type(sql_query *query,
                        default:
                                break;
                }
+               if (check) {
+                       sql_rel* btrel = check_rel->l;
+                       node* n = NULL;
+                       for (n = btrel->exps->h; n; n = n->next) {
+                               sql_exp* e = n->data;
+                               const char *nm = e->alias.name;
+                               sql_column *c = mvc_bind_column(sql, t, nm);
+                               if (!c) {
+                                       (void) sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42S22) "CONSTRAINT CHECK: no such column '%s' for table '%s'",
+                                                       nm, t->base.name);
+                                       return SQL_ERR;
+                               }
+                               switch (mvc_create_kc(sql, k, c)) {
+                                       case -1:
+                                               (void) sql_error(sql, 02, 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                                               return SQL_ERR;
+                                       case -2:
+                                       case -3:
+                                               (void) sql_error(sql, 02, 
SQLSTATE(42000) "CONSTRAINT CHECK: transaction conflict detected");
+                                               return SQL_ERR;
+                                       default:
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to