diff --git a/bdb/bdb_api.h b/bdb/bdb_api.h index 4bfc6ecb04..5d9ab7f01c 100644 --- a/bdb/bdb_api.h +++ b/bdb/bdb_api.h @@ -480,7 +480,7 @@ void bdb_free_cloned_handle_with_other_data_files(bdb_state_type *bdb_state); bdb_state_type * bdb_open_more(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int *bdberr); @@ -488,7 +488,7 @@ bdb_open_more(const char name[], const char dir[], int lrl, short numix, bdb_state_type * bdb_open_more_tran(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, tran_type *tran, uint32_t flags, int *bdberr); @@ -527,7 +527,7 @@ bdb_state_type *bdb_create_more_lite(const char name[], const char dir[], bdb_state_type * bdb_create(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int temp, int *bdberr); @@ -535,7 +535,7 @@ bdb_create(const char name[], const char dir[], int lrl, short numix, bdb_state_type * bdb_create_tran(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int temp, int *bdberr, tran_type *); diff --git a/bdb/bdb_int.h b/bdb/bdb_int.h index 0aedfa33c2..e99aae33b1 100644 --- a/bdb/bdb_int.h +++ b/bdb/bdb_int.h @@ -830,6 +830,7 @@ struct bdb_state_tag { short numix; /* number of indexes */ short ixlen[MAXINDEX]; /* size of each index */ signed char ixdta[MAXINDEX]; /* does this index contain the dta? */ + int ixdtalen[MAXINDEX]; /* dta len in bytes (0 if index does not contain the dta or is full datacopy) */ signed char ixcollattr[MAXINDEX]; /* does this index contain the column attributes? */ signed char ixnulls[MAXINDEX]; /*does this index contain any columns that diff --git a/bdb/bdb_verify.c b/bdb/bdb_verify.c index 877d2ecbf7..26dfd965f5 100644 --- a/bdb/bdb_verify.c +++ b/bdb/bdb_verify.c @@ -876,16 +876,19 @@ static int bdb_verify_key(verify_common_t *par, int ix, unsigned int lid) /* if dtacopy, does data payload in the key match the data * payload in the dta file? */ int expected_size; + int datacopy_size = bdb_state->ixdtalen[ix] > 0 ? bdb_state->ixdtalen[ix] : bdb_state->lrl; uint8_t *expected_data; - uint8_t datacopy_buffer[bdb_state->lrl]; + uint8_t datacopy_buffer[datacopy_size]; if (bdb_state->datacopy_odh) { int odhlen; unpack_index_odh(bdb_state, &dbt_data, &genid_right, datacopy_buffer, sizeof(datacopy_buffer), &odhlen, &ver); expected_size = odhlen; - par->vtag_callback(par->db_table, datacopy_buffer, - &expected_size, ver); + if (bdb_state->ixdtalen[ix] == 0) { // full datacopy + par->vtag_callback(par->db_table, datacopy_buffer, + &expected_size, ver); + } expected_data = datacopy_buffer; } else { expected_size = dbt_data.size - sizeof(genid); @@ -893,17 +896,29 @@ static int bdb_verify_key(verify_common_t *par, int ix, unsigned int lid) memcpy(&genid_right, (uint8_t *)dbt_data.data, sizeof(genid)); } - if (expected_size != bdb_state->lrl) { + if (expected_size != datacopy_size) { par->verify_status = 1; locprint(par, "!%016llx ix %d dtacpy payload wrong size expected %d " "got %d", - genid_flipped, ix, bdb_state->lrl, expected_size); + genid_flipped, ix, datacopy_size, expected_size); goto next_key; } - if (memcmp(expected_data, dbt_dta_check_data.data, - bdb_state->lrl)) { + char tail[datacopy_size]; + void *compared_data = dbt_dta_check_data.data; + if (bdb_state->ixdtalen[ix] > 0) { // partial datacopy + rc = par->partial_datacopy_callback(par->db_table, ix, dbt_dta_check_data.data, tail); + if (rc) { + par->verify_status = 1; + locprint(par, "!%016llx ix %d could not convert dta", genid_flipped); + goto next_key; + } + compared_data = tail; + } + + if (memcmp(expected_data, compared_data, + datacopy_size)) { par->verify_status = 1; locprint(par, "!%016llx ix %d dtacpy data mismatch", genid_flipped, ix); diff --git a/bdb/bdb_verify.h b/bdb/bdb_verify.h index 7e50e073aa..a6a92cab54 100644 --- a/bdb/bdb_verify.h +++ b/bdb/bdb_verify.h @@ -34,6 +34,7 @@ typedef struct { bdb_state_type *bdb_state; struct dbtable *db_table; const char *tablename; + int (*partial_datacopy_callback)(const struct dbtable *tbl, const int pd_ix, const void *inbuf, void *outbuf); int (*formkey_callback)(const struct dbtable *tbl, void *dta, void *blob_parm, int ix, void *keyout, int *keysz); int (*get_blob_sizes_callback)(const struct dbtable *tbl, void *dta, int blobs[16], diff --git a/bdb/cursor.c b/bdb/cursor.c index 5e7d27cf7b..6e20647abf 100644 --- a/bdb/cursor.c +++ b/bdb/cursor.c @@ -631,11 +631,12 @@ bdb_cursor_ifn_t *bdb_cursor_open( cur->idx = ixnum; cur->type = BDBC_IX; if (bdb_state->ixdta[ixnum]) { + int datacopy_size = bdb_state->ixdtalen[ixnum] > 0 ? bdb_state->ixdtalen[ixnum] : bdb_state->lrl; cur->datacopy = - malloc(bdb_state->lrl + 2 * sizeof(unsigned long long)); + malloc(datacopy_size + 2 * sizeof(unsigned long long)); if (!cur->datacopy) { logmsg(LOGMSG_ERROR, "%s: malloc %zu\n", __func__, - bdb_state->lrl + 2 * sizeof(unsigned long long)); + datacopy_size + 2 * sizeof(unsigned long long)); *bdberr = BDBERR_MALLOC; free(pcur_ifn); return NULL; @@ -6527,8 +6528,9 @@ static void *bdb_cursor_datacopy(bdb_cursor_ifn_t *cur) if (bdb_state->ondisk_header && bdb_state->datacopy_odh && (c->type == BDBC_DT || !is_genid_synthetic(c->genid))) { + int datacopy_size = bdb_state->ixdtalen[c->idx] > 0 ? bdb_state->ixdtalen[c->idx] : bdb_state->lrl; c->unpacked_datacopy = unpack_datacopy_odh( - cur, c->datacopy, bdb_state->lrl, from, size, &c->ver); + cur, c->datacopy, datacopy_size, from, size, &c->ver); } else { c->unpacked_datacopy = from; c->ver = c->state->version; diff --git a/bdb/cursor_rowlocks.c b/bdb/cursor_rowlocks.c index ec2a786ff8..23eacec284 100644 --- a/bdb/cursor_rowlocks.c +++ b/bdb/cursor_rowlocks.c @@ -2668,7 +2668,8 @@ int bdb_berkdb_rowlocks_init(bdb_berkdb_t *berkdb, DB *db, int *bdberr) r->keylen += sizeof(unsigned long long); r->dtalen = sizeof(unsigned long long); if (bdb_state->ixdta[cur->idx]) { - r->dtalen += bdb_state->lrl + (bdb_state->ondisk_header ? 7 : 0); + int datacopy_size = bdb_state->ixdtalen[cur->idx] > 0 ? bdb_state->ixdtalen[cur->idx] : bdb_state->lrl; + r->dtalen += datacopy_size + (bdb_state->ondisk_header ? 7 : 0); } r->keymem = malloc(r->keylen + 1); r->key = r->keymem; diff --git a/bdb/file.c b/bdb/file.c index f5bb81bf0f..9150e4f919 100644 --- a/bdb/file.c +++ b/bdb/file.c @@ -4531,11 +4531,12 @@ static int open_dbs_int(bdb_state_type *bdb_state, int iammaster, int upgrade, way to override this in the lrl file, we're gonna listen */ if (pagesize == 4096) { /* for datacopy indexes, use a potentially larger pagesize */ - if (bdb_state->ixdta[i]) + if (bdb_state->ixdta[i]) { + int datacopy_size = bdb_state->ixdtalen[i] > 0 ? bdb_state->ixdtalen[i] : bdb_state->lrl; pagesize = - calc_pagesize(bdb_state->attr->pagesizeix, bdb_state->lrl + bdb_state->ixlen[i]); + calc_pagesize(bdb_state->attr->pagesizeix, datacopy_size + bdb_state->ixlen[i]); /*else if (bdb_state->ixcollattr[i]) ignore this for now */ - else + } else pagesize = calc_pagesize(bdb_state->attr->pagesizeix, bdb_state->ixlen[i]); } @@ -5445,7 +5446,7 @@ static void bdb_blobmem_init_once(void) static bdb_state_type *bdb_open_int( int envonly, const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_attr_type *bdb_attr, bdb_callback_type *bdb_callback, void *usr_ptr, netinfo_type *netinfo, int upgrade, int create, int *bdberr, @@ -5684,6 +5685,11 @@ static bdb_state_type *bdb_open_int( else bdb_state->ixdta[i] = 0; + if (ixdtalen) + bdb_state->ixdtalen[i] = ixdtalen[i]; + else + bdb_state->ixdtalen[i] = 0; + if (ixcollattr) bdb_state->ixcollattr[i] = ixcollattr[i]; else @@ -6099,8 +6105,8 @@ bdb_state_type *bdb_open_env(const char name[], const char dir[], return bdb_open_int( 1, /* envonly */ - name, dir, 0, 0, NULL, NULL, NULL, NULL, - NULL, /* numix, ixlen, ixdups, ixrecnum, ixdta, ixcollattr */ + name, dir, 0, 0, NULL, NULL, NULL, NULL, NULL, + NULL, /* numix, ixlen, ixdups, ixrecnum, ixdta, ixdtalen, ixcollattr */ NULL, /* ixnulls */ 0, /* numdtafiles */ bdb_attr, /* bdb_attr */ @@ -6116,7 +6122,7 @@ bdb_state_type *bdb_open_env(const char name[], const char dir[], bdb_state_type * bdb_create_tran(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int temp, int *bdberr, tran_type *trans) @@ -6133,7 +6139,7 @@ bdb_create_tran(const char name[], const char dir[], int lrl, short numix, ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, ixdtalen, ixcollattr, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ @@ -6148,7 +6154,7 @@ bdb_create_tran(const char name[], const char dir[], int lrl, short numix, } else { ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, ixdtalen, ixcollattr, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ @@ -6168,7 +6174,7 @@ bdb_create_tran(const char name[], const char dir[], int lrl, short numix, bdb_state_type * bdb_open_more_int(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int *bdberr) @@ -6178,7 +6184,7 @@ bdb_open_more_int(const char name[], const char dir[], int lrl, short numix, *bdberr = BDBERR_NOERROR; ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, ixdtalen, ixcollattr, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ @@ -6194,13 +6200,13 @@ bdb_open_more_int(const char name[], const char dir[], int lrl, short numix, bdb_state_type * bdb_create(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int temp, int *bdberr) { return bdb_create_tran(name, dir, lrl, numix, ixlen, ixdups, ixrecnum, - ixdta, ixcollattr, ixnulls, numdtafiles, + ixdta, ixdtalen, ixcollattr, ixnulls, numdtafiles, parent_bdb_handle, temp, bdberr, NULL); } @@ -6209,7 +6215,7 @@ bdb_create(const char name[], const char dir[], int lrl, short numix, bdb_state_type * bdb_open_more(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, int *bdberr) { @@ -6221,7 +6227,7 @@ bdb_open_more(const char name[], const char dir[], int lrl, short numix, BDB_READLOCK("bdb_open_more"); ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, ixdtalen, ixcollattr, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ @@ -6241,7 +6247,7 @@ bdb_open_more(const char name[], const char dir[], int lrl, short numix, bdb_state_type * bdb_open_more_tran(const char name[], const char dir[], int lrl, short numix, const short ixlen[], const signed char ixdups[], - const signed char ixrecnum[], const signed char ixdta[], + const signed char ixrecnum[], const signed char ixdta[], const int ixdtalen[], const signed char ixcollattr[], const signed char ixnulls[], int numdtafiles, bdb_state_type *parent_bdb_handle, tran_type *tran, uint32_t flags, int *bdberr) @@ -6254,7 +6260,7 @@ bdb_open_more_tran(const char name[], const char dir[], int lrl, short numix, BDB_READLOCK("bdb_open_more_tran"); ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, ixlen, ixdups, ixrecnum, ixdta, ixdtalen, ixcollattr, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ @@ -6294,6 +6300,7 @@ bdb_state_type *bdb_open_more_lite(const char name[], const char dir[], int lrl, signed char ixdups[1] = {0}; signed char ixrecnum[1] = {0}; signed char ixdta[1] = {0}; + int ixdtalen[1] = {0}; signed char ixnulls[1] = {0}; short ixlen; @@ -6307,7 +6314,7 @@ bdb_state_type *bdb_open_more_lite(const char name[], const char dir[], int lrl, BDB_READLOCK("bdb_open_more_lite"); ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, &ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, &ixlen, ixdups, ixrecnum, ixdta, ixdtalen, NULL, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ @@ -6342,6 +6349,7 @@ bdb_state_type *bdb_open_more_queue(const char name[], const char dir[], NULL, /* ixdups */ NULL, /* ixrecnum */ NULL, /* ixdta */ + NULL, /* ixdtalen */ NULL, /* ixcollattr */ NULL, /* ixnulls */ 1, /* numdtafiles (berkdb queue file) */ @@ -6382,6 +6390,7 @@ bdb_state_type *bdb_create_queue_tran(tran_type *tran, const char name[], NULL, /* ixdups */ NULL, /* ixrecnum */ NULL, /* ixdta */ + NULL, /* ixdtalen */ NULL, /* ixcollattr */ NULL, /* ixnulls */ 1, /* numdtafiles (berkdb queue file) */ @@ -6418,6 +6427,7 @@ bdb_state_type *bdb_create_more_lite(const char name[], const char dir[], signed char ixdups[1] = {0}; signed char ixrecnum[1] = {0}; signed char ixdta[1] = {0}; + int ixdtalen[1] = {0}; signed char ixnulls[1] = {0}; short ixlen; @@ -6437,7 +6447,7 @@ bdb_state_type *bdb_create_more_lite(const char name[], const char dir[], } else { ret = bdb_open_int(0, /* envonly */ - name, dir, lrl, numix, &ixlen, ixdups, ixrecnum, ixdta, + name, dir, lrl, numix, &ixlen, ixdups, ixrecnum, ixdta, ixdtalen, NULL, ixnulls, numdtafiles, NULL, /* bdb_attr */ NULL, /* bdb_callback */ NULL, /* usr_ptr */ diff --git a/csc2/dynschemaload.h b/csc2/dynschemaload.h index 024eee34dc..74a73fda51 100644 --- a/csc2/dynschemaload.h +++ b/csc2/dynschemaload.h @@ -4,6 +4,11 @@ #include #include +struct partial_datacopy { + char *field; + struct partial_datacopy *next; +}; + enum fieldopttypes { FLDOPT_DBSTORE = 0, FLDOPT_DBLOAD = 1, @@ -39,6 +44,7 @@ int dyns_is_idx_dup(int index); int dyns_is_idx_recnum(int index); int dyns_is_idx_primary(int index); int dyns_is_idx_datacopy(int index); +int dyns_is_idx_partial_datacopy(int index); int dyns_is_idx_uniqnulls(int index); int dyns_get_idx_count(void); int dyns_get_idx_size(int index); @@ -57,6 +63,7 @@ int dyns_field_depth(int fidx, dpth_t *dpthinfo, int ndpthsinfo, int *ndpthout); int dyns_field_type(int fidx); int dyns_is_field_array(int fidx); int dyns_get_field_arr_dims(int fidx, int *dims, int ndims, int *nodims); +int dyns_get_idx_partial_datacopy(int index, struct partial_datacopy **partial_datacopy); int dyns_get_idx_tag(int index, char *tag, int tlen, char **where); /* calls to work with multiple tables */ diff --git a/csc2/macc.h b/csc2/macc.h index 98f0e4cfe2..e9300e4c7d 100644 --- a/csc2/macc.h +++ b/csc2/macc.h @@ -171,6 +171,7 @@ struct key { int exprtype; int exprarraysz; char *where; + struct partial_datacopy *pd; /* partial datacopy fields (if any) */ }; enum KEYFLAGS { @@ -183,7 +184,8 @@ enum INDEXFLAGS { RECNUMS = 0x00000002, /* index has key sequence numbers (COMDB2) */ PRIMARY = 0x00000004, DATAKEY = 0x00000008, /* key flag to indicate index has data */ - UNIQNULLS = 0x00000010 /* all NULL values are treated as UNIQUE */ + UNIQNULLS = 0x00000010, /* all NULL values are treated as UNIQUE */ + PARTIALDATAKEY = 0x00000020 /* key flag to indicate index has some data */ }; typedef struct macc_globals_t { @@ -201,6 +203,8 @@ typedef struct macc_globals_t { struct key *keys[MAXKEYS]; struct key *workkey; struct key *rngs[MAXRNGS]; + struct partial_datacopy *head_pd; + struct partial_datacopy *tail_pd; int keyixnum[MAXKEYS]; /* index # associated with a key */ int keyexprnum[MAXKEYS]; /* case number associated with a key */ int workkeyflag; /* work key's flag */ @@ -314,10 +318,12 @@ void key_setdup(); void key_setrecnums(void); void key_setprimary(void); void key_setdatakey(void); +void key_setpartialdatakey(void); void key_setuniqnulls(void); void reset_key_exprtype(void); void key_exprtype_add(int type, int arraysz); void key_piece_add(char *buf, int is_expr); +void datakey_piece_add(char *buf); void key_piece_setdescend(); char *strcpylower(char *c); int keysize(struct key *ck); diff --git a/csc2/macc_so.c b/csc2/macc_so.c index e5fff98010..6436e5c30e 100644 --- a/csc2/macc_so.c +++ b/csc2/macc_so.c @@ -909,9 +909,53 @@ void key_setprimary(void) void key_setdatakey(void) { + if (macc_globals->workkeyflag & PARTIALDATAKEY) { + csc2_error("Error at line %3d: CANNOT HAVE DATACOPY AND PARTIAL DATACOPY.\n", + current_line); + csc2_syntax_error("Error at line %3d: CANNOT HAVE DATACOPY AND PARTIAL DATACOPY.", + current_line); + any_errors++; + return; + } macc_globals->workkeyflag |= DATAKEY; } +void key_setpartialdatakey(void) +{ + if (macc_globals->workkeyflag & DATAKEY) { + csc2_error("Error at line %3d: CANNOT HAVE DATACOPY AND PARTIAL DATACOPY.\n", + current_line); + csc2_syntax_error("Error at line %3d: CANNOT HAVE DATACOPY AND PARTIAL DATACOPY.", + current_line); + any_errors++; + return; + } else if (macc_globals->workkeyflag & PARTIALDATAKEY) { + csc2_error("Error at line %3d: CANNOT HAVE MULTIPLE PARTIAL DATACOPIES.\n", + current_line); + csc2_syntax_error("Error at line %3d: CANNOT HAVE MULTIPLE PARTIAL DATACOPIES.", + current_line); + any_errors++; + return; + } + + // check for decimal columns (currently not supported) + struct table *tbl = &macc_globals->tables[macc_globals->ntables - 1]; + int type; + for (int i = 0; i < tbl->nsym; i++) { + type = tbl->sym[i].type; + if (type == T_DECIMAL32 || type == T_DECIMAL64 || type == T_DECIMAL128) { + csc2_error("Error at line %3d: CURRENTLY CANNOT HAVE PARTIAL DATACOPY WITH DECIMAL COLUMNS.\n", + current_line); + csc2_syntax_error("Error at line %3d: CURRENTLY CANNOT HAVE PARTIAL DATACOPY WITH DECIMAL COLUMNS.", + current_line); + any_errors++; + return; + } + } + + macc_globals->workkeyflag |= PARTIALDATAKEY; +} + void key_setuniqnulls(void) { CHECK_LEGACY_SCHEMA(1); @@ -923,6 +967,8 @@ void key_piece_clear() /* used by parser, clears work key */ macc_globals->workkey = 0; /* clear work key */ macc_globals->workkeyflag = 0; /* clear flag for work key */ macc_globals->workkeypieceflag = 0; /* clear key piece's flags */ + macc_globals->head_pd = 0; /* clear partial datacopy */ + macc_globals->tail_pd = 0; /* clear partial datacopy */ } void key_piece_setdescend() @@ -1111,6 +1157,19 @@ static void key_add_comn(int ix, char *tag, char *exprname, } else { macc_globals->keys[ii]->where = NULL; } + + if (macc_globals->workkeyflag & PARTIALDATAKEY) { + if (!macc_globals->head_pd) { + csc2_error("ERROR: PARTIAL DATACOPY FAILED\n"); + any_errors++; + return; + } + + macc_globals->keys[ii]->pd = macc_globals->head_pd; + } else { + macc_globals->keys[ii]->pd = NULL; + } + macc_globals->nkeys++; /* next key */ } @@ -1144,11 +1203,31 @@ void key_exprtype_add(int type, int arraysz) expridx_arraysz = arraysz; } +static int find_symbol(char *buf, int *tidx) { + char *tag = ONDISKTAG; + int i = getsymbol(tag, buf, tidx); + + if (i == -1) { + tag = (macc_globals->ntables > 1) ? ONDISKTAG : DEFAULTTAG; + i = getsymbol(tag, buf, tidx); + } + if (i == -1) { + csc2_error("Error at line %3d: SYMBOL NOT FOUND: %s.\n", + current_line, buf); + csc2_syntax_error("Error at line %3d: SYMBOL NOT FOUND: %s.", + current_line, buf); + csc2_error("IF IN MULTI-TABLE MODE MAKE SURE %s TAG IS DEFINED\n", + ONDISKTAG); + any_errors++; + } + return i; +} + void key_piece_add(char *buf, int is_expr) /* used by parser, adds a piece of a key */ { int el[6], rg[2], i, t, tidx = 0; - char *cp, *tag; + char *cp; if (is_expr) { CHECK_LEGACY_SCHEMA(1); @@ -1194,21 +1273,8 @@ void key_piece_add(char *buf, if (cp) *cp = 0; - tag = ONDISKTAG; - i = getsymbol(tag, buf, &tidx); - - if (i == -1) { - tag = (macc_globals->ntables > 1) ? ONDISKTAG : DEFAULTTAG; - i = getsymbol(tag, buf, &tidx); - } - if (i == -1) { - csc2_error("Error at line %3d: SYMBOL NOT FOUND: %s.\n", - current_line, buf); - csc2_syntax_error("Error at line %3d: SYMBOL NOT FOUND: %s.", - current_line, buf); - csc2_error("IF IN MULTI-TABLE MODE MAKE SURE %s TAG IS DEFINED\n", - ONDISKTAG); - any_errors++; + i = find_symbol(buf, &tidx); + if (i == -1) { // will error return; } else { struct table *tables = macc_globals->tables; @@ -1274,6 +1340,45 @@ void key_piece_add(char *buf, macc_globals->workkeypieceflag = 0; } +void datakey_piece_add(char *buf) { + int tidx = 0; + struct partial_datacopy *temp; + + strlower(buf, strlen(buf)); + int i = find_symbol(buf, &tidx); + if (i == -1) { // will error + return; + } + + // check if field already present + if (macc_globals->head_pd) { + temp = macc_globals->head_pd; + while (temp) { + if (strcmp(buf, temp->field) == 0) { + return; // just ignore duplicates + } + temp = temp->next; + } + } + + struct partial_datacopy *pd = (struct partial_datacopy *)csc2_malloc(sizeof(struct partial_datacopy)); + if (!pd) { + csc2_error("ERROR: OUT OF MEM: %s - ABORTING\n", strerror(errno)); + any_errors++; + return; + } + + pd->field = csc2_strdup(buf); + pd->next = NULL; + if (!macc_globals->head_pd) { + macc_globals->head_pd = pd; /* empty list */ + macc_globals->tail_pd = macc_globals->head_pd; + } else { + macc_globals->tail_pd->next = pd; + macc_globals->tail_pd = macc_globals->tail_pd->next; + } +} + extern int is_valid_datetime(const char *str, const char *tz); void rec_c_add(int typ, int size, char *name, char *cmnt) @@ -2601,6 +2706,12 @@ int dyns_is_idx_datacopy(int index) return dyns_is_idx_flagged(index, DATAKEY); } +/* is key copy-data key (partially)? */ +int dyns_is_idx_partial_datacopy(int index) +{ + return dyns_is_idx_flagged(index, PARTIALDATAKEY); +} + /* is key duplicate? */ int dyns_is_idx_primary(int index) { @@ -2619,6 +2730,24 @@ int dyns_is_idx_uniqnulls(int index) return dyns_is_idx_flagged(index, UNIQNULLS); } +int dyns_get_idx_partial_datacopy(int index, struct partial_datacopy **partial_datacopy) { + int lastix, i; + if (index < 0 || index >= numix()) { + return -1; + } + for (lastix = -1, i = 0; i < numkeys(); i++) { + if (lastix == macc_globals->keyixnum[i]) + continue; + lastix = macc_globals->keyixnum[i]; + if (macc_globals->keyixnum[i] != index) + continue; + *partial_datacopy = macc_globals->keys[i]->pd; + return 0; + } + + return -1; +} + int dyns_get_idx_tag(int index, char *tag, int tlen, char **where) { int lastix = 0, i = 0; diff --git a/csc2/maccparse.y b/csc2/maccparse.y index 2dea6cbd48..2f1592cd5b 100644 --- a/csc2/maccparse.y +++ b/csc2/maccparse.y @@ -458,10 +458,19 @@ multikeyflags: keyflags multikeyflags keyflags: T_DUP { key_setdup(); } | T_RECNUMS { key_setrecnums(); } | T_PRIMARY { key_setprimary(); } + | T_DATAKEY '(' compounddatakey ')' { key_setpartialdatakey(); } | T_DATAKEY { key_setdatakey(); } | T_UNIQNULLS { key_setuniqnulls(); } ; +compounddatakey: datakeypiece + | datakeypiece ',' compounddatakey + ; + +datakeypiece: varname { + datakey_piece_add($1); + }; + compoundkey: keypiece | keypiece '+' compoundkey ; diff --git a/db/comdb2.c b/db/comdb2.c index 4b1d298851..4dab5c6483 100644 --- a/db/comdb2.c +++ b/db/comdb2.c @@ -1011,10 +1011,10 @@ void showdbenv(struct dbenv *dbenv) for (ii = 0; ii < usedb->nix; ii++) { logmsg(LOGMSG_USER, " index %-2d keylen %-3d bytes dupes? %c recnums? %c" - " datacopy? %c collattr? %c uniqnulls %c\n", + " datacopy? %c collattr? %c uniqnulls %c datacopylen %-3d bytes\n", ii, usedb->ix_keylen[ii], (usedb->ix_dupes[ii] ? 'y' : 'n'), (usedb->ix_recnums[ii] ? 'y' : 'n'), (usedb->ix_datacopy[ii] ? 'y' : 'n'), (usedb->ix_collattr[ii] ? 'y' : 'n'), - (usedb->ix_nullsallowed[ii] ? 'y' : 'n')); + (usedb->ix_nullsallowed[ii] ? 'y' : 'n'), (usedb->ix_datacopy[ii] && !usedb->ix_datacopylen[ii] ? usedb->lrl : usedb->ix_datacopylen[ii])); } } for (ii = 0; ii < dbenv->nsiblings; ii++) { diff --git a/db/comdb2.h b/db/comdb2.h index 54652a9133..971b72d2f7 100644 --- a/db/comdb2.h +++ b/db/comdb2.h @@ -613,6 +613,7 @@ typedef struct dbtable { signed char ix_dupes[MAXINDEX]; signed char ix_recnums[MAXINDEX]; signed char ix_datacopy[MAXINDEX]; + int ix_datacopylen[MAXINDEX]; /* datacopy len in bytes (0 if full datacopy) */ signed char ix_collattr[MAXINDEX]; signed char ix_nullsallowed[MAXINDEX]; @@ -2616,10 +2617,10 @@ int process_allow_command(char *line, int lline); int gather_blob_data(struct ireq *iq, const char *tag, blob_status_t *b, const char *to_tag); int gather_blob_data_byname(const char *dbname, const char *tag, - blob_status_t *b); + blob_status_t *b, struct schema *pd); int check_one_blob_consistency(struct ireq *iq, const char *table, const char *tag, blob_status_t *b, void *record, - int blob_index, int cblob); + int blob_index, int cblob, struct schema *pd); int check_blob_consistency(struct ireq *iq, const char *table, const char *tag, blob_status_t *b, const void *record); int check_and_repair_blob_consistency(struct ireq *iq, const char *table, diff --git a/db/constraints.c b/db/constraints.c index 4eb708b0d9..31b9169735 100644 --- a/db/constraints.c +++ b/db/constraints.c @@ -457,7 +457,7 @@ int check_update_constraints(struct ireq *iq, void *trans, ixlen = getkeysize(iq->usedb, ixnum); snprintf(ondisk_tag, MAXTAGLEN, ".ONDISK_IX_%d", ixnum); if (iq->idxDelete) - rc = create_key_from_ireq(iq, ixnum, 1, NULL, NULL, NULL, + rc = create_key_from_ireq(iq, ixnum, 1, NULL, NULL, NULL, NULL, rec_dta, 0 /* not needed */, lkey); else rc = create_key_from_ondisk(iq->usedb, ixnum, rec_dta, lkey); @@ -477,7 +477,7 @@ int check_update_constraints(struct ireq *iq, void *trans, /* this part is for update */ if (newrec_dta != NULL) { if (iq->idxInsert) - rc = create_key_from_ireq(iq, ixnum, 0, NULL, NULL, NULL, + rc = create_key_from_ireq(iq, ixnum, 0, NULL, NULL, NULL, NULL, newrec_dta, 0 /* not needed */, nkey); else @@ -1146,6 +1146,7 @@ int delayed_key_adds(struct ireq *iq, void *trans, int *blkpos, int *ixout, char *od_dta_tail = NULL; int od_tail_len = 0; char mangled_key[MAXKEYLEN]; + char partial_datacopy_tail[MAXRECSZ]; #if DEBUG_REORDER logmsg(LOGMSG_DEBUG, "%s(): entering\n", __func__); @@ -1342,11 +1343,11 @@ int delayed_key_adds(struct ireq *iq, void *trans, int *blkpos, int *ixout, } if (iq->idxInsert) rc = create_key_from_ireq(iq, doidx, 0, &od_dta_tail, - &od_tail_len, mangled_key, od_dta, + &od_tail_len, mangled_key, partial_datacopy_tail, od_dta, ondisk_size, key); else - rc = create_key_from_schema(iq->usedb, NULL, doidx, &od_dta_tail, &od_tail_len, mangled_key, od_dta, - ondisk_size, key, NULL, 0, iq->tzname); + rc = create_key_from_schema(iq->usedb, NULL, doidx, &od_dta_tail, &od_tail_len, mangled_key, partial_datacopy_tail, + od_dta, ondisk_size, key, NULL, 0, iq->tzname); if (rc == -1) { if (iq->debug) reqprintf(iq, "ADDKYCNSTRT CANT FORM INDEX %d", ixnum); @@ -1635,7 +1636,7 @@ int verify_add_constraints(struct ireq *iq, void *trans, int *errout) snprintf(ondisk_tag, MAXTAGLEN, ".ONDISK_IX_%d", lixnum); if (iq->idxInsert) { - rc = create_key_from_ireq(iq, lixnum, 0, NULL, NULL, NULL, + rc = create_key_from_ireq(iq, lixnum, 0, NULL, NULL, NULL, NULL, od_dta, 0 /* not needed */, lkey); } else rc = create_key_from_ondisk(iq->usedb, lixnum, od_dta, lkey); diff --git a/db/fdb_bend_sql.c b/db/fdb_bend_sql.c index 3e809a19fc..b123a15a41 100644 --- a/db/fdb_bend_sql.c +++ b/db/fdb_bend_sql.c @@ -162,8 +162,8 @@ int fdb_svc_alter_schema(struct sqlclntstate *clnt, sqlite3_stmt *stmt, return 0; } - /* if this is a datacopy index, do not do anything */ - if (db->ix_datacopy[ixnum]) { + /* if this is a full datacopy index, do not do anything */ + if (db->ix_datacopy[ixnum] && db->ix_datacopylen[ixnum] == 0) { return 0; } @@ -171,12 +171,12 @@ int fdb_svc_alter_schema(struct sqlclntstate *clnt, sqlite3_stmt *stmt, tblschema = db->schema; ixschema = db->ixschema[ixnum]; - /* already datacopy indexes are ok */ + /* already full datacopy indexes are ok */ if (ixschema->flags & SCHEMA_DATACOPY) { return 0; } - /* we got a non datacopy index, export it as covered index */ + /* we got a non full datacopy index, export it as covered index */ /* get the sql create */ pMem = &upr->aMem[4]; diff --git a/db/glue.c b/db/glue.c index 80fcdc63c0..bb040d741c 100644 --- a/db/glue.c +++ b/db/glue.c @@ -3489,6 +3489,7 @@ int open_auxdbs(struct dbtable *db, int force_create) signed char ixdups[1]; signed char ixrecnum[1]; signed char ixdta[1]; + int ixdtalen[1]; char name[100]; char litename[100]; int bdberr; @@ -3517,6 +3518,7 @@ int open_auxdbs(struct dbtable *db, int force_create) ixdups[0] = 0; ixrecnum[0] = 0; ixdta[0] = 0; + ixdtalen[0] = 0; if (force_create) { if (gbl_meta_lite) @@ -3525,7 +3527,7 @@ int open_auxdbs(struct dbtable *db, int force_create) 0, db->dbenv->bdb_env, &bdberr); else db->meta = bdb_create(name, db->dbenv->basedir, 0, numix, ixlen, - ixdups, ixrecnum, ixdta, NULL, NULL, + ixdups, ixrecnum, ixdta, ixdtalen, NULL, NULL, numdtafiles, db->dbenv->bdb_env, 0, &bdberr); } else { /* see if we have a lite meta table - if so use that. otherwise @@ -3537,7 +3539,7 @@ int open_auxdbs(struct dbtable *db, int force_create) ctrace("bdb_open_more(meta) cannot open lite meta %d\n", bdberr); db->meta = bdb_open_more(name, db->dbenv->basedir, 0, numix, ixlen, - ixdups, ixrecnum, ixdta, NULL, NULL, + ixdups, ixrecnum, ixdta, ixdtalen, NULL, NULL, numdtafiles, db->dbenv->bdb_env, &bdberr); } } @@ -3903,7 +3905,7 @@ int backend_open_tran(struct dbenv *dbenv, tran_type *tran, uint32_t flags) db->handle = bdb_open_more_tran( db->tablename, dbenv->basedir, db->lrl, db->nix, (short *)db->ix_keylen, db->ix_dupes, db->ix_recnums, - db->ix_datacopy, db->ix_collattr, db->ix_nullsallowed, + db->ix_datacopy, db->ix_datacopylen, db->ix_collattr, db->ix_nullsallowed, db->numblobs + 1, /* main record + n blobs */ dbenv->bdb_env, tran, flags, &bdberr); diff --git a/db/indices.c b/db/indices.c index dee285a5fc..2ed5ff008b 100644 --- a/db/indices.c +++ b/db/indices.c @@ -172,6 +172,7 @@ static int check_index(struct ireq *iq, void *trans, int ixnum, blob_buffer_t *b int rc; char key[MAXKEYLEN]; char mangled_key[MAXKEYLEN]; + char partial_datacopy_tail[MAXRECSZ]; char *od_dta_tail = NULL; int od_tail_len; int fndrrn = 0; @@ -192,10 +193,10 @@ static int check_index(struct ireq *iq, void *trans, int ixnum, blob_buffer_t *b if (iq->idxInsert) rc = create_key_from_ireq(iq, ixnum, 0, &od_dta_tail, &od_tail_len, - mangled_key, od_dta, od_len, key); + mangled_key, partial_datacopy_tail, od_dta, od_len, key); else { - rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_dta_tail, &od_tail_len, mangled_key, od_dta, od_len, - key, blobs, maxblobs, iq->tzname); + rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_dta_tail, &od_tail_len, mangled_key, partial_datacopy_tail, + od_dta, od_len, key, blobs, maxblobs, iq->tzname); } if (rc == -1) { if (iq->debug) @@ -326,6 +327,7 @@ int add_record_indices(struct ireq *iq, void *trans, blob_buffer_t *blobs, for (int ixnum = 0; ixnum < iq->usedb->nix; ixnum++) { char *key = ditk.ixkey; // key points to chararray regardless reordering char mangled_key[MAXKEYLEN]; + char partial_datacopy_tail[MAXRECSZ]; if (gbl_use_plan && iq->usedb->plan && iq->usedb->plan->ix_plan[ixnum] != -1) @@ -351,10 +353,10 @@ int add_record_indices(struct ireq *iq, void *trans, blob_buffer_t *blobs, if (iq->idxInsert) rc = create_key_from_ireq(iq, ixnum, 0, &od_dta_tail, &od_tail_len, - mangled_key, od_dta, od_len, key); + mangled_key, partial_datacopy_tail, od_dta, od_len, key); else { - rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_dta_tail, &od_tail_len, mangled_key, od_dta, od_len, - key, blobs, maxblobs, iq->tzname); + rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_dta_tail, &od_tail_len, mangled_key, partial_datacopy_tail, + od_dta, od_len, key, blobs, maxblobs, iq->tzname); } if (rc == -1) { if (iq->debug) @@ -549,6 +551,8 @@ int upd_record_indices(struct ireq *iq, void *trans, int *opfailcode, char *newkey = ditk.ixkey; char mangled_oldkey[MAXKEYLEN]; char mangled_newkey[MAXKEYLEN]; + char partial_datacopy_oldtail[MAXRECSZ]; + char partial_datacopy_newtail[MAXRECSZ]; /* index doesnt change */ if (gbl_partial_indexes && iq->usedb->ix_partial && @@ -567,10 +571,10 @@ int upd_record_indices(struct ireq *iq, void *trans, int *opfailcode, if (!gbl_partial_indexes || !iq->usedb->ix_partial || (del_keys & (1ULL << ixnum))) rc = create_key_from_ireq(iq, ixnum, 1, &od_olddta_tail, - &od_oldtail_len, mangled_oldkey, + &od_oldtail_len, mangled_oldkey, partial_datacopy_oldtail, old_dta, od_len, oldkey); } else - rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_olddta_tail, &od_oldtail_len, mangled_oldkey, + rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_olddta_tail, &od_oldtail_len, mangled_oldkey, partial_datacopy_oldtail, old_dta, od_len, oldkey, del_idx_blobs, MAXBLOBS, NULL); if (rc < 0) { if (iq->debug) @@ -588,11 +592,11 @@ int upd_record_indices(struct ireq *iq, void *trans, int *opfailcode, if (!gbl_partial_indexes || !iq->usedb->ix_partial || (ins_keys & (1ULL << ixnum))) rc = create_key_from_ireq(iq, ixnum, 0, &od_dta_tail, - &od_tail_len, mangled_newkey, od_dta, + &od_tail_len, mangled_newkey, partial_datacopy_newtail, od_dta, od_len, newkey); } else /* form the new key from "od_dta" into "newkey" */ - rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_dta_tail, &od_tail_len, mangled_newkey, od_dta, - od_len, newkey, add_idx_blobs, MAXBLOBS, NULL); + rc = create_key_from_schema(iq->usedb, NULL, ixnum, &od_dta_tail, &od_tail_len, mangled_newkey, partial_datacopy_newtail, + od_dta, od_len, newkey, add_idx_blobs, MAXBLOBS, NULL); if (rc < 0) { if (iq->debug) reqprintf(iq, "CAN'T FORM NEW KEY IX %d", ixnum); @@ -960,6 +964,7 @@ int upd_new_record_add2indices(struct ireq *iq, void *trans, for (int ixnum = 0; ixnum < iq->usedb->nix; ixnum++) { char key[MAXKEYLEN]; char mangled_key[MAXKEYLEN]; + char partial_datacopy_tail[MAXRECSZ]; char *od_dta_tail = NULL; int od_tail_len = 0; @@ -977,11 +982,11 @@ int upd_new_record_add2indices(struct ireq *iq, void *trans, if (iq->idxInsert) rc = create_key_from_ireq(iq, ixnum, 0, &od_dta_tail, &od_tail_len, - mangled_key, (char *)new_dta, nd_len, key); + mangled_key, partial_datacopy_tail, (char *)new_dta, nd_len, key); else { rc = create_key_from_schema( iq->usedb, use_new_tag ? NULL : find_tag_schema(iq->usedb->tablename, ".ONDISK"), ixnum, &od_dta_tail, - &od_tail_len, mangled_key, new_dta, nd_len, key, blobs, MAXBLOBS, NULL); + &od_tail_len, mangled_key, partial_datacopy_tail, new_dta, nd_len, key, blobs, MAXBLOBS, NULL); } if (rc) { diff --git a/db/macc_glue.c b/db/macc_glue.c index be8a64f222..4c080891e2 100644 --- a/db/macc_glue.c +++ b/db/macc_glue.c @@ -200,7 +200,7 @@ static dbtable *newdb_from_schema(struct dbenv *env, char *tblname, int dbnum, return NULL; } - tbl->ix_datacopy[ii] = dyns_is_idx_datacopy(ii); + tbl->ix_datacopy[ii] = dyns_is_idx_datacopy(ii) | dyns_is_idx_partial_datacopy(ii); if (tbl->ix_datacopy[ii] < 0) { logmsg(LOGMSG_ERROR, "cant find index %d datacopy in csc schema %s\n", ii, @@ -292,6 +292,8 @@ static int create_key_schema(dbtable *db, struct schema *schema, int alt, int ascdesc; char *dbname = db->tablename; struct schema *s; + struct schema *p; + struct partial_datacopy *pd; /* keys not reqd for ver temp table; just ondisk tag */ if (strncasecmp(dbname, gbl_ver_temp_table, strlen(gbl_ver_temp_table)) == @@ -311,6 +313,8 @@ static int create_key_schema(dbtable *db, struct schema *schema, int alt, s->flags = SCHEMA_INDEX; + db->ix_datacopylen[ix] = 0; + if (dyns_is_idx_dup(ix)) s->flags |= SCHEMA_DUP; @@ -323,6 +327,68 @@ static int create_key_schema(dbtable *db, struct schema *schema, int alt, if (dyns_is_idx_uniqnulls(ix)) s->flags |= SCHEMA_UNIQNULLS; + if (dyns_is_idx_partial_datacopy(ix)) { + s->flags |= SCHEMA_PARTIALDATACOPY; + + rc = dyns_get_idx_partial_datacopy(ix, &pd); + if (rc == 0 && pd) { + p = s->partial_datacopy = calloc(1, sizeof(struct schema)); + + // find number of members + int numMembers = 0; + struct partial_datacopy *temp = pd; + while (temp) { + temp = temp->next; + numMembers++; + } + + p->tag = NULL; + p->datacopy = NULL; + p->csctag = NULL; + p->sqlitetag = NULL; + p->partial_datacopy = NULL; + p->flags = SCHEMA_PARTIALDATACOPY_ACTUAL; + + p->nmembers = numMembers; + p->member = calloc(p->nmembers, sizeof(struct field)); + + temp = pd; + piece = 0; + offset = 0; + while (temp) { + m = &p->member[piece]; + m->idx = find_field_idx(dbname, schema->tag, temp->field); + if (m->idx == -1) { + rc = -ix - 1; + goto errout; + } + + m->isExpr = 0; + m->in_default = NULL; + m->out_default = NULL; + m->name = strdup(temp->field); + m->offset = offset; + m->flags = schema->member[m->idx].flags; + m->blob_index = schema->member[m->idx].blob_index; + m->type = schema->member[m->idx].type; + m->len = schema->member[m->idx].len; + offset += m->len; + memcpy(&m->convopts, &schema->member[m->idx].convopts, sizeof(struct field_conv_opts)); + + temp = temp->next; + piece++; + } + + db->ix_datacopylen[ix] = offset; + + } else { + errstat_set_rcstrf(err, -1, "cannot form partial datacopy for index %d.", ix); + goto errout; + } + } else { + s->partial_datacopy = NULL; + } + s->nix = 0; s->ix = NULL; s->ixnum = ix; diff --git a/db/osqlshadtbl.c b/db/osqlshadtbl.c index a1c4792986..2d4c429f31 100644 --- a/db/osqlshadtbl.c +++ b/db/osqlshadtbl.c @@ -2208,8 +2208,18 @@ static int insert_record_indexes(BtCursor *pCur, struct sql_thread *thd, } if (pCur->db->ix_datacopy[ix]) { - datacopy = pCur->ondisk_buf; - datacopylen = getdatsize(pCur->db); + if (pCur->db->ix_datacopylen[ix] > 0) { // partial datacopy + datacopy = alloca(pCur->db->ix_datacopylen[ix]); + rc = stag_to_stag_buf_schemas(get_schema(pCur->db, -1), get_schema(pCur->db, ix)->partial_datacopy, pCur->ondisk_buf, datacopy, pCur->db->tablename); + if (rc == -1) { + logmsg(LOGMSG_ERROR, "insert_record:partial datacopy conversion ix %d\n", ix); + return SQLITE_INTERNAL; + } + datacopylen = pCur->db->ix_datacopylen[ix]; + } else { + datacopy = pCur->ondisk_buf; + datacopylen = getdatsize(pCur->db); + } } else if (pCur->db->ix_collattr[ix]) { datacopy = alloca(4 * pCur->db->ix_collattr[ix]); diff --git a/db/sqlglue.c b/db/sqlglue.c index 643712eb01..86795a5d1e 100644 --- a/db/sqlglue.c +++ b/db/sqlglue.c @@ -1459,9 +1459,24 @@ void form_new_style_name(char *namebuf, int len, struct schema *schema, unsigned int crc; SNPRINTF(buf, sizeof(buf), current, "%s", dbname) - if (schema->flags & SCHEMA_DATACOPY) + if (schema->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY)) { SNPRINTF(buf, sizeof(buf), current, "%s", "DATACOPY") + if (schema->flags & SCHEMA_PARTIALDATACOPY) { + struct schema *partial_datacopy = schema->partial_datacopy; + + SNPRINTF(buf, sizeof(buf), current, "%s", "(") + for (fieldctr = 0; fieldctr < partial_datacopy->nmembers; fieldctr++) { + if (fieldctr > 0) { + SNPRINTF(buf, sizeof(buf), current, "%s", ", ") + } + + SNPRINTF(buf, sizeof(buf), current, "%s", partial_datacopy->member[fieldctr].name) + } + SNPRINTF(buf, sizeof(buf), current, "%s", ")") + } + } + if (schema->flags & SCHEMA_DUP) SNPRINTF(buf, sizeof(buf), current, "%s", "DUP") @@ -1725,8 +1740,10 @@ int create_datacopy_array(struct dbtable *tbl) return -1; } - if (!(schema->flags & SCHEMA_DATACOPY)) { + if (!(schema->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY))) { continue; + } else if (schema->flags & SCHEMA_PARTIALDATACOPY) { + ondisk = schema->partial_datacopy; } int datacopy_pos = 0; @@ -1895,8 +1912,11 @@ static int create_sqlmaster_record(struct dbtable *tbl, void *tran) strbuf_append(sql, " DESC"); } - if (schema->flags & SCHEMA_DATACOPY) { + if (schema->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY)) { struct schema *ondisk = tbl->schema; + if (schema->flags & SCHEMA_PARTIALDATACOPY) { + ondisk = schema->partial_datacopy; + } int first = 1; /* Add all fields from ONDISK to index */ for (int ondisk_i = 0; ondisk_i < ondisk->nmembers; ++ondisk_i) { @@ -6591,10 +6611,15 @@ static int fetch_blob_into_sqlite_mem(BtCursor *pCur, struct schema *sc, int bdberr; int nretries = 0; struct sql_thread *thd = pCur->thd; + struct schema *pd = NULL; + + if (sc->flags & SCHEMA_PARTIALDATACOPY_ACTUAL) { + pd = sc; + } if (!pCur->have_blob_descriptor) { gather_blob_data_byname(pCur->db->tablename, ".ONDISK", - &pCur->blob_descriptor); + &pCur->blob_descriptor, pd); pCur->have_blob_descriptor = 1; } @@ -6651,7 +6676,7 @@ static int fetch_blob_into_sqlite_mem(BtCursor *pCur, struct schema *sc, iq.usedb = pCur->db; if (check_one_blob_consistency(&iq, iq.usedb->tablename, ".ONDISK", &blobs, - dta, f->blob_index, 0)) { + dta, f->blob_index, 0, pd)) { free_blob_status_data(&blobs); nretries++; if (nretries >= gbl_maxblobretries) { @@ -7146,14 +7171,18 @@ int get_data(BtCursor *pCur, struct schema *sc, uint8_t *in, int fnum, Mem *m, int get_datacopy(BtCursor *pCur, int fnum, Mem *m) { uint8_t *in; + struct schema *s; + s = pCur->db->schema; in = pCur->bdbcur->datacopy(pCur->bdbcur); - if (!is_genid_synthetic(pCur->genid)) { + if (s->ix[pCur->ixnum]->flags & SCHEMA_PARTIALDATACOPY) { + s = s->ix[pCur->ixnum]->partial_datacopy; + } else if (!is_genid_synthetic(pCur->genid)) { uint8_t ver = pCur->bdbcur->ver(pCur->bdbcur); vtag_to_ondisk_vermap(pCur->db, in, NULL, ver); } - return get_data(pCur, pCur->db->schema, in, fnum, m, 0, pCur->clnt->tzname); + return get_data(pCur, s, in, fnum, m, 0, pCur->clnt->tzname); } static int @@ -8064,7 +8093,7 @@ sqlite3BtreeCursor_cursor(Btree *pBt, /* The btree */ /* check one time if we have blobs when we open the cursor, * so we dont need to run this code for every row if we dont even * have them */ - rc = gather_blob_data_byname(cur->db->tablename, ".ONDISK", &cur->blobs); + rc = gather_blob_data_byname(cur->db->tablename, ".ONDISK", &cur->blobs, NULL); if (rc) { logmsg(LOGMSG_ERROR, "sqlite3BtreeCursor: gather_blob_data error rc=%d\n", rc); return SQLITE_INTERNAL; diff --git a/db/tag.c b/db/tag.c index fe395a8eba..2cba8d139e 100644 --- a/db/tag.c +++ b/db/tag.c @@ -3144,6 +3144,11 @@ void free_db_record(struct dbrecord *db) free(db); } +int stag_to_stag_buf_schemas(struct schema *fromsch, struct schema *tosch, const char *inbuf, char *outbuf, const char *tzname) +{ + return _stag_to_stag_buf_flags_blobs(fromsch, tosch, inbuf, outbuf, 0, NULL, NULL, NULL, 0, tzname); +} + int stag_to_stag_buf_blobs(const char *table, const char *fromtag, const char *inbuf, const char *totag, char *outbuf, struct convert_failure *reason, blob_buffer_t *blobs, @@ -4323,8 +4328,8 @@ int cmp_index_int(struct schema *oldix, struct schema *newix, char *descr, int oldattr, newattr; /* First compare attributes */ - oldattr = oldix->flags & (SCHEMA_DUP | SCHEMA_RECNUM | SCHEMA_DATACOPY | SCHEMA_UNIQNULLS); - newattr = newix->flags & (SCHEMA_DUP | SCHEMA_RECNUM | SCHEMA_DATACOPY | SCHEMA_UNIQNULLS); + oldattr = oldix->flags & (SCHEMA_DUP | SCHEMA_RECNUM | SCHEMA_DATACOPY | SCHEMA_UNIQNULLS | SCHEMA_PARTIALDATACOPY); + newattr = newix->flags & (SCHEMA_DUP | SCHEMA_RECNUM | SCHEMA_DATACOPY | SCHEMA_UNIQNULLS | SCHEMA_PARTIALDATACOPY); if (oldattr != newattr) { if (descr) snprintf(descr, descrlen, "properties have changed"); @@ -4362,6 +4367,21 @@ int cmp_index_int(struct schema *oldix, struct schema *newix, char *descr, return 1; } } + + if (oldix->flags & newix->flags & SCHEMA_PARTIALDATACOPY) { + struct schema *oldpd = oldix->partial_datacopy; + struct schema *newpd = newix->partial_datacopy; + char *descr_helper = descr ? calloc(descrlen, sizeof(char)) : descr; + if (cmp_index_int(oldpd, newpd, descr_helper, descrlen)) { + if (descr) { + snprintf(descr, descrlen, "%s in partial datacopy", descr_helper); + free(descr_helper); + } + return 1; + } + if (descr) + free(descr_helper); + } } return 0; } @@ -5310,6 +5330,14 @@ struct schema *clone_schema(struct schema *from) sc->datacopy = malloc(from->nmembers * sizeof(int)); memcpy(sc->datacopy, from->datacopy, from->nmembers * sizeof(int)); } + if (from->partial_datacopy) { + sc->partial_datacopy = calloc(1, sizeof(struct schema)); + sc->partial_datacopy->nmembers = from->partial_datacopy->nmembers; + sc->partial_datacopy->member = calloc(sc->partial_datacopy->nmembers, sizeof(struct field)); + for (i = 0; i < sc->partial_datacopy->nmembers; i++) { + sc->partial_datacopy->member[i].name = strdup(from->partial_datacopy->member[i].name); + } + } return sc; } @@ -6003,6 +6031,10 @@ void freeschema_internals(struct schema *schema) free(schema->sqlitetag); schema->sqlitetag = NULL; } + if (schema->partial_datacopy) { + freeschema(schema->partial_datacopy); + schema->partial_datacopy = NULL; + } } void freeschema(struct schema *schema) @@ -6233,7 +6265,7 @@ static int load_new_ondisk(dbtable *db, tran_type *tran) newdb->handle = bdb_open_more_tran( db->tablename, thedb->basedir, newdb->lrl, newdb->nix, (short *)newdb->ix_keylen, newdb->ix_dupes, newdb->ix_recnums, - newdb->ix_datacopy, newdb->ix_collattr, newdb->ix_nullsallowed, + newdb->ix_datacopy, newdb->ix_datacopylen, newdb->ix_collattr, newdb->ix_nullsallowed, newdb->numblobs + 1, thedb->bdb_env, arg_tran, 0, &bdberr); if (bdberr != 0 || newdb->handle == NULL) { @@ -6616,8 +6648,8 @@ int extract_decimal_quantum(const dbtable *db, int ix, char *inbuf, } int create_key_from_schema(const struct dbtable *db, struct schema *schema, int ixnum, char **tail, int *taillen, - char *mangled_key, const char *inbuf, int inbuflen, char *outbuf, blob_buffer_t *inblobs, - int maxblobs, const char *tzname) + char *mangled_key, char *partial_datacopy_tail, const char *inbuf, int inbuflen, + char *outbuf, blob_buffer_t *inblobs, int maxblobs, const char *tzname) { int rc = 0; struct schema *fromsch, *tosch; @@ -6669,8 +6701,18 @@ int create_key_from_schema(const struct dbtable *db, struct schema *schema, int fromtag, totag); abort(); } - *tail = (char *)inbuf; - *taillen = inbuflen; + if (partial_datacopy_tail && (tosch->flags & SCHEMA_PARTIALDATACOPY)) { + rc = _stag_to_stag_buf_flags_blobs(fromsch, tosch->partial_datacopy, inbuf, partial_datacopy_tail, 0 /*flags*/, NULL, inblobs, NULL /*outblobs*/, + maxblobs, tzname); + if (rc) + return rc; + + *tail = (char *)partial_datacopy_tail; + *taillen = get_size_of_schema(tosch->partial_datacopy); + } else { + *tail = (char *)inbuf; + *taillen = inbuflen; + } } } else if (db->ix_collattr[ixnum]) { assert(db->ix_datacopy[ixnum] == 0); @@ -6700,18 +6742,18 @@ int create_key_from_schema(const struct dbtable *db, struct schema *schema, int int create_key_from_ondisk(const struct dbtable *db, int ixnum, const char *inbuf, char *outbuf) { - return create_key_from_schema(db, NULL, ixnum, NULL, NULL, NULL, inbuf, 0, outbuf, NULL, 0, NULL); + return create_key_from_schema(db, NULL, ixnum, NULL, NULL, NULL, NULL, inbuf, 0, outbuf, NULL, 0, NULL); } int create_key_from_schema_simple(const struct dbtable *db, struct schema *schema, int ixnum, const char *inbuf, char *outbuf, blob_buffer_t *inblobs, int maxblobs) { - return create_key_from_schema(db, schema, ixnum, NULL, NULL, NULL, inbuf, 0, outbuf, inblobs, maxblobs, NULL); + return create_key_from_schema(db, schema, ixnum, NULL, NULL, NULL, NULL, inbuf, 0, outbuf, inblobs, maxblobs, NULL); } int create_key_from_ireq(struct ireq *iq, int ixnum, int isDelete, char **tail, - int *taillen, char *mangled_key, const char *inbuf, - int inbuflen, char *outbuf) + int *taillen, char *mangled_key, char *partial_datacopy_tail, + const char *inbuf, int inbuflen, char *outbuf) { int rc = 0; dbtable *db = iq->usedb; @@ -6737,8 +6779,20 @@ int create_key_from_ireq(struct ireq *iq, int ixnum, int isDelete, char **tail, } rc = -1; /* callers like -1 */ } else if (tail) { - *tail = (char *)inbuf; - *taillen = inbuflen; + struct schema *fromsch = get_schema(db, -1); + struct schema *tosch = get_schema(db, ixnum); + if (partial_datacopy_tail && (tosch->flags & SCHEMA_PARTIALDATACOPY)) { + rc = _stag_to_stag_buf_flags_blobs(fromsch, tosch->partial_datacopy, inbuf, partial_datacopy_tail, 0 /*flags*/, NULL, NULL /*inblobs*/, NULL /*outblobs*/, + 0 /*maxblobs*/, iq->tzname); + if (rc) + return rc; + + *tail = (char *)partial_datacopy_tail; + *taillen = get_size_of_schema(tosch->partial_datacopy); + } else { + *tail = (char *)inbuf; + *taillen = inbuflen; + } } } else if (db->ix_collattr[ixnum]) { assert(db->ix_datacopy[ixnum] == 0); diff --git a/db/tag.h b/db/tag.h index fb2686df00..d0a0ddaa51 100644 --- a/db/tag.h +++ b/db/tag.h @@ -65,6 +65,7 @@ struct schema { int flags; int nix; struct schema **ix; + struct schema *partial_datacopy; int ixnum; /* for indices, number of index in struct dbtable */ int ix_blob; /* set to 1 if blobs are involved in indexes */ int recsize; /* for tables, gives the length of the record structure */ @@ -102,7 +103,9 @@ enum { , SCHEMA_DYNAMIC = 16, SCHEMA_DATACOPY = 32, /* datacopy flag set on index */ - SCHEMA_UNIQNULLS = 64 /* treat all NULL values as UNIQUE */ + SCHEMA_UNIQNULLS = 64, /* treat all NULL values as UNIQUE */ + SCHEMA_PARTIALDATACOPY = 128, /* partial datacopy flag set on index */ + SCHEMA_PARTIALDATACOPY_ACTUAL = 256 /* schema that contains partial datacopy fields referenced by partial datacopy index */ }; /* sql_record_member.flags */ @@ -227,6 +230,8 @@ int stag_to_ctag_buf_blobs_tz(const char *table, const char *stag, blob_buffer_t *inblobs, blob_buffer_t *outblobs, int maxblobs, const char *tzname); +int stag_to_stag_buf_schemas(struct schema *fromsch, struct schema *tosch, + const char *inbuf, char *outbuf, const char *tzname); int stag_to_stag_buf_blobs(const char *table, const char *fromtag, const char *inbuf, const char *totag, char *outbuf, struct convert_failure *reason, blob_buffer_t *blobs, @@ -409,12 +414,12 @@ int create_key_from_schema_simple(const struct dbtable *db, struct schema *schem char *outbuf, blob_buffer_t *inblobs, int maxblobs); int create_key_from_schema(const struct dbtable *db, struct schema *schema, int ixnum, char **tail, int *taillen, - char *mangled_key, const char *inbuf, int inbuflen, char *outbuf, blob_buffer_t *inblobs, - int maxblobs, const char *tzname); + char *mangled_key, char *partial_datacopy_tail, const char *inbuf, int inbuflen, + char *outbuf, blob_buffer_t *inblobs, int maxblobs, const char *tzname); int create_key_from_ireq(struct ireq *iq, int ixnum, int isDelete, char **tail, - int *taillen, char *mangled_key, const char *inbuf, - int inbuflen, char *outbuf); + int *taillen, char *mangled_key, char *partial_datacopy_tail, + const char *inbuf, int inbuflen, char *outbuf); char* typestr(int type, int len); diff --git a/db/toblob.c b/db/toblob.c index 6f1848a635..9f457cca83 100644 --- a/db/toblob.c +++ b/db/toblob.c @@ -828,8 +828,24 @@ int gather_blob_data(struct ireq *iq, const char *tag, blob_status_t *b, return 0; } +/* helper function for gather_blob_data_byname + * to convert index of blob in full table schema + * to index in partial datacopy schema + */ +static int convert_idx_partial_datacopy(int blob_idx, struct schema *pd) { + for (int piece = 0; piece < pd->nmembers; piece++) { + if (pd->member[piece].idx == blob_idx) { + return piece; + } + } + + return -1; +} + +/* pd == NULL if not using partial datacopy fields + */ int gather_blob_data_byname(const char *dbname, const char *tag, - blob_status_t *b) + blob_status_t *b, struct schema *pd) { int cblob; memset(b, 0, sizeof(*b)); @@ -838,6 +854,9 @@ int gather_blob_data_byname(const char *dbname, const char *tag, int diskblob, blob_idx; diskblob = blob_no_to_blob_no(dbname, tag, cblob, ".ONDISK"); blob_idx = get_schema_blob_field_idx(dbname, tag, cblob); + if (pd) { // convert to index in partial datacopy schema + blob_idx = convert_idx_partial_datacopy(blob_idx, pd); + } if (diskblob < 0 || blob_idx < 0) { logmsg(LOGMSG_ERROR, "BLOB LOOKUP ERR SORTING CLIENT BLOB %d DISKBLOB " "%d SCHEMA IDX %d", @@ -1086,12 +1105,16 @@ static int check_blob_consistency_int(struct ireq *iq, const char *table, /* do what we do in check_blob_consistency_int(iq, table, tag, b, record, 0); * but for one blob only. + * pd == NULL if not using partial datacopy fields */ int check_one_blob_consistency(struct ireq *iq, const char *table, const char *tag, blob_status_t *b, void *record, - int blob_index, int cblob) + int blob_index, int cblob, struct schema *pd) { - struct schema *schema = find_tag_schema(table, tag); + struct schema *schema = pd; + if (!schema) { + schema = find_tag_schema(table, tag); + } int isondisk = is_tag_ondisk_sc(schema); b->total_length = 0; diff --git a/db/verify.c b/db/verify.c index 41b016992e..bda632fdab 100644 --- a/db/verify.c +++ b/db/verify.c @@ -252,6 +252,11 @@ static int verify_formkey_callback(const dbtable *tbl, void *dta, return create_key_from_schema_simple(tbl, NULL, ix, dta, keyout, blob_parm, MAXBLOBS); } +static int convert_to_partial_datacopy(const struct dbtable *tbl, const int pd_ix, const void *inbuf, void *outbuf) +{ + return stag_to_stag_buf_schemas(tbl->schema, tbl->schema->ix[pd_ix]->partial_datacopy, inbuf, outbuf, tbl->tablename); +} + static int verify_add_blob_buffer_callback(void *parm, void *dta, int dtasz, int blobno) { @@ -325,6 +330,7 @@ int verify_table(const char *table, int progress_report_seconds, pthread_once(&once, init_verify_thdpool); verify_common_t par = { .tablename = table, + .partial_datacopy_callback = convert_to_partial_datacopy, .formkey_callback = verify_formkey_callback, .get_blob_sizes_callback = verify_blobsizes_callback, .vtag_callback = (int (*)(void *, void *, int *, uint8_t))vtag_to_ondisk_vermap, diff --git a/docs/images/key-section.gif b/docs/images/key-section.gif index 5e6d6636bd..5b0c26a8f9 100644 Binary files a/docs/images/key-section.gif and b/docs/images/key-section.gif differ diff --git a/docs/pages/programming/system_tables.md b/docs/pages/programming/system_tables.md index 43eb5bcfc5..5db838661d 100644 --- a/docs/pages/programming/system_tables.md +++ b/docs/pages/programming/system_tables.md @@ -195,7 +195,7 @@ Describes all the components of the keys. Describes all of the keys in the database. comdb2_keys(tablename, keyname, keynumber, isunique, isdatacopy, - isrecnum, condition) + isrecnum, condition, ispartialdatacopy) * `tablename` - Name of the table * `keyname` - Name of the key @@ -204,6 +204,7 @@ Describes all of the keys in the database. * `isrecnum` - `Y` if this key has recnums * `condition` - Where condition for this index * `uniqnulls` - `Y` if this key treats NULL values as unique +* `ispartialdatacopy` - `Y` if some subset of the data is inlined with this key ## comdb2_keywords @@ -292,6 +293,16 @@ Lists all opcode handlers available in Comdb2. * `opcode` - Number assigned to the opcode handler * `name` - Name of the opcode handler +## comdb2_partial_datacopies + +Lists all of the partial datacopy columns for each relevant key in the database. + + comdb2_partial_datacopies(tablename, keyname, columnname) + +* `tablename` - Name of the table with partial datacopy +* `keyname` - Name of the key with partial datacopy +* `columnname` - Name of the column included in partial datacopy for `keyname` + ## comdb2_plugins Lists all plugins currently available in Comdb2. diff --git a/docs/pages/programming/table_schema.md b/docs/pages/programming/table_schema.md index 7ec51e3970..e054f68b9a 100644 --- a/docs/pages/programming/table_schema.md +++ b/docs/pages/programming/table_schema.md @@ -293,6 +293,10 @@ the data record in the btree used for the index. This copy is maintained transp This allows for large performance gains when reading sequential records from on a key. The trade-off is the use of more disk space. +To only copy a subset of the columns (partial datacopy), follow the ```datacopy``` keyword by a comma-separated list of columns +closed by parentheses to include in the datacopy. Note that currently partial datacopies cannot be used at all +in tables that contain decimal fields. + ### Unique NULL Keys. If the key definition is preceded by the ```uniqnulls``` keyword, then the backing index will treat NULL values as unique. diff --git a/docs/src/sqlitegen/bubble-generator-data.tcl b/docs/src/sqlitegen/bubble-generator-data.tcl index 416e91d6a9..d71b8fb357 100644 --- a/docs/src/sqlitegen/bubble-generator-data.tcl +++ b/docs/src/sqlitegen/bubble-generator-data.tcl @@ -589,7 +589,16 @@ stack {opt dup} {opt uniqnulls} } - {opt datacopy} + {opt datacopy + {opt + ( + {loop + column-name + , + } + ) + } + } {line /string-literal = } } {stack diff --git a/schemachange/sc_add_table.c b/schemachange/sc_add_table.c index 1e2b504612..f29686a1eb 100644 --- a/schemachange/sc_add_table.c +++ b/schemachange/sc_add_table.c @@ -59,7 +59,7 @@ static inline int get_db_handle(struct dbtable *newdb, void *trans) newdb->handle = bdb_create_tran( newdb->tablename, thedb->basedir, newdb->lrl, newdb->nix, (short *)newdb->ix_keylen, newdb->ix_dupes, newdb->ix_recnums, - newdb->ix_datacopy, newdb->ix_collattr, newdb->ix_nullsallowed, + newdb->ix_datacopy, newdb->ix_datacopylen, newdb->ix_collattr, newdb->ix_nullsallowed, newdb->numblobs + 1, thedb->bdb_env, 0, &bdberr, trans); open_auxdbs(newdb, 1); } else { @@ -67,7 +67,7 @@ static inline int get_db_handle(struct dbtable *newdb, void *trans) newdb->handle = bdb_open_more_tran( newdb->tablename, thedb->basedir, newdb->lrl, newdb->nix, (short *)newdb->ix_keylen, newdb->ix_dupes, newdb->ix_recnums, - newdb->ix_datacopy, newdb->ix_collattr, newdb->ix_nullsallowed, + newdb->ix_datacopy, newdb->ix_datacopylen, newdb->ix_collattr, newdb->ix_nullsallowed, newdb->numblobs + 1, thedb->bdb_env, trans, 0, &bdberr); open_auxdbs(newdb, 0); } diff --git a/schemachange/sc_logic.c b/schemachange/sc_logic.c index b700e091d0..c8a7c7781f 100644 --- a/schemachange/sc_logic.c +++ b/schemachange/sc_logic.c @@ -1220,7 +1220,7 @@ int open_temp_db_resume(struct dbtable *db, char *prefix, int resume, int temp, db->handle = bdb_open_more( tmpname, db->dbenv->basedir, db->lrl, db->nix, (short *)db->ix_keylen, db->ix_dupes, db->ix_recnums, - db->ix_datacopy, db->ix_collattr, db->ix_nullsallowed, + db->ix_datacopy, db->ix_datacopylen, db->ix_collattr, db->ix_nullsallowed, db->numblobs + 1, /* one main record + the blobs blobs */ db->dbenv->bdb_env, &bdberr); @@ -1243,7 +1243,7 @@ int open_temp_db_resume(struct dbtable *db, char *prefix, int resume, int temp, db->handle = bdb_create_tran( tmpname, db->dbenv->basedir, db->lrl, db->nix, (short *)db->ix_keylen, db->ix_dupes, db->ix_recnums, - db->ix_datacopy, db->ix_collattr, db->ix_nullsallowed, + db->ix_datacopy, db->ix_datacopylen, db->ix_collattr, db->ix_nullsallowed, db->numblobs + 1, /* one main record + the blobs blobs */ db->dbenv->bdb_env, temp, &bdberr, tran); if (db->handle == NULL) { diff --git a/schemachange/sc_schema.c b/schemachange/sc_schema.c index 5bfd1386a7..5a5a79449c 100644 --- a/schemachange/sc_schema.c +++ b/schemachange/sc_schema.c @@ -897,7 +897,7 @@ int create_schema_change_plan(struct schema_change_type *s, struct dbtable *oldd /* If the new index has datacopy and there are ondisk changes then * the index must be rebuilt. */ - if ((newixs->flags & SCHEMA_DATACOPY) && plan->dta_plan == -1) { + if ((newixs->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY)) && plan->dta_plan == -1) { plan->ix_plan[ixn] = -1; } else { /* Try to find an unused index in the old file which exactly matches @@ -915,7 +915,7 @@ int create_schema_change_plan(struct schema_change_type *s, struct dbtable *oldd } if (newdb->odh && /* table has odh */ - (newixs->flags & SCHEMA_DATACOPY) && /* index had datacopy */ + (newixs->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY)) && /* index had datacopy */ !datacopy_odh) /* index did not have odh in datacopy */ { plan->ix_plan[ixn] = -1; @@ -928,7 +928,7 @@ int create_schema_change_plan(struct schema_change_type *s, struct dbtable *oldd if (plan->ix_plan[ixn] == -1) plan->plan_convert = 1; char *str_datacopy; - if (newixs->flags & SCHEMA_DATACOPY) { + if (newixs->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY)) { if (olddb->odh) { if (newdb->odh) { if (datacopy_odh) { @@ -1265,7 +1265,7 @@ int check_sc_headroom(struct schema_change_type *s, struct dbtable *olddb, /* If an index has a blob field or is datacopy, the size will rise based on the blob size or data size. So still use the old way here. */ - if (!ix->ix_blob && !(ix->flags & SCHEMA_DATACOPY)) + if (!ix->ix_blob && !(ix->flags & (SCHEMA_DATACOPY | SCHEMA_PARTIALDATACOPY))) pct += get_size_of_schema(ix) / (double)lrl; } } diff --git a/schemachange/sc_struct.c b/schemachange/sc_struct.c index 897d6eff06..bc3aae3ef9 100644 --- a/schemachange/sc_struct.c +++ b/schemachange/sc_struct.c @@ -930,7 +930,7 @@ static int reload_csc2_schema(struct dbtable *db, tran_type *tran, newdb->handle = bdb_open_more_tran( table, thedb->basedir, newdb->lrl, newdb->nix, (short *)newdb->ix_keylen, newdb->ix_dupes, newdb->ix_recnums, - newdb->ix_datacopy, newdb->ix_collattr, newdb->ix_nullsallowed, + newdb->ix_datacopy, newdb->ix_datacopylen, newdb->ix_collattr, newdb->ix_nullsallowed, newdb->numblobs + 1, thedb->bdb_env, tran, 0, &bdberr); logmsg(LOGMSG_DEBUG, "reload_schema handle %p bdberr %d\n", newdb->handle, bdberr); @@ -1019,7 +1019,7 @@ int reload_schema(char *table, const char *csc2, tran_type *tran) /* faffing with schema required. schema can change in fastinit */ new_bdb_handle = bdb_open_more_tran( table, thedb->basedir, db->lrl, db->nix, (short *)db->ix_keylen, - db->ix_dupes, db->ix_recnums, db->ix_datacopy, db->ix_collattr, + db->ix_dupes, db->ix_recnums, db->ix_datacopy, db->ix_datacopylen, db->ix_collattr, db->ix_nullsallowed, db->numblobs + 1, thedb->bdb_env, tran, 0, &bdberr); logmsg(LOGMSG_DEBUG, diff --git a/sqlite/CMakeLists.txt b/sqlite/CMakeLists.txt index 2c4690b7f3..380ecdef0a 100644 --- a/sqlite/CMakeLists.txt +++ b/sqlite/CMakeLists.txt @@ -29,6 +29,7 @@ add_library(sqlite ext/comdb2/metrics.c ext/comdb2/netuserfunc.c ext/comdb2/opcode_handlers.c + ext/comdb2/partial_datacopies.c ext/comdb2/permissions.c ext/comdb2/plugins.c ext/comdb2/procedures.c diff --git a/sqlite/ext/comdb2/comdb2systblInt.h b/sqlite/ext/comdb2/comdb2systblInt.h index ea29d26cdd..c03038fc4d 100644 --- a/sqlite/ext/comdb2/comdb2systblInt.h +++ b/sqlite/ext/comdb2/comdb2systblInt.h @@ -67,6 +67,7 @@ int systblNetUserfuncsInit(sqlite3 *db); int systblClusterInit(sqlite3 *db); int systblActiveOsqlsInit(sqlite3 *db); int systblBlkseqInit(sqlite3 *db); +int systblPartialDatacopiesInit(sqlite3 *db); int systblTablePropertiesInit(sqlite3 *db); int systblTimepartInit(sqlite3*db); int systblCronInit(sqlite3*db); diff --git a/sqlite/ext/comdb2/keys.c b/sqlite/ext/comdb2/keys.c index a4405d0368..d780be0266 100644 --- a/sqlite/ext/comdb2/keys.c +++ b/sqlite/ext/comdb2/keys.c @@ -76,6 +76,7 @@ static int systblKeysConnect( #define STKEY_RECNUM 5 #define STKEY_CONDITION 6 #define STKEY_UNIQNULLS 7 +#define STKEY_PARTIALDATACOPY 8 rc = sqlite3_declare_vtab(db, "CREATE TABLE comdb2_keys(tablename," "keyname," @@ -84,7 +85,8 @@ static int systblKeysConnect( "isdatacopy," "isrecnum," "condition," - "uniqnulls)"); + "uniqnulls," + "ispartialdatacopy)"); if( rc==SQLITE_OK ){ pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; @@ -204,6 +206,11 @@ static int systblKeysColumn( sqlite3_result_text(ctx, pSchema->where, -1, SQLITE_STATIC); break; } + case STKEY_PARTIALDATACOPY: { + sqlite3_result_text(ctx, YESNO(pSchema->flags & SCHEMA_PARTIALDATACOPY), + -1, SQLITE_STATIC); + break; + } } return SQLITE_OK; } diff --git a/sqlite/ext/comdb2/partial_datacopies.c b/sqlite/ext/comdb2/partial_datacopies.c new file mode 100644 index 0000000000..ba35172ac3 --- /dev/null +++ b/sqlite/ext/comdb2/partial_datacopies.c @@ -0,0 +1,98 @@ +/* + Copyright 2022 Bloomberg Finance L.P. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +#include +#include +#include +#include "comdb2.h" +#include "sqlite3.h" +#include "ezsystables.h" + +extern struct dbenv *thedb; + +sqlite3_module systblPartialDatacopiesModule = { + .access_flag = CDB2_ALLOW_USER, + .systable_lock = "comdb2_tables", +}; + +typedef struct systable_partial_datacopies { + char *tablename; + char *keyname; + char *columnname; +} systable_partial_datacopies_t; + +int partial_datacopies_systable_collect(void **data, int *nrecords) +{ + // first find number of records + *nrecords = 0; + struct dbtable *db; + struct schema *schema; + for (int i = 0; i < thedb->num_dbs; i++) { + db = thedb->dbs[i]; + for (int j = 0; j < db->nix; j++) { + schema = db->ixschema[j]; + if (schema->flags & SCHEMA_PARTIALDATACOPY) { + *nrecords += schema->partial_datacopy->nmembers; + } + } + } + + int idx = 0; + struct field *member; + systable_partial_datacopies_t *arr = calloc(*nrecords, sizeof(systable_partial_datacopies_t)); + for (int i = 0; i < thedb->num_dbs; i++) { + db = thedb->dbs[i]; + for (int j = 0; j < db->nix; j++) { + schema = db->ixschema[j]; + if (schema->flags & SCHEMA_PARTIALDATACOPY) { + for (int k = 0; k < schema->partial_datacopy->nmembers; k++) { + member = &schema->partial_datacopy->member[k]; + arr[idx].tablename = strdup(db->tablename); + arr[idx].keyname = strdup(schema->csctag); + arr[idx].columnname = strdup(member->name); + idx++; + } + } + } + } + + *data = arr; + return 0; +} + +void partial_datacopies_systable_free(void *arr, int nrecords) +{ + systable_partial_datacopies_t *parr = (systable_partial_datacopies_t *)arr; + int i; + + for (i = 0; i < nrecords; i++) { + free(parr[i].tablename); + free(parr[i].keyname); + free(parr[i].columnname); + } + free(arr); +} + +int systblPartialDatacopiesInit(sqlite3*db) +{ + return create_system_table( + db, "comdb2_partial_datacopies", &systblPartialDatacopiesModule, + partial_datacopies_systable_collect, partial_datacopies_systable_free, + sizeof(systable_partial_datacopies_t), + CDB2_CSTRING, "tablename", -1, offsetof(systable_partial_datacopies_t, tablename), + CDB2_CSTRING, "keyname", -1, offsetof(systable_partial_datacopies_t, keyname), + CDB2_CSTRING, "columnname", -1, offsetof(systable_partial_datacopies_t, columnname), + SYSTABLE_END_OF_FIELDS); +} diff --git a/sqlite/ext/comdb2/tables.c b/sqlite/ext/comdb2/tables.c index 452fe515ad..f08b0958e9 100644 --- a/sqlite/ext/comdb2/tables.c +++ b/sqlite/ext/comdb2/tables.c @@ -280,6 +280,8 @@ int comdb2SystblInit( rc = sqlite3_create_module(db, "comdb2_logical_operations", &systblLogicalOpsModule, 0); if (rc == SQLITE_OK) rc = sqlite3_create_module(db, "comdb2_systables", &systblSystabsModule, 0); + if (rc == SQLITE_OK) + rc = systblPartialDatacopiesInit(db); if (rc == SQLITE_OK) rc = systblTablePropertiesInit(db); if (rc == SQLITE_OK) diff --git a/sqlite/src/comdb2build.c b/sqlite/src/comdb2build.c index 4ede4cd179..df85384a23 100644 --- a/sqlite/src/comdb2build.c +++ b/sqlite/src/comdb2build.c @@ -2662,6 +2662,14 @@ enum { KEY_DELETED = 1 << 2, KEY_UNIQNULLS = 1 << 3, KEY_RECNUM = 1 << 4, + KEY_PARTIALDATACOPY = 1 << 5, +}; + +struct comdb2_partial_datacopy_field{ + /* Field name */ + char *name; + /* Link */ + LINKC_T(struct comdb2_partial_datacopy_field) lnk; }; struct comdb2_key { @@ -2673,6 +2681,8 @@ struct comdb2_key { char *where; /* Key flags */ uint8_t flags; + /* List of fields in partial datacopy */ + LISTC_T(struct comdb2_partial_datacopy_field) partial_datacopy_list; /* List of columns */ comdb2_index_part_lst idx_col_list; /* Link */ @@ -3287,8 +3297,26 @@ static char *format_csc2(struct comdb2_ddl_context *ctx) strbuf_append(csc2, "dup "); } - if ((key->flags & KEY_DATACOPY) != 0) { + if ((key->flags & (KEY_DATACOPY | KEY_PARTIALDATACOPY)) != 0) { strbuf_append(csc2, "datacopy "); + + if (key->flags & KEY_PARTIALDATACOPY) { + int added = 0; + struct comdb2_partial_datacopy_field *partial_datacopy_field; + + strbuf_append(csc2, "("); + LISTC_FOR_EACH(&key->partial_datacopy_list, partial_datacopy_field, lnk) + { + if (added > 0) { + strbuf_append(csc2, ", "); + } + + strbuf_append(csc2, partial_datacopy_field->name); + + added++; + } + strbuf_append(csc2, ") "); + } } if ((key->flags & KEY_UNIQNULLS) != 0) { @@ -3396,10 +3424,29 @@ static int gen_key_name(struct comdb2_key *key, const char *table, char *out, /* Table name */ SNPRINTF(buf, sizeof(buf), pos, "%s", table) - /* DATACOPY */ - if (key->flags & KEY_DATACOPY) + /* DATACOPY/PARTIALDATACOPY */ + if (key->flags & (KEY_DATACOPY | KEY_PARTIALDATACOPY)) { SNPRINTF(buf, sizeof(buf), pos, "%s", "DATACOPY") + if (key->flags & KEY_PARTIALDATACOPY) { + int added = 0; + struct comdb2_partial_datacopy_field *partial_datacopy_field; + + SNPRINTF(buf, sizeof(buf), pos, "%s", "(") + LISTC_FOR_EACH(&key->partial_datacopy_list, partial_datacopy_field, lnk) + { + if (added > 0) { + SNPRINTF(buf, sizeof(buf), pos, "%s", ", ") + } + + SNPRINTF(buf, sizeof(buf), pos, "%s", partial_datacopy_field->name) + + added++; + } + SNPRINTF(buf, sizeof(buf), pos, "%s", ")") + } + } + /* DUP */ if (key->flags & KEY_DUP) SNPRINTF(buf, sizeof(buf), pos, "%s", "DUP") @@ -3727,6 +3774,8 @@ static char *prepare_csc2(Parse *pParse, struct comdb2_ddl_context *ctx) * Unique * Columns must not allow NULLs * Must be only one per table + * Check that datacopy and partial datacopy are both not set + * Check that partial datacopy columns are valid */ int pk_count = 0; LISTC_FOR_EACH(&ctx->schema->key_list, key, lnk) @@ -3762,6 +3811,27 @@ static char *prepare_csc2(Parse *pParse, struct comdb2_ddl_context *ctx) } } } + + if (key->flags & KEY_PARTIALDATACOPY) { + /* Make sure datacopy and partial datacopy are not set */ + if (key->flags & KEY_DATACOPY) { + pParse->rc = SQLITE_ERROR; + sqlite3ErrorMsg(pParse, "Cannot have datacopy and partial datacopy."); + goto cleanup; + } + + /* Make sure all partial datacopy fields are valid */ + struct comdb2_partial_datacopy_field *partial_datacopy_field; + LISTC_FOR_EACH(&key->partial_datacopy_list, partial_datacopy_field, lnk) + { + if (find_column_by_name(ctx, partial_datacopy_field->name) == 0) { + pParse->rc = SQLITE_ERROR; + sqlite3ErrorMsg(pParse, "Invalid partial datacopy field \"%s\".", partial_datacopy_field->name); + goto cleanup; + } + } + + } } /* @@ -4244,6 +4314,26 @@ static int retrieve_schema(Parse *pParse, struct comdb2_ddl_context *ctx) key->flags |= KEY_UNIQNULLS; } + listc_init(&key->partial_datacopy_list, offsetof(struct comdb2_partial_datacopy_field, lnk)); + + if (schema->ix[i]->flags & SCHEMA_PARTIALDATACOPY) { + key->flags |= KEY_PARTIALDATACOPY; + + struct comdb2_partial_datacopy_field *partial_datacopy_field; + struct schema *partial_datacopy = schema->ix[i]->partial_datacopy; + for (int j = 0; j < partial_datacopy->nmembers; j++) { + partial_datacopy_field = comdb2_calloc(ctx->mem, 1, sizeof(struct comdb2_partial_datacopy_field)); + if (partial_datacopy_field == 0) { + goto oom; + } + partial_datacopy_field->name = comdb2_strdup(ctx->mem, partial_datacopy->member[j].name); + if (partial_datacopy_field->name == 0) { + goto oom; + } + listc_abl(&key->partial_datacopy_list, partial_datacopy_field); + } + } + listc_init(&key->idx_col_list, offsetof(struct comdb2_index_part, lnk)); struct comdb2_column *column; diff --git a/tests/auth.test/t09.expected b/tests/auth.test/t09.expected index 8a21439d05..d950a9d222 100644 --- a/tests/auth.test/t09.expected +++ b/tests/auth.test/t09.expected @@ -242,6 +242,7 @@ (candidate='comdb2_metrics') (candidate='comdb2_net_userfuncs') (candidate='comdb2_opcode_handlers') +(candidate='comdb2_partial_datacopies') (candidate='comdb2_plugins') (candidate='comdb2_procedures') (candidate='comdb2_queues') diff --git a/tests/cdb2sql.test/t00.expected b/tests/cdb2sql.test/t00.expected index 73cabd23f9..f3fec8f130 100644 --- a/tests/cdb2sql.test/t00.expected +++ b/tests/cdb2sql.test/t00.expected @@ -42,6 +42,7 @@ unknown @ls sub-command foo (name='comdb2_metrics') (name='comdb2_net_userfuncs') (name='comdb2_opcode_handlers') +(name='comdb2_partial_datacopies') (name='comdb2_plugins') (name='comdb2_procedures') (name='comdb2_queues') @@ -76,7 +77,7 @@ Columns: (column='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N') Keys: -(keyname='COMDB2_PK', isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL) +(keyname='COMDB2_PK', isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, ispartialdatacopy='N') Constraints: (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t2', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) @@ -95,7 +96,7 @@ Columns: (column='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N') Keys: -(keyname='COMDB2_PK', isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL) +(keyname='COMDB2_PK', isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, ispartialdatacopy='N') Constraints: (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t2', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) @@ -118,7 +119,7 @@ Columns: (column='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N') Keys: -(keyname='COMDB2_PK', isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL) +(keyname='COMDB2_PK', isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, ispartialdatacopy='N') Constraints: (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t2', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) diff --git a/tests/comdb2sys.test/comdb2sys.expected b/tests/comdb2sys.test/comdb2sys.expected index 20ab2ce31d..96888db64e 100644 --- a/tests/comdb2sys.test/comdb2sys.expected +++ b/tests/comdb2sys.test/comdb2sys.expected @@ -49,14 +49,14 @@ (tablename='t3', columnname='value', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t4', columnname='value', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) [select * from comdb2_columns order by columnname, tablename] rc 0 -(tablename='t1', keyname='DUP_VALUE', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='partidx', keyname='UID', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='UID', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='UID1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t3', keyname='UID1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t4', keyname='UID1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='partidx', keyname='UID_WHERE', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition='where value > 10', uniqnulls='N') -(tablename='t1', keyname='VALUE', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='DUP_VALUE', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='partidx', keyname='UID', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='UID', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='UID1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t3', keyname='UID1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t4', keyname='UID1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='partidx', keyname='UID_WHERE', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition='where value > 10', uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='VALUE', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') [select * from comdb2_keys order by keyname, tablename] rc 0 (tablename='partidx', keyname='UID', columnnumber=0, columnname='uid', isdescending='N') (tablename='partidx', keyname='UID_WHERE', columnnumber=0, columnname='uid', isdescending='N') @@ -380,6 +380,7 @@ (name='comdb2_metrics') (name='comdb2_net_userfuncs') (name='comdb2_opcode_handlers') +(name='comdb2_partial_datacopies') (name='comdb2_plugins') (name='comdb2_procedures') (name='comdb2_queues') diff --git a/tests/ddl_no_csc2.test/t00_create_table.expected b/tests/ddl_no_csc2.test/t00_create_table.expected index 180c925bad..b1346c254c 100644 --- a/tests/ddl_no_csc2.test/t00_create_table.expected +++ b/tests/ddl_no_csc2.test/t00_create_table.expected @@ -103,13 +103,13 @@ (tablename='t9', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t10', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t10', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='$KEY_37A25A0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t6', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t6', keyname='$KEY_37496DB0', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t9', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t10', keyname='$KEY_FD8D4AAA', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='$KEY_37A25A0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t6', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t6', keyname='$KEY_37496DB0', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t9', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t10', keyname='$KEY_FD8D4AAA', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int);', csc2='schema { int i @@ -204,15 +204,15 @@ keys (tablename='t7', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t8', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t8', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t2', keyname='$KEY_9C18F596', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='$KEY_2E3CF7EF', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t4', keyname='$KEY_167DCD0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='$KEY_37A25A0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t6', keyname='$KEY_B9974512', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t7', keyname='$KEY_152B02D9', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t8', keyname='$KEY_4F831046', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t8', keyname='$KEY_762F1DF7', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t8', keyname='$KEY_9915B3B9', keynumber=2, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t2', keyname='$KEY_9C18F596', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='$KEY_2E3CF7EF', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t4', keyname='$KEY_167DCD0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='$KEY_37A25A0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t6', keyname='$KEY_B9974512', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t7', keyname='$KEY_152B02D9', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t8', keyname='$KEY_4F831046', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t8', keyname='$KEY_762F1DF7', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t8', keyname='$KEY_9915B3B9', keynumber=2, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (type='table', name='t2', tbl_name='t2', rootpage=4, sql='create table "t2"("i" int, "j" int);', csc2='schema { int i null = yes @@ -306,14 +306,14 @@ keys (tablename='t8', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t9', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t9', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t3', keyname='$KEY_37248BBB', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t6', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t7', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t8', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t9', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t9', keyname='$KEY_827A0A22', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t3', keyname='$KEY_37248BBB', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t6', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t7', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t8', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t9', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t9', keyname='$KEY_827A0A22', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t2', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t3', keyname='$KEY_37248BBB', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t6', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) @@ -569,11 +569,11 @@ constraints (tablename='t3', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t4', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t5', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t3', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t4', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t3', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t4', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t2', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t3', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='Y', iscascadingupdate='N', expr=NULL) (name='$CONSTRAINT_C6A17957', type='FOREIGN KEY', tablename='t4', keyname='COMDB2_PK', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='Y', iscascadingupdate='Y', expr=NULL) @@ -661,9 +661,9 @@ constraints (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t3', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t3', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t3', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t3', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int);', csc2='schema { int i @@ -736,21 +736,21 @@ keys (tablename='t6', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t7', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t7', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='T1_IJ', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='T1_JI', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='DUP1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='DUP2', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t3', keyname='$KEY_7BDB9F9', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t3', keyname='$KEY_B599BB80', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t4', keyname='UNIQ1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t4', keyname='UNIQ2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='$KEY_37A25A0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='$KEY_E8801C19', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='UNIQUE_KEY', keynumber=2, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t5', keyname='T5_IJ', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t5', keyname='DUP_KEY', keynumber=4, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t7', keyname='DUP', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t7', keyname='XXXX', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='T1_IJ', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='T1_JI', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='DUP1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='DUP2', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t3', keyname='$KEY_7BDB9F9', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t3', keyname='$KEY_B599BB80', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t4', keyname='UNIQ1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t4', keyname='UNIQ2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='$KEY_37A25A0B', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='$KEY_E8801C19', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='UNIQUE_KEY', keynumber=2, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t5', keyname='T5_IJ', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t5', keyname='DUP_KEY', keynumber=4, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t7', keyname='DUP', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t7', keyname='XXXX', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int);', csc2='schema { int i null = yes @@ -864,11 +864,11 @@ keys (tablename='t4', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t5', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t5', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t3', keyname='$KEY_DF179048', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t4', keyname='T4_I', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t5', keyname='T5_JI', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t3', keyname='$KEY_DF179048', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t4', keyname='T4_I', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t5', keyname='T5_JI', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int);', csc2='schema { int i @@ -925,7 +925,7 @@ keys [CREATE TABLE t1(unique INT UNIQUE)] failed with rc -3 near "unique": syntax error (part='---------------------------------- PART #49 ----------------------------------') (tablename='t1', columnname='unique', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='$KEY_A513E531', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='$KEY_A513E531', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("unique" int);', csc2='schema { int unique null = yes @@ -949,12 +949,12 @@ keys (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t4', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t4', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='T1_IJ1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='T1_IJ2', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='T1_IJ3', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='T1_IJ4', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='$KEY_A44A20B', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t4', keyname='$KEY_3EE419FC', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='T1_IJ1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='T1_IJ2', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='T1_IJ3', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='T1_IJ4', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='$KEY_A44A20B', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t4', keyname='$KEY_3EE419FC', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (name='$CONSTRAINT_8AAC02E5', type='FOREIGN KEY', tablename='t2', keyname='$KEY_A44A20B', foreigntablename='t1', foreignkeyname='T1_IJ1', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (name='$CONSTRAINT_95177019', type='FOREIGN KEY', tablename='t4', keyname='$KEY_3EE419FC', foreigntablename='t1', foreignkeyname='T1_IJ1', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int);', csc2='schema diff --git a/tests/ddl_no_csc2.test/t01_alter_table.expected b/tests/ddl_no_csc2.test/t01_alter_table.expected index bce455842b..ffabba7480 100644 --- a/tests/ddl_no_csc2.test/t01_alter_table.expected +++ b/tests/ddl_no_csc2.test/t01_alter_table.expected @@ -85,8 +85,8 @@ (tablename='t2', columnname='v', type='cstring', size=11, sqltype='char(10)', varinlinesize=NULL, defaultvalue=''foo'', dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='d', type='datetime', size=11, sqltype='datetime', varinlinesize=NULL, defaultvalue='CURRENT_TIMESTAMP', dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue='10', dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("v" char(10) DEFAULT 'foo', "d" datetime DEFAULT CURRENT_TIMESTAMP, "i" int DEFAULT 10);', csc2='schema { cstring v[11] dbstore = "foo" null = yes @@ -141,12 +141,12 @@ keys (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='k', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='IDX1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t1', keyname='IDX2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t1', keyname='IDX3', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='IDX4', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='COMDB2_PK', keynumber=4, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='IDX1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='IDX1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t1', keyname='IDX2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t1', keyname='IDX3', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='IDX4', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='COMDB2_PK', keynumber=4, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='IDX1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (name='$CONSTRAINT_95177019', type='FOREIGN KEY', tablename='t2', keyname='IDX1', foreigntablename='t1', foreignkeyname='IDX1', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int, "k" int);', csc2='schema { @@ -194,9 +194,9 @@ constraints (tablename='t2', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t3', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t3', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) -(tablename='t1', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t3', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='IDX', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t3', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (name='$CONSTRAINT_95177019', type='FOREIGN KEY', tablename='t2', keyname='IDX', foreigntablename='t1', foreignkeyname='IDX', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int);', csc2='schema { @@ -271,10 +271,10 @@ keys (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t2', columnname='k', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='IDX', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='$KEY_E8BDFAE1', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='IDX', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='$KEY_E8BDFAE1', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (name='$CONSTRAINT_6C9CE8ED', type='FOREIGN KEY', tablename='t2', keyname='$KEY_E8BDFAE1', foreigntablename='t1', foreignkeyname='COMDB2_PK', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int, "k" int);', csc2='schema { @@ -315,7 +315,7 @@ constraints (tablename='t1', columnname='k', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='k', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='N', lastsequence=NULL) -(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') +(tablename='t1', keyname='COMDB2_PK', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int, "k" int);', csc2='schema { int i @@ -376,9 +376,9 @@ constraints (tablename='t2', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t2', columnname='k', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='IDX1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t1', keyname='IDX2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t2', keyname='$KEY_E8BDFAE1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') +(tablename='t1', keyname='IDX1', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t1', keyname='IDX2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t2', keyname='$KEY_E8BDFAE1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') (name='$CONSTRAINT_6C9CE8ED', type='FOREIGN KEY', tablename='t2', keyname='$KEY_E8BDFAE1', foreigntablename='t1', foreignkeyname='IDX1', iscascadingdelete='N', iscascadingupdate='N', expr=NULL) (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int, "j" int, "k" int);', csc2='schema { diff --git a/tests/ddl_no_csc2.test/t02_create_index.expected b/tests/ddl_no_csc2.test/t02_create_index.expected index c7c793bc90..8ef9d6630a 100644 --- a/tests/ddl_no_csc2.test/t02_create_index.expected +++ b/tests/ddl_no_csc2.test/t02_create_index.expected @@ -17,18 +17,18 @@ (tablename='t3', columnname='j', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t4', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) (tablename='t5', columnname='i', type='int', size=5, sqltype='int', varinlinesize=NULL, defaultvalue=NULL, dbload=NULL, isnullable='Y', lastsequence=NULL) -(tablename='t1', keyname='IDX1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='IDX2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y') -(tablename='t1', keyname='IDX3', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='IDX4', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='IDX5', keynumber=4, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='IDX6', keynumber=5, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t1', keyname='IDX7', keynumber=6, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='IDX1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition='WHERE (j > 10) ', uniqnulls='N') -(tablename='t2', keyname='IDX3', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t2', keyname='IDX4', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t3', keyname='IDX1', keynumber=0, isunique='N', isdatacopy='Y', isrecnum='N', condition=NULL, uniqnulls='N') -(tablename='t3', keyname='IDX2', keynumber=1, isunique='N', isdatacopy='Y', isrecnum='N', condition='WHERE (j > 10) ', uniqnulls='N') +(tablename='t1', keyname='IDX1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='IDX2', keynumber=1, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='Y', ispartialdatacopy='N') +(tablename='t1', keyname='IDX3', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='IDX4', keynumber=3, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='IDX5', keynumber=4, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='IDX6', keynumber=5, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t1', keyname='IDX7', keynumber=6, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='IDX1', keynumber=0, isunique='N', isdatacopy='N', isrecnum='N', condition='WHERE (j > 10) ', uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='IDX3', keynumber=1, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t2', keyname='IDX4', keynumber=2, isunique='N', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t3', keyname='IDX1', keynumber=0, isunique='N', isdatacopy='Y', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='N') +(tablename='t3', keyname='IDX2', keynumber=1, isunique='N', isdatacopy='Y', isrecnum='N', condition='WHERE (j > 10) ', uniqnulls='N', ispartialdatacopy='N') (type='table', name='t1', tbl_name='t1', rootpage=4, sql='create table "t1"("i" int);', csc2='schema { int i null = yes diff --git a/tests/instant_sc.test/t08.req b/tests/instant_sc.test/t08.req index 892729b73e..b0aa6baa1e 100644 --- a/tests/instant_sc.test/t08.req +++ b/tests/instant_sc.test/t08.req @@ -17,5 +17,5 @@ tag "full" keys { "0" = j - datacopy "1" = i + datacopy(k) "1" = i } diff --git a/tests/instant_sc.test/t12.req b/tests/instant_sc.test/t12.req index a27073c452..15bfbff6ce 100644 --- a/tests/instant_sc.test/t12.req +++ b/tests/instant_sc.test/t12.req @@ -1,4 +1,4 @@ -//change dbstore only; old comdb2 will rebuild, new one will just increment version +//change dbstore only (and revert partial datacopy back to full datacopy); old comdb2 will rebuild, new one will just increment version schema { int k dbstore=9999 diff --git a/tests/partial_datacopy.test/Makefile b/tests/partial_datacopy.test/Makefile new file mode 100644 index 0000000000..2d39e80074 --- /dev/null +++ b/tests/partial_datacopy.test/Makefile @@ -0,0 +1,8 @@ +ifeq ($(TESTSROOTDIR),) + include ../testcase.mk +else + include $(TESTSROOTDIR)/testcase.mk +endif +ifeq ($(TEST_TIMEOUT),) + export TEST_TIMEOUT=3m +endif diff --git a/tests/partial_datacopy.test/runit b/tests/partial_datacopy.test/runit new file mode 100755 index 0000000000..6ed830baa2 --- /dev/null +++ b/tests/partial_datacopy.test/runit @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +bash -n "$0" | exit 1 + +${TESTSROOTDIR}/tools/compare_results.sh -s -d $1 -r sql +[ $? -eq 0 ] || exit 1 +exit 0 diff --git a/tests/partial_datacopy.test/t00.expected b/tests/partial_datacopy.test/t00.expected new file mode 100644 index 0000000000..9049234dc5 --- /dev/null +++ b/tests/partial_datacopy.test/t00.expected @@ -0,0 +1,33 @@ +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy datacopy(b, c) "a" = a + } +}] failed with rc 240 Error at line 8: CANNOT HAVE DATACOPY AND PARTIAL DATACOPY. +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) datacopy "a" = a + } +}] failed with rc 240 Error at line 8: CANNOT HAVE DATACOPY AND PARTIAL DATACOPY. +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) datacopy(d) "a" = a + } +}] failed with rc 240 Error at line 8: CANNOT HAVE MULTIPLE PARTIAL DATACOPIES. diff --git a/tests/partial_datacopy.test/t00.sql b/tests/partial_datacopy.test/t00.sql new file mode 100644 index 0000000000..f0bd5c50f4 --- /dev/null +++ b/tests/partial_datacopy.test/t00.sql @@ -0,0 +1,35 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy datacopy(b, c) "a" = a + } +};$$ + +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) datacopy "a" = a + } +};$$ + +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) datacopy(d) "a" = a + } +};$$ diff --git a/tests/partial_datacopy.test/t01.expected b/tests/partial_datacopy.test/t01.expected new file mode 100644 index 0000000000..764a32f0e3 --- /dev/null +++ b/tests/partial_datacopy.test/t01.expected @@ -0,0 +1,11 @@ +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy() "a" = a + } +}] failed with rc 240 ERROR at line 8: syntax error: ) diff --git a/tests/partial_datacopy.test/t01.sql b/tests/partial_datacopy.test/t01.sql new file mode 100644 index 0000000000..b812b115f1 --- /dev/null +++ b/tests/partial_datacopy.test/t01.sql @@ -0,0 +1,11 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy() "a" = a + } +};$$ diff --git a/tests/partial_datacopy.test/t02.expected b/tests/partial_datacopy.test/t02.expected new file mode 100644 index 0000000000..51a136f8ee --- /dev/null +++ b/tests/partial_datacopy.test/t02.expected @@ -0,0 +1,33 @@ +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(e) "a" = a + } +}] failed with rc 240 Error at line 8: SYMBOL NOT FOUND: e. +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, e, c) "a" = a + } +}] failed with rc 240 Error at line 8: SYMBOL NOT FOUND: e. +[create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, e, c, a, f, g) "a" = a + } +}] failed with rc 240 Error at line 8: SYMBOL NOT FOUND: e.Error at line 8: SYMBOL NOT FOUND: f.Error at line 8: SYMBOL NOT FOUND: g. diff --git a/tests/partial_datacopy.test/t02.sql b/tests/partial_datacopy.test/t02.sql new file mode 100644 index 0000000000..19037cf397 --- /dev/null +++ b/tests/partial_datacopy.test/t02.sql @@ -0,0 +1,35 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(e) "a" = a + } +};$$ + +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, e, c) "a" = a + } +};$$ + +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, e, c, a, f, g) "a" = a + } +};$$ diff --git a/tests/partial_datacopy.test/t03.expected b/tests/partial_datacopy.test/t03.expected new file mode 100644 index 0000000000..a919cf4ce0 --- /dev/null +++ b/tests/partial_datacopy.test/t03.expected @@ -0,0 +1,24 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='b') +(tablename='t', keyname='A', columnname='c') +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) diff --git a/tests/partial_datacopy.test/t03.sql b/tests/partial_datacopy.test/t03.sql new file mode 100644 index 0000000000..655a4fc5ff --- /dev/null +++ b/tests/partial_datacopy.test/t03.sql @@ -0,0 +1,20 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) "a" = a + } +};$$ + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t04.expected b/tests/partial_datacopy.test/t04.expected new file mode 100644 index 0000000000..685d9d81be --- /dev/null +++ b/tests/partial_datacopy.test/t04.expected @@ -0,0 +1,25 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='b') +(tablename='t', keyname='A', columnname='c') +(tablename='t', keyname='A', columnname='d') +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) diff --git a/tests/partial_datacopy.test/t04.sql b/tests/partial_datacopy.test/t04.sql new file mode 100644 index 0000000000..1c423860b5 --- /dev/null +++ b/tests/partial_datacopy.test/t04.sql @@ -0,0 +1,20 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, b, b, b, c, c, c, c, b, c, b, c, b, d) "a" = a + } +};$$ + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t05.expected b/tests/partial_datacopy.test/t05.expected new file mode 100644 index 0000000000..98aeda05da --- /dev/null +++ b/tests/partial_datacopy.test/t05.expected @@ -0,0 +1,39 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='a') +(tablename='t2', keyname='ABCD', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t2', keyname='ABCD', columnname='a') +(tablename='t2', keyname='ABCD', columnname='b') +(tablename='t2', keyname='ABCD', columnname='c') +(tablename='t2', keyname='ABCD', columnname='d') +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1) +(a=5) +(a=9) +(a=13) +(a=17) +(a=21) +(a=25) +(a=29) +(a=33) +(a=37) +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) diff --git a/tests/partial_datacopy.test/t05.sql b/tests/partial_datacopy.test/t05.sql new file mode 100644 index 0000000000..7b14c26525 --- /dev/null +++ b/tests/partial_datacopy.test/t05.sql @@ -0,0 +1,39 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(a) "a" = a + } +};$$ + +create table t2 { + schema { + int a + int b + int c + int d + } + keys { + datacopy(a, b, c, d) "abcd" = a + b + c + d + } +};$$ + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +select * from comdb2_keys where tablename='t2'; +select * from comdb2_partial_datacopies where tablename='t2'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a from t where a < 40; + +insert into t2 with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t2 where a < 40; + +drop table t; +drop table t2; diff --git a/tests/partial_datacopy.test/t06.expected b/tests/partial_datacopy.test/t06.expected new file mode 100644 index 0000000000..2bfd606567 --- /dev/null +++ b/tests/partial_datacopy.test/t06.expected @@ -0,0 +1,25 @@ +(tablename='t', keyname='AC', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='AC', columnname='a') +(tablename='t', keyname='AC', columnname='b') +(tablename='t', keyname='AC', columnname='c') +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) diff --git a/tests/partial_datacopy.test/t06.sql b/tests/partial_datacopy.test/t06.sql new file mode 100644 index 0000000000..3e9604b7ba --- /dev/null +++ b/tests/partial_datacopy.test/t06.sql @@ -0,0 +1,21 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(a, b, c) "ac" = a + c + } +};$$ + + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t07.expected b/tests/partial_datacopy.test/t07.expected new file mode 100644 index 0000000000..4385550178 --- /dev/null +++ b/tests/partial_datacopy.test/t07.expected @@ -0,0 +1,24 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='c') +(tablename='t', keyname='A', columnname='b') +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) diff --git a/tests/partial_datacopy.test/t07.sql b/tests/partial_datacopy.test/t07.sql new file mode 100644 index 0000000000..b4eb202002 --- /dev/null +++ b/tests/partial_datacopy.test/t07.sql @@ -0,0 +1,21 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(c, b) "a" = a + } +};$$ + + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t08.expected b/tests/partial_datacopy.test/t08.expected new file mode 100644 index 0000000000..d1e48ab03f --- /dev/null +++ b/tests/partial_datacopy.test/t08.expected @@ -0,0 +1,47 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='b') +(tablename='t', keyname='A', columnname='c') +(rows inserted=25) +(a=1, b='cdb2', c=3, d=4) +(a=5, b='cdb6', c=7, d=8) +(a=9, b='cdb10', c=11, d=12) +(a=13, b='cdb14', c=15, d=16) +(a=17, b='cdb18', c=19, d=20) +(a=21, b='cdb22', c=23, d=24) +(a=25, b='cdb26', c=27, d=28) +(a=29, b='cdb30', c=31, d=32) +(a=33, b='cdb34', c=35, d=36) +(a=37, b='cdb38', c=39, d=40) +(a=1, b='cdb2', c=3) +(a=5, b='cdb6', c=7) +(a=9, b='cdb10', c=11) +(a=13, b='cdb14', c=15) +(a=17, b='cdb18', c=19) +(a=21, b='cdb22', c=23) +(a=25, b='cdb26', c=27) +(a=29, b='cdb30', c=31) +(a=33, b='cdb34', c=35) +(a=37, b='cdb38', c=39) +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='b') +(tablename='t', keyname='A', columnname='c') +(a=1, b='cdb2', c=3, d=4) +(a=5, b='cdb6', c=7, d=8) +(a=9, b='cdb10', c=11, d=12) +(a=13, b='cdb14', c=15, d=16) +(a=17, b='cdb18', c=19, d=20) +(a=21, b='cdb22', c=23, d=24) +(a=25, b='cdb26', c=27, d=28) +(a=29, b='cdb30', c=31, d=32) +(a=33, b='cdb34', c=35, d=36) +(a=37, b='cdb38', c=39, d=40) +(a=1, b='cdb2', c=3) +(a=5, b='cdb6', c=7) +(a=9, b='cdb10', c=11) +(a=13, b='cdb14', c=15) +(a=17, b='cdb18', c=19) +(a=21, b='cdb22', c=23) +(a=25, b='cdb26', c=27) +(a=29, b='cdb30', c=31) +(a=33, b='cdb34', c=35) +(a=37, b='cdb38', c=39) diff --git a/tests/partial_datacopy.test/t08.sql b/tests/partial_datacopy.test/t08.sql new file mode 100644 index 0000000000..b0272da9e4 --- /dev/null +++ b/tests/partial_datacopy.test/t08.sql @@ -0,0 +1,39 @@ +create table t { + schema { + int a + vutf8 b[6] + int c + int d + } + keys { + datacopy(b, c) "a" = a + } +};$$ + + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, "cdb" || (n + 1), n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +alter table t { + schema { + int a + vutf8 b[4] + int c + int d + } + keys { + datacopy(b, c) "a" = a + } +};$$ + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t09.expected b/tests/partial_datacopy.test/t09.expected new file mode 100644 index 0000000000..0683c4430c --- /dev/null +++ b/tests/partial_datacopy.test/t09.expected @@ -0,0 +1,24 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='c') +(tablename='t', keyname='A', columnname='b') +(rows inserted=25) +(a=1, b='bbb2', c='ccc3', d=4) +(a=5, b='bbb6', c='ccc7', d=8) +(a=9, b='bbb10', c='ccc11', d=12) +(a=13, b='bbb14', c='ccc15', d=16) +(a=17, b='bbb18', c='ccc19', d=20) +(a=21, b='bbb22', c='ccc23', d=24) +(a=25, b='bbb26', c='ccc27', d=28) +(a=29, b='bbb30', c='ccc31', d=32) +(a=33, b='bbb34', c='ccc35', d=36) +(a=37, b='bbb38', c='ccc39', d=40) +(a=1, b='bbb2', c='ccc3') +(a=5, b='bbb6', c='ccc7') +(a=9, b='bbb10', c='ccc11') +(a=13, b='bbb14', c='ccc15') +(a=17, b='bbb18', c='ccc19') +(a=21, b='bbb22', c='ccc23') +(a=25, b='bbb26', c='ccc27') +(a=29, b='bbb30', c='ccc31') +(a=33, b='bbb34', c='ccc35') +(a=37, b='bbb38', c='ccc39') diff --git a/tests/partial_datacopy.test/t09.sql b/tests/partial_datacopy.test/t09.sql new file mode 100644 index 0000000000..231c298954 --- /dev/null +++ b/tests/partial_datacopy.test/t09.sql @@ -0,0 +1,21 @@ +create table t { + schema { + int a + vutf8 b[4] + vutf8 c[4] + int d + } + keys { + datacopy(c, b) "a" = a + } +};$$ + + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, "bbb" || (n + 1), "ccc" || (n + 2), n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t10.expected b/tests/partial_datacopy.test/t10.expected new file mode 100644 index 0000000000..f4fe04d0b3 --- /dev/null +++ b/tests/partial_datacopy.test/t10.expected @@ -0,0 +1,4 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='b') +(rows inserted=1) +[insert into t values (1,2,1)] failed with rc 299 add key constraint duplicate key 'A' on table 't' index 0 diff --git a/tests/partial_datacopy.test/t10.sql b/tests/partial_datacopy.test/t10.sql new file mode 100644 index 0000000000..6149d799db --- /dev/null +++ b/tests/partial_datacopy.test/t10.sql @@ -0,0 +1,19 @@ +create table t { + schema { + int a + int b + int c + } + keys { + datacopy(b) "a" = a + } +};$$ + + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t values (1,1,1); +insert into t values (1,2,1); + +drop table t; diff --git a/tests/partial_datacopy.test/t11.expected b/tests/partial_datacopy.test/t11.expected new file mode 100644 index 0000000000..6ba41cedb2 --- /dev/null +++ b/tests/partial_datacopy.test/t11.expected @@ -0,0 +1,25 @@ +(tablename='t', keyname='A', keynumber=0, isunique='Y', isdatacopy='N', isrecnum='N', condition=NULL, uniqnulls='N', ispartialdatacopy='Y') +(tablename='t', keyname='A', columnname='a') +(tablename='t', keyname='A', columnname='c') +(tablename='t', keyname='A', columnname='b') +(rows inserted=25) +(a=1, b='bbb2', c='ccc3', d=4) +(a=5, b='bbb6', c='ccc7', d=8) +(a=9, b='bbb10', c='ccc11', d=12) +(a=13, b='bbb14', c='ccc15', d=16) +(a=17, b='bbb18', c='ccc19', d=20) +(a=21, b='bbb22', c='ccc23', d=24) +(a=25, b='bbb26', c='ccc27', d=28) +(a=29, b='bbb30', c='ccc31', d=32) +(a=33, b='bbb34', c='ccc35', d=36) +(a=37, b='bbb38', c='ccc39', d=40) +(a=1, b='bbb2', c='ccc3') +(a=5, b='bbb6', c='ccc7') +(a=9, b='bbb10', c='ccc11') +(a=13, b='bbb14', c='ccc15') +(a=17, b='bbb18', c='ccc19') +(a=21, b='bbb22', c='ccc23') +(a=25, b='bbb26', c='ccc27') +(a=29, b='bbb30', c='ccc31') +(a=33, b='bbb34', c='ccc35') +(a=37, b='bbb38', c='ccc39') diff --git a/tests/partial_datacopy.test/t11.sql b/tests/partial_datacopy.test/t11.sql new file mode 100644 index 0000000000..c2e0ad679f --- /dev/null +++ b/tests/partial_datacopy.test/t11.sql @@ -0,0 +1,21 @@ +create table t { + schema { + int a + vutf8 b[4] + vutf8 c[4] + int d + } + keys { + datacopy(a, c, b) "a" = (int)"a + 1" + } +};$$ + + +select * from comdb2_keys where tablename='t'; +select * from comdb2_partial_datacopies where tablename='t'; + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, "bbb" || (n + 1), "ccc" || (n + 2), n + 3 from r; +select * from t where a + 1 < 40; +select a, b, c from t where a + 1 < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t12.expected b/tests/partial_datacopy.test/t12.expected new file mode 100644 index 0000000000..22b94396c5 --- /dev/null +++ b/tests/partial_datacopy.test/t12.expected @@ -0,0 +1,2 @@ +(rows inserted=25) +(out='Verify succeeded.') diff --git a/tests/partial_datacopy.test/t12.sql b/tests/partial_datacopy.test/t12.sql new file mode 100644 index 0000000000..a00541305c --- /dev/null +++ b/tests/partial_datacopy.test/t12.sql @@ -0,0 +1,16 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) "a" = a + } +};$$ + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +exec procedure sys.cmd.verify("t"); + +drop table t; diff --git a/tests/partial_datacopy.test/t13.expected b/tests/partial_datacopy.test/t13.expected new file mode 100644 index 0000000000..96e17bd1a1 --- /dev/null +++ b/tests/partial_datacopy.test/t13.expected @@ -0,0 +1,40 @@ +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) diff --git a/tests/partial_datacopy.test/t13.sql b/tests/partial_datacopy.test/t13.sql new file mode 100644 index 0000000000..fc68c421b0 --- /dev/null +++ b/tests/partial_datacopy.test/t13.sql @@ -0,0 +1,23 @@ +create table t { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) "a" = a + } +};$$ + +set transaction read committed; +begin; +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; +commit; + +select * from t where a < 40; +select a, b, c from t where a < 40; + +drop table t; diff --git a/tests/partial_datacopy.test/t14.expected b/tests/partial_datacopy.test/t14.expected new file mode 100644 index 0000000000..15d050fd91 --- /dev/null +++ b/tests/partial_datacopy.test/t14.expected @@ -0,0 +1,22 @@ +(rows inserted=25) +(a=1, b=2, c=3, d=4) +(a=5, b=6, c=7, d=8) +(a=9, b=10, c=11, d=12) +(a=13, b=14, c=15, d=16) +(a=17, b=18, c=19, d=20) +(a=21, b=22, c=23, d=24) +(a=25, b=26, c=27, d=28) +(a=29, b=30, c=31, d=32) +(a=33, b=34, c=35, d=36) +(a=37, b=38, c=39, d=40) +(a=1, b=2, c=3) +(a=5, b=6, c=7) +(a=9, b=10, c=11) +(a=13, b=14, c=15) +(a=17, b=18, c=19) +(a=21, b=22, c=23) +(a=25, b=26, c=27) +(a=29, b=30, c=31) +(a=33, b=34, c=35) +(a=37, b=38, c=39) +(out='Verify succeeded.') diff --git a/tests/partial_datacopy.test/t14.sql b/tests/partial_datacopy.test/t14.sql new file mode 100644 index 0000000000..8bd0a30a26 --- /dev/null +++ b/tests/partial_datacopy.test/t14.sql @@ -0,0 +1,19 @@ +create table t options odh off, rec none, blobfield none, ipu off, isc off { + schema { + int a + int b + int c + int d + } + keys { + datacopy(b, c) "a" = a + } +};$$ + +insert into t with recursive r(n) as (select 1 union all select n + 4 from r where n < 97) select n, n + 1, n + 2, n + 3 from r; +select * from t where a < 40; +select a, b, c from t where a < 40; + +exec procedure sys.cmd.verify("t"); + +drop table t; diff --git a/tests/sc_partial_datacopy.test/Makefile b/tests/sc_partial_datacopy.test/Makefile new file mode 100644 index 0000000000..4f1a0fb623 --- /dev/null +++ b/tests/sc_partial_datacopy.test/Makefile @@ -0,0 +1,8 @@ +ifeq ($(TESTSROOTDIR),) + include ../testcase.mk +else + include $(TESTSROOTDIR)/testcase.mk +endif +ifeq ($(TEST_TIMEOUT),) + export TEST_TIMEOUT=10m +endif diff --git a/tests/sc_partial_datacopy.test/logicalsc.testopts b/tests/sc_partial_datacopy.test/logicalsc.testopts new file mode 100644 index 0000000000..a0142013e6 --- /dev/null +++ b/tests/sc_partial_datacopy.test/logicalsc.testopts @@ -0,0 +1 @@ +on logical_live_sc diff --git a/tests/sc_partial_datacopy.test/lrl.options b/tests/sc_partial_datacopy.test/lrl.options new file mode 100644 index 0000000000..222a44dcc8 --- /dev/null +++ b/tests/sc_partial_datacopy.test/lrl.options @@ -0,0 +1,3 @@ +maxosqltransfer 500000 +logmsg level info +dont_forbid_ulonglong diff --git a/tests/sc_partial_datacopy.test/runit b/tests/sc_partial_datacopy.test/runit new file mode 100755 index 0000000000..536835abfb --- /dev/null +++ b/tests/sc_partial_datacopy.test/runit @@ -0,0 +1,144 @@ +#!/usr/bin/env bash + +maxt1=100000 + +wrpid=-1 + +# Grab my database name. +dbnm=$1 + +# Verify that the user at least supplied a dbname +if [[ -z "$dbnm" ]]; then + + echo "Testcase requires argument." + exit 1 + +fi + +function errquit +{ + typeset msg=$1 + + echo "ERROR: $msg" + echo "Testcase failed." + + [[ $wrpid != "-1" ]] && kill -9 $wrpid >/dev/null 2>&1 + + exit 1 +} + +function do_verify +{ + typeset cnt=0 + + cdb2sql ${CDB2_OPTIONS} $dbnm default "exec procedure sys.cmd.verify('t1')" &> verify.out + if ! grep succeeded verify.out > /dev/null ; then + errquit "Verify failed. see verify.out" + fi +} + +function update_t1 +{ + typeset id + typeset out + + id=$(( RANDOM % (maxt1) )) + cdb2sql ${CDB2_OPTIONS} $dbnm default "update t1 set time = `echo $(($(date +%s%N)/1000000))` where id = $id" >> update.log + if [[ $? != 0 ]]; then + errquit "update failed, see update.log" + fi +} + +function writer +{ + while true; do + update_t1 + sleep 0.02 + done +} + +cdb2sql ${CDB2_OPTIONS} $dbnm default - <<"EOF" +drop table if exists t1 +create table t1 { + tag ondisk { + longlong id + u_longlong time + } + keys { + datacopy(time) "ID" = id + } +}$$ +EOF + +cdb2sql ${CDB2_OPTIONS} $dbnm default "WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cnt LIMIT $maxt1) insert into t1(id, time) SELECT x, `echo $(($(date +%s%N)/1000000))` FROM cnt" +if [[ $? != 0 ]]; then + echo "initial insert failed" + exit 1 +fi + +# Trap to errquit if the user presses Ctrl-C +trap "errquit \"Cancelling test on INT EXIT\"" INT EXIT + +writer & +wrpid=$! +echo "Background writer pid: $wrpid" + +echo "Starting schemachange" +cdb2sql ${CDB2_OPTIONS} $dbnm default "PUT SCHEMACHANGE COMMITSLEEP 3" +cdb2sql ${CDB2_OPTIONS} $dbnm default "PUT SCHEMACHANGE CONVERTSLEEP 3" + +cdb2sql ${CDB2_OPTIONS} $dbnm default - <<"EOF" +alter table t1 { + tag ondisk { + longlong id + longlong time + } + keys { + datacopy(id, time) "ID" = id + } +}$$ +EOF +if [[ $? != 0 ]]; then + errquit "schemachange 1 failed" +fi +do_verify + +cdb2sql ${CDB2_OPTIONS} $dbnm default - <<"EOF" +alter table t1 { + tag ondisk { + longlong id + double time + } + keys { + datacopy(time) "ID" = id + } +}$$ +EOF +if [[ $? != 0 ]]; then + errquit "schemachange 2 failed" +fi +do_verify + +cdb2sql ${CDB2_OPTIONS} $dbnm default - <<"EOF" +alter table t1 { + tag ondisk { + longlong id + u_longlong time + } + keys { + datacopy(time) "ID" = (longlong)"id*1" + } +}$$ +EOF +if [[ $? != 0 ]]; then + errquit "schemachange 3 failed" +fi +do_verify + +# Remove trap-command. +trap - INT EXIT + +[[ $wrpid != "-1" ]] && kill -9 $wrpid >/dev/null 2>&1 + +echo "Testcase passed." +exit 0 diff --git a/tests/userschema.test/t00.expected b/tests/userschema.test/t00.expected index 084a062308..7759fb99ff 100644 --- a/tests/userschema.test/t00.expected +++ b/tests/userschema.test/t00.expected @@ -29,6 +29,7 @@ (tablename='comdb2_metrics', username='mohit', READ='Y', WRITE='Y', DDL='Y') (tablename='comdb2_net_userfuncs', username='mohit', READ='Y', WRITE='Y', DDL='Y') (tablename='comdb2_opcode_handlers', username='mohit', READ='Y', WRITE='Y', DDL='Y') +(tablename='comdb2_partial_datacopies', username='mohit', READ='Y', WRITE='Y', DDL='Y') (tablename='comdb2_plugins', username='mohit', READ='Y', WRITE='Y', DDL='Y') (tablename='comdb2_procedures', username='mohit', READ='Y', WRITE='Y', DDL='Y') (tablename='comdb2_queues', username='mohit', READ='Y', WRITE='Y', DDL='Y') diff --git a/tools/cdb2sql/cdb2sql.cpp b/tools/cdb2sql/cdb2sql.cpp index 379b7e9db6..6a953b0482 100644 --- a/tools/cdb2sql/cdb2sql.cpp +++ b/tools/cdb2sql/cdb2sql.cpp @@ -924,7 +924,7 @@ static int process_escape(const char *cmdstr) fprintf(out, "Keys:\n"); snprintf(sql, sizeof(sql), "select keyname, isunique, isdatacopy, isrecnum, " - "condition from comdb2_keys where tablename = '%s'", + "condition, ispartialdatacopy from comdb2_keys where tablename = '%s'", tok); rc = run_statement(sql, 0, NULL, &start_time_ms, &run_time_ms); if (rc != 0) {