1# 2001 September 15 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. The 12# focus of this file is testing built-in functions. 13# 14# $Id: func.test,v 1.59 2007/03/17 17:52:42 drh Exp $ 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18 19# Create a table to work with. 20# 21do_test func-0.0 { 22 execsql {CREATE TABLE tbl1(t1 text)} 23 foreach word {this program is free software} { 24 execsql "INSERT INTO tbl1 VALUES('$word')" 25 } 26 execsql {SELECT t1 FROM tbl1 ORDER BY t1} 27} {free is program software this} 28do_test func-0.1 { 29 execsql { 30 CREATE TABLE t2(a); 31 INSERT INTO t2 VALUES(1); 32 INSERT INTO t2 VALUES(NULL); 33 INSERT INTO t2 VALUES(345); 34 INSERT INTO t2 VALUES(NULL); 35 INSERT INTO t2 VALUES(67890); 36 SELECT * FROM t2; 37 } 38} {1 {} 345 {} 67890} 39 40# Check out the length() function 41# 42do_test func-1.0 { 43 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 44} {4 2 7 8 4} 45do_test func-1.1 { 46 set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg] 47 lappend r $msg 48} {1 {wrong number of arguments to function length()}} 49do_test func-1.2 { 50 set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg] 51 lappend r $msg 52} {1 {wrong number of arguments to function length()}} 53do_test func-1.3 { 54 execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1) 55 ORDER BY length(t1)} 56} {2 1 4 2 7 1 8 1} 57do_test func-1.4 { 58 execsql {SELECT coalesce(length(a),-1) FROM t2} 59} {1 -1 3 -1 5} 60 61# Check out the substr() function 62# 63do_test func-2.0 { 64 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 65} {fr is pr so th} 66do_test func-2.1 { 67 execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1} 68} {r s r o h} 69do_test func-2.2 { 70 execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1} 71} {ee {} ogr ftw is} 72do_test func-2.3 { 73 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 74} {e s m e s} 75do_test func-2.4 { 76 execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1} 77} {e s m e s} 78do_test func-2.5 { 79 execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1} 80} {e i a r i} 81do_test func-2.6 { 82 execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1} 83} {ee is am re is} 84do_test func-2.7 { 85 execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1} 86} {fr {} gr wa th} 87do_test func-2.8 { 88 execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)} 89} {this software free program is} 90do_test func-2.9 { 91 execsql {SELECT substr(a,1,1) FROM t2} 92} {1 {} 3 {} 6} 93do_test func-2.10 { 94 execsql {SELECT substr(a,2,2) FROM t2} 95} {{} {} 45 {} 78} 96 97# Only do the following tests if TCL has UTF-8 capabilities 98# 99if {"\u1234"!="u1234"} { 100 101# Put some UTF-8 characters in the database 102# 103do_test func-3.0 { 104 execsql {DELETE FROM tbl1} 105 foreach word "contains UTF-8 characters hi\u1234ho" { 106 execsql "INSERT INTO tbl1 VALUES('$word')" 107 } 108 execsql {SELECT t1 FROM tbl1 ORDER BY t1} 109} "UTF-8 characters contains hi\u1234ho" 110do_test func-3.1 { 111 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 112} {5 10 8 5} 113do_test func-3.2 { 114 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 115} {UT ch co hi} 116do_test func-3.3 { 117 execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1} 118} "UTF cha con hi\u1234" 119do_test func-3.4 { 120 execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1} 121} "TF ha on i\u1234" 122do_test func-3.5 { 123 execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1} 124} "TF- har ont i\u1234h" 125do_test func-3.6 { 126 execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1} 127} "F- ar nt \u1234h" 128do_test func-3.7 { 129 execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1} 130} "-8 ra ta ho" 131do_test func-3.8 { 132 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 133} "8 s s o" 134do_test func-3.9 { 135 execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1} 136} "F- er in \u1234h" 137do_test func-3.10 { 138 execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1} 139} "TF- ter ain i\u1234h" 140do_test func-3.99 { 141 execsql {DELETE FROM tbl1} 142 foreach word {this program is free software} { 143 execsql "INSERT INTO tbl1 VALUES('$word')" 144 } 145 execsql {SELECT t1 FROM tbl1} 146} {this program is free software} 147 148} ;# End \u1234!=u1234 149 150# Test the abs() and round() functions. 151# 152do_test func-4.1 { 153 execsql { 154 CREATE TABLE t1(a,b,c); 155 INSERT INTO t1 VALUES(1,2,3); 156 INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890); 157 INSERT INTO t1 VALUES(3,-2,-5); 158 } 159 catchsql {SELECT abs(a,b) FROM t1} 160} {1 {wrong number of arguments to function abs()}} 161do_test func-4.2 { 162 catchsql {SELECT abs() FROM t1} 163} {1 {wrong number of arguments to function abs()}} 164do_test func-4.3 { 165 catchsql {SELECT abs(b) FROM t1 ORDER BY a} 166} {0 {2 1.2345678901234 2}} 167do_test func-4.4 { 168 catchsql {SELECT abs(c) FROM t1 ORDER BY a} 169} {0 {3 12345.6789 5}} 170do_test func-4.4.1 { 171 execsql {SELECT abs(a) FROM t2} 172} {1 {} 345 {} 67890} 173do_test func-4.4.2 { 174 execsql {SELECT abs(t1) FROM tbl1} 175} {0.0 0.0 0.0 0.0 0.0} 176 177do_test func-4.5 { 178 catchsql {SELECT round(a,b,c) FROM t1} 179} {1 {wrong number of arguments to function round()}} 180do_test func-4.6 { 181 catchsql {SELECT round(b,2) FROM t1 ORDER BY b} 182} {0 {-2.0 1.23 2.0}} 183do_test func-4.7 { 184 catchsql {SELECT round(b,0) FROM t1 ORDER BY a} 185} {0 {2.0 1.0 -2.0}} 186do_test func-4.8 { 187 catchsql {SELECT round(c) FROM t1 ORDER BY a} 188} {0 {3.0 -12346.0 -5.0}} 189do_test func-4.9 { 190 catchsql {SELECT round(c,a) FROM t1 ORDER BY a} 191} {0 {3.0 -12345.68 -5.0}} 192do_test func-4.10 { 193 catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a} 194} {0 {x3.0y x-12345.68y x-5.0y}} 195do_test func-4.11 { 196 catchsql {SELECT round() FROM t1 ORDER BY a} 197} {1 {wrong number of arguments to function round()}} 198do_test func-4.12 { 199 execsql {SELECT coalesce(round(a,2),'nil') FROM t2} 200} {1.0 nil 345.0 nil 67890.0} 201do_test func-4.13 { 202 execsql {SELECT round(t1,2) FROM tbl1} 203} {0.0 0.0 0.0 0.0 0.0} 204do_test func-4.14 { 205 execsql {SELECT typeof(round(5.1,1));} 206} {real} 207do_test func-4.15 { 208 execsql {SELECT typeof(round(5.1));} 209} {real} 210 211 212# Test the upper() and lower() functions 213# 214do_test func-5.1 { 215 execsql {SELECT upper(t1) FROM tbl1} 216} {THIS PROGRAM IS FREE SOFTWARE} 217do_test func-5.2 { 218 execsql {SELECT lower(upper(t1)) FROM tbl1} 219} {this program is free software} 220do_test func-5.3 { 221 execsql {SELECT upper(a), lower(a) FROM t2} 222} {1 1 {} {} 345 345 {} {} 67890 67890} 223do_test func-5.4 { 224 catchsql {SELECT upper(a,5) FROM t2} 225} {1 {wrong number of arguments to function upper()}} 226do_test func-5.5 { 227 catchsql {SELECT upper(*) FROM t2} 228} {1 {wrong number of arguments to function upper()}} 229 230# Test the coalesce() and nullif() functions 231# 232do_test func-6.1 { 233 execsql {SELECT coalesce(a,'xyz') FROM t2} 234} {1 xyz 345 xyz 67890} 235do_test func-6.2 { 236 execsql {SELECT coalesce(upper(a),'nil') FROM t2} 237} {1 nil 345 nil 67890} 238do_test func-6.3 { 239 execsql {SELECT coalesce(nullif(1,1),'nil')} 240} {nil} 241do_test func-6.4 { 242 execsql {SELECT coalesce(nullif(1,2),'nil')} 243} {1} 244do_test func-6.5 { 245 execsql {SELECT coalesce(nullif(1,NULL),'nil')} 246} {1} 247 248 249# Test the last_insert_rowid() function 250# 251do_test func-7.1 { 252 execsql {SELECT last_insert_rowid()} 253} [db last_insert_rowid] 254 255# Tests for aggregate functions and how they handle NULLs. 256# 257do_test func-8.1 { 258 ifcapable explain { 259 execsql {EXPLAIN SELECT sum(a) FROM t2;} 260 } 261 execsql { 262 SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2; 263 } 264} {68236 3 22745.33 1 67890 5} 265do_test func-8.2 { 266 execsql { 267 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; 268 } 269} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 270 271ifcapable tempdb { 272 do_test func-8.3 { 273 execsql { 274 CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 275 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 276 } 277 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 278} else { 279 do_test func-8.3 { 280 execsql { 281 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 282 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 283 } 284 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 285} 286do_test func-8.4 { 287 execsql { 288 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 289 } 290} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 291 292# How do you test the random() function in a meaningful, deterministic way? 293# 294do_test func-9.1 { 295 execsql { 296 SELECT random() is not null; 297 } 298} {1} 299do_test func-9.2 { 300 execsql { 301 SELECT typeof(random()); 302 } 303} {integer} 304do_test func-9.3 { 305 execsql { 306 SELECT randomblob(32) is not null; 307 } 308} {1} 309do_test func-9.4 { 310 execsql { 311 SELECT typeof(randomblob(32)); 312 } 313} {blob} 314do_test func-9.5 { 315 execsql { 316 SELECT length(randomblob(32)), length(randomblob(-5)), 317 length(randomblob(2000)) 318 } 319} {32 1 2000} 320 321# The "hex()" function was added in order to be able to render blobs 322# generated by randomblob(). So this seems like a good place to test 323# hex(). 324# 325do_test func-9.10 { 326 execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')} 327} {00112233445566778899AABBCCDDEEFF} 328 329# Use the "sqlite_register_test_function" TCL command which is part of 330# the text fixture in order to verify correct operation of some of 331# the user-defined SQL function APIs that are not used by the built-in 332# functions. 333# 334set ::DB [sqlite3_connection_pointer db] 335sqlite_register_test_function $::DB testfunc 336do_test func-10.1 { 337 catchsql { 338 SELECT testfunc(NULL,NULL); 339 } 340} {1 {first argument should be one of: int int64 string double null value}} 341do_test func-10.2 { 342 execsql { 343 SELECT testfunc( 344 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 345 'int', 1234 346 ); 347 } 348} {1234} 349do_test func-10.3 { 350 execsql { 351 SELECT testfunc( 352 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 353 'string', NULL 354 ); 355 } 356} {{}} 357do_test func-10.4 { 358 execsql { 359 SELECT testfunc( 360 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 361 'double', 1.234 362 ); 363 } 364} {1.234} 365do_test func-10.5 { 366 execsql { 367 SELECT testfunc( 368 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 369 'int', 1234, 370 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 371 'string', NULL, 372 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 373 'double', 1.234, 374 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 375 'int', 1234, 376 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 377 'string', NULL, 378 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 379 'double', 1.234 380 ); 381 } 382} {1.234} 383 384# Test the built-in sqlite_version(*) SQL function. 385# 386do_test func-11.1 { 387 execsql { 388 SELECT sqlite_version(*); 389 } 390} [sqlite3 -version] 391 392# Test that destructors passed to sqlite3 by calls to sqlite3_result_text() 393# etc. are called. These tests use two special user-defined functions 394# (implemented in func.c) only available in test builds. 395# 396# Function test_destructor() takes one argument and returns a copy of the 397# text form of that argument. A destructor is associated with the return 398# value. Function test_destructor_count() returns the number of outstanding 399# destructor calls for values returned by test_destructor(). 400# 401do_test func-12.1 { 402 execsql { 403 SELECT test_destructor('hello world'), test_destructor_count(); 404 } 405} {{hello world} 1} 406do_test func-12.2 { 407 execsql { 408 SELECT test_destructor_count(); 409 } 410} {0} 411do_test func-12.3 { 412 execsql { 413 SELECT test_destructor('hello')||' world', test_destructor_count(); 414 } 415} {{hello world} 0} 416do_test func-12.4 { 417 execsql { 418 SELECT test_destructor_count(); 419 } 420} {0} 421do_test func-12.5 { 422 execsql { 423 CREATE TABLE t4(x); 424 INSERT INTO t4 VALUES(test_destructor('hello')); 425 INSERT INTO t4 VALUES(test_destructor('world')); 426 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4; 427 } 428} {hello world} 429do_test func-12.6 { 430 execsql { 431 SELECT test_destructor_count(); 432 } 433} {0} 434do_test func-12.7 { 435 execsql { 436 DROP TABLE t4; 437 } 438} {} 439 440# Test that the auxdata API for scalar functions works. This test uses 441# a special user-defined function only available in test builds, 442# test_auxdata(). Function test_auxdata() takes any number of arguments. 443do_test func-13.1 { 444 execsql { 445 SELECT test_auxdata('hello world'); 446 } 447} {0} 448 449do_test func-13.2 { 450 execsql { 451 CREATE TABLE t4(a, b); 452 INSERT INTO t4 VALUES('abc', 'def'); 453 INSERT INTO t4 VALUES('ghi', 'jkl'); 454 } 455} {} 456do_test func-13.3 { 457 execsql { 458 SELECT test_auxdata('hello world') FROM t4; 459 } 460} {0 1} 461do_test func-13.4 { 462 execsql { 463 SELECT test_auxdata('hello world', 123) FROM t4; 464 } 465} {{0 0} {1 1}} 466do_test func-13.5 { 467 execsql { 468 SELECT test_auxdata('hello world', a) FROM t4; 469 } 470} {{0 0} {1 0}} 471do_test func-13.6 { 472 execsql { 473 SELECT test_auxdata('hello'||'world', a) FROM t4; 474 } 475} {{0 0} {1 0}} 476 477# Test that auxilary data is preserved between calls for SQL variables. 478do_test func-13.7 { 479 set DB [sqlite3_connection_pointer db] 480 set sql "SELECT test_auxdata( ? , a ) FROM t4;" 481 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 482 sqlite3_bind_text $STMT 1 hello -1 483 set res [list] 484 while { "SQLITE_ROW"==[sqlite3_step $STMT] } { 485 lappend res [sqlite3_column_text $STMT 0] 486 } 487 lappend res [sqlite3_finalize $STMT] 488} {{0 0} {1 0} SQLITE_OK} 489 490# Make sure that a function with a very long name is rejected 491do_test func-14.1 { 492 catch { 493 db function [string repeat X 254] {return "hello"} 494 } 495} {0} 496do_test func-14.2 { 497 catch { 498 db function [string repeat X 256] {return "hello"} 499 } 500} {1} 501 502do_test func-15.1 { 503 catchsql { 504 select test_error(NULL); 505 } 506} {1 {}} 507 508# Test the quote function for BLOB and NULL values. 509do_test func-16.1 { 510 execsql { 511 CREATE TABLE tbl2(a, b); 512 } 513 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL] 514 sqlite3_bind_blob $::STMT 1 abc 3 515 sqlite3_step $::STMT 516 sqlite3_finalize $::STMT 517 execsql { 518 SELECT quote(a), quote(b) FROM tbl2; 519 } 520} {X'616263' NULL} 521 522# Correctly handle function error messages that include %. Ticket #1354 523# 524do_test func-17.1 { 525 proc testfunc1 args {error "Error %d with %s percents %p"} 526 db function testfunc1 ::testfunc1 527 catchsql { 528 SELECT testfunc1(1,2,3); 529 } 530} {1 {Error %d with %s percents %p}} 531 532# The SUM function should return integer results when all inputs are integer. 533# 534do_test func-18.1 { 535 execsql { 536 CREATE TABLE t5(x); 537 INSERT INTO t5 VALUES(1); 538 INSERT INTO t5 VALUES(-99); 539 INSERT INTO t5 VALUES(10000); 540 SELECT sum(x) FROM t5; 541 } 542} {9902} 543do_test func-18.2 { 544 execsql { 545 INSERT INTO t5 VALUES(0.0); 546 SELECT sum(x) FROM t5; 547 } 548} {9902.0} 549 550# The sum of nothing is NULL. But the sum of all NULLs is NULL. 551# 552# The TOTAL of nothing is 0.0. 553# 554do_test func-18.3 { 555 execsql { 556 DELETE FROM t5; 557 SELECT sum(x), total(x) FROM t5; 558 } 559} {{} 0.0} 560do_test func-18.4 { 561 execsql { 562 INSERT INTO t5 VALUES(NULL); 563 SELECT sum(x), total(x) FROM t5 564 } 565} {{} 0.0} 566do_test func-18.5 { 567 execsql { 568 INSERT INTO t5 VALUES(NULL); 569 SELECT sum(x), total(x) FROM t5 570 } 571} {{} 0.0} 572do_test func-18.6 { 573 execsql { 574 INSERT INTO t5 VALUES(123); 575 SELECT sum(x), total(x) FROM t5 576 } 577} {123 123.0} 578 579# Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes 580# an error. The non-standard TOTAL() function continues to give a helpful 581# result. 582# 583do_test func-18.10 { 584 execsql { 585 CREATE TABLE t6(x INTEGER); 586 INSERT INTO t6 VALUES(1); 587 INSERT INTO t6 VALUES(1<<62); 588 SELECT sum(x) - ((1<<62)+1) from t6; 589 } 590} 0 591do_test func-18.11 { 592 execsql { 593 SELECT typeof(sum(x)) FROM t6 594 } 595} integer 596do_test func-18.12 { 597 catchsql { 598 INSERT INTO t6 VALUES(1<<62); 599 SELECT sum(x) - ((1<<62)*2.0+1) from t6; 600 } 601} {1 {integer overflow}} 602do_test func-18.13 { 603 execsql { 604 SELECT total(x) - ((1<<62)*2.0+1) FROM t6 605 } 606} 0.0 607do_test func-18.14 { 608 execsql { 609 SELECT sum(-9223372036854775805); 610 } 611} -9223372036854775805 612 613ifcapable compound&&subquery { 614 615do_test func-18.15 { 616 catchsql { 617 SELECT sum(x) FROM 618 (SELECT 9223372036854775807 AS x UNION ALL 619 SELECT 10 AS x); 620 } 621} {1 {integer overflow}} 622do_test func-18.16 { 623 catchsql { 624 SELECT sum(x) FROM 625 (SELECT 9223372036854775807 AS x UNION ALL 626 SELECT -10 AS x); 627 } 628} {0 9223372036854775797} 629do_test func-18.17 { 630 catchsql { 631 SELECT sum(x) FROM 632 (SELECT -9223372036854775807 AS x UNION ALL 633 SELECT 10 AS x); 634 } 635} {0 -9223372036854775797} 636do_test func-18.18 { 637 catchsql { 638 SELECT sum(x) FROM 639 (SELECT -9223372036854775807 AS x UNION ALL 640 SELECT -10 AS x); 641 } 642} {1 {integer overflow}} 643do_test func-18.19 { 644 catchsql { 645 SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x); 646 } 647} {0 -1} 648do_test func-18.20 { 649 catchsql { 650 SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x); 651 } 652} {0 1} 653do_test func-18.21 { 654 catchsql { 655 SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x); 656 } 657} {0 -1} 658do_test func-18.22 { 659 catchsql { 660 SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x); 661 } 662} {0 1} 663 664} ;# ifcapable compound&&subquery 665 666# Integer overflow on abs() 667# 668do_test func-18.31 { 669 catchsql { 670 SELECT abs(-9223372036854775807); 671 } 672} {0 9223372036854775807} 673do_test func-18.32 { 674 catchsql { 675 SELECT abs(-9223372036854775807-1); 676 } 677} {1 {integer overflow}} 678 679# The MATCH function exists but is only a stub and always throws an error. 680# 681do_test func-19.1 { 682 execsql { 683 SELECT match(a,b) FROM t1 WHERE 0; 684 } 685} {} 686do_test func-19.2 { 687 catchsql { 688 SELECT 'abc' MATCH 'xyz'; 689 } 690} {1 {unable to use function MATCH in the requested context}} 691do_test func-19.3 { 692 catchsql { 693 SELECT 'abc' NOT MATCH 'xyz'; 694 } 695} {1 {unable to use function MATCH in the requested context}} 696do_test func-19.4 { 697 catchsql { 698 SELECT match(1,2,3); 699 } 700} {1 {wrong number of arguments to function match()}} 701 702# Soundex tests. 703# 704if {![catch {db eval {SELECT soundex('hello')}}]} { 705 set i 0 706 foreach {name sdx} { 707 euler E460 708 EULER E460 709 Euler E460 710 ellery E460 711 gauss G200 712 ghosh G200 713 hilbert H416 714 Heilbronn H416 715 knuth K530 716 kant K530 717 Lloyd L300 718 LADD L300 719 Lukasiewicz L222 720 Lissajous L222 721 A A000 722 12345 ?000 723 } { 724 incr i 725 do_test func-20.$i { 726 execsql {SELECT soundex($name)} 727 } $sdx 728 } 729} 730 731# Tests of the REPLACE function. 732# 733do_test func-21.1 { 734 catchsql { 735 SELECT replace(1,2); 736 } 737} {1 {wrong number of arguments to function replace()}} 738do_test func-21.2 { 739 catchsql { 740 SELECT replace(1,2,3,4); 741 } 742} {1 {wrong number of arguments to function replace()}} 743do_test func-21.3 { 744 execsql { 745 SELECT typeof(replace("This is the main test string", NULL, "ALT")); 746 } 747} {null} 748do_test func-21.4 { 749 execsql { 750 SELECT typeof(replace(NULL, "main", "ALT")); 751 } 752} {null} 753do_test func-21.5 { 754 execsql { 755 SELECT typeof(replace("This is the main test string", "main", NULL)); 756 } 757} {null} 758do_test func-21.6 { 759 execsql { 760 SELECT replace("This is the main test string", "main", "ALT"); 761 } 762} {{This is the ALT test string}} 763do_test func-21.7 { 764 execsql { 765 SELECT replace("This is the main test string", "main", "larger-main"); 766 } 767} {{This is the larger-main test string}} 768do_test func-21.8 { 769 execsql { 770 SELECT replace("aaaaaaa", "a", "0123456789"); 771 } 772} {0123456789012345678901234567890123456789012345678901234567890123456789} 773 774# Tests for the TRIM, LTRIM and RTRIM functions. 775# 776do_test func-22.1 { 777 catchsql {SELECT trim(1,2,3)} 778} {1 {wrong number of arguments to function trim()}} 779do_test func-22.2 { 780 catchsql {SELECT ltrim(1,2,3)} 781} {1 {wrong number of arguments to function ltrim()}} 782do_test func-22.3 { 783 catchsql {SELECT rtrim(1,2,3)} 784} {1 {wrong number of arguments to function rtrim()}} 785do_test func-22.4 { 786 execsql {SELECT trim(' hi ');} 787} {hi} 788do_test func-22.5 { 789 execsql {SELECT ltrim(' hi ');} 790} {{hi }} 791do_test func-22.6 { 792 execsql {SELECT rtrim(' hi ');} 793} {{ hi}} 794do_test func-22.7 { 795 execsql {SELECT trim(' hi ','xyz');} 796} {{ hi }} 797do_test func-22.8 { 798 execsql {SELECT ltrim(' hi ','xyz');} 799} {{ hi }} 800do_test func-22.9 { 801 execsql {SELECT rtrim(' hi ','xyz');} 802} {{ hi }} 803do_test func-22.10 { 804 execsql {SELECT trim('xyxzy hi zzzy','xyz');} 805} {{ hi }} 806do_test func-22.11 { 807 execsql {SELECT ltrim('xyxzy hi zzzy','xyz');} 808} {{ hi zzzy}} 809do_test func-22.12 { 810 execsql {SELECT rtrim('xyxzy hi zzzy','xyz');} 811} {{xyxzy hi }} 812do_test func-22.13 { 813 execsql {SELECT trim(' hi ','');} 814} {{ hi }} 815do_test func-22.20 { 816 execsql {SELECT typeof(trim(NULL));} 817} {null} 818do_test func-22.21 { 819 execsql {SELECT typeof(trim(NULL,'xyz'));} 820} {null} 821do_test func-22.22 { 822 execsql {SELECT typeof(trim('hello',NULL));} 823} {null} 824 825finish_test 826