Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fixes to the UPDATE logic in Geopoly. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
7c3cee0a2a5ccacff27400c38bd708f7 |
User & Date: | drh 2018-08-29 20:52:40.880 |
Context
2018-08-29
| ||
21:01 | Additional test cases for geopoly. (check-in: 19b5eb45e0 user: drh tags: trunk) | |
20:52 | Fixes to the UPDATE logic in Geopoly. (check-in: 7c3cee0a2a user: drh tags: trunk) | |
20:24 | Also free up the MEM_RowSet bit in the Mem.flags field and have RowSet objects be destroyed using Mem.xDel. This change results in faster code. (check-in: f48e9feb3f user: drh tags: trunk) | |
Changes
Changes to ext/rtree/geopoly.c.
︙ | ︙ | |||
1118 1119 1120 1121 1122 1123 1124 | /* Create/Connect to the underlying relational database schema. If ** that is successful, call sqlite3_declare_vtab() to configure ** the r-tree table schema. */ pSql = sqlite3_str_new(db); sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); | | > | 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 | /* Create/Connect to the underlying relational database schema. If ** that is successful, call sqlite3_declare_vtab() to configure ** the r-tree table schema. */ pSql = sqlite3_str_new(db); sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); pRtree->nAux = 1; /* Add one for _shape */ pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ for(ii=3; ii<argc; ii++){ pRtree->nAux++; sqlite3_str_appendf(pSql, ",%s", argv[ii]); } sqlite3_str_appendf(pSql, ");"); zSql = sqlite3_str_finish(pSql); if( !zSql ){ |
︙ | ︙ | |||
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 | RtreeCursor *pCsr = (RtreeCursor *)cur; RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); int rc = SQLITE_OK; RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); if( rc ) return rc; if( p==0 ) return SQLITE_OK; if( i<=pRtree->nAux ){ if( !pCsr->bAuxValid ){ if( pCsr->pReadAux==0 ){ rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, &pCsr->pReadAux, 0); if( rc ) return rc; } | > | 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | RtreeCursor *pCsr = (RtreeCursor *)cur; RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); int rc = SQLITE_OK; RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); if( rc ) return rc; if( p==0 ) return SQLITE_OK; if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; if( i<=pRtree->nAux ){ if( !pCsr->bAuxValid ){ if( pCsr->pReadAux==0 ){ rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, &pCsr->pReadAux, 0); if( rc ) return rc; } |
︙ | ︙ | |||
1461 1462 1463 1464 1465 1466 1467 | ** since the write might do a rebalance which would disrupt the read ** cursor. */ return SQLITE_LOCKED_VTAB; } rtreeReference(pRtree); assert(nData>=1); | < | 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 | ** since the write might do a rebalance which would disrupt the read ** cursor. */ return SQLITE_LOCKED_VTAB; } rtreeReference(pRtree); assert(nData>=1); oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; cell.iRowid = newRowid; if( nData>1 /* not a DELETE */ |
︙ | ︙ | |||
1485 1486 1487 1488 1489 1490 1491 | } goto geopoly_update_end; } coordChange = 1; /* If a rowid value was supplied, check if it is already present in ** the table. If so, the constraint has failed. */ | | | 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 | } goto geopoly_update_end; } coordChange = 1; /* If a rowid value was supplied, check if it is already present in ** the table. If so, the constraint has failed. */ if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ int steprc; sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); steprc = sqlite3_step(pRtree->pReadRowid); rc = sqlite3_reset(pRtree->pReadRowid); if( SQLITE_ROW==steprc ){ if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ rc = rtreeDeleteRowid(pRtree, cell.iRowid); |
︙ | ︙ | |||
1539 1540 1541 1542 1543 1544 1545 | /* Change the data */ if( rc==SQLITE_OK ){ sqlite3_stmt *pUp = pRtree->pWriteAux; int jj; int nChange = 0; sqlite3_bind_int64(pUp, 1, cell.iRowid); | > > > > > > > | | | 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 | /* Change the data */ if( rc==SQLITE_OK ){ sqlite3_stmt *pUp = pRtree->pWriteAux; int jj; int nChange = 0; sqlite3_bind_int64(pUp, 1, cell.iRowid); assert( pRtree->nAux>=1 ); if( sqlite3_value_nochange(aData[2]) ){ sqlite3_bind_null(pUp, 2); }else{ sqlite3_bind_value(pUp, 2, aData[2]); nChange = 1; } for(jj=1; jj<pRtree->nAux; jj++){ nChange++; sqlite3_bind_value(pUp, jj+2, aData[jj+2]); } if( nChange ){ sqlite3_step(pUp); rc = sqlite3_reset(pUp); } } |
︙ | ︙ |
Changes to ext/rtree/rtree.c.
︙ | ︙ | |||
123 124 125 126 127 128 129 130 131 132 133 134 135 136 | int iNodeSize; /* Size in bytes of each node in the node table */ u8 nDim; /* Number of dimensions */ u8 nDim2; /* Twice the number of dimensions */ u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ u8 nBytesPerCell; /* Bytes consumed per cell */ u8 inWrTrans; /* True if inside write transaction */ u8 nAux; /* # of auxiliary columns in %_rowid */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ u32 nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ u32 nCursor; /* Number of open cursors */ u32 nNodeRef; /* Number RtreeNodes with positive nRef */ | > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | int iNodeSize; /* Size in bytes of each node in the node table */ u8 nDim; /* Number of dimensions */ u8 nDim2; /* Twice the number of dimensions */ u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ u8 nBytesPerCell; /* Bytes consumed per cell */ u8 inWrTrans; /* True if inside write transaction */ u8 nAux; /* # of auxiliary columns in %_rowid */ u8 nAuxNotNull; /* Number of initial not-null aux columns */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ u32 nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ u32 nCursor; /* Number of open cursors */ u32 nNodeRef; /* Number RtreeNodes with positive nRef */ |
︙ | ︙ | |||
3449 3450 3451 3452 3453 3454 3455 | }else{ sqlite3_str *p = sqlite3_str_new(db); int ii; char *zSql; sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); for(ii=0; ii<pRtree->nAux; ii++){ if( ii ) sqlite3_str_append(p, ",", 1); | > > > | > | 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 | }else{ sqlite3_str *p = sqlite3_str_new(db); int ii; char *zSql; sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); for(ii=0; ii<pRtree->nAux; ii++){ if( ii ) sqlite3_str_append(p, ",", 1); if( ii<pRtree->nAuxNotNull ){ sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); }else{ sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); } } sqlite3_str_appendf(p, " WHERE rowid=?1"); zSql = sqlite3_str_finish(p); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, |
︙ | ︙ |
Changes to ext/rtree/visual01.txt.
︙ | ︙ | |||
532 533 534 535 536 537 538 539 | FROM geo1, querypoly WHERE NOT geopoly_within(_shape, poly); SELECT geopoly_svg(poly, printf('style="fill:%s;fill-opacity:0.5;"',clr) ) FROM querypoly; .print '</svg>' .print '</html>' | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | FROM geo1, querypoly WHERE NOT geopoly_within(_shape, poly); SELECT geopoly_svg(poly, printf('style="fill:%s;fill-opacity:0.5;"',clr) ) FROM querypoly; .print '</svg>' .print '<h1>Color-Change For Overlapping Elements</h1>' BEGIN; UPDATE geo1 SET clr=CASE WHEN rowid IN (SELECT geo1.rowid FROM geo1, querypoly WHERE geopoly_overlap(_shape,poly)) THEN 'red' ELSE 'blue' END; .print '<svg width="1000" height="800" style="border:1px solid black">' SELECT geopoly_svg(_shape, printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) ) FROM geo1; SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') FROM querypoly; ROLLBACK; .print '</svg>' .print '<h1>Color-Change And Move Overlapping Elements</h1>' BEGIN; UPDATE geo1 SET clr=CASE WHEN rowid IN (SELECT geo1.rowid FROM geo1, querypoly WHERE geopoly_overlap(_shape,poly)) THEN 'red' ELSE 'blue' END; UPDATE geo1 SET _shape=geopoly_xform(_shape,1,0,0,1,300,0) WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly)); .print '<svg width="1000" height="800" style="border:1px solid black">' SELECT geopoly_svg(_shape, printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) ) FROM geo1; SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') FROM querypoly; ROLLBACK; .print '</svg>' .print '</html>' |