os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/collate3.test
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
# 2001 September 15
sl@0
     2
#
sl@0
     3
# The author disclaims copyright to this source code.  In place of
sl@0
     4
# a legal notice, here is a blessing:
sl@0
     5
#
sl@0
     6
#    May you do good and not evil.
sl@0
     7
#    May you find forgiveness for yourself and forgive others.
sl@0
     8
#    May you share freely, never taking more than you give.
sl@0
     9
#
sl@0
    10
#***********************************************************************
sl@0
    11
# This file implements regression tests for SQLite library.  The
sl@0
    12
# focus of this script is page cache subsystem.
sl@0
    13
#
sl@0
    14
# $Id: collate3.test,v 1.13 2008/08/20 16:35:10 drh Exp $
sl@0
    15
sl@0
    16
set testdir [file dirname $argv0]
sl@0
    17
source $testdir/tester.tcl
sl@0
    18
sl@0
    19
#
sl@0
    20
# Tests are organised as follows:
sl@0
    21
#
sl@0
    22
# collate3.1.* - Errors related to unknown collation sequences.
sl@0
    23
# collate3.2.* - Errors related to undefined collation sequences.
sl@0
    24
# collate3.3.* - Writing to a table that has an index with an undefined c.s.
sl@0
    25
# collate3.4.* - Misc errors.
sl@0
    26
# collate3.5.* - Collation factory.
sl@0
    27
#
sl@0
    28
sl@0
    29
#
sl@0
    30
# These tests ensure that when a user executes a statement with an 
sl@0
    31
# unknown collation sequence an error is returned.
sl@0
    32
#
sl@0
    33
do_test collate3-1.0 {
sl@0
    34
  execsql {
sl@0
    35
    CREATE TABLE collate3t1(c1);
sl@0
    36
  }
sl@0
    37
} {}
sl@0
    38
do_test collate3-1.1 {
sl@0
    39
  catchsql {
sl@0
    40
    SELECT * FROM collate3t1 ORDER BY 1 collate garbage;
sl@0
    41
  }
sl@0
    42
} {1 {no such collation sequence: garbage}}
sl@0
    43
do_test collate3-1.2 {
sl@0
    44
  catchsql {
sl@0
    45
    CREATE TABLE collate3t2(c1 collate garbage);
sl@0
    46
  }
sl@0
    47
} {1 {no such collation sequence: garbage}}
sl@0
    48
do_test collate3-1.3 {
sl@0
    49
  catchsql {
sl@0
    50
    CREATE INDEX collate3i1 ON collate3t1(c1 COLLATE garbage);
sl@0
    51
  }
sl@0
    52
} {1 {no such collation sequence: garbage}}
sl@0
    53
sl@0
    54
execsql {
sl@0
    55
  DROP TABLE collate3t1;
sl@0
    56
}
sl@0
    57
sl@0
    58
#
sl@0
    59
# Create a table with a default collation sequence, then close
sl@0
    60
# and re-open the database without re-registering the collation
sl@0
    61
# sequence. Then make sure the library stops us from using
sl@0
    62
# the collation sequence in:
sl@0
    63
# * an explicitly collated ORDER BY
sl@0
    64
# * an ORDER BY that uses the default collation sequence
sl@0
    65
# * an expression (=)
sl@0
    66
# * a CREATE TABLE statement
sl@0
    67
# * a CREATE INDEX statement that uses a default collation sequence
sl@0
    68
# * a GROUP BY that uses the default collation sequence
sl@0
    69
# * a SELECT DISTINCT that uses the default collation sequence
sl@0
    70
# * Compound SELECTs that uses the default collation sequence
sl@0
    71
# * An ORDER BY on a compound SELECT with an explicit ORDER BY.
sl@0
    72
#
sl@0
    73
do_test collate3-2.0 {
sl@0
    74
  db collate string_compare {string compare}
sl@0
    75
  execsql {
sl@0
    76
    CREATE TABLE collate3t1(c1 COLLATE string_compare, c2);
sl@0
    77
  }
sl@0
    78
  db close
sl@0
    79
  sqlite3 db test.db
sl@0
    80
  expr 0
sl@0
    81
} 0
sl@0
    82
do_test collate3-2.1 {
sl@0
    83
  catchsql {
sl@0
    84
    SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
sl@0
    85
  }
sl@0
    86
} {1 {no such collation sequence: string_compare}} 
sl@0
    87
do_test collate3-2.2 {
sl@0
    88
  catchsql {
sl@0
    89
    SELECT * FROM collate3t1 ORDER BY c1;
sl@0
    90
  }
sl@0
    91
} {1 {no such collation sequence: string_compare}} 
sl@0
    92
do_test collate3-2.3 {
sl@0
    93
  catchsql {
sl@0
    94
    SELECT * FROM collate3t1 WHERE c1 = 'xxx';
sl@0
    95
  }
sl@0
    96
} {1 {no such collation sequence: string_compare}} 
sl@0
    97
do_test collate3-2.4 {
sl@0
    98
  catchsql {
sl@0
    99
    CREATE TABLE collate3t2(c1 COLLATE string_compare);
sl@0
   100
  }
sl@0
   101
} {1 {no such collation sequence: string_compare}} 
sl@0
   102
do_test collate3-2.5 {
sl@0
   103
  catchsql {
sl@0
   104
    CREATE INDEX collate3t1_i1 ON collate3t1(c1);
sl@0
   105
  }
sl@0
   106
} {1 {no such collation sequence: string_compare}}
sl@0
   107
do_test collate3-2.6 {
sl@0
   108
  catchsql {
sl@0
   109
    SELECT * FROM collate3t1;
sl@0
   110
  }
sl@0
   111
} {0 {}}
sl@0
   112
do_test collate3-2.7.1 {
sl@0
   113
  catchsql {
sl@0
   114
    SELECT count(*) FROM collate3t1 GROUP BY c1;
sl@0
   115
  }
sl@0
   116
} {1 {no such collation sequence: string_compare}} 
sl@0
   117
# do_test collate3-2.7.2 {
sl@0
   118
#   catchsql {
sl@0
   119
#     SELECT * FROM collate3t1 GROUP BY c1;
sl@0
   120
#   }
sl@0
   121
# } {1 {GROUP BY may only be used on aggregate queries}}
sl@0
   122
do_test collate3-2.7.2 {
sl@0
   123
  catchsql {
sl@0
   124
    SELECT * FROM collate3t1 GROUP BY c1;
sl@0
   125
  }
sl@0
   126
} {1 {no such collation sequence: string_compare}} 
sl@0
   127
do_test collate3-2.8 {
sl@0
   128
  catchsql {
sl@0
   129
    SELECT DISTINCT c1 FROM collate3t1;
sl@0
   130
  }
sl@0
   131
} {1 {no such collation sequence: string_compare}} 
sl@0
   132
sl@0
   133
ifcapable compound {
sl@0
   134
  do_test collate3-2.9 {
sl@0
   135
    catchsql {
sl@0
   136
      SELECT c1 FROM collate3t1 UNION SELECT c1 FROM collate3t1;
sl@0
   137
    }
sl@0
   138
  } {1 {no such collation sequence: string_compare}} 
sl@0
   139
  do_test collate3-2.10 {
sl@0
   140
    catchsql {
sl@0
   141
      SELECT c1 FROM collate3t1 EXCEPT SELECT c1 FROM collate3t1;
sl@0
   142
    }
sl@0
   143
  } {1 {no such collation sequence: string_compare}} 
sl@0
   144
  do_test collate3-2.11 {
sl@0
   145
    catchsql {
sl@0
   146
      SELECT c1 FROM collate3t1 INTERSECT SELECT c1 FROM collate3t1;
sl@0
   147
    }
sl@0
   148
  } {1 {no such collation sequence: string_compare}} 
sl@0
   149
  do_test collate3-2.12 {
sl@0
   150
    catchsql {
sl@0
   151
      SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1;
sl@0
   152
    }
sl@0
   153
  } {0 {}}
sl@0
   154
  do_test collate3-2.13 {
sl@0
   155
    catchsql {
sl@0
   156
      SELECT 10 UNION ALL SELECT 20 ORDER BY 1 COLLATE string_compare;
sl@0
   157
    }
sl@0
   158
  } {1 {no such collation sequence: string_compare}} 
sl@0
   159
  do_test collate3-2.14 {
sl@0
   160
    catchsql {
sl@0
   161
      SELECT 10 INTERSECT SELECT 20 ORDER BY 1 COLLATE string_compare;
sl@0
   162
    }
sl@0
   163
  } {1 {no such collation sequence: string_compare}} 
sl@0
   164
  do_test collate3-2.15 {
sl@0
   165
    catchsql {
sl@0
   166
      SELECT 10 EXCEPT SELECT 20 ORDER BY 1 COLLATE string_compare;
sl@0
   167
    }
sl@0
   168
  } {1 {no such collation sequence: string_compare}} 
sl@0
   169
  do_test collate3-2.16 {
sl@0
   170
    catchsql {
sl@0
   171
      SELECT 10 UNION SELECT 20 ORDER BY 1 COLLATE string_compare;
sl@0
   172
    }
sl@0
   173
  } {1 {no such collation sequence: string_compare}} 
sl@0
   174
  do_test collate3-2.17 {
sl@0
   175
    catchsql {
sl@0
   176
      SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1 ORDER BY 1;
sl@0
   177
    }
sl@0
   178
  } {1 {no such collation sequence: string_compare}} 
sl@0
   179
} ;# ifcapable compound
sl@0
   180
sl@0
   181
#
sl@0
   182
# Create an index that uses a collation sequence then close and
sl@0
   183
# re-open the database without re-registering the collation
sl@0
   184
# sequence. Then check that for the table with the index 
sl@0
   185
# * An INSERT fails,
sl@0
   186
# * An UPDATE on the column with the index fails,
sl@0
   187
# * An UPDATE on a different column succeeds.
sl@0
   188
# * A DELETE with a WHERE clause fails
sl@0
   189
# * A DELETE without a WHERE clause succeeds
sl@0
   190
#
sl@0
   191
# Also, ensure that the restrictions tested by collate3-2.* still
sl@0
   192
# apply after the index has been created.
sl@0
   193
#
sl@0
   194
do_test collate3-3.0 {
sl@0
   195
  db collate string_compare {string compare}
sl@0
   196
  execsql {
sl@0
   197
    CREATE INDEX collate3t1_i1 ON collate3t1(c1);
sl@0
   198
    INSERT INTO collate3t1 VALUES('xxx', 'yyy');
sl@0
   199
  }
sl@0
   200
  db close
sl@0
   201
  sqlite3 db test.db
sl@0
   202
  expr 0
sl@0
   203
} 0
sl@0
   204
db eval {select * from collate3t1}
sl@0
   205
do_test collate3-3.1 {
sl@0
   206
  catchsql {
sl@0
   207
    INSERT INTO collate3t1 VALUES('xxx', 0);
sl@0
   208
  }
sl@0
   209
} {1 {no such collation sequence: string_compare}} 
sl@0
   210
do_test collate3-3.2 {
sl@0
   211
  catchsql {
sl@0
   212
    UPDATE collate3t1 SET c1 = 'xxx';
sl@0
   213
  }
sl@0
   214
} {1 {no such collation sequence: string_compare}} 
sl@0
   215
do_test collate3-3.3 {
sl@0
   216
  catchsql {
sl@0
   217
    UPDATE collate3t1 SET c2 = 'xxx';
sl@0
   218
  }
sl@0
   219
} {0 {}}
sl@0
   220
do_test collate3-3.4 {
sl@0
   221
  catchsql {
sl@0
   222
    DELETE FROM collate3t1 WHERE 1;
sl@0
   223
  }
sl@0
   224
} {1 {no such collation sequence: string_compare}} 
sl@0
   225
do_test collate3-3.5 {
sl@0
   226
  catchsql {
sl@0
   227
    SELECT * FROM collate3t1;
sl@0
   228
  }
sl@0
   229
} {0 {xxx xxx}}
sl@0
   230
do_test collate3-3.6 {
sl@0
   231
  catchsql {
sl@0
   232
    DELETE FROM collate3t1;
sl@0
   233
  }
sl@0
   234
} {0 {}}
sl@0
   235
ifcapable {integrityck} {
sl@0
   236
  do_test collate3-3.8 {
sl@0
   237
    catchsql {
sl@0
   238
      PRAGMA integrity_check
sl@0
   239
    }
sl@0
   240
  } {1 {no such collation sequence: string_compare}}
sl@0
   241
}
sl@0
   242
do_test collate3-3.9 {
sl@0
   243
  catchsql {
sl@0
   244
    SELECT * FROM collate3t1;
sl@0
   245
  }
sl@0
   246
} {0 {}}
sl@0
   247
do_test collate3-3.10 {
sl@0
   248
  catchsql {
sl@0
   249
    SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
sl@0
   250
  }
sl@0
   251
} {1 {no such collation sequence: string_compare}} 
sl@0
   252
do_test collate3-3.11 {
sl@0
   253
  catchsql {
sl@0
   254
    SELECT * FROM collate3t1 ORDER BY c1;
sl@0
   255
  }
sl@0
   256
} {1 {no such collation sequence: string_compare}} 
sl@0
   257
do_test collate3-3.12 {
sl@0
   258
  catchsql {
sl@0
   259
    SELECT * FROM collate3t1 WHERE c1 = 'xxx';
sl@0
   260
  }
sl@0
   261
} {1 {no such collation sequence: string_compare}} 
sl@0
   262
do_test collate3-3.13 {
sl@0
   263
  catchsql {
sl@0
   264
    CREATE TABLE collate3t2(c1 COLLATE string_compare);
sl@0
   265
  }
sl@0
   266
} {1 {no such collation sequence: string_compare}} 
sl@0
   267
do_test collate3-3.14 {
sl@0
   268
  catchsql {
sl@0
   269
    CREATE INDEX collate3t1_i2 ON collate3t1(c1);
sl@0
   270
  }
sl@0
   271
} {1 {no such collation sequence: string_compare}} 
sl@0
   272
do_test collate3-3.15 {
sl@0
   273
  execsql {
sl@0
   274
    DROP TABLE collate3t1;
sl@0
   275
  }
sl@0
   276
} {}
sl@0
   277
sl@0
   278
# Check we can create an index that uses an explicit collation 
sl@0
   279
# sequence and then close and re-open the database.
sl@0
   280
do_test collate3-4.6 {
sl@0
   281
  db collate user_defined "string compare"
sl@0
   282
  execsql {
sl@0
   283
    CREATE TABLE collate3t1(a, b);
sl@0
   284
    INSERT INTO collate3t1 VALUES('hello', NULL);
sl@0
   285
    CREATE INDEX collate3i1 ON collate3t1(a COLLATE user_defined);
sl@0
   286
  }
sl@0
   287
} {}
sl@0
   288
do_test collate3-4.7 {
sl@0
   289
  db close
sl@0
   290
  sqlite3 db test.db
sl@0
   291
  catchsql {
sl@0
   292
    SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
sl@0
   293
  }
sl@0
   294
} {1 {no such collation sequence: user_defined}}
sl@0
   295
do_test collate3-4.8.1 {
sl@0
   296
  db collate user_defined "string compare"
sl@0
   297
  catchsql {
sl@0
   298
    SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
sl@0
   299
  }
sl@0
   300
} {0 {hello {}}}
sl@0
   301
do_test collate3-4.8.2 {
sl@0
   302
  db close
sl@0
   303
  lindex [catch {
sl@0
   304
    sqlite3 db test.db
sl@0
   305
  }] 0
sl@0
   306
} {0}
sl@0
   307
do_test collate3-4.8.3 {
sl@0
   308
  execsql {
sl@0
   309
    DROP TABLE collate3t1;
sl@0
   310
  }
sl@0
   311
} {}
sl@0
   312
sl@0
   313
# Compare strings as numbers.
sl@0
   314
proc numeric_compare {lhs rhs} {
sl@0
   315
  if {$rhs > $lhs} {
sl@0
   316
    set res -1
sl@0
   317
  } else {
sl@0
   318
    set res [expr ($lhs > $rhs)?1:0]
sl@0
   319
  }
sl@0
   320
  return $res
sl@0
   321
}
sl@0
   322
sl@0
   323
# Check we can create a view that uses an explicit collation 
sl@0
   324
# sequence and then close and re-open the database.
sl@0
   325
ifcapable view {
sl@0
   326
do_test collate3-4.9 {
sl@0
   327
  db collate user_defined numeric_compare
sl@0
   328
  execsql {
sl@0
   329
    CREATE TABLE collate3t1(a, b);
sl@0
   330
    INSERT INTO collate3t1 VALUES('2', NULL);
sl@0
   331
    INSERT INTO collate3t1 VALUES('101', NULL);
sl@0
   332
    INSERT INTO collate3t1 VALUES('12', NULL);
sl@0
   333
    CREATE VIEW collate3v1 AS SELECT * FROM collate3t1 
sl@0
   334
        ORDER BY 1 COLLATE user_defined;
sl@0
   335
    SELECT * FROM collate3v1;
sl@0
   336
  }
sl@0
   337
} {2 {} 12 {} 101 {}}
sl@0
   338
do_test collate3-4.10 {
sl@0
   339
  db close
sl@0
   340
  sqlite3 db test.db
sl@0
   341
  catchsql {
sl@0
   342
    SELECT * FROM collate3v1;
sl@0
   343
  }
sl@0
   344
} {1 {no such collation sequence: user_defined}}
sl@0
   345
do_test collate3-4.11 {
sl@0
   346
  db collate user_defined numeric_compare
sl@0
   347
  catchsql {
sl@0
   348
    SELECT * FROM collate3v1;
sl@0
   349
  }
sl@0
   350
} {0 {2 {} 12 {} 101 {}}}
sl@0
   351
do_test collate3-4.12 {
sl@0
   352
  execsql {
sl@0
   353
    DROP TABLE collate3t1;
sl@0
   354
  }
sl@0
   355
} {}
sl@0
   356
} ;# ifcapable view
sl@0
   357
sl@0
   358
#
sl@0
   359
# Test the collation factory. In the code, the "no such collation sequence"
sl@0
   360
# message is only generated in two places. So these tests just test that
sl@0
   361
# the collation factory can be called once from each of those points.
sl@0
   362
#
sl@0
   363
do_test collate3-5.0 {
sl@0
   364
  catchsql {
sl@0
   365
    CREATE TABLE collate3t1(a);
sl@0
   366
    INSERT INTO collate3t1 VALUES(10);
sl@0
   367
    SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
sl@0
   368
  }
sl@0
   369
} {1 {no such collation sequence: unk}}
sl@0
   370
do_test collate3-5.1 {
sl@0
   371
  set ::cfact_cnt 0
sl@0
   372
  proc cfact {nm} {
sl@0
   373
    db collate $nm {string compare}
sl@0
   374
    incr ::cfact_cnt
sl@0
   375
  }
sl@0
   376
  db collation_needed cfact
sl@0
   377
} {}
sl@0
   378
do_test collate3-5.2 {
sl@0
   379
  catchsql {
sl@0
   380
    SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
sl@0
   381
  }
sl@0
   382
} {0 10}
sl@0
   383
do_test collate3-5.3 {
sl@0
   384
  set ::cfact_cnt
sl@0
   385
} {1}
sl@0
   386
do_test collate3-5.4 {
sl@0
   387
  catchsql {
sl@0
   388
    SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
sl@0
   389
  }
sl@0
   390
} {0 10}
sl@0
   391
do_test collate3-5.5 {
sl@0
   392
  set ::cfact_cnt
sl@0
   393
} {1}
sl@0
   394
do_test collate3-5.6 {
sl@0
   395
  catchsql {
sl@0
   396
    SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
sl@0
   397
  }
sl@0
   398
} {0 10}
sl@0
   399
do_test collate3-5.7 {
sl@0
   400
  execsql {
sl@0
   401
    DROP TABLE collate3t1;
sl@0
   402
    CREATE TABLE collate3t1(a COLLATE unk);
sl@0
   403
  }
sl@0
   404
  db close
sl@0
   405
  sqlite3 db test.db
sl@0
   406
  catchsql {
sl@0
   407
    SELECT a FROM collate3t1 ORDER BY 1;
sl@0
   408
  }
sl@0
   409
} {1 {no such collation sequence: unk}}
sl@0
   410
do_test collate3-5.8 {
sl@0
   411
  set ::cfact_cnt 0
sl@0
   412
  proc cfact {nm} {
sl@0
   413
    db collate $nm {string compare}
sl@0
   414
    incr ::cfact_cnt
sl@0
   415
  }
sl@0
   416
  db collation_needed cfact
sl@0
   417
  catchsql {
sl@0
   418
    SELECT a FROM collate3t1 ORDER BY 1;
sl@0
   419
  }
sl@0
   420
} {0 {}}
sl@0
   421
sl@0
   422
do_test collate3-5.9 {
sl@0
   423
  execsql {
sl@0
   424
    DROP TABLE collate3t1;
sl@0
   425
  }
sl@0
   426
} {}
sl@0
   427
sl@0
   428
finish_test