Annotation of embedaddon/sqlite3/test/func.test, revision 1.1

1.1     ! misho       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: 
        !            15: set testdir [file dirname $argv0]
        !            16: source $testdir/tester.tcl
        !            17: 
        !            18: # Create a table to work with.
        !            19: #
        !            20: do_test func-0.0 {
        !            21:   execsql {CREATE TABLE tbl1(t1 text)}
        !            22:   foreach word {this program is free software} {
        !            23:     execsql "INSERT INTO tbl1 VALUES('$word')"
        !            24:   }
        !            25:   execsql {SELECT t1 FROM tbl1 ORDER BY t1}
        !            26: } {free is program software this}
        !            27: do_test func-0.1 {
        !            28:   execsql {
        !            29:      CREATE TABLE t2(a);
        !            30:      INSERT INTO t2 VALUES(1);
        !            31:      INSERT INTO t2 VALUES(NULL);
        !            32:      INSERT INTO t2 VALUES(345);
        !            33:      INSERT INTO t2 VALUES(NULL);
        !            34:      INSERT INTO t2 VALUES(67890);
        !            35:      SELECT * FROM t2;
        !            36:   }
        !            37: } {1 {} 345 {} 67890}
        !            38: 
        !            39: # Check out the length() function
        !            40: #
        !            41: do_test func-1.0 {
        !            42:   execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
        !            43: } {4 2 7 8 4}
        !            44: do_test func-1.1 {
        !            45:   set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
        !            46:   lappend r $msg
        !            47: } {1 {wrong number of arguments to function length()}}
        !            48: do_test func-1.2 {
        !            49:   set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
        !            50:   lappend r $msg
        !            51: } {1 {wrong number of arguments to function length()}}
        !            52: do_test func-1.3 {
        !            53:   execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1)
        !            54:            ORDER BY length(t1)}
        !            55: } {2 1 4 2 7 1 8 1}
        !            56: do_test func-1.4 {
        !            57:   execsql {SELECT coalesce(length(a),-1) FROM t2}
        !            58: } {1 -1 3 -1 5}
        !            59: 
        !            60: # Check out the substr() function
        !            61: #
        !            62: do_test func-2.0 {
        !            63:   execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
        !            64: } {fr is pr so th}
        !            65: do_test func-2.1 {
        !            66:   execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1}
        !            67: } {r s r o h}
        !            68: do_test func-2.2 {
        !            69:   execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1}
        !            70: } {ee {} ogr ftw is}
        !            71: do_test func-2.3 {
        !            72:   execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
        !            73: } {e s m e s}
        !            74: do_test func-2.4 {
        !            75:   execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1}
        !            76: } {e s m e s}
        !            77: do_test func-2.5 {
        !            78:   execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1}
        !            79: } {e i a r i}
        !            80: do_test func-2.6 {
        !            81:   execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1}
        !            82: } {ee is am re is}
        !            83: do_test func-2.7 {
        !            84:   execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1}
        !            85: } {fr {} gr wa th}
        !            86: do_test func-2.8 {
        !            87:   execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)}
        !            88: } {this software free program is}
        !            89: do_test func-2.9 {
        !            90:   execsql {SELECT substr(a,1,1) FROM t2}
        !            91: } {1 {} 3 {} 6}
        !            92: do_test func-2.10 {
        !            93:   execsql {SELECT substr(a,2,2) FROM t2}
        !            94: } {{} {} 45 {} 78}
        !            95: 
        !            96: # Only do the following tests if TCL has UTF-8 capabilities
        !            97: #
        !            98: if {"\u1234"!="u1234"} {
        !            99: 
        !           100: # Put some UTF-8 characters in the database
        !           101: #
        !           102: do_test func-3.0 {
        !           103:   execsql {DELETE FROM tbl1}
        !           104:   foreach word "contains UTF-8 characters hi\u1234ho" {
        !           105:     execsql "INSERT INTO tbl1 VALUES('$word')"
        !           106:   }
        !           107:   execsql {SELECT t1 FROM tbl1 ORDER BY t1}
        !           108: } "UTF-8 characters contains hi\u1234ho"
        !           109: do_test func-3.1 {
        !           110:   execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
        !           111: } {5 10 8 5}
        !           112: do_test func-3.2 {
        !           113:   execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
        !           114: } {UT ch co hi}
        !           115: do_test func-3.3 {
        !           116:   execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1}
        !           117: } "UTF cha con hi\u1234"
        !           118: do_test func-3.4 {
        !           119:   execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1}
        !           120: } "TF ha on i\u1234"
        !           121: do_test func-3.5 {
        !           122:   execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1}
        !           123: } "TF- har ont i\u1234h"
        !           124: do_test func-3.6 {
        !           125:   execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1}
        !           126: } "F- ar nt \u1234h"
        !           127: do_test func-3.7 {
        !           128:   execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1}
        !           129: } "-8 ra ta ho"
        !           130: do_test func-3.8 {
        !           131:   execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
        !           132: } "8 s s o"
        !           133: do_test func-3.9 {
        !           134:   execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1}
        !           135: } "F- er in \u1234h"
        !           136: do_test func-3.10 {
        !           137:   execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1}
        !           138: } "TF- ter ain i\u1234h"
        !           139: do_test func-3.99 {
        !           140:   execsql {DELETE FROM tbl1}
        !           141:   foreach word {this program is free software} {
        !           142:     execsql "INSERT INTO tbl1 VALUES('$word')"
        !           143:   }
        !           144:   execsql {SELECT t1 FROM tbl1}
        !           145: } {this program is free software}
        !           146: 
        !           147: } ;# End \u1234!=u1234
        !           148: 
        !           149: # Test the abs() and round() functions.
        !           150: #
        !           151: ifcapable !floatingpoint {
        !           152:   do_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,12345678901234,-1234567890);
        !           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()}}
        !           161: }
        !           162: ifcapable floatingpoint {
        !           163:   do_test func-4.1 {
        !           164:     execsql {
        !           165:       CREATE TABLE t1(a,b,c);
        !           166:       INSERT INTO t1 VALUES(1,2,3);
        !           167:       INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
        !           168:       INSERT INTO t1 VALUES(3,-2,-5);
        !           169:     }
        !           170:     catchsql {SELECT abs(a,b) FROM t1}
        !           171:   } {1 {wrong number of arguments to function abs()}}
        !           172: }
        !           173: do_test func-4.2 {
        !           174:   catchsql {SELECT abs() FROM t1}
        !           175: } {1 {wrong number of arguments to function abs()}}
        !           176: ifcapable floatingpoint {
        !           177:   do_test func-4.3 {
        !           178:     catchsql {SELECT abs(b) FROM t1 ORDER BY a}
        !           179:   } {0 {2 1.2345678901234 2}}
        !           180:   do_test func-4.4 {
        !           181:     catchsql {SELECT abs(c) FROM t1 ORDER BY a}
        !           182:   } {0 {3 12345.6789 5}}
        !           183: }
        !           184: ifcapable !floatingpoint {
        !           185:   if {[working_64bit_int]} {
        !           186:     do_test func-4.3 {
        !           187:       catchsql {SELECT abs(b) FROM t1 ORDER BY a}
        !           188:     } {0 {2 12345678901234 2}}
        !           189:   }
        !           190:   do_test func-4.4 {
        !           191:     catchsql {SELECT abs(c) FROM t1 ORDER BY a}
        !           192:   } {0 {3 1234567890 5}}
        !           193: }
        !           194: do_test func-4.4.1 {
        !           195:   execsql {SELECT abs(a) FROM t2}
        !           196: } {1 {} 345 {} 67890}
        !           197: do_test func-4.4.2 {
        !           198:   execsql {SELECT abs(t1) FROM tbl1}
        !           199: } {0.0 0.0 0.0 0.0 0.0}
        !           200: 
        !           201: ifcapable floatingpoint {
        !           202:   do_test func-4.5 {
        !           203:     catchsql {SELECT round(a,b,c) FROM t1}
        !           204:   } {1 {wrong number of arguments to function round()}}
        !           205:   do_test func-4.6 {
        !           206:     catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
        !           207:   } {0 {-2.0 1.23 2.0}}
        !           208:   do_test func-4.7 {
        !           209:     catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
        !           210:   } {0 {2.0 1.0 -2.0}}
        !           211:   do_test func-4.8 {
        !           212:     catchsql {SELECT round(c) FROM t1 ORDER BY a}
        !           213:   } {0 {3.0 -12346.0 -5.0}}
        !           214:   do_test func-4.9 {
        !           215:     catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
        !           216:   } {0 {3.0 -12345.68 -5.0}}
        !           217:   do_test func-4.10 {
        !           218:     catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a}
        !           219:   } {0 {x3.0y x-12345.68y x-5.0y}}
        !           220:   do_test func-4.11 {
        !           221:     catchsql {SELECT round() FROM t1 ORDER BY a}
        !           222:   } {1 {wrong number of arguments to function round()}}
        !           223:   do_test func-4.12 {
        !           224:     execsql {SELECT coalesce(round(a,2),'nil') FROM t2}
        !           225:   } {1.0 nil 345.0 nil 67890.0}
        !           226:   do_test func-4.13 {
        !           227:     execsql {SELECT round(t1,2) FROM tbl1}
        !           228:   } {0.0 0.0 0.0 0.0 0.0}
        !           229:   do_test func-4.14 {
        !           230:     execsql {SELECT typeof(round(5.1,1));}
        !           231:   } {real}
        !           232:   do_test func-4.15 {
        !           233:     execsql {SELECT typeof(round(5.1));}
        !           234:   } {real}
        !           235:   do_test func-4.16 {
        !           236:     catchsql {SELECT round(b,2.0) FROM t1 ORDER BY b}
        !           237:   } {0 {-2.0 1.23 2.0}}
        !           238:   # Verify some values reported on the mailing list.
        !           239:   # Some of these fail on MSVC builds with 64-bit
        !           240:   # long doubles, but not on GCC builds with 80-bit
        !           241:   # long doubles.
        !           242:   for {set i 1} {$i<999} {incr i} {
        !           243:     set x1 [expr 40222.5 + $i]
        !           244:     set x2 [expr 40223.0 + $i]
        !           245:     do_test func-4.17.$i {
        !           246:       execsql {SELECT round($x1);}
        !           247:     } $x2
        !           248:   }
        !           249:   for {set i 1} {$i<999} {incr i} {
        !           250:     set x1 [expr 40222.05 + $i]
        !           251:     set x2 [expr 40222.10 + $i]
        !           252:     do_test func-4.18.$i {
        !           253:       execsql {SELECT round($x1,1);}
        !           254:     } $x2
        !           255:   }
        !           256:   do_test func-4.20 {
        !           257:     execsql {SELECT round(40223.4999999999);}
        !           258:   } {40223.0}
        !           259:   do_test func-4.21 {
        !           260:     execsql {SELECT round(40224.4999999999);}
        !           261:   } {40224.0}
        !           262:   do_test func-4.22 {
        !           263:     execsql {SELECT round(40225.4999999999);}
        !           264:   } {40225.0}
        !           265:   for {set i 1} {$i<10} {incr i} {
        !           266:     do_test func-4.23.$i {
        !           267:       execsql {SELECT round(40223.4999999999,$i);}
        !           268:     } {40223.5}
        !           269:     do_test func-4.24.$i {
        !           270:       execsql {SELECT round(40224.4999999999,$i);}
        !           271:     } {40224.5}
        !           272:     do_test func-4.25.$i {
        !           273:       execsql {SELECT round(40225.4999999999,$i);}
        !           274:     } {40225.5}
        !           275:   }
        !           276:   for {set i 10} {$i<32} {incr i} {
        !           277:     do_test func-4.26.$i {
        !           278:       execsql {SELECT round(40223.4999999999,$i);}
        !           279:     } {40223.4999999999}
        !           280:     do_test func-4.27.$i {
        !           281:       execsql {SELECT round(40224.4999999999,$i);}
        !           282:     } {40224.4999999999}
        !           283:     do_test func-4.28.$i {
        !           284:       execsql {SELECT round(40225.4999999999,$i);}
        !           285:     } {40225.4999999999}
        !           286:   }
        !           287:   do_test func-4.29 {
        !           288:     execsql {SELECT round(1234567890.5);}
        !           289:   } {1234567891.0}
        !           290:   do_test func-4.30 {
        !           291:     execsql {SELECT round(12345678901.5);}
        !           292:   } {12345678902.0}
        !           293:   do_test func-4.31 {
        !           294:     execsql {SELECT round(123456789012.5);}
        !           295:   } {123456789013.0}
        !           296:   do_test func-4.32 {
        !           297:     execsql {SELECT round(1234567890123.5);}
        !           298:   } {1234567890124.0}
        !           299:   do_test func-4.33 {
        !           300:     execsql {SELECT round(12345678901234.5);}
        !           301:   } {12345678901235.0}
        !           302:   do_test func-4.34 {
        !           303:     execsql {SELECT round(1234567890123.35,1);}
        !           304:   } {1234567890123.4}
        !           305:   do_test func-4.35 {
        !           306:     execsql {SELECT round(1234567890123.445,2);}
        !           307:   } {1234567890123.45}
        !           308:   do_test func-4.36 {
        !           309:     execsql {SELECT round(99999999999994.5);}
        !           310:   } {99999999999995.0}
        !           311:   do_test func-4.37 {
        !           312:     execsql {SELECT round(9999999999999.55,1);}
        !           313:   } {9999999999999.6}
        !           314:   do_test func-4.38 {
        !           315:     execsql {SELECT round(9999999999999.555,2);}
        !           316:   } {9999999999999.56}
        !           317: }
        !           318: 
        !           319: # Test the upper() and lower() functions
        !           320: #
        !           321: do_test func-5.1 {
        !           322:   execsql {SELECT upper(t1) FROM tbl1}
        !           323: } {THIS PROGRAM IS FREE SOFTWARE}
        !           324: do_test func-5.2 {
        !           325:   execsql {SELECT lower(upper(t1)) FROM tbl1}
        !           326: } {this program is free software}
        !           327: do_test func-5.3 {
        !           328:   execsql {SELECT upper(a), lower(a) FROM t2}
        !           329: } {1 1 {} {} 345 345 {} {} 67890 67890}
        !           330: ifcapable !icu {
        !           331:   do_test func-5.4 {
        !           332:     catchsql {SELECT upper(a,5) FROM t2}
        !           333:   } {1 {wrong number of arguments to function upper()}}
        !           334: }
        !           335: do_test func-5.5 {
        !           336:   catchsql {SELECT upper(*) FROM t2}
        !           337: } {1 {wrong number of arguments to function upper()}}
        !           338: 
        !           339: # Test the coalesce() and nullif() functions
        !           340: #
        !           341: do_test func-6.1 {
        !           342:   execsql {SELECT coalesce(a,'xyz') FROM t2}
        !           343: } {1 xyz 345 xyz 67890}
        !           344: do_test func-6.2 {
        !           345:   execsql {SELECT coalesce(upper(a),'nil') FROM t2}
        !           346: } {1 nil 345 nil 67890}
        !           347: do_test func-6.3 {
        !           348:   execsql {SELECT coalesce(nullif(1,1),'nil')}
        !           349: } {nil}
        !           350: do_test func-6.4 {
        !           351:   execsql {SELECT coalesce(nullif(1,2),'nil')}
        !           352: } {1}
        !           353: do_test func-6.5 {
        !           354:   execsql {SELECT coalesce(nullif(1,NULL),'nil')}
        !           355: } {1}
        !           356: 
        !           357: 
        !           358: # Test the last_insert_rowid() function
        !           359: #
        !           360: do_test func-7.1 {
        !           361:   execsql {SELECT last_insert_rowid()}
        !           362: } [db last_insert_rowid]
        !           363: 
        !           364: # Tests for aggregate functions and how they handle NULLs.
        !           365: #
        !           366: ifcapable floatingpoint {
        !           367:   do_test func-8.1 {
        !           368:     ifcapable explain {
        !           369:       execsql {EXPLAIN SELECT sum(a) FROM t2;}
        !           370:     }
        !           371:     execsql {
        !           372:       SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
        !           373:     }
        !           374:   } {68236 3 22745.33 1 67890 5}
        !           375: }
        !           376: ifcapable !floatingpoint {
        !           377:   do_test func-8.1 {
        !           378:     ifcapable explain {
        !           379:       execsql {EXPLAIN SELECT sum(a) FROM t2;}
        !           380:     }
        !           381:     execsql {
        !           382:       SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2;
        !           383:     }
        !           384:   } {68236 3 22745.0 1 67890 5}
        !           385: }
        !           386: do_test func-8.2 {
        !           387:   execsql {
        !           388:     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
        !           389:   }
        !           390: } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
        !           391: 
        !           392: ifcapable tempdb {
        !           393:   do_test func-8.3 {
        !           394:     execsql {
        !           395:       CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
        !           396:       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
        !           397:     }
        !           398:   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
        !           399: } else {
        !           400:   do_test func-8.3 {
        !           401:     execsql {
        !           402:       CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
        !           403:       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
        !           404:     }
        !           405:   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
        !           406: }
        !           407: do_test func-8.4 {
        !           408:   execsql {
        !           409:     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
        !           410:   }
        !           411: } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
        !           412: ifcapable compound {
        !           413:   do_test func-8.5 {
        !           414:     execsql {
        !           415:       SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
        !           416:                           UNION ALL SELECT -9223372036854775807)
        !           417:     }
        !           418:   } {0}
        !           419:   do_test func-8.6 {
        !           420:     execsql {
        !           421:       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
        !           422:                           UNION ALL SELECT -9223372036854775807)
        !           423:     }
        !           424:   } {integer}
        !           425:   do_test func-8.7 {
        !           426:     execsql {
        !           427:       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
        !           428:                           UNION ALL SELECT -9223372036854775807)
        !           429:     }
        !           430:   } {real}
        !           431: ifcapable floatingpoint {
        !           432:   do_test func-8.8 {
        !           433:     execsql {
        !           434:       SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
        !           435:                           UNION ALL SELECT -9223372036850000000)
        !           436:     }
        !           437:   } {1}
        !           438: }
        !           439: ifcapable !floatingpoint {
        !           440:   do_test func-8.8 {
        !           441:     execsql {
        !           442:       SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x
        !           443:                           UNION ALL SELECT -9223372036850000000)
        !           444:     }
        !           445:   } {1}
        !           446: }
        !           447: }
        !           448: 
        !           449: # How do you test the random() function in a meaningful, deterministic way?
        !           450: #
        !           451: do_test func-9.1 {
        !           452:   execsql {
        !           453:     SELECT random() is not null;
        !           454:   }
        !           455: } {1}
        !           456: do_test func-9.2 {
        !           457:   execsql {
        !           458:     SELECT typeof(random());
        !           459:   }
        !           460: } {integer}
        !           461: do_test func-9.3 {
        !           462:   execsql {
        !           463:     SELECT randomblob(32) is not null;
        !           464:   }
        !           465: } {1}
        !           466: do_test func-9.4 {
        !           467:   execsql {
        !           468:     SELECT typeof(randomblob(32));
        !           469:   }
        !           470: } {blob}
        !           471: do_test func-9.5 {
        !           472:   execsql {
        !           473:     SELECT length(randomblob(32)), length(randomblob(-5)),
        !           474:            length(randomblob(2000))
        !           475:   }
        !           476: } {32 1 2000}
        !           477: 
        !           478: # The "hex()" function was added in order to be able to render blobs
        !           479: # generated by randomblob().  So this seems like a good place to test
        !           480: # hex().
        !           481: #
        !           482: ifcapable bloblit {
        !           483:   do_test func-9.10 {
        !           484:     execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
        !           485:   } {00112233445566778899AABBCCDDEEFF}
        !           486: }
        !           487: set encoding [db one {PRAGMA encoding}]
        !           488: if {$encoding=="UTF-16le"} {
        !           489:   do_test func-9.11-utf16le {
        !           490:     execsql {SELECT hex(replace('abcdefg','ef','12'))}
        !           491:   } {6100620063006400310032006700}
        !           492:   do_test func-9.12-utf16le {
        !           493:     execsql {SELECT hex(replace('abcdefg','','12'))}
        !           494:   } {6100620063006400650066006700}
        !           495:   do_test func-9.13-utf16le {
        !           496:     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
        !           497:   } {610061006100610061006100620063006400650066006700}
        !           498: } elseif {$encoding=="UTF-8"} {
        !           499:   do_test func-9.11-utf8 {
        !           500:     execsql {SELECT hex(replace('abcdefg','ef','12'))}
        !           501:   } {61626364313267}
        !           502:   do_test func-9.12-utf8 {
        !           503:     execsql {SELECT hex(replace('abcdefg','','12'))}
        !           504:   } {61626364656667}
        !           505:   do_test func-9.13-utf8 {
        !           506:     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
        !           507:   } {616161616161626364656667}
        !           508: }
        !           509:   
        !           510: # Use the "sqlite_register_test_function" TCL command which is part of
        !           511: # the text fixture in order to verify correct operation of some of
        !           512: # the user-defined SQL function APIs that are not used by the built-in
        !           513: # functions.
        !           514: #
        !           515: set ::DB [sqlite3_connection_pointer db]
        !           516: sqlite_register_test_function $::DB testfunc
        !           517: do_test func-10.1 {
        !           518:   catchsql {
        !           519:     SELECT testfunc(NULL,NULL);
        !           520:   }
        !           521: } {1 {first argument should be one of: int int64 string double null value}}
        !           522: do_test func-10.2 {
        !           523:   execsql {
        !           524:     SELECT testfunc(
        !           525:      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           526:      'int', 1234
        !           527:     );
        !           528:   }
        !           529: } {1234}
        !           530: do_test func-10.3 {
        !           531:   execsql {
        !           532:     SELECT testfunc(
        !           533:      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           534:      'string', NULL
        !           535:     );
        !           536:   }
        !           537: } {{}}
        !           538: 
        !           539: ifcapable floatingpoint {
        !           540:   do_test func-10.4 {
        !           541:     execsql {
        !           542:       SELECT testfunc(
        !           543:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           544:        'double', 1.234
        !           545:       );
        !           546:     }
        !           547:   } {1.234}
        !           548:   do_test func-10.5 {
        !           549:     execsql {
        !           550:       SELECT testfunc(
        !           551:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           552:        'int', 1234,
        !           553:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           554:        'string', NULL,
        !           555:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           556:        'double', 1.234,
        !           557:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           558:        'int', 1234,
        !           559:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           560:        'string', NULL,
        !           561:        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        !           562:        'double', 1.234
        !           563:       );
        !           564:     }
        !           565:   } {1.234}
        !           566: }
        !           567: 
        !           568: # Test the built-in sqlite_version(*) SQL function.
        !           569: #
        !           570: do_test func-11.1 {
        !           571:   execsql {
        !           572:     SELECT sqlite_version(*);
        !           573:   }
        !           574: } [sqlite3 -version]
        !           575: 
        !           576: # Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
        !           577: # etc. are called. These tests use two special user-defined functions
        !           578: # (implemented in func.c) only available in test builds. 
        !           579: #
        !           580: # Function test_destructor() takes one argument and returns a copy of the
        !           581: # text form of that argument. A destructor is associated with the return
        !           582: # value. Function test_destructor_count() returns the number of outstanding
        !           583: # destructor calls for values returned by test_destructor().
        !           584: #
        !           585: if {[db eval {PRAGMA encoding}]=="UTF-8"} {
        !           586:   do_test func-12.1-utf8 {
        !           587:     execsql {
        !           588:       SELECT test_destructor('hello world'), test_destructor_count();
        !           589:     }
        !           590:   } {{hello world} 1}
        !           591: } else {
        !           592:     ifcapable {utf16} {
        !           593:       do_test func-12.1-utf16 {
        !           594:         execsql {
        !           595:           SELECT test_destructor16('hello world'), test_destructor_count();
        !           596:         }
        !           597:       } {{hello world} 1}
        !           598:     }
        !           599: }
        !           600: do_test func-12.2 {
        !           601:   execsql {
        !           602:     SELECT test_destructor_count();
        !           603:   }
        !           604: } {0}
        !           605: do_test func-12.3 {
        !           606:   execsql {
        !           607:     SELECT test_destructor('hello')||' world'
        !           608:   }
        !           609: } {{hello world}}
        !           610: do_test func-12.4 {
        !           611:   execsql {
        !           612:     SELECT test_destructor_count();
        !           613:   }
        !           614: } {0}
        !           615: do_test func-12.5 {
        !           616:   execsql {
        !           617:     CREATE TABLE t4(x);
        !           618:     INSERT INTO t4 VALUES(test_destructor('hello'));
        !           619:     INSERT INTO t4 VALUES(test_destructor('world'));
        !           620:     SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
        !           621:   }
        !           622: } {hello world}
        !           623: do_test func-12.6 {
        !           624:   execsql {
        !           625:     SELECT test_destructor_count();
        !           626:   }
        !           627: } {0}
        !           628: do_test func-12.7 {
        !           629:   execsql {
        !           630:     DROP TABLE t4;
        !           631:   }
        !           632: } {}
        !           633: 
        !           634: 
        !           635: # Test that the auxdata API for scalar functions works. This test uses
        !           636: # a special user-defined function only available in test builds,
        !           637: # test_auxdata(). Function test_auxdata() takes any number of arguments.
        !           638: do_test func-13.1 {
        !           639:   execsql {
        !           640:     SELECT test_auxdata('hello world');
        !           641:   }
        !           642: } {0}
        !           643: 
        !           644: do_test func-13.2 {
        !           645:   execsql {
        !           646:     CREATE TABLE t4(a, b);
        !           647:     INSERT INTO t4 VALUES('abc', 'def');
        !           648:     INSERT INTO t4 VALUES('ghi', 'jkl');
        !           649:   }
        !           650: } {}
        !           651: do_test func-13.3 {
        !           652:   execsql {
        !           653:     SELECT test_auxdata('hello world') FROM t4;
        !           654:   }
        !           655: } {0 1}
        !           656: do_test func-13.4 {
        !           657:   execsql {
        !           658:     SELECT test_auxdata('hello world', 123) FROM t4;
        !           659:   }
        !           660: } {{0 0} {1 1}}
        !           661: do_test func-13.5 {
        !           662:   execsql {
        !           663:     SELECT test_auxdata('hello world', a) FROM t4;
        !           664:   }
        !           665: } {{0 0} {1 0}}
        !           666: do_test func-13.6 {
        !           667:   execsql {
        !           668:     SELECT test_auxdata('hello'||'world', a) FROM t4;
        !           669:   }
        !           670: } {{0 0} {1 0}}
        !           671: 
        !           672: # Test that auxilary data is preserved between calls for SQL variables.
        !           673: do_test func-13.7 {
        !           674:   set DB [sqlite3_connection_pointer db]
        !           675:   set sql "SELECT test_auxdata( ? , a ) FROM t4;"
        !           676:   set STMT [sqlite3_prepare $DB $sql -1 TAIL]
        !           677:   sqlite3_bind_text $STMT 1 hello\000 -1
        !           678:   set res [list]
        !           679:   while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
        !           680:     lappend res [sqlite3_column_text $STMT 0]
        !           681:   }
        !           682:   lappend res [sqlite3_finalize $STMT]
        !           683: } {{0 0} {1 0} SQLITE_OK}
        !           684: 
        !           685: # Make sure that a function with a very long name is rejected
        !           686: do_test func-14.1 {
        !           687:   catch {
        !           688:     db function [string repeat X 254] {return "hello"}
        !           689:   } 
        !           690: } {0}
        !           691: do_test func-14.2 {
        !           692:   catch {
        !           693:     db function [string repeat X 256] {return "hello"}
        !           694:   }
        !           695: } {1}
        !           696: 
        !           697: do_test func-15.1 {
        !           698:   catchsql {select test_error(NULL)}
        !           699: } {1 {}}
        !           700: do_test func-15.2 {
        !           701:   catchsql {select test_error('this is the error message')}
        !           702: } {1 {this is the error message}}
        !           703: do_test func-15.3 {
        !           704:   catchsql {select test_error('this is the error message',12)}
        !           705: } {1 {this is the error message}}
        !           706: do_test func-15.4 {
        !           707:   db errorcode
        !           708: } {12}
        !           709: 
        !           710: # Test the quote function for BLOB and NULL values.
        !           711: do_test func-16.1 {
        !           712:   execsql {
        !           713:     CREATE TABLE tbl2(a, b);
        !           714:   }
        !           715:   set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
        !           716:   sqlite3_bind_blob $::STMT 1 abc 3
        !           717:   sqlite3_step $::STMT
        !           718:   sqlite3_finalize $::STMT
        !           719:   execsql {
        !           720:     SELECT quote(a), quote(b) FROM tbl2;
        !           721:   }
        !           722: } {X'616263' NULL}
        !           723: 
        !           724: # Correctly handle function error messages that include %.  Ticket #1354
        !           725: #
        !           726: do_test func-17.1 {
        !           727:   proc testfunc1 args {error "Error %d with %s percents %p"}
        !           728:   db function testfunc1 ::testfunc1
        !           729:   catchsql {
        !           730:     SELECT testfunc1(1,2,3);
        !           731:   }
        !           732: } {1 {Error %d with %s percents %p}}
        !           733: 
        !           734: # The SUM function should return integer results when all inputs are integer.
        !           735: #
        !           736: do_test func-18.1 {
        !           737:   execsql {
        !           738:     CREATE TABLE t5(x);
        !           739:     INSERT INTO t5 VALUES(1);
        !           740:     INSERT INTO t5 VALUES(-99);
        !           741:     INSERT INTO t5 VALUES(10000);
        !           742:     SELECT sum(x) FROM t5;
        !           743:   }
        !           744: } {9902}
        !           745: ifcapable floatingpoint {
        !           746:   do_test func-18.2 {
        !           747:     execsql {
        !           748:       INSERT INTO t5 VALUES(0.0);
        !           749:       SELECT sum(x) FROM t5;
        !           750:     }
        !           751:   } {9902.0}
        !           752: }
        !           753: 
        !           754: # The sum of nothing is NULL.  But the sum of all NULLs is NULL.
        !           755: #
        !           756: # The TOTAL of nothing is 0.0.
        !           757: #
        !           758: do_test func-18.3 {
        !           759:   execsql {
        !           760:     DELETE FROM t5;
        !           761:     SELECT sum(x), total(x) FROM t5;
        !           762:   }
        !           763: } {{} 0.0}
        !           764: do_test func-18.4 {
        !           765:   execsql {
        !           766:     INSERT INTO t5 VALUES(NULL);
        !           767:     SELECT sum(x), total(x) FROM t5
        !           768:   }
        !           769: } {{} 0.0}
        !           770: do_test func-18.5 {
        !           771:   execsql {
        !           772:     INSERT INTO t5 VALUES(NULL);
        !           773:     SELECT sum(x), total(x) FROM t5
        !           774:   }
        !           775: } {{} 0.0}
        !           776: do_test func-18.6 {
        !           777:   execsql {
        !           778:     INSERT INTO t5 VALUES(123);
        !           779:     SELECT sum(x), total(x) FROM t5
        !           780:   }
        !           781: } {123 123.0}
        !           782: 
        !           783: # Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
        !           784: # an error. The non-standard TOTAL() function continues to give a helpful
        !           785: # result.
        !           786: #
        !           787: do_test func-18.10 {
        !           788:   execsql {
        !           789:     CREATE TABLE t6(x INTEGER);
        !           790:     INSERT INTO t6 VALUES(1);
        !           791:     INSERT INTO t6 VALUES(1<<62);
        !           792:     SELECT sum(x) - ((1<<62)+1) from t6;
        !           793:   }
        !           794: } 0
        !           795: do_test func-18.11 {
        !           796:   execsql {
        !           797:     SELECT typeof(sum(x)) FROM t6
        !           798:   }
        !           799: } integer
        !           800: ifcapable floatingpoint {
        !           801:   do_test func-18.12 {
        !           802:     catchsql {
        !           803:       INSERT INTO t6 VALUES(1<<62);
        !           804:       SELECT sum(x) - ((1<<62)*2.0+1) from t6;
        !           805:     }
        !           806:   } {1 {integer overflow}}
        !           807:   do_test func-18.13 {
        !           808:     execsql {
        !           809:       SELECT total(x) - ((1<<62)*2.0+1) FROM t6
        !           810:     }
        !           811:   } 0.0
        !           812: }
        !           813: ifcapable !floatingpoint {
        !           814:   do_test func-18.12 {
        !           815:     catchsql {
        !           816:       INSERT INTO t6 VALUES(1<<62);
        !           817:       SELECT sum(x) - ((1<<62)*2+1) from t6;
        !           818:     }
        !           819:   } {1 {integer overflow}}
        !           820:   do_test func-18.13 {
        !           821:     execsql {
        !           822:       SELECT total(x) - ((1<<62)*2+1) FROM t6
        !           823:     }
        !           824:   } 0.0
        !           825: }
        !           826: if {[working_64bit_int]} {
        !           827:   do_test func-18.14 {
        !           828:     execsql {
        !           829:       SELECT sum(-9223372036854775805);
        !           830:     }
        !           831:   } -9223372036854775805
        !           832: }
        !           833: ifcapable compound&&subquery {
        !           834: 
        !           835: do_test func-18.15 {
        !           836:   catchsql {
        !           837:     SELECT sum(x) FROM 
        !           838:        (SELECT 9223372036854775807 AS x UNION ALL
        !           839:         SELECT 10 AS x);
        !           840:   }
        !           841: } {1 {integer overflow}}
        !           842: if {[working_64bit_int]} {
        !           843:   do_test func-18.16 {
        !           844:     catchsql {
        !           845:       SELECT sum(x) FROM 
        !           846:          (SELECT 9223372036854775807 AS x UNION ALL
        !           847:           SELECT -10 AS x);
        !           848:     }
        !           849:   } {0 9223372036854775797}
        !           850:   do_test func-18.17 {
        !           851:     catchsql {
        !           852:       SELECT sum(x) FROM 
        !           853:          (SELECT -9223372036854775807 AS x UNION ALL
        !           854:           SELECT 10 AS x);
        !           855:     }
        !           856:   } {0 -9223372036854775797}
        !           857: }
        !           858: do_test func-18.18 {
        !           859:   catchsql {
        !           860:     SELECT sum(x) FROM 
        !           861:        (SELECT -9223372036854775807 AS x UNION ALL
        !           862:         SELECT -10 AS x);
        !           863:   }
        !           864: } {1 {integer overflow}}
        !           865: do_test func-18.19 {
        !           866:   catchsql {
        !           867:     SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
        !           868:   }
        !           869: } {0 -1}
        !           870: do_test func-18.20 {
        !           871:   catchsql {
        !           872:     SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
        !           873:   }
        !           874: } {0 1}
        !           875: do_test func-18.21 {
        !           876:   catchsql {
        !           877:     SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
        !           878:   }
        !           879: } {0 -1}
        !           880: do_test func-18.22 {
        !           881:   catchsql {
        !           882:     SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
        !           883:   }
        !           884: } {0 1}
        !           885: 
        !           886: } ;# ifcapable compound&&subquery
        !           887: 
        !           888: # Integer overflow on abs()
        !           889: #
        !           890: if {[working_64bit_int]} {
        !           891:   do_test func-18.31 {
        !           892:     catchsql {
        !           893:       SELECT abs(-9223372036854775807);
        !           894:     }
        !           895:   } {0 9223372036854775807}
        !           896: }
        !           897: do_test func-18.32 {
        !           898:   catchsql {
        !           899:     SELECT abs(-9223372036854775807-1);
        !           900:   }
        !           901: } {1 {integer overflow}}
        !           902: 
        !           903: # The MATCH function exists but is only a stub and always throws an error.
        !           904: #
        !           905: do_test func-19.1 {
        !           906:   execsql {
        !           907:     SELECT match(a,b) FROM t1 WHERE 0;
        !           908:   }
        !           909: } {}
        !           910: do_test func-19.2 {
        !           911:   catchsql {
        !           912:     SELECT 'abc' MATCH 'xyz';
        !           913:   }
        !           914: } {1 {unable to use function MATCH in the requested context}}
        !           915: do_test func-19.3 {
        !           916:   catchsql {
        !           917:     SELECT 'abc' NOT MATCH 'xyz';
        !           918:   }
        !           919: } {1 {unable to use function MATCH in the requested context}}
        !           920: do_test func-19.4 {
        !           921:   catchsql {
        !           922:     SELECT match(1,2,3);
        !           923:   }
        !           924: } {1 {wrong number of arguments to function match()}}
        !           925: 
        !           926: # Soundex tests.
        !           927: #
        !           928: if {![catch {db eval {SELECT soundex('hello')}}]} {
        !           929:   set i 0
        !           930:   foreach {name sdx} {
        !           931:     euler        E460
        !           932:     EULER        E460
        !           933:     Euler        E460
        !           934:     ellery       E460
        !           935:     gauss        G200
        !           936:     ghosh        G200
        !           937:     hilbert      H416
        !           938:     Heilbronn    H416
        !           939:     knuth        K530
        !           940:     kant         K530
        !           941:     Lloyd        L300
        !           942:     LADD         L300
        !           943:     Lukasiewicz  L222
        !           944:     Lissajous    L222
        !           945:     A            A000
        !           946:     12345        ?000
        !           947:   } {
        !           948:     incr i
        !           949:     do_test func-20.$i {
        !           950:       execsql {SELECT soundex($name)}
        !           951:     } $sdx
        !           952:   }
        !           953: }
        !           954: 
        !           955: # Tests of the REPLACE function.
        !           956: #
        !           957: do_test func-21.1 {
        !           958:   catchsql {
        !           959:     SELECT replace(1,2);
        !           960:   }
        !           961: } {1 {wrong number of arguments to function replace()}}
        !           962: do_test func-21.2 {
        !           963:   catchsql {
        !           964:     SELECT replace(1,2,3,4);
        !           965:   }
        !           966: } {1 {wrong number of arguments to function replace()}}
        !           967: do_test func-21.3 {
        !           968:   execsql {
        !           969:     SELECT typeof(replace("This is the main test string", NULL, "ALT"));
        !           970:   }
        !           971: } {null}
        !           972: do_test func-21.4 {
        !           973:   execsql {
        !           974:     SELECT typeof(replace(NULL, "main", "ALT"));
        !           975:   }
        !           976: } {null}
        !           977: do_test func-21.5 {
        !           978:   execsql {
        !           979:     SELECT typeof(replace("This is the main test string", "main", NULL));
        !           980:   }
        !           981: } {null}
        !           982: do_test func-21.6 {
        !           983:   execsql {
        !           984:     SELECT replace("This is the main test string", "main", "ALT");
        !           985:   }
        !           986: } {{This is the ALT test string}}
        !           987: do_test func-21.7 {
        !           988:   execsql {
        !           989:     SELECT replace("This is the main test string", "main", "larger-main");
        !           990:   }
        !           991: } {{This is the larger-main test string}}
        !           992: do_test func-21.8 {
        !           993:   execsql {
        !           994:     SELECT replace("aaaaaaa", "a", "0123456789");
        !           995:   }
        !           996: } {0123456789012345678901234567890123456789012345678901234567890123456789}
        !           997: 
        !           998: ifcapable tclvar {
        !           999:   do_test func-21.9 {
        !          1000:     # Attempt to exploit a buffer-overflow that at one time existed 
        !          1001:     # in the REPLACE function. 
        !          1002:     set ::str "[string repeat A 29998]CC[string repeat A 35537]"
        !          1003:     set ::rep [string repeat B 65536]
        !          1004:     execsql {
        !          1005:       SELECT LENGTH(REPLACE($::str, 'C', $::rep));
        !          1006:     }
        !          1007:   } [expr 29998 + 2*65536 + 35537]
        !          1008: }
        !          1009: 
        !          1010: # Tests for the TRIM, LTRIM and RTRIM functions.
        !          1011: #
        !          1012: do_test func-22.1 {
        !          1013:   catchsql {SELECT trim(1,2,3)}
        !          1014: } {1 {wrong number of arguments to function trim()}}
        !          1015: do_test func-22.2 {
        !          1016:   catchsql {SELECT ltrim(1,2,3)}
        !          1017: } {1 {wrong number of arguments to function ltrim()}}
        !          1018: do_test func-22.3 {
        !          1019:   catchsql {SELECT rtrim(1,2,3)}
        !          1020: } {1 {wrong number of arguments to function rtrim()}}
        !          1021: do_test func-22.4 {
        !          1022:   execsql {SELECT trim('  hi  ');}
        !          1023: } {hi}
        !          1024: do_test func-22.5 {
        !          1025:   execsql {SELECT ltrim('  hi  ');}
        !          1026: } {{hi  }}
        !          1027: do_test func-22.6 {
        !          1028:   execsql {SELECT rtrim('  hi  ');}
        !          1029: } {{  hi}}
        !          1030: do_test func-22.7 {
        !          1031:   execsql {SELECT trim('  hi  ','xyz');}
        !          1032: } {{  hi  }}
        !          1033: do_test func-22.8 {
        !          1034:   execsql {SELECT ltrim('  hi  ','xyz');}
        !          1035: } {{  hi  }}
        !          1036: do_test func-22.9 {
        !          1037:   execsql {SELECT rtrim('  hi  ','xyz');}
        !          1038: } {{  hi  }}
        !          1039: do_test func-22.10 {
        !          1040:   execsql {SELECT trim('xyxzy  hi  zzzy','xyz');}
        !          1041: } {{  hi  }}
        !          1042: do_test func-22.11 {
        !          1043:   execsql {SELECT ltrim('xyxzy  hi  zzzy','xyz');}
        !          1044: } {{  hi  zzzy}}
        !          1045: do_test func-22.12 {
        !          1046:   execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
        !          1047: } {{xyxzy  hi  }}
        !          1048: do_test func-22.13 {
        !          1049:   execsql {SELECT trim('  hi  ','');}
        !          1050: } {{  hi  }}
        !          1051: if {[db one {PRAGMA encoding}]=="UTF-8"} {
        !          1052:   do_test func-22.14 {
        !          1053:     execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
        !          1054:   } {F48FBFBF6869}
        !          1055:   do_test func-22.15 {
        !          1056:     execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
        !          1057:                              x'6162e1bfbfc280f48fbfbf'))}
        !          1058:   } {6869}
        !          1059:   do_test func-22.16 {
        !          1060:     execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
        !          1061:   } {CEB2CEB3}
        !          1062: }
        !          1063: do_test func-22.20 {
        !          1064:   execsql {SELECT typeof(trim(NULL));}
        !          1065: } {null}
        !          1066: do_test func-22.21 {
        !          1067:   execsql {SELECT typeof(trim(NULL,'xyz'));}
        !          1068: } {null}
        !          1069: do_test func-22.22 {
        !          1070:   execsql {SELECT typeof(trim('hello',NULL));}
        !          1071: } {null}
        !          1072: 
        !          1073: # This is to test the deprecated sqlite3_aggregate_count() API.
        !          1074: #
        !          1075: ifcapable deprecated {
        !          1076:   do_test func-23.1 {
        !          1077:     sqlite3_create_aggregate db
        !          1078:     execsql {
        !          1079:       SELECT legacy_count() FROM t6;
        !          1080:     }
        !          1081:   } {3}
        !          1082: }
        !          1083: 
        !          1084: # The group_concat() function.
        !          1085: #
        !          1086: do_test func-24.1 {
        !          1087:   execsql {
        !          1088:     SELECT group_concat(t1) FROM tbl1
        !          1089:   }
        !          1090: } {this,program,is,free,software}
        !          1091: do_test func-24.2 {
        !          1092:   execsql {
        !          1093:     SELECT group_concat(t1,' ') FROM tbl1
        !          1094:   }
        !          1095: } {{this program is free software}}
        !          1096: do_test func-24.3 {
        !          1097:   execsql {
        !          1098:     SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
        !          1099:   }
        !          1100: } {{this 2 program 3 is 4 free 5 software}}
        !          1101: do_test func-24.4 {
        !          1102:   execsql {
        !          1103:     SELECT group_concat(NULL,t1) FROM tbl1
        !          1104:   }
        !          1105: } {{}}
        !          1106: do_test func-24.5 {
        !          1107:   execsql {
        !          1108:     SELECT group_concat(t1,NULL) FROM tbl1
        !          1109:   }
        !          1110: } {thisprogramisfreesoftware}
        !          1111: do_test func-24.6 {
        !          1112:   execsql {
        !          1113:     SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
        !          1114:   }
        !          1115: } {BEGIN-this,program,is,free,software}
        !          1116: 
        !          1117: # Ticket #3179:  Make sure aggregate functions can take many arguments.
        !          1118: # None of the built-in aggregates do this, so use the md5sum() from the
        !          1119: # test extensions.
        !          1120: #
        !          1121: unset -nocomplain midargs
        !          1122: set midargs {}
        !          1123: unset -nocomplain midres
        !          1124: set midres {}
        !          1125: unset -nocomplain result
        !          1126: for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
        !          1127:   append midargs ,'/$i'
        !          1128:   append midres /$i
        !          1129:   set result [md5 \
        !          1130:      "this${midres}program${midres}is${midres}free${midres}software${midres}"]
        !          1131:   set sql "SELECT md5sum(t1$midargs) FROM tbl1"
        !          1132:   do_test func-24.7.$i {
        !          1133:      db eval $::sql
        !          1134:   } $result
        !          1135: }
        !          1136: 
        !          1137: # Ticket #3806.  If the initial string in a group_concat is an empty
        !          1138: # string, the separator that follows should still be present.
        !          1139: #
        !          1140: do_test func-24.8 {
        !          1141:   execsql {
        !          1142:     SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
        !          1143:   }
        !          1144: } {,program,is,free,software}
        !          1145: do_test func-24.9 {
        !          1146:   execsql {
        !          1147:     SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
        !          1148:   }
        !          1149: } {,,,,software}
        !          1150: 
        !          1151: # Ticket #3923.  Initial empty strings have a separator.  But initial
        !          1152: # NULLs do not.
        !          1153: #
        !          1154: do_test func-24.10 {
        !          1155:   execsql {
        !          1156:     SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1
        !          1157:   }
        !          1158: } {program,is,free,software}
        !          1159: do_test func-24.11 {
        !          1160:   execsql {
        !          1161:    SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1
        !          1162:   }
        !          1163: } {software}
        !          1164: do_test func-24.12 {
        !          1165:   execsql {
        !          1166:     SELECT group_concat(CASE t1 WHEN 'this' THEN ''
        !          1167:                           WHEN 'program' THEN null ELSE t1 END) FROM tbl1
        !          1168:   }
        !          1169: } {,is,free,software}
        !          1170: 
        !          1171: 
        !          1172: # Use the test_isolation function to make sure that type conversions
        !          1173: # on function arguments do not effect subsequent arguments.
        !          1174: #
        !          1175: do_test func-25.1 {
        !          1176:   execsql {SELECT test_isolation(t1,t1) FROM tbl1}
        !          1177: } {this program is free software}
        !          1178: 
        !          1179: # Try to misuse the sqlite3_create_function() interface.  Verify that
        !          1180: # errors are returned.
        !          1181: #
        !          1182: do_test func-26.1 {
        !          1183:   abuse_create_function db
        !          1184: } {}
        !          1185: 
        !          1186: # The previous test (func-26.1) registered a function with a very long
        !          1187: # function name that takes many arguments and always returns NULL.  Verify
        !          1188: # that this function works correctly.
        !          1189: #
        !          1190: do_test func-26.2 {
        !          1191:   set a {}
        !          1192:   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
        !          1193:     lappend a $i
        !          1194:   }
        !          1195:   db eval "
        !          1196:      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]);
        !          1197:   "
        !          1198: } {{}}
        !          1199: do_test func-26.3 {
        !          1200:   set a {}
        !          1201:   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
        !          1202:     lappend a $i
        !          1203:   }
        !          1204:   catchsql "
        !          1205:      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]);
        !          1206:   "
        !          1207: } {1 {too many arguments on function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789}}
        !          1208: do_test func-26.4 {
        !          1209:   set a {}
        !          1210:   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
        !          1211:     lappend a $i
        !          1212:   }
        !          1213:   catchsql "
        !          1214:      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]);
        !          1215:   "
        !          1216: } {1 {wrong number of arguments to function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789()}}
        !          1217: do_test func-26.5 {
        !          1218:   catchsql "
        !          1219:      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12345678a(0);
        !          1220:   "
        !          1221: } {1 {no such function: nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12345678a}}
        !          1222: do_test func-26.6 {
        !          1223:   catchsql "
        !          1224:      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789a(0);
        !          1225:   "
        !          1226: } {1 {no such function: nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789a}}
        !          1227: 
        !          1228: do_test func-27.1 {
        !          1229:   catchsql {SELECT coalesce()}
        !          1230: } {1 {wrong number of arguments to function coalesce()}}
        !          1231: do_test func-27.2 {
        !          1232:   catchsql {SELECT coalesce(1)}
        !          1233: } {1 {wrong number of arguments to function coalesce()}}
        !          1234: do_test func-27.3 {
        !          1235:   catchsql {SELECT coalesce(1,2)}
        !          1236: } {0 1}
        !          1237: 
        !          1238: # Ticket 2d401a94287b5
        !          1239: # Unknown function in a DEFAULT expression causes a segfault.
        !          1240: #
        !          1241: do_test func-28.1 {
        !          1242:   db eval {
        !          1243:     CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1)));
        !          1244:   }
        !          1245:   catchsql {
        !          1246:     INSERT INTO t28(x) VALUES(1);
        !          1247:   }
        !          1248: } {1 {unknown function: nosuchfunc()}}
        !          1249: 
        !          1250: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>