Hello. I have only minor remarks mostly concerning codestyle.
As for functional part of this patch, it seems to be OK.
This patch contains fix for that, in addition
related code was refactored and necessary comments were added.
@@ -1038,10 +1042,12 @@ checkConstraintUnchanged(Expr * pExpr, int *aiChng)
*
* CHECK REPLACE Illegal. The results in an exception.
*
- * Which action to take is determined by the overrideError parameter.
- * Or if overrideError==ON_CONFLICT_ACTION_DEFAULT, then the pParse->onError
parameter
- * is used. Or if pParse->onError==ON_CONFLICT_ACTION_DEFAULT then the
onError value
- * for the constraint is used.
+ * Which action to take is determined by the override_error parameter
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK
conflict */
int nPkField; /* Number of fields in PRIMARY KEY. */
u8 isUpdate; /* True if this is an UPDATE operation */
u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been
run */
struct session *user_session = current_session();
+ enum on_conflict_action override_error = on_conflict->override_error;
+ enum on_conflict_action on_error;
+ on_error = table_column_nullable_action(pTab, i);
+ if (override_error != ON_CONFLICT_ACTION_DEFAULT) {
+ on_error = override_error;
+ } else if (on_error == ON_CONFLICT_ACTION_DEFAULT) {
+ on_error = ON_CONFLICT_ACTION_ABORT;
- assert(onError == ON_CONFLICT_ACTION_ROLLBACK
- || onError == ON_CONFLICT_ACTION_ABORT
- || onError == ON_CONFLICT_ACTION_FAIL
- || onError == ON_CONFLICT_ACTION_IGNORE
- || onError == ON_CONFLICT_ACTION_REPLACE);
- if (overrideError != ON_CONFLICT_ACTION_DEFAULT) {
- onError = overrideError;
- } else if (onError == ON_CONFLICT_ACTION_DEFAULT) {
- onError = ON_CONFLICT_ACTION_ABORT;
+
+ if (override_error != ON_CONFLICT_ACTION_DEFAULT) {
+ on_error = override_error;
+ } else if (on_error == ON_CONFLICT_ACTION_DEFAULT) {
+ on_error = ON_CONFLICT_ACTION_ABORT;
}
if ((ix == 0 && pIdx->pNext == 0) /* Condition 2 */
- && onError == ON_CONFLICT_ACTION_REPLACE /* Condition 1
*/
- && (0 == (user_session->sql_flags & SQLITE_RecTriggers)
/* Condition 3 */
+ /* Condition 1 */
+ && (on_error == ON_CONFLICT_ACTION_REPLACE ||
+ on_error == ON_CONFLICT_ACTION_IGNORE)
+ /* Condition 3 */
+ && (0 == (user_session->sql_flags & SQLITE_RecTriggers)
||0 == sqlite3TriggersExist(pTab, TK_DELETE, 0, 0))
- /* Generate code that executes if the new index entry is not
unique */
- assert(onError == ON_CONFLICT_ACTION_ROLLBACK
- || onError == ON_CONFLICT_ACTION_ABORT
- || onError == ON_CONFLICT_ACTION_FAIL
- || onError == ON_CONFLICT_ACTION_IGNORE
- || onError == ON_CONFLICT_ACTION_REPLACE);
void
-vdbe_emit_insertion_completion(Vdbe *v, int cursor_id, int tuple_id, u8
on_error)
+vdbe_emit_insertion_completion(Vdbe *v, int cursor_id, int tuple_id,
+ struct on_conflict *on_conflict)
- else
+ } else {
opcode = OP_IdxInsert;
+ }
u16 pik_flags = OPFLAG_NCHANGE;
- if (on_error == ON_CONFLICT_ACTION_IGNORE)
+ if (override_error == ON_CONFLICT_ACTION_IGNORE)
+ pik_flags |= OPFLAG_OE_IGNORE;
+ if (override_error == ON_CONFLICT_ACTION_IGNORE ||
+ (optimized_action == ON_CONFLICT_ACTION_IGNORE &&
+ override_error == ON_CONFLICT_ACTION_DEFAULT)) {
pik_flags |= OPFLAG_OE_IGNORE;
- else if (on_error == ON_CONFLICT_ACTION_FAIL)
+ }
+ else if (override_error == ON_CONFLICT_ACTION_FAIL) {