SQLite

Check-in [73efca985a]
Login

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

Overview
Comment:Use one less temporary table in genfkey.c. The retired table was being used to workaround the bug fixed by (5812). (CVS 5813)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 73efca985a05930df761b42886a3ba1c5199f32a
User & Date: danielk1977 2008-10-13 10:56:48.000
Context
2008-10-13
14:16
In rollback.test, do not check for journal deletion if the journal mode is not DELETE. Call show_memstats after each test module in all.test and quick.test. (CVS 5814) (check-in: df2c28dc73 user: drh tags: trunk)
10:56
Use one less temporary table in genfkey.c. The retired table was being used to workaround the bug fixed by (5812). (CVS 5813) (check-in: 73efca985a user: danielk1977 tags: trunk)
10:37
If sqlite3_column_value() is called to obtain a value with the MEM_Static flag set, clear it and set the MEM_Ephem flag before returning. Otherwise, if the value is passed to sqlite3_bind_value() or sqlite3_result_value(), sqlite may attempt to use the buffer after the statement has been finalized. This is not always valid, as MEM_Static only guarantees that a MEM.z buffer will be valid for the lifetime of the owner statement, not that it is actually a static buffer. (CVS 5812) (check-in: b055bfc4e5 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to tool/genfkey.c.
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 for 'genfkey', a program to generate trigger
** definitions that emulate foreign keys. See genfkey.README for details.
**
** $Id: genfkey.c,v 1.1 2008/10/10 17:58:27 danielk1977 Exp $
*/

#include "sqlite3.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>







|







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 for 'genfkey', a program to generate trigger
** definitions that emulate foreign keys. See genfkey.README for details.
**
** $Id: genfkey.c,v 1.2 2008/10/13 10:56:48 danielk1977 Exp $
*/

#include "sqlite3.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
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
      "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
      "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
      "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"

      "CREATE TABLE temp.fkey AS "
        "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
        "FROM temp.v_fkey WHERE database = 'main';"
      "CREATE TABLE temp.col AS "
        "SELECT * FROM temp.v_col WHERE database = 'main';"

      , 0, 0, pzErr
  );
  if( rc!=SQLITE_OK ) return rc;

  rc = detectSchemaProblem(db, "foreign key columns do not exist",
    "SELECT fkid, from_tbl "
    "FROM temp.fkey "
    "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
        "FROM temp.col WHERE tablename=to_tbl AND name==to_col"
    ")", pHasErrors
  );
  if( rc!=SQLITE_OK ) return rc;

  /* At this point the temp.fkey table is mostly populated. If any foreign
  ** keys were specified so that they implicitly refer to they primary
  ** key of the parent table, the "to_col" values of the temp.fkey rows







<
<









|







581
582
583
584
585
586
587


588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
      "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
      "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
      "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"

      "CREATE TABLE temp.fkey AS "
        "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
        "FROM temp.v_fkey WHERE database = 'main';"



      , 0, 0, pzErr
  );
  if( rc!=SQLITE_OK ) return rc;

  rc = detectSchemaProblem(db, "foreign key columns do not exist",
    "SELECT fkid, from_tbl "
    "FROM temp.fkey "
    "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
        "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col"
    ")", pHasErrors
  );
  if( rc!=SQLITE_OK ) return rc;

  /* At this point the temp.fkey table is mostly populated. If any foreign
  ** keys were specified so that they implicitly refer to they primary
  ** key of the parent table, the "to_col" values of the temp.fkey rows
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
  /* Detect attempts to implicitly map to the primary key of a table 
  ** that has no primary key column.
  */
  rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
    "SELECT fkid, from_tbl "
    "FROM temp.fkey "
    "WHERE to_col IS NULL AND NOT EXISTS "
      "(SELECT 1 FROM temp.col WHERE pk AND tablename = temp.fkey.to_tbl)"
    , pHasErrors
  );
  if( rc!=SQLITE_OK ) return rc;

  /* Fix all the implicit primary key mappings in the temp.fkey table. */
  rc = sqlite3_exec(db, 
    "UPDATE temp.fkey SET to_col = "
      "(SELECT name FROM temp.col WHERE pk AND tablename=temp.fkey.to_tbl)"
    " WHERE to_col IS NULL;"
    , 0, 0, pzErr
  );
  if( rc!=SQLITE_OK ) return rc;

  /* Now check that all all parent keys are either primary keys or 
  ** subject to a unique constraint.
  */
  rc = sqlite3_exec(db, 
    "CREATE TABLE temp.idx2 AS SELECT "
      "il.tablename AS tablename,"
      "ii.indexname AS indexname,"
      "ii.name AS col "
      "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
      "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
    "INSERT INTO temp.idx2 SELECT tablename, 'pk', name FROM temp.col WHERE pk;"


    "CREATE TABLE temp.idx AS SELECT "
      "tablename, indexname, sj(dq(col),',') AS cols "
      "FROM (SELECT * FROM temp.idx2 ORDER BY col) " 
      "GROUP BY tablename, indexname;"

    "CREATE TABLE temp.fkey2 AS SELECT "







|







|















|
>







623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
  /* Detect attempts to implicitly map to the primary key of a table 
  ** that has no primary key column.
  */
  rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
    "SELECT fkid, from_tbl "
    "FROM temp.fkey "
    "WHERE to_col IS NULL AND NOT EXISTS "
      "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)"
    , pHasErrors
  );
  if( rc!=SQLITE_OK ) return rc;

  /* Fix all the implicit primary key mappings in the temp.fkey table. */
  rc = sqlite3_exec(db, 
    "UPDATE temp.fkey SET to_col = "
      "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)"
    " WHERE to_col IS NULL;"
    , 0, 0, pzErr
  );
  if( rc!=SQLITE_OK ) return rc;

  /* Now check that all all parent keys are either primary keys or 
  ** subject to a unique constraint.
  */
  rc = sqlite3_exec(db, 
    "CREATE TABLE temp.idx2 AS SELECT "
      "il.tablename AS tablename,"
      "ii.indexname AS indexname,"
      "ii.name AS col "
      "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
      "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
    "INSERT INTO temp.idx2 "
      "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;"

    "CREATE TABLE temp.idx AS SELECT "
      "tablename, indexname, sj(dq(col),',') AS cols "
      "FROM (SELECT * FROM temp.idx2 ORDER BY col) " 
      "GROUP BY tablename, indexname;"

    "CREATE TABLE temp.fkey2 AS SELECT "