SQLite

Check-in [7b69968618]
Login

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

Overview
Comment:Fix a bug with explicit collation sequences attached to a column reference expression that is on the right-hand-side of a binary comparison operator. (CVS 4187)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7b69968618bfc19f0c1ab25c5f16c9fdff5af094
User & Date: danielk1977 2007-07-30 14:40:48.000
Context
2007-07-30
18:24
Get rid of the following compile-time warning: "src/shell.c:112: warning: 'iotracePrintf' defined but not used" (CVS 4188) (check-in: 271e27fd30 user: rse tags: trunk)
14:40
Fix a bug with explicit collation sequences attached to a column reference expression that is on the right-hand-side of a binary comparison operator. (CVS 4187) (check-in: 7b69968618 user: danielk1977 tags: trunk)
2007-07-26
10:16
Test that an explicit collation sequence overrides an implicit one attached to a 'new' reference (it does). No code changes. (CVS 4186) (check-in: a443b07ed6 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/where.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.253 2007/06/11 12:56:15 drh Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.254 2007/07/30 14:40:48 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
379
380
381
382
383
384
385








386
387


388
389


390
391
392
393
394
395
396
** Swap two objects of type T.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparision operator.  Expressions of the form "X op Y"
** are converted into "Y op X".








*/
static void exprCommute(Expr *pExpr){


  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);


  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );







>
>
>
>
>
>
>
>


>
>


>
>







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
** Swap two objects of type T.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparision operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If a collation sequence is associated with either the left or right
** side of the comparison, it remains associated with the same side after
** the commutation. So "Y collate NOCASE op X" becomes 
** "X collate NOCASE op Y". This is because any collation sequence on
** the left hand side of a comparison overrides any collation sequence 
** attached to the right. For the same reason the EP_ExpCollate flag
** is not commuted.
*/
static void exprCommute(Expr *pExpr){
  u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
  u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
  pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
  pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
Changes to test/collate6.test.
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 implements regression tests for SQLite library.  The
# focus of this script is collation sequences in concert with triggers.
#
# $Id: collate6.test,v 1.3 2007/07/26 10:16:30 danielk1977 Exp $

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

# There are no tests in this file that will work without
# trigger support.
#







|







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 implements regression tests for SQLite library.  The
# focus of this script is collation sequences in concert with triggers.
#
# $Id: collate6.test,v 1.4 2007/07/30 14:40:48 danielk1977 Exp $

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

# There are no tests in this file that will work without
# trigger support.
#
131
132
133
134
135
136
137













138
139
140
    UPDATE abc SET a = 'four' WHERE a = 'one';
    CREATE TRIGGER abc_t2 AFTER UPDATE ON abc BEGIN
      INSERT INTO def SELECT * FROM abc WHERE a < new.a COLLATE nocase;
    END;
    SELECT * FROM def;
  }
} {}















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    UPDATE abc SET a = 'four' WHERE a = 'one';
    CREATE TRIGGER abc_t2 AFTER UPDATE ON abc BEGIN
      INSERT INTO def SELECT * FROM abc WHERE a < new.a COLLATE nocase;
    END;
    SELECT * FROM def;
  }
} {}

# At one point the 6-3.2 (but not 6-3.1) was causing an assert() to fail.
#
do_test collate6-3.1 {
  execsql {
    SELECT 1 FROM sqlite_master WHERE name COLLATE nocase = 'hello';
  }
} {}
do_test collate6-3.2 {
  execsql {
    SELECT 1 FROM sqlite_master WHERE 'hello' = name COLLATE nocase;
  }
} {}


finish_test