Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix new issues in the geopoly module discovered by TH3. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
22fff9afc2fb20906173f258aa8feae9 |
User & Date: | drh 2018-08-28 15:51:10.106 |
Context
2018-08-28
| ||
19:23 | Stricter enforcement of the JSON and GeoJSON standards in the Geopoly extension. (check-in: c0bf3ff3af user: drh tags: trunk) | |
15:51 | Fix new issues in the geopoly module discovered by TH3. (check-in: 22fff9afc2 user: drh tags: trunk) | |
11:23 | Fix a problem causing spurious SQLITE_CORRUPT errors when using the snapshot API to read from old database snapshots. (check-in: 535155be58 user: dan tags: trunk) | |
Changes
Changes to ext/rtree/geopoly.c.
︙ | ︙ | |||
183 184 185 186 187 188 189 | if( z[j-1]<'0' ) return 0; if( pVal ) *pVal = atof((const char*)p->z); p->z += j; return 1; } /* | | | | > | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | if( z[j-1]<'0' ) return 0; if( pVal ) *pVal = atof((const char*)p->z); p->z += j; return 1; } /* ** If the input is a well-formed JSON array of coordinates with at least ** four coordinates and where each coordinate is itself a two-value array, ** then convert the JSON into a GeoPoly object and return a pointer to ** that object. ** ** If any error occurs, return NULL. */ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ GeoParse s; int rc = SQLITE_OK; memset(&s, 0, sizeof(s)); |
︙ | ︙ | |||
217 218 219 220 221 222 223 | } while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ ii++; if( ii==2 ) s.nVertex++; c = geopolySkipSpace(&s); s.z++; if( c==',' ) continue; | | | > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | } while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ ii++; if( ii==2 ) s.nVertex++; c = geopolySkipSpace(&s); s.z++; if( c==',' ) continue; if( c==']' && ii>=2 ) break; s.nErr++; rc = SQLITE_ERROR; goto parse_json_err; } if( geopolySkipSpace(&s)==',' ){ s.z++; continue; } break; } if( geopolySkipSpace(&s)==']' && s.nVertex>=4 && (s.z++, geopolySkipSpace(&s)==0) ){ int nByte; GeoPoly *pOut; int x = (s.nVertex-1)*2; if( s.a[x]==s.a[0] && s.a[x+1]==s.a[1] ) s.nVertex--; nByte = sizeof(GeoPoly) * (s.nVertex-1)*2*sizeof(GeoCoord); pOut = sqlite3_malloc64( nByte ); x = 1; |
︙ | ︙ | |||
301 302 303 304 305 306 307 | } } if( pRc ) *pRc = SQLITE_OK; return p; }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ return geopolyParseJson(sqlite3_value_text(pVal), pRc); }else{ | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | } } if( pRc ) *pRc = SQLITE_OK; return p; }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ return geopolyParseJson(sqlite3_value_text(pVal), pRc); }else{ if( pRc ) *pRc = SQLITE_ERROR; if( pCtx!=0 ) sqlite3_result_error(pCtx, "not a valid polygon", -1); return 0; } } /* ** Implementation of the geopoly_blob(X) function. |
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 | rc = nodeAcquire(pRtree, 1, 0, &pRoot); if( rc==SQLITE_OK && idxNum<=3 ){ RtreeCoord bbox[4]; RtreeConstraint *p; assert( argc==1 ); geopolyBBox(0, argv[0], bbox, &rc); if( rc ){ | | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 | rc = nodeAcquire(pRtree, 1, 0, &pRoot); if( rc==SQLITE_OK && idxNum<=3 ){ RtreeCoord bbox[4]; RtreeConstraint *p; assert( argc==1 ); geopolyBBox(0, argv[0], bbox, &rc); if( rc ){ goto geopoly_filter_end; } pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); pCsr->nConstraint = 4; if( p==0 ){ rc = SQLITE_NOMEM; }else{ memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); |
︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 | p->u.rValue = bbox[3].f; } } } if( rc==SQLITE_OK ){ RtreeSearchPoint *pNew; pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); | | > > > > | 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 | p->u.rValue = bbox[3].f; } } } if( rc==SQLITE_OK ){ RtreeSearchPoint *pNew; pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); if( pNew==0 ){ rc = SQLITE_NOMEM; goto geopoly_filter_end; } pNew->id = 1; pNew->iCell = 0; pNew->eWithin = PARTLY_WITHIN; assert( pCsr->bPoint==1 ); pCsr->aNode[0] = pRoot; pRoot = 0; RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); rc = rtreeStepToLeaf(pCsr); } } geopoly_filter_end: nodeRelease(pRtree, pRoot); rtreeRelease(pRtree); return rc; } /* ** Rtree virtual table module xBestIndex method. There are three |
︙ | ︙ | |||
1398 1399 1400 1401 1402 1403 1404 | ){ geopolyBBox(0, aData[2], cell.aCoord, &rc); if( rc ){ if( rc==SQLITE_ERROR ){ pVtab->zErrMsg = sqlite3_mprintf("_shape does not contain a valid polygon"); } | | | 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 | ){ geopolyBBox(0, aData[2], cell.aCoord, &rc); if( rc ){ if( rc==SQLITE_ERROR ){ pVtab->zErrMsg = sqlite3_mprintf("_shape does not contain a valid polygon"); } 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 ){ int steprc; |
︙ | ︙ | |||
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 | } if( nChange ){ sqlite3_step(pUp); rc = sqlite3_reset(pUp); } } rtreeRelease(pRtree); return rc; } /* ** Report that geopoly_overlap() is an overloaded function suitable ** for use in xBestIndex. | > | 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 | } if( nChange ){ sqlite3_step(pUp); rc = sqlite3_reset(pUp); } } geopoly_update_end: rtreeRelease(pRtree); return rc; } /* ** Report that geopoly_overlap() is an overloaded function suitable ** for use in xBestIndex. |
︙ | ︙ |