Changeset: 4f3d242147a5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/4f3d242147a5 Modified Files: sql/storage/bat/bat_storage.c Branch: default Log Message:
Merged with Jan2022 diffs (truncated from 5609 to 300 lines): diff --git a/clients/Tests/MAL-signatures.stable.out b/clients/Tests/MAL-signatures.stable.out --- a/clients/Tests/MAL-signatures.stable.out +++ b/clients/Tests/MAL-signatures.stable.out @@ -6386,6 +6386,8 @@ [ "batsql", "ntile", "pattern batsql.ntile(X_0:bat[:any], X_1:any_1, X_2:any_2, X_3:any_3):bat[:any_1] ", "SQLntile;", "return the groups divided as equally as possible" ] [ "batsql", "ntile", "pattern batsql.ntile(X_0:bat[:any], X_1:bat[:any_1], X_2:any_2, X_3:any_3):bat[:any_1] ", "SQLntile;", "return the groups divided as equally as possible" ] [ "batsql", "password", "pattern batsql.password(X_0:bat[:str]):bat[:str] ", "db_password_wrap;", "Return password hash of user" ] +[ "batsql", "peak_next_value", "pattern batsql.peak_next_value(X_0:bat[:str], X_1:bat[:str]):bat[:lng] ", "mvc_peak_next_value_bulk;", "Peaks at the next value of the sequence" ] +[ "batsql", "peak_next_value", "pattern batsql.peak_next_value(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], X_3:bat[:oid]):bat[:lng] ", "mvc_peak_next_value_bulk;", "Peaks at the next value of the sequence" ] [ "batsql", "percent_rank", "pattern batsql.percent_rank(X_0:bat[:any_1], X_1:any_2, X_2:any_3):bat[:dbl] ", "SQLpercent_rank;", "return the percentage into the total number of groups for each row" ] [ "batsql", "prod", "pattern batsql.prod(X_0:bat[:bte], X_1:any, X_2:any, X_3:int, X_4:any, X_5:any):bat[:lng] ", "SQLprod;", "return the product of groups" ] [ "batsql", "prod", "pattern batsql.prod(X_0:bat[:dbl], X_1:any, X_2:any, X_3:int, X_4:any, X_5:any):bat[:dbl] ", "SQLprod;", "return the product of groups" ] diff --git a/clients/Tests/MAL-signatures.stable.out.int128 b/clients/Tests/MAL-signatures.stable.out.int128 --- a/clients/Tests/MAL-signatures.stable.out.int128 +++ b/clients/Tests/MAL-signatures.stable.out.int128 @@ -8927,6 +8927,8 @@ [ "batsql", "ntile", "pattern batsql.ntile(X_0:bat[:any], X_1:any_1, X_2:any_2, X_3:any_3):bat[:any_1] ", "SQLntile;", "return the groups divided as equally as possible" ] [ "batsql", "ntile", "pattern batsql.ntile(X_0:bat[:any], X_1:bat[:any_1], X_2:any_2, X_3:any_3):bat[:any_1] ", "SQLntile;", "return the groups divided as equally as possible" ] [ "batsql", "password", "pattern batsql.password(X_0:bat[:str]):bat[:str] ", "db_password_wrap;", "Return password hash of user" ] +[ "batsql", "peak_next_value", "pattern batsql.peak_next_value(X_0:bat[:str], X_1:bat[:str]):bat[:lng] ", "mvc_peak_next_value_bulk;", "Peaks at the next value of the sequence" ] +[ "batsql", "peak_next_value", "pattern batsql.peak_next_value(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], X_3:bat[:oid]):bat[:lng] ", "mvc_peak_next_value_bulk;", "Peaks at the next value of the sequence" ] [ "batsql", "percent_rank", "pattern batsql.percent_rank(X_0:bat[:any_1], X_1:any_2, X_2:any_3):bat[:dbl] ", "SQLpercent_rank;", "return the percentage into the total number of groups for each row" ] [ "batsql", "prod", "pattern batsql.prod(X_0:bat[:bte], X_1:any, X_2:any, X_3:int, X_4:any, X_5:any):bat[:hge] ", "SQLprod;", "return the product of groups" ] [ "batsql", "prod", "pattern batsql.prod(X_0:bat[:bte], X_1:any, X_2:any, X_3:int, X_4:any, X_5:any):bat[:lng] ", "SQLprod;", "return the product of groups" ] diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -985,6 +985,100 @@ mvc_peak_next_value(Client cntxt, MalBlk throw(SQL, "sql.peak_next_value", SQLSTATE(HY050) "Cannot peak at next sequence value %s.%s", sname, seqname); } +/* needed for msqldump and describe_sequences view */ +static str +mvc_peak_next_value_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + mvc *m = NULL; + sql_schema *s; + sql_sequence *seq; + BATiter schi, seqi; + BAT *bn = NULL, *scheb = NULL, *sches = NULL, *seqb = NULL, *seqs = NULL; + BUN q = 0; + lng *restrict vals; + str msg = MAL_SUCCEED; + bool nils = false; + struct canditer ci1 = {0}, ci2 = {0}; + oid off1, off2; + bat *res = getArgReference_bat(stk, pci, 0), *l = getArgReference_bat(stk, pci, 1), *r = getArgReference_bat(stk, pci, 2), + *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL, *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL; + + if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL) + return msg; + if ((msg = checkSQLContext(cntxt)) != NULL) + return msg; + if (!(scheb = BATdescriptor(*l)) || !(seqb = BATdescriptor(*r))) { + msg = createException(SQL, "sql.peak_next_value", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + goto bailout; + } + if ((sid1 && !is_bat_nil(*sid1) && !(sches = BATdescriptor(*sid1))) || (sid2 && !is_bat_nil(*sid2) && !(seqs = BATdescriptor(*sid2)))) { + msg = createException(SQL, "sql.peak_next_value", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + goto bailout; + } + q = canditer_init(&ci1, scheb, sches); + if (canditer_init(&ci2, seqb, seqs) != q || ci1.hseq != ci2.hseq) { + msg = createException(SQL, "sql.peak_next_value", ILLEGAL_ARGUMENT " Requires bats of identical size"); + goto bailout; + } + if (!(bn = COLnew(ci1.hseq, TYPE_lng, q, TRANSIENT))) { + msg = createException(SQL, "sql.peak_next_value", SQLSTATE(HY013) MAL_MALLOC_FAIL); + goto bailout; + } + + off1 = scheb->hseqbase; + off2 = seqb->hseqbase; + schi = bat_iterator(scheb); + seqi = bat_iterator(seqb); + vals = Tloc(bn, 0); + for (BUN i = 0; i < q; i++) { + oid p1 = canditer_next(&ci1) - off1, p2 = canditer_next(&ci2) - off2; + const char *sname = (str) BUNtvar(schi, p1); + const char *seqname = (str) BUNtvar(seqi, p2); + + if (strNil(sname) || strNil(seqname)) { + vals[i] = lng_nil; + nils = true; + } else { + if (!(s = mvc_bind_schema(m, sname))) { + msg = createException(SQL, "sql.peak_next_value", SQLSTATE(3F000) "Cannot find the schema %s", sname); + goto bailout1; + } + if (!(seq = find_sql_sequence(m->session->tr, s, seqname))) { + msg = createException(SQL, "sql.peak_next_value", SQLSTATE(HY050) "Cannot find the sequence %s.%s", sname, seqname); + goto bailout1; + } + if (!seq_peak_next_value(m->session->tr->store, seq, &(vals[i]))) { + msg = createException(SQL, "sql.peak_next_value", SQLSTATE(HY050) "Cannot peak at next sequence value %s.%s", sname, seqname); + goto bailout1; + } + } + } + +bailout1: + bat_iterator_end(&schi); + bat_iterator_end(&seqi); +bailout: + if (scheb) + BBPunfix(scheb->batCacheid); + if (sches) + BBPunfix(sches->batCacheid); + if (seqb) + BBPunfix(seqb->batCacheid); + if (seqs) + BBPunfix(seqs->batCacheid); + if (bn && !msg) { + BATsetcount(bn, q); + bn->tnil = nils; + bn->tnonil = !nils; + bn->tkey = BATcount(bn) <= 1; + bn->tsorted = BATcount(bn) <= 1; + bn->trevsorted = BATcount(bn) <= 1; + BBPkeepref(*res = bn->batCacheid); + } else if (bn) + BBPreclaim(bn); + return msg; +} + str mvc_getVersion(lng *version, const int *clientid) { @@ -4787,35 +4881,18 @@ finalize: } static str -do_str_column_vacuum(sql_trans *tr, sql_column *c, int access, char *sname, char *tname, char *cname) { +do_str_column_vacuum(sql_trans *tr, sql_column *c, char *sname, char *tname, char *cname) +{ int res; - BAT* b = NULL; - BAT* bn = NULL; sqlstore *store = tr->store; - if ((b = store->storage_api.bind_col(tr, c, access)) == NULL) - throw(SQL, "do_str_column_vacuum", SQLSTATE(42S22) "storage_api.bind_col failed for %s.%s.%s", sname, tname, cname); - // vacuum only string bats - if (ATOMstorage(b->ttype) == TYPE_str) { - // TODO check for num of updates on the BAT against some threshold - // and decide whether to proceed - if ((bn = COLcopy(b, b->ttype, true, b->batRole)) == NULL) { - BBPunfix(b->batCacheid); - throw(SQL, "do_str_column_vacuum", SQLSTATE(42S22) "COLcopy failed for %s.%s.%s", sname, tname, cname); - } - if ((res = (int) store->storage_api.swap_bats(tr, c, bn)) != LOG_OK) { - BBPreclaim(bn); - BBPunfix(b->batCacheid); - if (res == LOG_CONFLICT) - throw(SQL, "do_str_column_vacuum", SQLSTATE(25S01) "TRANSACTION CONFLICT in storage_api.swap_bats %s.%s.%s", sname, tname, cname); - if (res == LOG_ERR) - throw(SQL, "do_str_column_vacuum", SQLSTATE(HY000) "LOG ERROR in storage_api.swap_bats %s.%s.%s", sname, tname, cname); - throw(SQL, "do_str_column_vacuum", SQLSTATE(HY000) "ERROR in storage_api.swap_bats %s.%s.%s", sname, tname, cname); - } - } - BBPunfix(b->batCacheid); - if (bn) - BBPunfix(bn->batCacheid); + if ((res = store->storage_api.swap_bats(tr, c)) != LOG_OK) { + if (res == LOG_CONFLICT) + throw(SQL, "do_str_column_vacuum", SQLSTATE(25S01) "TRANSACTION CONFLICT in storage_api.swap_bats %s.%s.%s", sname, tname, cname); + if (res == LOG_ERR) + throw(SQL, "do_str_column_vacuum", SQLSTATE(HY000) "LOG ERROR in storage_api.swap_bats %s.%s.%s", sname, tname, cname); + throw(SQL, "do_str_column_vacuum", SQLSTATE(HY000) "ERROR in storage_api.swap_bats %s.%s.%s", sname, tname, cname); + } return MAL_SUCCEED; } @@ -4824,7 +4901,6 @@ SQLstr_column_vacuum(Client cntxt, MalBl { mvc *m = NULL; str msg = NULL; - int access = 0; char *sname = *getArgReference_str(stk, pci, 1); char *tname = *getArgReference_str(stk, pci, 2); char *cname = *getArgReference_str(stk, pci, 3); @@ -4855,7 +4931,7 @@ SQLstr_column_vacuum(Client cntxt, MalBl if ((c = mvc_bind_column(m, t, cname)) == NULL) throw(SQL, "sql.str_column_vacuum", SQLSTATE(42S22) "Column not found %s.%s",sname,tname); - return do_str_column_vacuum(tr, c, access, sname, tname, cname); + return do_str_column_vacuum(tr, c, sname, tname, cname); } @@ -4870,7 +4946,6 @@ str_column_vacuum_callback(int argc, voi sql_schema *s = NULL; sql_table *t = NULL; sql_column *c = NULL; - int access = 0; char *msg; gdk_return res = GDK_SUCCEED; @@ -4913,7 +4988,7 @@ str_column_vacuum_callback(int argc, voi break; } - if((msg=do_str_column_vacuum(session->tr, c, access, sname, tname, cname)) != MAL_SUCCEED) { + if((msg=do_str_column_vacuum(session->tr, c, sname, tname, cname)) != MAL_SUCCEED) { TRC_ERROR((component_t) SQL, "[str_column_vacuum_callback] -- %s", msg); res = GDK_FAIL; } @@ -5075,6 +5150,8 @@ static mel_func sql_init_funcs[] = { pattern("batsql", "next_value", mvc_next_value_bulk, true, "return the next value of the sequence", args(1,4, batarg("",lng),arg("card",lng), arg("sname",str),arg("sequence",str))), pattern("sql", "get_value", mvc_get_value, false, "return the current value of the sequence", args(1,3, arg("",lng),arg("sname",str),arg("sequence",str))), pattern("sql", "peak_next_value", mvc_peak_next_value, false, "Peaks at the next value of the sequence", args(1,3, arg("",lng),arg("sname",str),arg("sequence",str))), + pattern("batsql", "peak_next_value", mvc_peak_next_value_bulk, false, "Peaks at the next value of the sequence", args(1,3, batarg("",lng),batarg("sname",str),batarg("sequence",str))), + pattern("batsql", "peak_next_value", mvc_peak_next_value_bulk, false, "Peaks at the next value of the sequence", args(1,5, batarg("",lng),batarg("sname",str),batarg("sequence",str),batarg("s1",oid),batarg("s2",oid))), pattern("sql", "restart", mvc_restart_seq, true, "restart the sequence with value start", args(1,4, arg("",lng),arg("sname",str),arg("sequence",str),arg("start",lng))), pattern("sql", "deltas", mvc_delta_values, false, "Return the delta values sizes of all columns of the schema's tables, plus the current transaction level", args(7,8, batarg("ids",int),batarg("segments",lng),batarg("all",lng),batarg("inserted",lng),batarg("updated",lng),batarg("deleted",lng),batarg("tr_level",int),arg("schema",str))), pattern("sql", "deltas", mvc_delta_values, false, "Return the delta values sizes from the table's columns, plus the current transaction level", args(7,9, batarg("ids",int),batarg("segments",lng),batarg("all",lng),batarg("inserted",lng),batarg("updated",lng),batarg("deleted",lng),batarg("tr_level",int),arg("schema",str),arg("table",str))), diff --git a/sql/backends/monet5/sql_transaction.c b/sql/backends/monet5/sql_transaction.c --- a/sql/backends/monet5/sql_transaction.c +++ b/sql/backends/monet5/sql_transaction.c @@ -105,9 +105,6 @@ SQLtransaction_begin(Client cntxt, MalBl throw(SQL, "sql.trans", SQLSTATE(25001) "START TRANSACTION: cannot start a transaction within a transaction"); if (sql->session->tr->active) msg = mvc_rollback(sql, 0, NULL, false); - sql->session->auto_commit = 0; - sql->session->ac_on_commit = 1; - sql->session->level = chain; if (msg) return msg; switch (mvc_trans(sql)) { @@ -118,5 +115,9 @@ SQLtransaction_begin(Client cntxt, MalBl default: break; } + /* set transaction properties after successfuly starting */ + sql->session->auto_commit = 0; + sql->session->ac_on_commit = 1; + sql->session->level = chain; return MAL_SUCCEED; } diff --git a/sql/backends/monet5/sql_upgrades.c b/sql/backends/monet5/sql_upgrades.c --- a/sql/backends/monet5/sql_upgrades.c +++ b/sql/backends/monet5/sql_upgrades.c @@ -2954,16 +2954,8 @@ sql_update_jul2021(Client c, mvc *sql, c " 'CREATE SEQUENCE ' || sys.FQN(sch, seq) || ' AS BIGINT ' ||\n" " CASE WHEN \"s\" <> 0 THEN 'START WITH ' || \"rs\" ELSE '' END ||\n" " CASE WHEN \"inc\" <> 1 THEN ' INCREMENT BY ' || \"inc\" ELSE '' END ||\n" - " CASE\n" - " WHEN nomin THEN ' NO MINVALUE'\n" - " WHEN rmi IS NOT NULL THEN ' MINVALUE ' || rmi\n" - " ELSE ''\n" - " END ||\n" - " CASE\n" - " WHEN nomax THEN ' NO MAXVALUE'\n" - " WHEN rma IS NOT NULL THEN ' MAXVALUE ' || rma\n" - " ELSE ''\n" - " END ||\n" + " CASE WHEN \"mi\" <> 0 THEN ' MINVALUE ' || \"mi\" ELSE '' END ||\n" + " CASE WHEN \"ma\" <> 0 THEN ' MAXVALUE ' || \"ma\" ELSE '' END ||\n" " CASE WHEN \"cache\" <> 1 THEN ' CACHE ' || \"cache\" ELSE '' END ||\n" " CASE WHEN \"cycle\" THEN ' CYCLE' ELSE '' END || ';' stmt\n" " FROM sys.describe_sequences;\n" @@ -3537,6 +3529,7 @@ sql_update_jan2022(Client c, mvc *sql, c "drop view sys.describe_privileges;\n" "drop view sys.describe_comments;\n" "drop view sys.describe_tables;\n" + "drop view sys.describe_sequences;\n" "drop function sys.schema_guard(string, string, string);\n" "drop function sys.get_remote_table_expressions(string, string);\n" "drop function sys.get_merge_table_partition_expressions(int);\n" @@ -3774,6 +3767,41 @@ sql_update_jan2022(Client c, mvc *sql, c " JOIN sys.function_types ft ON f.type = ft.function_type_id\n" " LEFT OUTER JOIN sys.function_languages fl ON f.language = fl.language_id\n" " WHERE s.name <> 'tmp' AND NOT f.system;\n" + "CREATE VIEW sys.describe_sequences AS\n" + " SELECT\n" + " s.name sch,\n" + " seq.name seq,\n" + " seq.\"start\" s,\n" + " peak_next_value_for(s.name, seq.name) rs,\n" + " CASE WHEN seq.\"minvalue\" = -9223372036854775807 AND seq.\"increment\" > 0 AND seq.\"start\" = 1 THEN TRUE ELSE FALSE END nomin,\n" + " CASE WHEN seq.\"maxvalue\" = 9223372036854775807 AND seq.\"increment\" < 0 AND seq.\"start\" = -1 THEN TRUE ELSE FALSE END nomax,\n" + " CASE\n" + " WHEN seq.\"minvalue\" = 0 AND seq.\"increment\" > 0 THEN NULL\n" + " WHEN seq.\"minvalue\" <> -9223372036854775807 THEN seq.\"minvalue\"\n" + " ELSE\n" + " CASE\n" + " WHEN seq.\"increment\" < 0 THEN NULL\n" + " ELSE CASE WHEN seq.\"start\" = 1 THEN NULL ELSE seq.\"maxvalue\" END\n" + " END\n" + " END rmi,\n" + " CASE\n" + " WHEN seq.\"maxvalue\" = 0 AND seq.\"increment\" < 0 THEN NULL\n" + " WHEN seq.\"maxvalue\" <> 9223372036854775807 THEN seq.\"maxvalue\"\n" + " ELSE\n" + " CASE\n" + " WHEN seq.\"increment\" > 0 THEN NULL\n" + " ELSE CASE WHEN seq.\"start\" = -1 THEN NULL ELSE seq.\"maxvalue\" END\n" + " END\n" + " END rma,\n" + " seq.\"minvalue\" mi,\n" _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list