/ Check-in [82a2ae71]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use SQLITE_PREPARE_NO_VTAB in rtree as well.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | prepare-no-vtab
Files: files | file ages | folders
SHA3-256: 82a2ae7132964eab0dfad9a8314a399ffd3b72366b35e1767df6452125dd1d80
User & Date: dan 2018-12-21 19:55:20
Context
2018-12-21
20:18
Add new sqlite3_prepare_v3() flag SQLITE_PREPARE_NO_VTAB, for preparing statements that are not allowed to use any virtual tables. Use this to prevent circular references in triggers on virtual table shadow tables from causing resource leaks. check-in: da587d18 user: dan tags: trunk
19:55
Use SQLITE_PREPARE_NO_VTAB in rtree as well. Closed-Leaf check-in: 82a2ae71 user: dan tags: prepare-no-vtab
19:30
Add tests for the use of SQLITE_PREPARE_NO_VTAB in fts5. check-in: 19996120 user: dan tags: prepare-no-vtab
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to ext/rtree/rtree.c.

3419
3420
3421
3422
3423
3424
3425

3426
3427
3428
3429
3430
3431
3432
....
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
....
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
    /* Read and write the xxx_parent table */
    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
  };
  sqlite3_stmt **appStmt[N_STATEMENT];
  int i;


  pRtree->db = db;

  if( isCreate ){
    char *zCreate;
    sqlite3_str *p = sqlite3_str_new(db);
    int ii;
................................................................................
       /* An UPSERT is very slightly slower than REPLACE, but it is needed
       ** if there are auxiliary columns */
       zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
                  "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
    }
    zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
    if( zSql ){
      rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
                              appStmt[i], 0); 
    }else{
      rc = SQLITE_NOMEM;
    }
    sqlite3_free(zSql);
  }
  if( pRtree->nAux ){
    pRtree->zReadAuxSql = sqlite3_mprintf(
................................................................................
        }
      }
      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,
                                &pRtree->pWriteAux, 0); 
        sqlite3_free(zSql);
      }
    }
  }

  return rc;
}







>







 







|
<







 







|
<







3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
....
3476
3477
3478
3479
3480
3481
3482
3483

3484
3485
3486
3487
3488
3489
3490
....
3506
3507
3508
3509
3510
3511
3512
3513

3514
3515
3516
3517
3518
3519
3520
    /* Read and write the xxx_parent table */
    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
  };
  sqlite3_stmt **appStmt[N_STATEMENT];
  int i;
  const int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;

  pRtree->db = db;

  if( isCreate ){
    char *zCreate;
    sqlite3_str *p = sqlite3_str_new(db);
    int ii;
................................................................................
       /* An UPSERT is very slightly slower than REPLACE, but it is needed
       ** if there are auxiliary columns */
       zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
                  "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
    }
    zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
    if( zSql ){
      rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); 

    }else{
      rc = SQLITE_NOMEM;
    }
    sqlite3_free(zSql);
  }
  if( pRtree->nAux ){
    pRtree->zReadAuxSql = sqlite3_mprintf(
................................................................................
        }
      }
      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, f, &pRtree->pWriteAux, 0); 

        sqlite3_free(zSql);
      }
    }
  }

  return rc;
}

Added ext/rtree/rtreecirc.test.





































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 2018 Dec 22
#
# 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 script is testing the FTS5 module.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
set testprefix rtreecirc

ifcapable !rtree {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, y1, y2);
  SELECT name FROM sqlite_master ORDER BY 1;
} {
  rt rt_node rt_parent rt_rowid
}
db_save_and_close

foreach {tn schema sql} {
  1 {
    CREATE TRIGGER tr1 AFTER INSERT ON rt_node BEGIN
      SELECT * FROM rt;
    END;
  } {
    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
  }
  2 {
    CREATE TRIGGER tr1 AFTER INSERT ON rt_parent BEGIN
      SELECT * FROM rt;
    END;
  } {
    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
  }
  3 {
    CREATE TRIGGER tr1 AFTER INSERT ON rt_rowid BEGIN
      SELECT * FROM rt;
    END;
  } {
    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
  }
} {
  db_restore_and_reopen
  do_execsql_test  1.1.$tn.1 $schema
  do_catchsql_test 1.1.$tn.2 $sql {1 {no such table: main.rt}}
  db close
}


finish_test