摘要:
2023-11-07 monetdb-事务-核心流程分析
核心流程:
sql_trans_begin
#0 sql_trans_begin (s=0x7f818c0018e0) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/store.c:7151
#1 0x00007f821f159309 in mvc_trans (m=0x7f818c0394a0) at /root/work/monetdb-dev/trunk/monetdb/sql/server/sql_mvc.c:482
#2 0x00007f821f00efab in SQLtransaction_begin (cntxt=0x1a51290, mb=0x7f818c003470, stk=0x7f818c0362f0, pci=0x7f818c004ed0)
at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_transaction.c:112
#3 0x00007f82327ab007 in runMALsequence (cntxt=0x1a51290, mb=0x7f818c003470, startpc=1, stoppc=0, stk=0x7f818c0362f0, env=0x0, pcicaller=0x0)
at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:688
#4 0x00007f82327a977e in runMAL (cntxt=0x1a51290, mb=0x7f818c003470, mbcaller=0x0, env=0x0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:357
#5 0x00007f821efce5eb in SQLrun (c=0x1a51290, m=0x7f818c0394a0) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:259
#6 0x00007f821efcfee7 in SQLengineIntern (c=0x1a51290, be=0x7f818c034d20) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:709
#7 0x00007f821efcd4b5 in SQLengine (c=0x1a51290) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:1358
#8 0x00007f82327ca862 in runPhase (c=0x1a51290, phase=4) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#9 0x00007f82327ca9cc in runScenarioBody (c=0x1a51290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:479
#10 0x00007f82327cabd8 in runScenario (c=0x1a51290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#11 0x00007f82327ccfea in MSserveClient (c=0x1a51290) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#12 0x00007f82327cc863 in MSscheduleClient (command=0x7f818c005e00 "", challenge=0x7f821936ace3 "bWwPy3DTsm", fin=0x7f818c002f10, fout=0x7f8188003e20, protocol=PROTOCOL_9, blocksize=8190)
at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#13 0x00007f82328921d4 in doChallenge (data=0x7f8188000b70) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#14 0x00007f8232144729 in THRstarter (a=0x7f8188006310) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#15 0x00007f82321c1b23 in thread_starter (arg=0x7f8188006380) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#16 0x00007f82317021ca in start_thread () from /lib64/libpthread.so.0
#17 0x00007f823136ee73 in clone () from /lib64/libc.so.6
/* set transaction properties after successfuly starting */
sql->session->auto_commit = 0;
sql->session->ac_on_commit = 1;
char ac_on_commit; /* if 1, auto_commit should be enabled on
commit, rollback, etc. */
char auto_commit;
trans_add
#0 trans_add (tr=0x7f9fbc001c40, b=0x1952aa60, data=0x1952b170, cleanup=0x7fa055d18d52 <tc_gc_del>, commit=0x7fa055d1834a <commit_update_del>, log=0x7fa055d18238 <log_update_del>)
at /root/work/monetdb-dev/trunk/monetdb/sql/storage/sql_catalog.c:56
#1 0x00007fa055d19a8e in claim_segments (tr=0x7f9fbc001c40, t=0x1952aa60, s=0x1952b170, cnt=1, offset=0x7f9fbc03ae50, offsets=0x7f9ff7dfd2b8, locked=false)
at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:4712
#2 0x00007fa055d19bc4 in claim_tab (tr=0x7f9fbc001c40, t=0x1952aa60, cnt=1, offset=0x7f9fbc03ae50, offsets=0x7f9ff7dfd2b8)
at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:4741
#3 0x00007fa055b8f4e7 in mvc_claim_slots (tr=0x7f9fbc001c40, t=0x1952aa60, cnt=1, offset=0x7f9fbc03ae50, pos=0x7f9ff7dfd2b8)
at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql.c:505
#4 0x00007fa055b8f95d in mvc_claim_wrap (cntxt=0x13b4290, mb=0x7f9fbc044e40, stk=0x7f9fbc03acc0, pci=0x7f9fbc001d60) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql.c:536
#5 0x00007fa069395007 in runMALsequence (cntxt=0x13b4290, mb=0x7f9fbc044e40, startpc=1, stoppc=0, stk=0x7f9fbc03acc0, env=0x0, pcicaller=0x0)
at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:688
#6 0x00007fa06939377e in runMAL (cntxt=0x13b4290, mb=0x7f9fbc044e40, mbcaller=0x0, env=0x0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:357
#7 0x00007fa055bb85eb in SQLrun (c=0x13b4290, m=0x7f9fbc145090) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:259
#8 0x00007fa055bb9ee7 in SQLengineIntern (c=0x13b4290, be=0x7f9fbc02cc70) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:709
#9 0x00007fa055bb74b5 in SQLengine (c=0x13b4290) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:1358
#10 0x00007fa0693b4862 in runPhase (c=0x13b4290, phase=4) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#11 0x00007fa0693b49cc in runScenarioBody (c=0x13b4290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:479
#12 0x00007fa0693b4bd8 in runScenario (c=0x13b4290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#13 0x00007fa0693b6fea in MSserveClient (c=0x13b4290) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#14 0x00007fa0693b6863 in MSscheduleClient (command=0x7f9fbc0400c0 '\333' <repeats 199 times>, <incomplete sequence \333>..., challenge=0x7f9ff7dfdce3 "OpIo5EFLCRg", fin=0x7f9fbc045090,
fout=0x7f9fc4003e20, protocol=PROTOCOL_9, blocksize=8190) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#15 0x00007fa06947c1d4 in doChallenge (data=0x7f9fc4000b70) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#16 0x00007fa068d2e729 in THRstarter (a=0x7f9fc4006310) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#17 0x00007fa068dabb23 in thread_starter (arg=0x7f9fc4006380) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#18 0x00007fa0682ec1ca in start_thread () from /lib64/libpthread.so.0
#19 0x00007fa067f58e73 in clone () from /lib64/libc.so.6
BUNappendmulti
#0 BUNappendmulti (b=0x1a24ec0, values=0x7f818c0d6510, count=1, force=true) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_bat.c:1028
#1 0x00007f821f125386 in delta_append_val (tr=0x7f818c001940, batp=0x7f821936a1e8, id=7590, offset=9, i=0x7f818c0d6510, cnt=1, storage_type=0x0, tt=6)
at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:2319
#2 0x00007f821f125638 in append_col_execute (tr=0x7f818c001940, delta=0x7f821936a1e8, id=7590, offset=9, offsets=0x0, incoming_data=0x7f818c0d6510, cnt=1, tt=6, storage_type=0x0)
at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:2354
#3 0x00007f821f125919 in append_col (tr=0x7f818c001940, c=0x19b80c00, offset=9, offsets=0x0, data=0x7f818c0d6510, cnt=1, tpe=6)
at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:2384
#4 0x00007f821efad9ec in mvc_append_wrap (cntxt=0x1a51290, mb=0x7f818c003470, stk=0x7f818c0d63e0, pci=0x7f818c035500) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql.c:1842
#5 0x00007f82327ab007 in runMALsequence (cntxt=0x1a51290, mb=0x7f818c003470, startpc=1, stoppc=0, stk=0x7f818c0d63e0, env=0x0, pcicaller=0x0)
at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:688
#6 0x00007f82327a977e in runMAL (cntxt=0x1a51290, mb=0x7f818c003470, mbcaller=0x0, env=0x0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:357
#7 0x00007f821efce5eb in SQLrun (c=0x1a51290, m=0x7f818c0394a0) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:259
#8 0x00007f821efcfee7 in SQLengineIntern (c=0x1a51290, be=0x7f818c034d20) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:709
#9 0x00007f821efcd4b5 in SQLengine (c=0x1a51290) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:1358
#10 0x00007f82327ca862 in runPhase (c=0x1a51290, phase=4) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#11 0x00007f82327ca9cc in runScenarioBody (c=0x1a51290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:479
#12 0x00007f82327cabd8 in runScenario (c=0x1a51290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#13 0x00007f82327ccfea in MSserveClient (c=0x1a51290) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#14 0x00007f82327cc863 in MSscheduleClient (command=0x7f818c005e00 "", challenge=0x7f821936ace3 "bWwPy3DTsm", fin=0x7f818c002f10, fout=0x7f8188003e20, protocol=PROTOCOL_9, blocksize=8190)
at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#15 0x00007f82328921d4 in doChallenge (data=0x7f8188000b70) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#16 0x00007f8232144729 in THRstarter (a=0x7f8188006310) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#17 0x00007f82321c1b23 in thread_starter (arg=0x7f8188006380) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#18 0x00007f82317021ca in start_thread () from /lib64/libpthread.so.0
#19 0x00007f823136ee73 in clone () from /lib64/libc.so.6
mvc_commit
#0 mvc_commit (m=0x7f9fbc145090, chain=0, name=0x0, enabling_auto_commit=false) at /root/work/monetdb-dev/trunk/monetdb/sql/server/sql_mvc.c:500
#1 0x00007fa055bb4594 in SQLautocommit (m=0x7f9fbc145090) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:624
#2 0x00007fa055bb5083 in SQLreader (c=0x13b4290) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:861
#3 0x00007fa0693b4862 in runPhase (c=0x13b4290, phase=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#4 0x00007fa0693b4902 in runScenarioBody (c=0x13b4290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:471
#5 0x00007fa0693b4bd8 in runScenario (c=0x13b4290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#6 0x00007fa0693b6fea in MSserveClient (c=0x13b4290) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#7 0x00007fa0693b6863 in MSscheduleClient (command=0x7f9fbc0400c0 '\333' <repeats 199 times>, <incomplete sequence \333>..., challenge=0x7f9ff7dfdce3 "OpIo5EFLCRg", fin=0x7f9fbc045090,
fout=0x7f9fc4003e20, protocol=PROTOCOL_9, blocksize=8190) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#8 0x00007fa06947c1d4 in doChallenge (data=0x7f9fc4000b70) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#9 0x00007fa068d2e729 in THRstarter (a=0x7f9fc4006310) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#10 0x00007fa068dabb23 in thread_starter (arg=0x7f9fc4006380) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#11 0x00007fa0682ec1ca in start_thread () from /lib64/libpthread.so.0
#12 0x00007fa067f58e73 in clone () from /lib64/libc.so.6
sql_trans_commit
#0 sql_trans_commit (tr=0x7f9fbc001c40) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/store.c:3975
#1 0x00007fa055ce3412 in sql_trans_end (s=0x7f9fbc001be0, ok=1) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/store.c:7175
#2 0x00007fa055d43909 in mvc_commit (m=0x7f9fbc145090, chain=0, name=0x0, enabling_auto_commit=false) at /root/work/monetdb-dev/trunk/monetdb/sql/server/sql_mvc.c:548
#3 0x00007fa055bb4594 in SQLautocommit (m=0x7f9fbc145090) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:624
#4 0x00007fa055bb5083 in SQLreader (c=0x13b4290) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:861
#5 0x00007fa0693b4862 in runPhase (c=0x13b4290, phase=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#6 0x00007fa0693b4902 in runScenarioBody (c=0x13b4290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:471
#7 0x00007fa0693b4bd8 in runScenario (c=0x13b4290, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#8 0x00007fa0693b6fea in MSserveClient (c=0x13b4290) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#9 0x00007fa0693b6863 in MSscheduleClient (command=0x7f9fbc0400c0 '\333' <repeats 199 times>, <incomplete sequence \333>..., challenge=0x7f9ff7dfdce3 "OpIo5EFLCRg", fin=0x7f9fbc045090,
fout=0x7f9fc4003e20, protocol=PROTOCOL_9, blocksize=8190) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#10 0x00007fa06947c1d4 in doChallenge (data=0x7f9fc4000b70) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#11 0x00007fa068d2e729 in THRstarter (a=0x7f9fc4006310) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#12 0x00007fa068dabb23 in thread_starter (arg=0x7f9fc4006380) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#13 0x00007fa0682ec1ca in start_thread () from /lib64/libpthread.so.0
#14 0x00007fa067f58e73 in clone () from /lib64/libc.so.6
count_col
#0 segs_end (segs=0x1952b230, tr=0x7f9fb0104450, table=0x1952aa60) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:442
#1 0x00007fa055d07ad1 in count_col (tr=0x7f9fb0104450, c=0x1952b2d0, access=10) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:773
#2 0x00007fa055c85186 in SQLbasecount (cntxt=0x13b4580, mb=0x7f9fb0135570, stk=0x7f9fb01395e0, pci=0x7f9fb01384c0) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_rank.c:1289
#3 0x00007fa069395007 in runMALsequence (cntxt=0x13b4580, mb=0x7f9fb0135570, startpc=1, stoppc=0, stk=0x7f9fb01395e0, env=0x0, pcicaller=0x0)
at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:688
#4 0x00007fa06939377e in runMAL (cntxt=0x13b4580, mb=0x7f9fb0135570, mbcaller=0x0, env=0x0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:357
#5 0x00007fa055bb85eb in SQLrun (c=0x13b4580, m=0x7f9fb01167e0) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:259
#6 0x00007fa055bb9ee7 in SQLengineIntern (c=0x13b4580, be=0x7f9fb0136060) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:709
#7 0x00007fa055bb74b5 in SQLengine (c=0x13b4580) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:1358
#8 0x00007fa0693b4862 in runPhase (c=0x13b4580, phase=4) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#9 0x00007fa0693b49cc in runScenarioBody (c=0x13b4580, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:479
#10 0x00007fa0693b4bd8 in runScenario (c=0x13b4580, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#11 0x00007fa0693b6fea in MSserveClient (c=0x13b4580) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#12 0x00007fa0693b6863 in MSscheduleClient (command=0x7f9fb0000b70 '\333' <repeats 199 times>, <incomplete sequence \333>..., challenge=0x7f9ff7bfcce3 "gWPRtbcO", fin=0x7f9fb0002b90,
fout=0x7f9fc4009630, protocol=PROTOCOL_9, blocksize=8190) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#13 0x00007fa06947c1d4 in doChallenge (data=0x7f9fc4006790) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#14 0x00007fa068d2e729 in THRstarter (a=0x7f9fc400bb20) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#15 0x00007fa068dabb23 in thread_starter (arg=0x7f9fc400bb90) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#16 0x00007fa0682ec1ca in start_thread () from /lib64/libpthread.so.0
#17 0x00007fa067f58e73 in clone () from /lib64/libc.so.6
核心函数:
mvc_append_wrap
/*mvc_append_wrap(int *bid, str *sname, str *tname, str *cname, ptr d) */
str
mvc_append_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
int *res = getArgReference_int(stk, pci, 0);
mvc *m = NULL;
str msg;
const char *sname = *getArgReference_str(stk, pci, 2);
const char *tname = *getArgReference_str(stk, pci, 3);
const char *cname = *getArgReference_str(stk, pci, 4);
BUN offset = *(BUN*)getArgReference_oid(stk, pci, 5);
bat Pos = *getArgReference_bat(stk, pci, 6);
ptr ins = getArgReference(stk, pci, 7);
int tpe = getArgType(mb, pci, 7), log_res = LOG_OK;
sql_schema *s;
sql_table *t;
sql_column *c;
sql_idx *i;
BAT *b = NULL, *pos = NULL;
BUN cnt = 1;
*res = 0;
if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
return msg;
if ((msg = checkSQLContext(cntxt)) != NULL)
return msg;
if (tpe > GDKatomcnt)
tpe = TYPE_bat;
if (Pos != bat_nil && (pos = BATdescriptor(Pos)) == NULL)
throw(SQL, "sql.append", SQLSTATE(HY005) "Cannot access append positions descriptor");
if (tpe == TYPE_bat && (ins = BATdescriptor(*(bat *) ins)) == NULL) {
bat_destroy(pos);
throw(SQL, "sql.append", SQLSTATE(HY005) "Cannot access append values descriptor");
}
if (ATOMextern(tpe) && !ATOMvarsized(tpe))
ins = *(ptr *) ins;
if ( tpe == TYPE_bat)
b = (BAT*) ins;
s = mvc_bind_schema(m, sname);
if (s == NULL) {
bat_destroy(pos);
bat_destroy(b);
throw(SQL, "sql.append", SQLSTATE(3F000) "Schema missing %s",sname);
}
t = mvc_bind_table(m, s, tname);
if (t == NULL) {
bat_destroy(pos);
bat_destroy(b);
throw(SQL, "sql.append", SQLSTATE(42S02) "Table missing %s",tname);
}
if (!isTable(t)) {
bat_destroy(pos);
bat_destroy(b);
throw(SQL, "sql.append", SQLSTATE(42000) "%s '%s' is not persistent", TABLE_TYPE_DESCRIPTION(t->type, t->properties), t->base.name);
}
if (b)
cnt = BATcount(b);
sqlstore *store = m->session->tr->store;
if (cname[0] != '%' && (c = mvc_bind_column(m, t, cname)) != NULL) {
log_res = store->storage_api.append_col(m->session->tr, c, offset, pos, ins, cnt, tpe);
} else if (cname[0] == '%' && (i = mvc_bind_idx(m, s, cname + 1)) != NULL) {
log_res = store->storage_api.append_idx(m->session->tr, i, offset, pos, ins, cnt, tpe);
} else {
bat_destroy(pos);
bat_destroy(b);
throw(SQL, "sql.append", SQLSTATE(38000) "Unable to find column or index %s.%s.%s",sname,tname,cname);
}
bat_destroy(pos);
bat_destroy(b);
if (log_res != LOG_OK) /* the conflict case should never happen, but leave it here */
throw(SQL, "sql.append", SQLSTATE(42000) "Append failed%s", log_res == LOG_CONFLICT ? " due to conflict with another transaction" : "");
return MAL_SUCCEED;
}
delta_append_val
static int
delta_append_val(sql_trans *tr, sql_delta **batp, sqlid id, BUN offset, void *i, BUN cnt, char *storage_type, int tt)
{
void *oi = i;
BAT *b;
lock_column(tr->store, id);
sql_delta *bat = *batp;
if (bat->cs.st == ST_DICT) {
/* possibly a new array is returned */
i = dict_append_val(tr, batp, i, cnt);
bat = *batp;
if (!i) {
unlock_column(tr->store, id);
return LOG_ERR;
}
}
if (bat->cs.st == ST_FOR) {
/* possibly a new array is returned */
i = for_append_val(&bat->cs, i, cnt, storage_type, tt);
bat = *batp;
if (!i) {
unlock_column(tr->store, id);
return LOG_ERR;
}
}
b = temp_descriptor(bat->cs.bid);
if (b == NULL) {
if (i != oi)
GDKfree(i);
unlock_column(tr->store, id);
return LOG_ERR;
}
BUN bcnt = BATcount(b);
if (bcnt > offset){
size_t ccnt = ((offset+cnt) > bcnt)? (bcnt - offset):cnt;
if (BUNreplacemultiincr(b, offset, i, ccnt, true) != GDK_SUCCEED) {
bat_destroy(b);
if (i != oi)
GDKfree(i);
unlock_column(tr->store, id);
return LOG_ERR;
}
cnt -= ccnt;
offset += ccnt;
}
if (cnt) {
if (BATcount(b) < offset) { /* add space */
BUN d = offset - BATcount(b);
if (BUNappendmulti(b, NULL, d, true) != GDK_SUCCEED) {
bat_destroy(b);
if (i != oi)
GDKfree(i);
unlock_column(tr->store, id);
return LOG_ERR;
}
}
if (BUNappendmulti(b, i, cnt, true) != GDK_SUCCEED) {
bat_destroy(b);
if (i != oi)
GDKfree(i);
unlock_column(tr->store, id);
return LOG_ERR;
}
}
bat_destroy(b);
if (i != oi)
GDKfree(i);
unlock_column(tr->store, id);
return LOG_OK;
}
BUNinplacemulti
/* @- BUN replace
* The last operation in this context is BUN replace. It assumes that
* the header denotes a key. The old value association is destroyed
* (if it exists in the first place) and the new value takes its
* place.
*
* In order to make updates on void columns workable; replaces on them
* are always done in-place. Performing them without bun-movements
* greatly simplifies the problem. The 'downside' is that when
* transaction management has to be performed, replaced values should
* be saved explicitly.
*/
static gdk_return
BUNinplacemulti(BAT *b, const oid *positions, const void *values, BUN count, bool force, bool autoincr)
{
int tt;
BUN prv, nxt;
const void *val;
MT_lock_set(&b->theaplock);
BUN last = BATcount(b) - 1;
BATiter bi = bat_iterator_nolock(b);
/* zap alignment info */
if (!force && (b->batRestricted != BAT_WRITE || b->batSharecnt > 0)) {
MT_lock_unset(&b->theaplock);
GDKerror("access denied to %s, aborting.\n",
BATgetId(b));
return GDK_FAIL;
}
TRC_DEBUG(ALGO, ALGOBATFMT " replacing " BUNFMT " values\n", ALGOBATPAR(b), count);
if (b->ttype == TYPE_void) {
PROPdestroy(b);
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
b->tunique_est = 0.0;
} else if (count > BATcount(b) / gdk_unique_estimate_keep_fraction) {
b->tunique_est = 0;
}
MT_lock_unset(&b->theaplock);
/* load hash so that we can maintain it */
(void) BATcheckhash(b);
MT_rwlock_wrlock(&b->thashlock);
for (BUN i = 0; i < count; i++) {
BUN p = autoincr ? positions[0] - b->hseqbase + i : positions[i] - b->hseqbase;
const void *t = b->ttype && b->tvheap ?
((const void **) values)[i] :
(const void *) ((const char *) values + (i << b->tshift));
const bool isnil = ATOMlinear(b->ttype) &&
ATOMcmp(b->ttype, t, ATOMnilptr(b->ttype)) == 0;
/* retrieve old value, but if this comes from the
* logger, we need to deal with offsets that point
* outside of the valid vheap */
if (b->ttype == TYPE_void) {
val = BUNtpos(bi, p);
} else if (bi.type == TYPE_msk) {
val = BUNtmsk(bi, p);
} else if (b->tvheap) {
size_t off = BUNtvaroff(bi, p);
if (off < bi.vhfree)
val = bi.vh->base + off;
else
val = NULL; /* bad offset */
} else {
val = BUNtloc(bi, p);
}
if (val) {
if (ATOMcmp(b->ttype, val, t) == 0)
continue; /* nothing to do */
if (!isnil &&
b->tnil &&
ATOMcmp(b->ttype, val, ATOMnilptr(b->ttype)) == 0) {
/* if old value is nil and new value
* isn't, we're not sure anymore about
* the nil property, so we must clear
* it */
MT_lock_set(&b->theaplock);
b->tnil = false;
MT_lock_unset(&b->theaplock);
}
if (b->ttype != TYPE_void) {
if (bi.maxpos != BUN_NONE) {
if (!isnil && ATOMcmp(b->ttype, BUNtail(bi, bi.maxpos), t) < 0) {
/* new value is larger
* than previous
* largest */
bi.maxpos = p;
} else if (bi.maxpos == p && ATOMcmp(b->ttype, BUNtail(bi, bi.maxpos), t) != 0) {
/* old value is equal to
* largest and new value
* is smaller or nil (see
* above), so we don't
* know anymore which is
* the largest */
bi.maxpos = BUN_NONE;
}
}
if (bi.minpos != BUN_NONE) {
if (!isnil && ATOMcmp(b->ttype, BUNtail(bi, bi.minpos), t) > 0) {
/* new value is smaller
* than previous
* smallest */
bi.minpos = p;
} else if (bi.minpos == p && ATOMcmp(b->ttype, BUNtail(bi, bi.minpos), t) != 0) {
/* old value is equal to
* smallest and new value
* is larger or nil (see
* above), so we don't
* know anymore which is
* the largest */
bi.minpos = BUN_NONE;
}
}
}
HASHdelete_locked(&bi, p, val); /* first delete old value from hash */
} else {
/* out of range old value, so the properties and
* hash cannot be trusted */
PROPdestroy(b);
Hash *hs = b->thash;
if (hs) {
b->thash = NULL;
doHASHdestroy(b, hs);
}
MT_lock_set(&b->theaplock);
bi.minpos = BUN_NONE;
bi.maxpos = BUN_NONE;
b->tunique_est = 0.0;
MT_lock_unset(&b->theaplock);
}
OIDXdestroy(b);
IMPSdestroy(b);
STRMPdestroy(b);
if (b->tvheap && b->ttype) {
var_t _d;
ptr _ptr;
_ptr = BUNtloc(bi, p);
switch (b->twidth) {
case 1:
_d = (var_t) * (uint8_t *) _ptr + GDK_VAROFFSET;
break;
case 2:
_d = (var_t) * (uint16_t *) _ptr + GDK_VAROFFSET;
break;
case 4:
_d = (var_t) * (uint32_t *) _ptr;
break;
#if SIZEOF_VAR_T == 8
case 8:
_d = (var_t) * (uint64_t *) _ptr;
break;
#endif
default:
MT_UNREACHABLE();
}
if (ATOMreplaceVAR(b, &_d, t) != GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
return GDK_FAIL;
}
if (b->twidth < SIZEOF_VAR_T &&
(b->twidth <= 2 ? _d - GDK_VAROFFSET : _d) >= ((size_t) 1 << (8 << b->tshift))) {
/* doesn't fit in current heap, upgrade it */
if (GDKupgradevarheap(b, _d, 0, bi.count) != GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
return GDK_FAIL;
}
}
/* reinitialize iterator after possible heap upgrade */
{
/* save and restore minpos/maxpos */
BUN minpos = bi.minpos;
BUN maxpos = bi.maxpos;
bi = bat_iterator_nolock(b);
bi.minpos = minpos;
bi.maxpos = maxpos;
}
_ptr = BUNtloc(bi, p);
switch (b->twidth) {
case 1:
* (uint8_t *) _ptr = (uint8_t) (_d - GDK_VAROFFSET);
break;
case 2:
* (uint16_t *) _ptr = (uint16_t) (_d - GDK_VAROFFSET);
break;
case 4:
* (uint32_t *) _ptr = (uint32_t) _d;
break;
#if SIZEOF_VAR_T == 8
case 8:
* (uint64_t *) _ptr = (uint64_t) _d;
break;
#endif
default:
MT_UNREACHABLE();
}
} else if (ATOMstorage(b->ttype) == TYPE_msk) {
mskSetVal(b, p, * (msk *) t);
} else {
assert(BATatoms[b->ttype].atomPut == NULL);
if (ATOMfix(b->ttype, t) != GDK_SUCCEED ||
ATOMunfix(b->ttype, BUNtloc(bi, p)) != GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
return GDK_FAIL;
}
switch (ATOMsize(b->ttype)) {
case 0: /* void */
break;
case 1:
((bte *) b->theap->base)[p] = * (bte *) t;
break;
case 2:
((sht *) b->theap->base)[p] = * (sht *) t;
break;
case 4:
((int *) b->theap->base)[p] = * (int *) t;
break;
case 8:
((lng *) b->theap->base)[p] = * (lng *) t;
break;
case 16:
#ifdef HAVE_HGE
((hge *) b->theap->base)[p] = * (hge *) t;
#else
((uuid *) b->theap->base)[p] = * (uuid *) t;
#endif
break;
default:
memcpy(BUNtloc(bi, p), t, ATOMsize(b->ttype));
break;
}
}
HASHinsert_locked(&bi, p, t); /* insert new value into hash */
tt = b->ttype;
prv = p > 0 ? p - 1 : BUN_NONE;
nxt = p < last ? p + 1 : BUN_NONE;
MT_lock_set(&b->theaplock);
if (b->tsorted) {
if (prv != BUN_NONE &&
ATOMcmp(tt, t, BUNtail(bi, prv)) < 0) {
b->tsorted = false;
b->tnosorted = p;
} else if (nxt != BUN_NONE &&
ATOMcmp(tt, t, BUNtail(bi, nxt)) > 0) {
b->tsorted = false;
b->tnosorted = nxt;
} else if (b->ttype != TYPE_void && BATtdense(b)) {
if (prv != BUN_NONE &&
1 + * (oid *) BUNtloc(bi, prv) != * (oid *) t) {
b->tseqbase = oid_nil;
} else if (nxt != BUN_NONE &&
* (oid *) BUNtloc(bi, nxt) != 1 + * (oid *) t) {
b->tseqbase = oid_nil;
} else if (prv == BUN_NONE &&
nxt == BUN_NONE) {
b->tseqbase = * (oid *) t;
}
}
} else if (b->tnosorted >= p)
b->tnosorted = 0;
if (b->trevsorted) {
if (prv != BUN_NONE &&
ATOMcmp(tt, t, BUNtail(bi, prv)) > 0) {
b->trevsorted = false;
b->tnorevsorted = p;
} else if (nxt != BUN_NONE &&
ATOMcmp(tt, t, BUNtail(bi, nxt)) < 0) {
b->trevsorted = false;
b->tnorevsorted = nxt;
}
} else if (b->tnorevsorted >= p)
b->tnorevsorted = 0;
if (((b->ttype != TYPE_void) & b->tkey) && b->batCount > 1) {
BATkey(b, false);
} else if (!b->tkey && (b->tnokey[0] == p || b->tnokey[1] == p))
b->tnokey[0] = b->tnokey[1] = 0;
if (b->tnonil && ATOMstorage(b->ttype) != TYPE_msk)
b->tnonil = t && ATOMcmp(b->ttype, t, ATOMnilptr(b->ttype)) != 0;
MT_lock_unset(&b->theaplock);
}
BUN nunique = b->thash ? b->thash->nunique : 0;
MT_rwlock_wrunlock(&b->thashlock);
MT_lock_set(&b->theaplock);
if (nunique != 0)
b->tunique_est = (double) nunique;
b->tminpos = bi.minpos;
b->tmaxpos = bi.maxpos;
b->theap->dirty = true;
if (b->tvheap)
b->tvheap->dirty = true;
MT_lock_unset(&b->theaplock);
return GDK_SUCCEED;
}
mvc_claim_wrap
str
mvc_claim_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
BUN *offset = (BUN*)getArgReference_oid(stk, pci, 0);
bat *res = getArgReference_bat(stk, pci, 1);
mvc *m = NULL;
str msg;
const char *sname = *getArgReference_str(stk, pci, 3);
const char *tname = *getArgReference_str(stk, pci, 4);
lng cnt = *(lng*)getArgReference_lng(stk, pci, 5);
BAT *pos = NULL;
sql_schema *s;
sql_table *t;
*res = 0;
if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
return msg;
if ((msg = checkSQLContext(cntxt)) != NULL)
return msg;
s = mvc_bind_schema(m, sname);
if (s == NULL)
throw(SQL, "sql.claim", SQLSTATE(3F000) "Schema missing %s", sname);
t = mvc_bind_table(m, s, tname);
if (t == NULL)
throw(SQL, "sql.claim", SQLSTATE(42S02) "Table missing %s.%s", sname, tname);
if (!isTable(t))
throw(SQL, "sql.claim", SQLSTATE(42000) "%s '%s' is not persistent", TABLE_TYPE_DESCRIPTION(t->type, t->properties), t->base.name);
if (mvc_claim_slots(m->session->tr, t, (size_t)cnt, offset, &pos) == LOG_OK) {
*res = bat_nil;
if (pos) {
*res = pos->batCacheid;
BBPkeepref(pos);
}
return MAL_SUCCEED;
}
throw(SQL, "sql.claim", SQLSTATE(3F000) "Could not claim slots");
}
sql_trans_end
int
sql_trans_end(sql_session *s, int ok)
{
TRC_DEBUG(SQL_STORE, "End of transaction: " ULLFMT "\n", s->tr->tid);
if (ok == SQL_OK) {
ok = sql_trans_commit(s->tr);
} else if (ok == SQL_ERR) { /* if a conflict happened, it was already rollbacked */
sql_trans_rollback(s->tr, false);
}
assert(s->tr->active);
sqlstore *store = s->tr->store;
store_lock(store);
s->tr->active = 0;
s->tr->status = 0;
s->auto_commit = s->ac_on_commit;
list_remove_data(store->active, NULL, s->tr);
ATOMIC_SET(&store->lastactive, GDKusec());
(void) ATOMIC_DEC(&store->nr_active);
ulng oldest = store_get_timestamp(store);
if (store->active && store->active->h) {
for(node *n = store->active->h; n; n = n->next) {
sql_trans *tr = n->data;
if (tr->ts < oldest)
oldest = tr->ts;
}
}
store->oldest = oldest;
assert(list_length(store->active) == (int) ATOMIC_GET(&store->nr_active));
store_unlock(store);
return ok;
}