From ec54f1c7b50df944ae4a8d3e29cd7eaf1cc97b21 Mon Sep 17 00:00:00 2001 From: Mitko Iliev Date: Fri, 14 Apr 2023 14:31:40 +0200 Subject: [PATCH] Fixed cannot add non-null column to existing data (fixes #1130) --- libsrc/Wi/ddlrun.c | 26 +++++++++++++++++++++++--- libsrc/Wi/page.c | 8 +++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/libsrc/Wi/ddlrun.c b/libsrc/Wi/ddlrun.c index fff421d05a..3c21792e38 100644 --- a/libsrc/Wi/ddlrun.c +++ b/libsrc/Wi/ddlrun.c @@ -1882,7 +1882,7 @@ ddl_ensure_index (const char *table, const char * index_name, const char *text) client_connection_t *old_cli = sqlc_client(); sqlc_set_client (NULL); dbe_table_t * tb = sch_name_to_table (wi_inst.wi_schema, table); - dbe_key_t * key = tb ? tb_find_key (tb, index_name, NULL) : NULL; + dbe_key_t * key = tb ? tb_find_key (tb, index_name, 0) : NULL; if (!key) { caddr_t err = NULL; @@ -2513,7 +2513,23 @@ ddl_table_and_subtables_changed (query_instance_t *qi, char *tb_name) } } - +int +ddl_col_opt_set (caddr_t * col_def, caddr_t opt) +{ + caddr_t * col_meta = ARRAYP(col_def) && BOX_ELEMENTS_0(col_def) > 1 ? (caddr_t *)(col_def[1]) : NULL; + caddr_t * col_opts = ARRAYP(col_meta) && BOX_ELEMENTS_0(col_meta) > 1 ? (caddr_t *)(col_meta[1]) : NULL; + int inx; + if (!col_opts) + return 0; + DO_BOX (caddr_t, k, inx, col_opts) + { + caddr_t kn = ARRAYP(k) && BOX_ELEMENTS_0(k) > 0 ? ((caddr_t*)k)[0] : k; + if (opt == kn) + return 1; + } + END_DO_BOX; + return 0; +} void ddl_add_col (query_instance_t * qi, const char *table, caddr_t * col, int if_not_exists) @@ -2523,6 +2539,7 @@ ddl_add_col (query_instance_t * qi, const char *table, caddr_t * col, int if_not client_connection_t *cli = qi->qi_client; dbe_column_t *col_ref; dbe_table_t *tb = qi_name_to_table (qi, table); + int not_empty; if (!add_col_proc) add_col_proc = sql_compile_static ("DB.DBA.add_col (?, ?,?)", @@ -2533,10 +2550,13 @@ ddl_add_col (query_instance_t * qi, const char *table, caddr_t * col, int if_not col_ref = tb_name_to_column (tb, col[0]); if (col_ref && if_not_exists) return; + not_empty = count_exceed (qi, tb->tb_name, 0, NULL); + if (not_empty && ddl_col_opt_set (col, (caddr_t)(ptrlong)COL_NOT_NULL) && !ddl_col_opt_set (col, (caddr_t)(ptrlong)COL_DEFAULT)) + sqlr_new_error ("42000", "SQ018", "column '%s' of table '%s' contains null values", col[0], table); AS_DBA (qi, err = qr_rec_exec (add_col_proc, cli, NULL, qi, NULL, 3, ":0", (0 == strcmp (tb->tb_name, "DB.DBA.SYS_TRIGGERS")) ? "SYS_TRIGGERS" : tb->tb_name, QRP_STR, ":1", col[0], QRP_STR, - ":2", box_copy_tree ((caddr_t) col), QRP_RAW)); + ":2", box_copy_tree ((caddr_t) col), QRP_RAW)); if (err != SQL_SUCCESS) { diff --git a/libsrc/Wi/page.c b/libsrc/Wi/page.c index 2af34b383a..a2ba223e4e 100644 --- a/libsrc/Wi/page.c +++ b/libsrc/Wi/page.c @@ -139,7 +139,13 @@ kc_var_col (dbe_key_t * key, buffer_desc_t * buf, db_buf_t row, dbe_col_loc_t * len = cl->cl_pos[rv]; if (CL_FIRST_VAR == len) { - if (key->key_version != IE_KEY_VERSION (row)) + key_ver_t kv = IE_KEY_VERSION (row); + if (KV_LEFT_DUMMY == kv) + { + dp_addr_t leaf = LONG_REF (row + LD_LEAF); + GPF_T1("Not supposed to have such layout"); + } + if (key->key_version != kv) key = key->key_versions[IE_KEY_VERSION (row)]; off = 0 == IE_KEY_VERSION (row) ? key->key_key_var_start[rv] : key->key_row_var_start[rv]; len = SHORT_REF (row + key->key_length_area[rv]) - off;