<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Accidentally I have sent patch to outdate mailing list.</div><div class="">Resending it again to the new one.</div><div class="">Reply with fixes to this mail.</div><br class=""><div><blockquote type="cite" class=""><div class="">On 3 Apr 2018, at 13:20, n.pettik <<a href="mailto:korablev@tarantool.org" class="">korablev@tarantool.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Hello. See comments below.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">On 30 Mar 2018, at 01:25, Bulat Niatshin <<a href="mailto:niatshin@tarantool.org" class="">niatshin@tarantool.org</a>> wrote:<br class=""><br class="">In some cases ON CONFLICT REPLACE/IGNORE can be optimized. If<br class="">following conditions are true:<br class="">1) Space has PRIMARY KEY index only.<br class="">2) There are no foreign keys to other spaces.<br class="">3) There are no delete triggers to be fired if conflict happens.<br class="">4) The errt or action is REPLACE or IGNORE.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">errt: typo.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">Then uniqueness can be ensured by Tarantool only, without VDBE<br class="">bytecode. This patch contains a small fix for that +<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Replace ‘+’ with word. Don’t mention that it is ’small’ fix, let it be just fix.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">related code was refactored a little bit and necessary comments<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">The same: don’t use ‘little bit’ — it sounds like you left smth</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">in a shitty state consciously.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">were added.<br class=""><br class="">Closes #3293<br class="">---<br class=""><br class="">Branch:<br class=""><a href="https://github.com/tarantool/tarantool/tree/bn/gh-3293-unique-opt" class="">https://github.com/tarantool/tarantool/tree/bn/gh-3293-unique-opt</a><br class=""><br class="">Issue:<br class="">https://github.com/tarantool/tarantool/issues/3293<br class=""><br class="">src/box/sql/insert.c          | 144 ++++++++++++++++++++++++++++++++----------<br class="">src/box/sql/sqliteInt.h       |  27 +++++++-<br class="">src/box/sql/update.c          |   9 ++-<br class="">test/sql/on-conflict.result   |  32 ++++++++++<br class="">test/sql/on-conflict.test.lua |  13 ++++<br class="">5 files changed, 186 insertions(+), 39 deletions(-)<br class=""><br class="">diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c<br class="">index 0e305d34b..fc9b121b0 100644<br class="">--- a/src/box/sql/insert.c<br class="">+++ b/src/box/sql/insert.c<br class="">@@ -835,9 +835,13 @@ sqlite3Insert(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">   </span>/* Parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int isReplace;<span class="Apple-tab-span" style="white-space: pre;">    </span>/* Set to true if constraints may cause a replace */<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int bUseSeek;<span class="Apple-tab-span" style="white-space: pre;">     </span>/* True to use OPFLAG_SEEKRESULT */<br class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>struct on_conflict on_conflict;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>on_conflict.override_error = onError;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>on_conflict.optimized_on_conflict = ON_CONFLICT_ACTION_NONE;<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur,<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>iIdxCur, regIns, 0,<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>ipkColumn >= 0, onError,<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>ipkColumn >= 0, &on_conflict,<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>endOfLoop, &isReplace, 0);<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3FkCheck(pParse, pTab, 0, regIns, 0);<br class=""><br class="">@@ -855,7 +859,7 @@ sqlite3Insert(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">    </span>/* Parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>SQLITE_ForeignKeys) == 0 ||<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>      sqlite3FkReferences(pTab) == 0));<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3CompleteInsertion(pParse, pTab, iIdxCur, aRegIdx,<br class="">-<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>bUseSeek, onError);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>bUseSeek, &on_conflict);<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span>/* Update the count of rows that are inserted<br class="">@@ -1056,7 +1060,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int regNewData,<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* First register in a range holding values to insert */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int regOldData,<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Previous content.  0 for INSERTs */<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>u8 pkChng,<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Non-zero if the PRIMARY KEY changed */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>u8 overrideError,<span class="Apple-tab-span" style="white-space: pre;"> </span>/* Override onError to this if not ON_CONFLICT_ACTION_DEFAULT */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>struct on_conflict *on_conflict,<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int ignoreDest,<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Jump to this label on an ON_CONFLICT_ACTION_IGNORE resolution */<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int *pbMayReplace,<span class="Apple-tab-span" style="white-space: pre;">        </span>/* OUT: Set to true if constraint may cause a replace */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int *aiChng)<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* column i is unchanged if aiChng[i]<0 */<br class="">@@ -1075,6 +1079,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span>u8 isUpdate;<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* True if this is an UPDATE operation */<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span>u8 bAffinityDone = 0;<span class="Apple-tab-span" style="white-space: pre;">     </span>/* True if the OP_Affinity operation has been run */<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>struct session *user_session = current_session();<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>int override_error = on_conflict->override_error;<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span>isUpdate = regOldData != 0;<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span>db = pParse->db;<br class="">@@ -1107,8 +1112,8 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>continue;<span class="Apple-tab-span" style="white-space: pre;"> </span>/* This column is allowed to be NULL */<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = table_column_nullable_action(pTab, i);<br class="">-<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (overrideError != ON_CONFLICT_ACTION_DEFAULT) {<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = overrideError;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (override_error != ON_CONFLICT_ACTION_DEFAULT) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = override_error;<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>} else if (onError == ON_CONFLICT_ACTION_DEFAULT) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = ON_CONFLICT_ACTION_ABORT;<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class="">@@ -1166,9 +1171,12 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    SQLITE_IgnoreChecks) == 0) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>ExprList *pCheck = pTab->pCheck;<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>pParse->ckBase = regNewData + 1;<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError =<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   overrideError != ON_CONFLICT_ACTION_DEFAULT ? overrideError<br class="">-<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>: ON_CONFLICT_ACTION_ABORT;<br class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (override_error != ON_CONFLICT_ACTION_DEFAULT)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = override_error;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>else<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = ON_CONFLICT_ACTION_ABORT;<br class="">+<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>for (i = 0; i < pCheck->nExpr; i++) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int allOk;<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>Expr *pExpr = pCheck->a[i].pExpr;<br class="">@@ -1210,10 +1218,15 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int addrUniqueOk;<span class="Apple-tab-span" style="white-space: pre;"> </span>/* Jump here if the UNIQUE constraint is satisfied */<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span>bool uniqueByteCodeNeeded = false;<br class=""><br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* ABORT and DEFAULT error actions can be handled<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* by Tarantool only without emitting VDBE<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Remove word ‘only’: it confuses little bit (IMHO).</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* bytecode.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if ((pIdx->onError != ON_CONFLICT_ACTION_ABORT &&<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    pIdx->onError != ON_CONFLICT_ACTION_DEFAULT) ||<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   (overrideError != ON_CONFLICT_ACTION_ABORT &&<br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    overrideError != ON_CONFLICT_ACTION_DEFAULT)) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   (override_error != ON_CONFLICT_ACTION_ABORT &&<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    override_error != ON_CONFLICT_ACTION_DEFAULT)) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>uniqueByteCodeNeeded = true;<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><br class="">@@ -1318,41 +1331,73 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>continue;<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Find out what action to take in case there is a uniqueness conflict */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = pIdx->onError;<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (onError == ON_CONFLICT_ACTION_NONE) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (!IsUniqueIndex(pIdx)) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3VdbeResolveLabel(v, addrUniqueOk);<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>continue;<span class="Apple-tab-span" style="white-space: pre;"> </span>/* pIdx is not a UNIQUE index */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>continue;<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* If pIdx is not a UNIQUE or we are doing INSERT OR IGNORE,<br class="">-<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* INSERT OR FAIL then skip uniqueness checks and let it to be<br class="">-<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* done by Tarantool.<br class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* Find out what action to take in case there is<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* a uniqueness conflict.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = pIdx->onError;<br class="">+<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Nit-picking: don’t put too many empty lines.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">In this particular case, you outline very elementary statement.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* If we are doing INSERT OR IGNORE,<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* INSERT OR REPLACE then uniqueness can be<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* ensured by Tarantool only without bytecode,<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* because IGNORE/REPLACE error action will be<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* used for all indexes.<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (overrideError == ON_CONFLICT_ACTION_FAIL ||<br class="">-<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   overrideError == ON_CONFLICT_ACTION_IGNORE ||<br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   overrideError == ON_CONFLICT_ACTION_ABORT) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (override_error == ON_CONFLICT_ACTION_FAIL ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   override_error == ON_CONFLICT_ACTION_IGNORE ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   override_error == ON_CONFLICT_ACTION_ABORT) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3VdbeResolveLabel(v, addrUniqueOk);<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>continue;<span class="Apple-tab-span" style="white-space: pre;"> </span>/* pIdx is not a UNIQUE index */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (overrideError != ON_CONFLICT_ACTION_DEFAULT) {<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = overrideError;<br class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* override_error is an action which is directly<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* specified by user in queries like<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* INSERT OR <override_error> and therefore<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* should have higher priority than indexes<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* error actions.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">You put almost the same comment to on_error struct.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Change it to more informative or remove.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if (override_error != ON_CONFLICT_ACTION_DEFAULT) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = override_error;<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>} else if (onError == ON_CONFLICT_ACTION_DEFAULT) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError = ON_CONFLICT_ACTION_ABORT;<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Collision detection may be omitted if all of the following are true:<br class="">-<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (1) The conflict resolution algorithm is REPLACE<br class="">-<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (2) There are no secondary indexes on the table<br class="">-<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (3) No delete triggers need to be fired if there is a conflict<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (4) No FK constraint counters need to be updated if a conflict occurs.<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* Collision detection may be omitted if all of<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* the following are true:<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (1) The conflict resolution algorithm is<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*       REPLACE or IGNORE.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (2) There are no secondary indexes on the<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*       table.<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (3) No delete triggers need to be fired if<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*       there is a conflict.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*   (4) No FK constraint counters need to be<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*       updated if a conflict occurs.<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>if ((ix == 0 && pIdx->pNext == 0)<span class="Apple-tab-span" style="white-space: pre;">      </span>/* Condition 2 */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   && onError == ON_CONFLICT_ACTION_REPLACE<span class="Apple-tab-span" style="white-space: pre;"> </span>/* Condition 1 */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   && (0 == (user_session->sql_flags & SQLITE_RecTriggers)<span class="Apple-tab-span" style="white-space: pre;">   </span>/* Condition 3 */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   /* Condition 1 */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   && (onError == ON_CONFLICT_ACTION_REPLACE ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>onError == ON_CONFLICT_ACTION_IGNORE)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   /* Condition 3 */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   && (0 == (user_session->sql_flags & SQLITE_RecTriggers)<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>||0 == sqlite3TriggersExist(pTab, TK_DELETE, 0, 0))<br class="">-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   && (0 == (user_session->sql_flags & SQLITE_ForeignKeys) ||<span class="Apple-tab-span" style="white-space: pre;">        </span>/* Condition 4 */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   /* Condition 4 */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   && (0 == (user_session->sql_flags & SQLITE_ForeignKeys) ||<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>(0 == pTab->pFKey && 0 == sqlite3FkReferences(pTab)))<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   ) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* In that case assign optimized error<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* action as IGNORE or REPLACE.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>on_conflict->optimized_on_conflict = onError;<br class="">+<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3VdbeResolveLabel(v, addrUniqueOk);<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>continue;<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class="">@@ -1425,7 +1470,19 @@ sqlite3GenerateConstraintChecks(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Generate code that executes if the new index entry is not unique */<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* Generate bytecode which executes when entry is<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* not unique for constraints with following<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* error actions:<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* 1) ROLLBACK.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* 2) FAIL.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* 3) IGNORE.<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* 4) REPLACE.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* ON CONFLICT ABORT is a default error action<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* for constraints and therefore can be handled<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* by Tarantool only.<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>*/<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>assert(onError == ON_CONFLICT_ACTION_ROLLBACK<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>      || onError == ON_CONFLICT_ACTION_ABORT<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>      || onError == ON_CONFLICT_ACTION_FAIL<br class="">@@ -1490,12 +1547,18 @@ sqlite3CompleteInsertion(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">     </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>int iIdxCur,<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Primary index cursor */<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>int *aRegIdx,<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Register used by each index.  0 for unused indices */<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>int useSeekResult,<span class="Apple-tab-span" style="white-space: pre;"> </span>/* True to set the USESEEKRESULT flag on OP_[Idx]Insert */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>u8 onError)<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>struct on_conflict *on_conflict)<br class="">{<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Vdbe *v;<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Prepared statements under construction */<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>Index *pIdx;<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* An index being inserted or updated */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span>u16 pik_flags;<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* flag values passed to the btree insert */<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>int opcode;<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span>int override_error = on_conflict->override_error;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>int optimized_error_action = on_conflict->optimized_on_conflict;<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">If you used enum type, you wouldn’t have to add assertion below.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>assert(optimized_error_action == ON_CONFLICT_ACTION_NONE ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>      optimized_error_action == ON_CONFLICT_ACTION_REPLACE ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>      optimized_error_action == ON_CONFLICT_ACTION_IGNORE);<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>v = sqlite3GetVdbe(pParse);<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span>assert(v != 0);<br class="">@@ -1524,15 +1587,26 @@ sqlite3CompleteInsertion(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">      </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span>}<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span>assert(pParse->nested == 0);<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">        </span>if (onError == ON_CONFLICT_ACTION_REPLACE) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>/*<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* override_error represents error action in queries like<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-converted-space"> </span>* INSERT/UPDATE OR REPLACE, INSERT/UPDATE OR IGNORE,<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>* which is strictly specified by user and therefore<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* should have been used even when optimization is<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-converted-space"> </span>* possible (uniqueness can be checked by Tarantool).<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>*/<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">This comment is almost copy of one from struct declaration.<span class="Apple-converted-space"> </span></span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Remove or rephrase.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span>if (override_error == ON_CONFLICT_ACTION_REPLACE ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>   (optimized_error_action == ON_CONFLICT_ACTION_REPLACE &&<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-converted-space"> </span>    override_error == ON_CONFLICT_ACTION_DEFAULT)) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>opcode = OP_IdxReplace;<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span>} else {<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>opcode = OP_IdxInsert;<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span>}<br class=""><br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span>if (onError == ON_CONFLICT_ACTION_IGNORE) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span>if (override_error == ON_CONFLICT_ACTION_IGNORE ||<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>   (optimized_error_action == ON_CONFLICT_ACTION_IGNORE &&<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-converted-space"> </span>    override_error == ON_CONFLICT_ACTION_DEFAULT)) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>pik_flags |= OPFLAG_OE_IGNORE;<br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span>} else if (onError == ON_CONFLICT_ACTION_FAIL) {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span>} else if (override_error == ON_CONFLICT_ACTION_FAIL) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>pik_flags |= OPFLAG_OE_FAIL;<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>}<br class=""><br class="">diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h<br class="">index dc045f97b..5492ca44c 100644<br class="">--- a/src/box/sql/sqliteInt.h<br class="">+++ b/src/box/sql/sqliteInt.h<br class="">@@ -666,6 +666,27 @@ enum sql_type {<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>SQLITE_NULL = 5,<br class="">};<br class=""><br class="">+/**<br class="">+ * Structure for internal usage during INSERT/UPDATE<br class="">+ * statements compilation.<br class="">+ */<br class="">+struct on_conflict {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span>/**<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>* Represents an error action in queries like<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>* INSERT/UPDATE OR <override_error>, which<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-converted-space"> </span>* overrides all space constraints error actions.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-converted-space"> </span>*/<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>int override_error;<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Why do you declare type of this field as int,</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">when it can take values from on_conflict_action enum?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<span class="Apple-tab-span" style="white-space: pre;">        </span>/**<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>* Represents an ON CONFLICT action which can be<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-converted-space"> </span>* optimized and executed without VDBE bytecode, by<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-converted-space"> </span>* Tarantool only. If optimization is not available, then<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">"Only by Tarantool facilities" would sound better, wouldn’t it?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>* the value is ON_CONFLICT_ACTION_NONE, otherwise it is<br class="">+<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-converted-space"> </span>* ON_CONFLICT_ACTON_IGNORE or ON_CONFLICT_ACTION_REPLACE.<br class="">+<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-converted-space"> </span>*/<br class="">+<span class="Apple-tab-span" style="white-space: pre;">   </span>int optimized_on_conflict;<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Your structure is already called ‘on_conflict’,</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">so don’t repeat this phrase in field’s name.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Also, the same as previous field: better declare it as enum.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+};<br class="">+<br class="">void *<br class="">sqlite3_user_data(sqlite3_context *);<br class=""><br class="">@@ -3709,8 +3730,10 @@ void sqlite3GenerateRowIndexDelete(Parse *, Table *, int, int);<br class="">int sqlite3GenerateIndexKey(Parse *, Index *, int, int, int *, Index *, int);<br class="">void sqlite3ResolvePartIdxLabel(Parse *, int);<br class="">void sqlite3GenerateConstraintChecks(Parse *, Table *, int *, int, int, int,<br class="">-<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    int, u8, u8, int, int *, int *);<br class="">-void sqlite3CompleteInsertion(Parse *, Table *, int, int *, int, u8);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    int, u8, struct on_conflict *, int,<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>    int *, int *);<br class="">+void sqlite3CompleteInsertion(Parse *, Table *, int, int *, int,<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>     struct on_conflict *);<br class="">int sqlite3OpenTableAndIndices(Parse *, Table *, int, u8, int, u8 *, int *,<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>      int *, u8, u8);<br class="">void sqlite3BeginWriteOperation(Parse *, int);<br class="">diff --git a/src/box/sql/update.c b/src/box/sql/update.c<br class="">index bf413252d..c888aab1a 100644<br class="">--- a/src/box/sql/update.c<br class="">+++ b/src/box/sql/update.c<br class="">@@ -563,11 +563,15 @@ sqlite3Update(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int addr1 = 0;<span class="Apple-tab-span" style="white-space: pre;">    </span>/* Address of jump instruction */<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-tab-span" style="white-space: pre;">  </span>int bReplace = 0;<span class="Apple-tab-span" style="white-space: pre;"> </span>/* True if REPLACE conflict resolution might happen */<br class=""><br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span>struct on_conflict on_conflict;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>on_conflict.override_error = onError;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>on_conflict.optimized_on_conflict = ON_CONFLICT_ACTION_NONE;<br class="">+<br class=""><span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Do constraint checks. */<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>assert(regOldPk > 0);<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur,<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>iIdxCur, regNewPk,<br class="">-<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>regOldPk, chngPk, onError,<br class="">+<span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>regOldPk, chngPk, &on_conflict,<br class=""><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>labelContinue, &bReplace,<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span>aXRef);<br class=""><br class="">@@ -616,7 +620,8 @@ sqlite3Update(Parse * pParse,<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* The parser context */<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-tab-span" style="white-space: pre;">  </span>}<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Insert the new index entries and the new record. */<br class="">-<span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3CompleteInsertion(pParse, pTab, iIdxCur, aRegIdx, 0, onError);<br class="">+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>sqlite3CompleteInsertion(pParse, pTab, iIdxCur, aRegIdx, 0,<br class="">+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>&on_conflict);<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-tab-span" style="white-space: pre;">  </span>/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to<br class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;">  </span><span class="Apple-converted-space"> </span>* handle rows (possibly in other tables) that refer via a foreign key<br class="">diff --git a/test/sql/on-conflict.result b/test/sql/on-conflict.result<br class="">index b011a6e6a..5e892eada 100644<br class="">--- a/test/sql/on-conflict.result<br class="">+++ b/test/sql/on-conflict.result<br class="">@@ -50,6 +50,32 @@ box.sql.execute("SELECT * FROM e")<br class=""> - [2, 2]<br class=""> - [3, 1]<br class="">...<br class="">+box.sql.execute("CREATE TABLE t1(a INT PRIMARY KEY ON CONFLICT REPLACE)")<br class="">+---<br class="">+...<br class="">+box.sql.execute("INSERT INTO t1 VALUES (9)")<br class="">+---<br class="">+...<br class="">+box.sql.execute("INSERT INTO t1 VALUES (9)")<br class="">+---<br class="">+...<br class="">+box.sql.execute("SELECT * FROM t1")<br class="">+---<br class="">+- - [9]<br class="">+...<br class="">+box.sql.execute("CREATE TABLE t2(a INT PRIMARY KEY ON CONFLICT IGNORE)")<br class="">+---<br class="">+...<br class="">+box.sql.execute("INSERT INTO t2 VALUES (9)")<br class="">+---<br class="">+...<br class="">+box.sql.execute("INSERT INTO t2 VALUES (9)")<br class="">+---<br class="">+...<br class="">+box.sql.execute("SELECT * FROM t2")<br class="">+---<br class="">+- - [9]<br class="">+...<br class="">box.sql.execute('DROP TABLE t')<br class="">---<br class="">...<br class="">@@ -62,3 +88,9 @@ box.sql.execute('DROP TABLE p')<br class="">box.sql.execute('DROP TABLE e')<br class="">---<br class="">...<br class="">+box.sql.execute('DROP TABLE t1')<br class="">+---<br class="">+...<br class="">+box.sql.execute('DROP TABLE t2')<br class="">+---<br class="">+...<br class="">diff --git a/test/sql/on-conflict.test.lua b/test/sql/on-conflict.test.lua<br class="">index dbf572a8b..1ff199d32 100644<br class="">--- a/test/sql/on-conflict.test.lua<br class="">+++ b/test/sql/on-conflict.test.lua<br class="">@@ -19,7 +19,20 @@ box.sql.execute("SELECT * FROM p")<br class="">box.sql.execute("INSERT INTO e values (1, 1), (2, 2), (3, 1)")<br class="">box.sql.execute("SELECT * FROM e")<br class=""><br class="">+box.sql.execute("CREATE TABLE t1(a INT PRIMARY KEY ON CONFLICT REPLACE)")<br class="">+box.sql.execute("INSERT INTO t1 VALUES (9)")<br class="">+box.sql.execute("INSERT INTO t1 VALUES (9)")<br class="">+box.sql.execute("SELECT * FROM t1")<br class="">+<br class="">+box.sql.execute("CREATE TABLE t2(a INT PRIMARY KEY ON CONFLICT IGNORE)")<br class="">+box.sql.execute("INSERT INTO t2 VALUES (9)")<br class="">+box.sql.execute("INSERT INTO t2 VALUES (9)")<br class="">+<br class="">+box.sql.execute("SELECT * FROM t2")<br class="">+<br class="">box.sql.execute('DROP TABLE t')<br class="">box.sql.execute('DROP TABLE q')<br class="">box.sql.execute('DROP TABLE p')<br class="">box.sql.execute('DROP TABLE e')<br class="">+box.sql.execute('DROP TABLE t1')<br class="">+box.sql.execute('DROP TABLE t2')<br class="">--<span class="Apple-converted-space"> </span><br class="">2.14.1</blockquote></div></blockquote></div><br class=""></body></html>