Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Simplifications to the uniqueness constraint failure error message generation code. (CVS 6595) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8f3cac7682a0c992f95f7453aaf9a29b |
User & Date: | drh 2009-05-02 15:46:47.000 |
Context
2009-05-03
| ||
01:01 | More changes to insert.c to facilitate full coverage testing. (CVS 6596) (check-in: 46c4ec968b user: drh tags: trunk) | |
2009-05-02
| ||
15:46 | Simplifications to the uniqueness constraint failure error message generation code. (CVS 6595) (check-in: 8f3cac7682 user: drh tags: trunk) | |
13:29 | Remove the aFKey hash table, which was not being used. Simplify the FKey object. Simplify the hash.c module since the copyKey parameter formerly used only by aFKey is now no longer required. (CVS 6594) (check-in: 80c43a355c user: drh tags: trunk) | |
Changes
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.265 2009/05/02 15:46:47 drh Exp $ */ #include "sqliteInt.h" /* ** Generate code that will open a table for reading. */ void sqlite3OpenTable( |
︙ | ︙ | |||
431 432 433 434 435 436 437 | goto insert_cleanup; } /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); zTab = pTabList->a[0].zName; | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | goto insert_cleanup; } /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); zTab = pTabList->a[0].zName; if( NEVER(zTab==0) ) goto insert_cleanup; pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb<db->nDb ); pDb = &db->aDb[iDb]; |
︙ | ︙ | |||
553 554 555 556 557 558 559 | addrSelect = sqlite3VdbeCurrentAddr(v)+2; sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm); j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); VdbeComment((v, "Jump over SELECT coroutine")); /* Resolve the expressions in the SELECT statement and execute it. */ rc = sqlite3Select(pParse, pSelect, &dest); | > | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 | addrSelect = sqlite3VdbeCurrentAddr(v)+2; sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm); j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); VdbeComment((v, "Jump over SELECT coroutine")); /* Resolve the expressions in the SELECT statement and execute it. */ rc = sqlite3Select(pParse, pSelect, &dest); assert( pParse->nErr==0 || rc ); if( rc || NEVER(pParse->nErr) || db->mallocFailed ){ goto insert_cleanup; } sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); VdbeComment((v, "End of SELECT coroutine")); sqlite3VdbeJumpHere(v, j1); /* label B: */ |
︙ | ︙ | |||
1163 1164 1165 1166 1167 1168 1169 | sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC); break; } case OE_Ignore: { sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest); break; } | > | | 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 | sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC); break; } case OE_Ignore: { sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest); break; } default: { assert( onError==OE_Replace ); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i); sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i); sqlite3VdbeJumpHere(v, j1); break; } } } |
︙ | ︙ | |||
1291 1292 1293 1294 1295 1296 1297 | /* Generate code that executes if the new index entry is not unique */ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Rollback: case OE_Abort: case OE_Fail: { | | > > | | > > | < | | < < | < < | < < < < < | < | | > | > > | | 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 | /* Generate code that executes if the new index entry is not unique */ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Rollback: case OE_Abort: case OE_Fail: { int j; StrAccum errMsg; const char *zSep; char *zErr; sqlite3StrAccumInit(&errMsg, 0, 0, 200); errMsg.db = pParse->db; zSep = pIdx->nColumn>1 ? "columns " : "column "; for(j=0; j<pIdx->nColumn; j++){ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; sqlite3StrAccumAppend(&errMsg, zSep, -1); zSep = ", "; sqlite3StrAccumAppend(&errMsg, zCol, -1); } sqlite3StrAccumAppend(&errMsg, pIdx->nColumn>1 ? " are not unique" : " is not unique", -1); zErr = sqlite3StrAccumFinish(&errMsg); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, zErr, 0); sqlite3DbFree(errMsg.db, zErr); break; } case OE_Ignore: { assert( seenReplace==0 ); sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); break; } default: { assert( onError==OE_Replace ); sqlite3GenerateRowDelete(pParse, pTab, baseCur, regR, 0); seenReplace = 1; break; } } sqlite3VdbeJumpHere(v, j2); sqlite3VdbeJumpHere(v, j3); |
︙ | ︙ |
Changes to test/unique.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE UNIQUE INDEX statement, # and primary keys, and the UNIQUE constraint on table columns # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE UNIQUE INDEX statement, # and primary keys, and the UNIQUE constraint on table columns # # $Id: unique.test,v 1.9 2009/05/02 15:46:47 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Try to create a table with two primary keys. # (This is allowed in SQLite even that it is not valid SQL) # |
︙ | ︙ | |||
244 245 246 247 248 249 250 | SELECT * FROM t5; } } {1 2 3 4 5 6} do_test unique-5.2 { catchsql { INSERT INTO t5 VALUES(1,2,3,4,5,6); } | | | 244 245 246 247 248 249 250 251 252 253 | SELECT * FROM t5; } } {1 2 3 4 5 6} do_test unique-5.2 { catchsql { INSERT INTO t5 VALUES(1,2,3,4,5,6); } } {1 {columns first_column_with_long_name, second_column_with_long_name, third_column_with_long_name, fourth_column_with_long_name, fifth_column_with_long_name, sixth_column_with_long_name are not unique}} finish_test |