diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index 54fcca5c93b6..431f5af881a2 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -741,7 +741,10 @@ sqlite3Insert(Parse * pParse, /* Parser context */ if (j < 0 || nColumn == 0 || (pColumn && j >= pColumn->nId)) { if (i == pTab->iAutoIncPKey) { - sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore); + sqlite3VdbeAddOp2(v, + OP_NextAutoincValue, + pTab->tnum, + iRegStore); continue; } sqlite3ExprCodeFactorable(pParse, diff --git a/src/box/sql/opcodes.c b/src/box/sql/opcodes.c index 53603037d338..cc1d6023fefa 100644 --- a/src/box/sql/opcodes.c +++ b/src/box/sql/opcodes.c @@ -79,75 +79,76 @@ const char *sqlite3OpcodeName(int i){ /* 65 */ "Bool" OpHelp("r[P2]=P1"), /* 66 */ "Int64" OpHelp("r[P2]=P4"), /* 67 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 68 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 69 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 70 */ "Blob" OpHelp("r[P2]=P4 (len=P1, subtype=P3)"), - /* 71 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 72 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 73 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 74 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 68 */ "NextAutoincValue" OpHelp("r[P2] = next value from space sequence, which pageno is r[P1]"), + /* 69 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 70 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 71 */ "Blob" OpHelp("r[P2]=P4 (len=P1, subtype=P3)"), + /* 72 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 73 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 74 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), /* 75 */ "String8" OpHelp("r[P2]='P4'"), - /* 76 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 77 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 78 */ "CollSeq" OpHelp(""), - /* 79 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), - /* 80 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), - /* 81 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 82 */ "RealAffinity" OpHelp(""), - /* 83 */ "Cast" OpHelp("affinity(r[P1])"), - /* 84 */ "Permutation" OpHelp(""), - /* 85 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 86 */ "Column" OpHelp("r[P3]=PX"), - /* 87 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 88 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 89 */ "Count" OpHelp("r[P2]=count()"), - /* 90 */ "FkCheckCommit" OpHelp(""), - /* 91 */ "TTransaction" OpHelp(""), - /* 92 */ "ReadCookie" OpHelp(""), - /* 93 */ "SetCookie" OpHelp(""), - /* 94 */ "ReopenIdx" OpHelp("root=P2"), - /* 95 */ "OpenRead" OpHelp("root=P2"), - /* 96 */ "OpenWrite" OpHelp("root=P2"), - /* 97 */ "OpenTEphemeral" OpHelp("nColumn = P2"), - /* 98 */ "SorterOpen" OpHelp(""), - /* 99 */ "SequenceTest" OpHelp("if (cursor[P1].ctr++) pc = P2"), - /* 100 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 101 */ "Close" OpHelp(""), - /* 102 */ "ColumnsUsed" OpHelp(""), - /* 103 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 104 */ "NextId" OpHelp("r[P3]=get_max(space_index[P1]{Column[P2]})"), - /* 105 */ "NextIdEphemeral" OpHelp("r[P3]=get_max(space_index[P1]{Column[P2]})"), - /* 106 */ "FCopy" OpHelp("reg[P2@cur_frame]= reg[P1@root_frame(OPFLAG_SAME_FRAME)]"), - /* 107 */ "Delete" OpHelp(""), - /* 108 */ "ResetCount" OpHelp(""), - /* 109 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 110 */ "SorterData" OpHelp("r[P2]=data"), - /* 111 */ "RowData" OpHelp("r[P2]=data"), - /* 112 */ "NullRow" OpHelp(""), - /* 113 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 114 */ "IdxReplace" OpHelp("key=r[P2]"), + /* 76 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 77 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 78 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 79 */ "CollSeq" OpHelp(""), + /* 80 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), + /* 81 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), + /* 82 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 83 */ "RealAffinity" OpHelp(""), + /* 84 */ "Cast" OpHelp("affinity(r[P1])"), + /* 85 */ "Permutation" OpHelp(""), + /* 86 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 87 */ "Column" OpHelp("r[P3]=PX"), + /* 88 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 89 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 90 */ "Count" OpHelp("r[P2]=count()"), + /* 91 */ "FkCheckCommit" OpHelp(""), + /* 92 */ "TTransaction" OpHelp(""), + /* 93 */ "ReadCookie" OpHelp(""), + /* 94 */ "SetCookie" OpHelp(""), + /* 95 */ "ReopenIdx" OpHelp("root=P2"), + /* 96 */ "OpenRead" OpHelp("root=P2"), + /* 97 */ "OpenWrite" OpHelp("root=P2"), + /* 98 */ "OpenTEphemeral" OpHelp("nColumn = P2"), + /* 99 */ "SorterOpen" OpHelp(""), + /* 100 */ "SequenceTest" OpHelp("if (cursor[P1].ctr++) pc = P2"), + /* 101 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 102 */ "Close" OpHelp(""), + /* 103 */ "ColumnsUsed" OpHelp(""), + /* 104 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 105 */ "NextId" OpHelp("r[P3]=get_max(space_index[P1]{Column[P2]})"), + /* 106 */ "NextIdEphemeral" OpHelp("r[P3]=get_max(space_index[P1]{Column[P2]})"), + /* 107 */ "FCopy" OpHelp("reg[P2@cur_frame]= reg[P1@root_frame(OPFLAG_SAME_FRAME)]"), + /* 108 */ "Delete" OpHelp(""), + /* 109 */ "ResetCount" OpHelp(""), + /* 110 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 111 */ "SorterData" OpHelp("r[P2]=data"), + /* 112 */ "RowData" OpHelp("r[P2]=data"), + /* 113 */ "NullRow" OpHelp(""), + /* 114 */ "SorterInsert" OpHelp("key=r[P2]"), /* 115 */ "Real" OpHelp("r[P2]=P4"), - /* 116 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 117 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 118 */ "Clear" OpHelp(""), - /* 119 */ "ResetSorter" OpHelp(""), - /* 120 */ "ParseSchema2" OpHelp("rows=r[P1@P2]"), - /* 121 */ "ParseSchema3" OpHelp("name=r[P1] sql=r[P1+1]"), - /* 122 */ "RenameTable" OpHelp("P1 = root, P4 = name"), - /* 123 */ "LoadAnalysis" OpHelp(""), - /* 124 */ "DropTable" OpHelp(""), - /* 125 */ "DropIndex" OpHelp(""), - /* 126 */ "DropTrigger" OpHelp(""), - /* 127 */ "Param" OpHelp(""), - /* 128 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 129 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 130 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 131 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 132 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 133 */ "Expire" OpHelp(""), - /* 134 */ "IncMaxid" OpHelp(""), - /* 135 */ "Noop" OpHelp(""), - /* 136 */ "Explain" OpHelp(""), + /* 116 */ "IdxReplace" OpHelp("key=r[P2]"), + /* 117 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 118 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 119 */ "Clear" OpHelp(""), + /* 120 */ "ResetSorter" OpHelp(""), + /* 121 */ "ParseSchema2" OpHelp("rows=r[P1@P2]"), + /* 122 */ "ParseSchema3" OpHelp("name=r[P1] sql=r[P1+1]"), + /* 123 */ "RenameTable" OpHelp("P1 = root, P4 = name"), + /* 124 */ "LoadAnalysis" OpHelp(""), + /* 125 */ "DropTable" OpHelp(""), + /* 126 */ "DropIndex" OpHelp(""), + /* 127 */ "DropTrigger" OpHelp(""), + /* 128 */ "Param" OpHelp(""), + /* 129 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 130 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 131 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 132 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 133 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 134 */ "Expire" OpHelp(""), + /* 135 */ "IncMaxid" OpHelp(""), + /* 136 */ "Noop" OpHelp(""), + /* 137 */ "Explain" OpHelp(""), }; return azName[i]; } diff --git a/src/box/sql/opcodes.h b/src/box/sql/opcodes.h index 1fbb6b690699..86ea6cf94a7d 100644 --- a/src/box/sql/opcodes.h +++ b/src/box/sql/opcodes.h @@ -68,75 +68,76 @@ #define OP_Bool 65 /* synopsis: r[P2]=P1 */ #define OP_Int64 66 /* synopsis: r[P2]=P4 */ #define OP_String 67 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_Null 68 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 69 /* synopsis: r[P1]=NULL */ -#define OP_Blob 70 /* synopsis: r[P2]=P4 (len=P1, subtype=P3) */ -#define OP_Variable 71 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 72 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 73 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 74 /* synopsis: r[P2]=r[P1] */ +#define OP_NextAutoincValue 68 /* synopsis: r[P2] = next value from space sequence, which pageno is r[P1] */ +#define OP_Null 69 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 70 /* synopsis: r[P1]=NULL */ +#define OP_Blob 71 /* synopsis: r[P2]=P4 (len=P1, subtype=P3) */ +#define OP_Variable 72 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 73 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 74 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_String8 75 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_IntCopy 76 /* synopsis: r[P2]=r[P1] */ -#define OP_ResultRow 77 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 78 -#define OP_Function0 79 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_Function 80 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_AddImm 81 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 82 -#define OP_Cast 83 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 84 -#define OP_Compare 85 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_Column 86 /* synopsis: r[P3]=PX */ -#define OP_Affinity 87 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 88 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 89 /* synopsis: r[P2]=count() */ -#define OP_FkCheckCommit 90 -#define OP_TTransaction 91 -#define OP_ReadCookie 92 -#define OP_SetCookie 93 -#define OP_ReopenIdx 94 /* synopsis: root=P2 */ -#define OP_OpenRead 95 /* synopsis: root=P2 */ -#define OP_OpenWrite 96 /* synopsis: root=P2 */ -#define OP_OpenTEphemeral 97 /* synopsis: nColumn = P2 */ -#define OP_SorterOpen 98 -#define OP_SequenceTest 99 /* synopsis: if (cursor[P1].ctr++) pc = P2 */ -#define OP_OpenPseudo 100 /* synopsis: P3 columns in r[P2] */ -#define OP_Close 101 -#define OP_ColumnsUsed 102 -#define OP_Sequence 103 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NextId 104 /* synopsis: r[P3]=get_max(space_index[P1]{Column[P2]}) */ -#define OP_NextIdEphemeral 105 /* synopsis: r[P3]=get_max(space_index[P1]{Column[P2]}) */ -#define OP_FCopy 106 /* synopsis: reg[P2@cur_frame]= reg[P1@root_frame(OPFLAG_SAME_FRAME)] */ -#define OP_Delete 107 -#define OP_ResetCount 108 -#define OP_SorterCompare 109 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 110 /* synopsis: r[P2]=data */ -#define OP_RowData 111 /* synopsis: r[P2]=data */ -#define OP_NullRow 112 -#define OP_SorterInsert 113 /* synopsis: key=r[P2] */ -#define OP_IdxReplace 114 /* synopsis: key=r[P2] */ +#define OP_SCopy 76 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 77 /* synopsis: r[P2]=r[P1] */ +#define OP_ResultRow 78 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 79 +#define OP_Function0 80 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_Function 81 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_AddImm 82 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 83 +#define OP_Cast 84 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 85 +#define OP_Compare 86 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_Column 87 /* synopsis: r[P3]=PX */ +#define OP_Affinity 88 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 89 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 90 /* synopsis: r[P2]=count() */ +#define OP_FkCheckCommit 91 +#define OP_TTransaction 92 +#define OP_ReadCookie 93 +#define OP_SetCookie 94 +#define OP_ReopenIdx 95 /* synopsis: root=P2 */ +#define OP_OpenRead 96 /* synopsis: root=P2 */ +#define OP_OpenWrite 97 /* synopsis: root=P2 */ +#define OP_OpenTEphemeral 98 /* synopsis: nColumn = P2 */ +#define OP_SorterOpen 99 +#define OP_SequenceTest 100 /* synopsis: if (cursor[P1].ctr++) pc = P2 */ +#define OP_OpenPseudo 101 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 102 +#define OP_ColumnsUsed 103 +#define OP_Sequence 104 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NextId 105 /* synopsis: r[P3]=get_max(space_index[P1]{Column[P2]}) */ +#define OP_NextIdEphemeral 106 /* synopsis: r[P3]=get_max(space_index[P1]{Column[P2]}) */ +#define OP_FCopy 107 /* synopsis: reg[P2@cur_frame]= reg[P1@root_frame(OPFLAG_SAME_FRAME)] */ +#define OP_Delete 108 +#define OP_ResetCount 109 +#define OP_SorterCompare 110 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 111 /* synopsis: r[P2]=data */ +#define OP_RowData 112 /* synopsis: r[P2]=data */ +#define OP_NullRow 113 +#define OP_SorterInsert 114 /* synopsis: key=r[P2] */ #define OP_Real 115 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_IdxInsert 116 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 117 /* synopsis: key=r[P2@P3] */ -#define OP_Clear 118 -#define OP_ResetSorter 119 -#define OP_ParseSchema2 120 /* synopsis: rows=r[P1@P2] */ -#define OP_ParseSchema3 121 /* synopsis: name=r[P1] sql=r[P1+1] */ -#define OP_RenameTable 122 /* synopsis: P1 = root, P4 = name */ -#define OP_LoadAnalysis 123 -#define OP_DropTable 124 -#define OP_DropIndex 125 -#define OP_DropTrigger 126 -#define OP_Param 127 -#define OP_FkCounter 128 /* synopsis: fkctr[P1]+=P2 */ -#define OP_OffsetLimit 129 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggStep0 130 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep 131 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggFinal 132 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 133 -#define OP_IncMaxid 134 -#define OP_Noop 135 -#define OP_Explain 136 +#define OP_IdxReplace 116 /* synopsis: key=r[P2] */ +#define OP_IdxInsert 117 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 118 /* synopsis: key=r[P2@P3] */ +#define OP_Clear 119 +#define OP_ResetSorter 120 +#define OP_ParseSchema2 121 /* synopsis: rows=r[P1@P2] */ +#define OP_ParseSchema3 122 /* synopsis: name=r[P1] sql=r[P1+1] */ +#define OP_RenameTable 123 /* synopsis: P1 = root, P4 = name */ +#define OP_LoadAnalysis 124 +#define OP_DropTable 125 +#define OP_DropIndex 126 +#define OP_DropTrigger 127 +#define OP_Param 128 +#define OP_FkCounter 129 /* synopsis: fkctr[P1]+=P2 */ +#define OP_OffsetLimit 130 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggStep0 131 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep 132 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggFinal 133 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 134 +#define OP_IncMaxid 135 +#define OP_Noop 136 +#define OP_Explain 137 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -157,16 +158,16 @@ /* 40 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01, 0x01,\ /* 48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 56 */ 0x03, 0x03, 0x03, 0x01, 0x02, 0x02, 0x08, 0x00,\ -/* 64 */ 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\ -/* 72 */ 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,\ -/* 80 */ 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,\ -/* 88 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ -/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ -/* 104 */ 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 112 */ 0x00, 0x04, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00,\ -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ -/* 128 */ 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 136 */ 0x00,} +/* 64 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10,\ +/* 72 */ 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\ +/* 80 */ 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00,\ +/* 88 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 104 */ 0x10, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ +/* 112 */ 0x00, 0x00, 0x04, 0x10, 0x00, 0x04, 0x00, 0x00,\ +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x10, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 136 */ 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 49ce51096056..a194a6e72788 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -44,12 +44,12 @@ #include "sqliteInt.h" #include "vdbeInt.h" #include "tarantoolInt.h" -#include "box/sql.h" #include "msgpuck/msgpuck.h" #include "box/schema.h" #include "box/space.h" +#include "box/sequence.h" /* * Invoke this macro on memory cells just prior to changing the @@ -1140,6 +1140,40 @@ case OP_String: { /* out2 */ break; } +/* Opcode: NextAutoincValue P1 P2 * * * + * Synopsis: r[P2] = next value from space sequence, which pageno is r[P1] + * + * Get next value from space sequence, which pageno is written into register + * P1, write this value into register P2. If space doesn't exists (invalid + * space_id or something else), raise an error. If space with + * specified space_id doesn't have attached sequence, also raise an error. + */ +case OP_NextAutoincValue: { + assert(pOp->p1 > 0); + assert(pOp->p2 > 0); + + int64_t value; + uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(pOp->p1); + + struct space *space = space_by_id(space_id); + if (space == NULL) { + rc = SQL_TARANTOOL_ERROR; + goto abort_due_to_error; + } + + struct sequence *sequence = space->sequence; + if (sequence == NULL || sequence_next(sequence, &value) != 0) { + rc = SQL_TARANTOOL_ERROR; + goto abort_due_to_error; + } + + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Int; + pOut->u.i = value; + + break; +} + /* Opcode: Null P1 P2 P3 * * * Synopsis: r[P2..P3]=NULL * diff --git a/test/sql/gh-2981-check-autoinc.result b/test/sql/gh-2981-check-autoinc.result new file mode 100644 index 000000000000..aaa0785d0e8c --- /dev/null +++ b/test/sql/gh-2981-check-autoinc.result @@ -0,0 +1,49 @@ +box.cfg{} +--- +... +box.sql.execute("CREATE TABLE t1 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19));"); +--- +... +box.sql.execute("CREATE TABLE t2 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19 AND s1 <> 25));"); +--- +... +box.sql.execute("CREATE TABLE t3 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 < 10));"); +--- +... +box.sql.execute("insert into t1 values (18, null);") +--- +... +box.sql.execute("insert into t1(s2) values (null);") +--- +- error: 'CHECK constraint failed: T1' +... +box.sql.execute("insert into t2 values (18, null);") +--- +... +box.sql.execute("insert into t2(s2) values (null);") +--- +- error: 'CHECK constraint failed: T2' +... +box.sql.execute("insert into t2 values (24, null);") +--- +... +box.sql.execute("insert into t2(s2) values (null);") +--- +- error: 'CHECK constraint failed: T2' +... +box.sql.execute("insert into t3 values (9, null)") +--- +... +box.sql.execute("insert into t3(s2) values (null)") +--- +- error: 'CHECK constraint failed: T3' +... +box.sql.execute("DROP TABLE t1") +--- +... +box.sql.execute("DROP TABLE t2") +--- +... +box.sql.execute("DROP TABLE t3") +--- +... diff --git a/test/sql/gh-2981-check-autoinc.test.lua b/test/sql/gh-2981-check-autoinc.test.lua new file mode 100644 index 000000000000..f13650519533 --- /dev/null +++ b/test/sql/gh-2981-check-autoinc.test.lua @@ -0,0 +1,21 @@ +box.cfg{} + +box.sql.execute("CREATE TABLE t1 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19));"); +box.sql.execute("CREATE TABLE t2 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19 AND s1 <> 25));"); +box.sql.execute("CREATE TABLE t3 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 < 10));"); + +box.sql.execute("insert into t1 values (18, null);") +box.sql.execute("insert into t1(s2) values (null);") + +box.sql.execute("insert into t2 values (18, null);") +box.sql.execute("insert into t2(s2) values (null);") +box.sql.execute("insert into t2 values (24, null);") +box.sql.execute("insert into t2(s2) values (null);") + +box.sql.execute("insert into t3 values (9, null)") +box.sql.execute("insert into t3(s2) values (null)") + +box.sql.execute("DROP TABLE t1") +box.sql.execute("DROP TABLE t2") +box.sql.execute("DROP TABLE t3") +