SQLite

Check-in [12e77e759e]
Login

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

Overview
Comment:Handle conflicting ON CONFLICT clauses in table definitions. (CVS 1611)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 12e77e759ec5b45b7fb94aa815435127f395162e
User & Date: danielk1977 2004-06-17 06:13:34.000
Context
2004-06-17
07:53
Remove redundant opcodes OP_MakeKey and OP_MakeIdxKey. (CVS 1612) (check-in: a71a9ff114 user: danielk1977 tags: trunk)
06:13
Handle conflicting ON CONFLICT clauses in table definitions. (CVS 1611) (check-in: 12e77e759e user: danielk1977 tags: trunk)
05:36
Use the faster LIKE function from sqlite v2. Add special user functions to test builds to test the auxdata APIs. (CVS 1610) (check-in: b9493c5fac user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.219 2004/06/15 16:51:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.220 2004/06/17 06:13:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087








2088
2089
2090
2091
2092
2093
2094

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){
        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
        if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
      }
      if( k==pIdx->nColumn ){
        /* FIX ME: It's possible the onError of the old index should be
        ** adjusted. For example in the statement:
        **
        ** CREATE TABLE t (x UNIQUE, UNIQUE(x) ON CONFLICT ROLLBACK);
        **
        ** The Index.onError should be upgraded from OE_Abort to
        ** OE_Rollback when the second UNIQUE is parsed.
        */








        goto exit_create_index;
      }
    }
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 







|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>







2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){
        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
        if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
      }
      if( k==pIdx->nColumn ){
        if( pIdx->onError!=pIndex->onError ){
          /* This constraint creates the same index as a previous
          ** constraint specified somewhere in the CREATE TABLE statement.
          ** However the ON CONFLICT clauses are different. If both this 
          ** constraint and the previous equivalent constraint have explicit
          ** ON CONFLICT clauses this is an error. Otherwise, use the
          ** explicitly specified behaviour for the index.
          */
          if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
            sqlite3ErrorMsg(pParse, 
                "conflicting ON CONFLICT clauses specified", 0);
          }
          if( pIdx->onError==OE_Default ){
            pIdx->onError = pIndex->onError;
          }
        }
        goto exit_create_index;
      }
    }
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 
Changes to test/index.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 testing the CREATE INDEX statement.
#
# $Id: index.test,v 1.28 2004/06/12 09:25:30 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a basic index and verify it is added to sqlite_master
#
do_test index-1.1 {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 testing the CREATE INDEX statement.
#
# $Id: index.test,v 1.29 2004/06/17 06:13:35 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a basic index and verify it is added to sqlite_master
#
do_test index-1.1 {
597
598
599
600
601
602
603



604













































605
606
  }
} {1 {object name reserved for internal use: sqlite_v1}}
do_test index-18.4 {
  catchsql {
    CREATE TRIGGER sqlite_tr1 BEFORE INSERT ON t7 BEGIN SELECT 1; END;
  }
} {1 {object name reserved for internal use: sqlite_tr1}}

















































finish_test








>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
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
  }
} {1 {object name reserved for internal use: sqlite_v1}}
do_test index-18.4 {
  catchsql {
    CREATE TRIGGER sqlite_tr1 BEFORE INSERT ON t7 BEGIN SELECT 1; END;
  }
} {1 {object name reserved for internal use: sqlite_tr1}}
do_test index-18.5 {
  execsql {
    DROP TABLE t7;
  }
} {}

# These tests ensure that if multiple table definition constraints are
# implemented by a single indice, the correct ON CONFLICT policy applies.
do_test index-19.1 {
  execsql {
    CREATE TABLE t7(a UNIQUE PRIMARY KEY);
    CREATE TABLE t8(a UNIQUE PRIMARY KEY ON CONFLICT ROLLBACK);
    INSERT INTO t7 VALUES(1);
    INSERT INTO t8 VALUES(1);
  }
} {}
do_test index-19.2 {
  catchsql {
    BEGIN;
    INSERT INTO t7 VALUES(1);
  }
} {1 {column a is not unique}}
do_test index-19.3 {
  catchsql {
    BEGIN;
  }
} {1 {cannot start a transaction within a transaction}}
do_test index-19.4 {
  catchsql {
    INSERT INTO t8 VALUES(1);
  }
} {1 {column a is not unique}}
do_test index-19.5 {
  catchsql {
    BEGIN;
    COMMIT;
  }
} {0 {}}
do_test index-19.6 {
  catchsql {
    DROP TABLE t7;
    DROP TABLE t8;
    CREATE TABLE t7(
       a PRIMARY KEY ON CONFLICT FAIL, 
       UNIQUE(a) ON CONFLICT IGNORE
    );
  }
} {1 {conflicting ON CONFLICT clauses specified}}

finish_test