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]