Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add tests (and modify test code) for writing to virtual tables. (CVS 3253) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6380a9b118cf972c3c7d4886ecdb62c4 |
User & Date: | danielk1977 2006-06-15 10:41:16.000 |
Context
2006-06-15
| ||
13:22 | Asserts added that verify that the code works correctly that ticket #1849 claims is wrong. (CVS 3254) (check-in: d145dc1c4b user: drh tags: trunk) | |
10:41 | Add tests (and modify test code) for writing to virtual tables. (CVS 3253) (check-in: 6380a9b118 user: danielk1977 tags: trunk) | |
07:29 | Simple tests and fixes for writing to virtual tables. (CVS 3252) (check-in: 88fa510e4c user: danielk1977 tags: trunk) | |
Changes
Changes to src/test8.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test8.c,v 1.22 2006/06/15 10:41:16 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
424 425 426 427 428 429 430 431 432 433 434 435 436 437 | pConstraint = &pIdxInfo->aConstraint[ii]; pUsage = &pIdxInfo->aConstraintUsage[ii]; int iCol = pConstraint->iColumn; if( pVtab->aIndex[iCol] ){ char *zCol = pVtab->aCol[iCol]; char *zOp = 0; switch( pConstraint->op ){ case SQLITE_INDEX_CONSTRAINT_EQ: zOp = "="; break; case SQLITE_INDEX_CONSTRAINT_LT: zOp = "<"; break; case SQLITE_INDEX_CONSTRAINT_GT: zOp = ">"; break; | > > > | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | pConstraint = &pIdxInfo->aConstraint[ii]; pUsage = &pIdxInfo->aConstraintUsage[ii]; int iCol = pConstraint->iColumn; if( pVtab->aIndex[iCol] ){ char *zCol = pVtab->aCol[iCol]; char *zOp = 0; if( iCol<0 ){ zCol = "rowid"; } switch( pConstraint->op ){ case SQLITE_INDEX_CONSTRAINT_EQ: zOp = "="; break; case SQLITE_INDEX_CONSTRAINT_LT: zOp = "<"; break; case SQLITE_INDEX_CONSTRAINT_GT: zOp = ">"; break; |
︙ | ︙ | |||
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 | pIdxInfo->idxNum = hashString(zQuery); pIdxInfo->idxStr = zQuery; pIdxInfo->needToFreeIdxStr = 1; pIdxInfo->estimatedCost = 1.0; return SQLITE_OK; } int echoUpdate(sqlite3_vtab *tab, int nData, sqlite3_value **apData){ echo_vtab *pVtab = (echo_vtab *)tab; sqlite3 *db = pVtab->db; int rc = SQLITE_OK; assert( nData==pVtab->nCol+2 || nData==1 ); /* If apData[0] is an integer and nData>1 then do an UPDATE */ if( nData>1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < | | > | > | < < < > | < < | > | < < < < < < | | < | < > | | > | < > > > | > | > | < > | < < < < | > > | | > | < | | < > > > > | | < > > > | < < < < < < < < | | > | > | < < | < < | < < < < < < < | < < | < < < < | < < < < < < < < < < < < | | < | | < < < < < < < < < < < < | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | pIdxInfo->idxNum = hashString(zQuery); pIdxInfo->idxStr = zQuery; pIdxInfo->needToFreeIdxStr = 1; pIdxInfo->estimatedCost = 1.0; return SQLITE_OK; } static void string_concat(char **pzStr, char *zAppend, int doFree){ char *zIn = *pzStr; if( zIn ){ char *zTemp = zIn; zIn = sqlite3_mprintf("%s%s", zIn, zAppend); sqlite3_free(zTemp); }else{ zIn = sqlite3_mprintf("%s", zAppend); } *pzStr = zIn; if( doFree ){ sqlite3_free(zAppend); } } /* ** apData[0] apData[1] apData[2..] ** ** INTEGER DELETE ** ** INTEGER NULL (nCol args) UPDATE (do not set rowid) ** INTEGER INTEGER (nCol args) UPDATE (with SET rowid = <arg1>) ** ** NULL NULL (nCol args) INSERT INTO (automatic rowid value) ** NULL INTEGER (nCol args) INSERT (incl. rowid value) ** */ int echoUpdate(sqlite3_vtab *tab, int nData, sqlite3_value **apData){ echo_vtab *pVtab = (echo_vtab *)tab; sqlite3 *db = pVtab->db; int rc = SQLITE_OK; sqlite3_stmt *pStmt; char *z = 0; /* SQL statement to execute */ int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */ int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */ int i; /* Counter variable used by for loops */ assert( nData==pVtab->nCol+2 || nData==1 ); /* If apData[0] is an integer and nData>1 then do an UPDATE */ if( nData>1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){ z = sqlite3_mprintf("UPDATE %Q", pVtab->zTableName); char *zSep = " SET"; bindArgOne = (apData[1] && sqlite3_value_type(apData[1])==SQLITE_INTEGER); bindArgZero = 1; if( bindArgOne ){ string_concat(&z, " SET rowid=?1 ", 0); zSep = ","; } for(i=2; i<nData; i++){ if( apData[i]==0 ) continue; string_concat(&z, sqlite3_mprintf( "%s %Q=?%d", zSep, pVtab->aCol[i-2], i), 1); zSep = ","; } string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 0); } /* If apData[0] is an integer and nData==1 then do a DELETE */ else if( nData==1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){ z = sqlite3_mprintf("DELETE FROM %Q WHERE rowid = ?1", pVtab->zTableName); bindArgZero = 1; } /* If the first argument is NULL and there are more than two args, INSERT */ else if( nData>2 && sqlite3_value_type(apData[0])==SQLITE_NULL ){ int ii; char *zInsert = 0; char *zValues = 0; zInsert = sqlite3_mprintf("INSERT OR REPLACE INTO %Q (", pVtab->zTableName); if( sqlite3_value_type(apData[1])==SQLITE_INTEGER ){ bindArgOne = 1; zValues = sqlite3_mprintf("?"); string_concat(&zInsert, "rowid", 0); } assert((pVtab->nCol+2)==nData); for(ii=2; ii<nData; ii++){ string_concat(&zInsert, sqlite3_mprintf("%s%Q", zValues?", ":"", pVtab->aCol[ii-2]), 1); string_concat(&zValues, sqlite3_mprintf("%s?%d", zValues?", ":"", ii), 1); } string_concat(&z, zInsert, 1); string_concat(&z, ") VALUES(", 0); string_concat(&z, zValues, 1); string_concat(&z, ")", 0); } /* Anything else is an error */ else{ assert(0); return SQLITE_ERROR; } rc = sqlite3_prepare(db, z, -1, &pStmt, 0); assert( rc!=SQLITE_OK || pStmt ); sqlite3_free(z); if( rc==SQLITE_OK ) { if( bindArgZero ){ sqlite3_bind_value(pStmt, nData, apData[0]); } if( bindArgOne ){ sqlite3_bind_value(pStmt, 1, apData[1]); } for(i=2; i<nData; i++){ if( apData[i] ) sqlite3_bind_value(pStmt, i, apData[i]); } sqlite3_step(pStmt); rc = sqlite3_finalize(pStmt); } return rc; } /* ** A virtual table module that merely echos method calls into TCL |
︙ | ︙ |
Changes to test/vtab1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # # $Id: vtab1.test,v 1.17 2006/06/15 10:41:16 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab { finish_test return |
︙ | ︙ | |||
430 431 432 433 434 435 436 | } {1 2 3} do_test vtab1-6-4 { execsql { UPDATE techo SET a = 5; SELECT * FROM techo; } } {5 2 3} | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | } {1 2 3} do_test vtab1-6-4 { execsql { UPDATE techo SET a = 5; SELECT * FROM techo; } } {5 2 3} # TODO: This causes a crash at present. # # do_test vtab1-6-5 { # explain { # UPDATE techo set a = a||b||c; # } # execsql { # UPDATE techo set a = a||b||c; # SELECT * FROM techo; # } #} {523 2 3} do_test vtab1-6-6 { execsql { UPDATE techo set rowid = 10; SELECT rowid FROM techo; } } {10} do_test vtab1-6-7 { execsql { DELETE FROM techo; SELECT * FROM techo; } } {} file delete -force test2.db file delete -force test2.db-journal sqlite3 db2 test2.db execsql { CREATE TABLE techo(a PRIMARY KEY, b, c); } db2 proc check_echo_table {tn} { set ::data1 [execsql {SELECT rowid, * FROM techo}] set ::data2 [execsql {SELECT rowid, * FROM techo} db2] do_test $tn { string equal $::data1 $::data2 } 1 } set tn 0 foreach stmt [list \ {INSERT INTO techo VALUES('abc', 'def', 'ghi')} \ {INSERT INTO techo SELECT a||'.'||rowid, b, c FROM techo} \ {INSERT INTO techo SELECT a||'x'||rowid, b, c FROM techo} \ {INSERT INTO techo SELECT a||'y'||rowid, b, c FROM techo} \ {DELETE FROM techo WHERE (oid % 3) = 0} \ {UPDATE techo set rowid = 100 WHERE rowid = 1} \ {INSERT INTO techo(a, b) VALUES('hello', 'world')} \ {DELETE FROM techo} \ ] { execsql $stmt execsql $stmt db2 check_echo_table vtab1-6.6.[incr tn] } db2 close finish_test |