3
# Tests for the tdbc::postgres bridge
5
# Copyright (c) 2008 by Slawomir Cygan
6
# See the file "license.terms" for information on usage and redistribution
7
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10
#------------------------------------------------------------------------------
12
package require tcltest 2.2
13
namespace import -force ::tcltest::*
15
package require tdbc::postgres
17
# We need to know the parameters of the Postgre database for testing.
20
if {[info exists env(TDBCPOSTGRES_HOST)]} {
21
lappend connFlags -host $env(TDBCPOSTGRES_HOST)
23
if {[info exists env(TDBCPOSTGRES_USER)]} {
24
lappend connFlags -user $env(TDBCPOSTGRES_USER)
26
if {[info exists env(TDBCPOSTGRES_PASSWD)]} {
27
lappend connFlags -password $env(TDBCPOSTGRES_PASSWD)
29
if {[info exists env(TDBCPOSTGRES_DB)]} {
30
lappend connFlags -db $env(TDBCPOSTGRES_DB)
31
tcltest::testConstraint connect 1
33
tcltest::testConstraint connect 0
35
if {[info exists env(TDBCPOSTGRES_PORT)]} {
36
lappend connFlags -port $env(TDBCPOSTGRES_PORT)
39
#------------------------------------------------------------------------------
40
test tdbc::postgres-1.1 {create a connection, wrong # args} {*}{
42
tdbc::postgres::connection create
46
-result {wrong # args*}
49
test tdbc::postgres-1.2 {create a connection, connection string missing} {*}{
51
tdbc::postgres::connection create db -user
55
-result {wrong # args*}
58
test tdbc::postgres-1.3 {create a connection, bad arg} {*}{
60
tdbc::postgres::connection create db -rubbish rubbish
64
-result {bad option "-rubbish"*}
67
test tdbc::postgres-1.4 {create a connection, bad port} {*}{
69
tdbc::postgres::connection create db -port rubbish
72
-result {expected integer but got "rubbish"}
75
test tdbc::postgres-1.5 {create a connection, bad port} {*}{
77
tdbc::postgres::connection create db -port 999999999999
81
-result {integer value too large to represent*}
84
test tdbc::postgres-1.6 {create a connection, bad port} {*}{
86
tdbc::postgres::connection create db -port -1
89
-result {port number must be in range [0..65535]}
92
test tdbc::postgres-1.7 {create a connection, bad port} {*}{
94
tdbc::postgres::connection create db -port 65536
97
-result {port number must be in range [0..65535]}
100
test tdbc::postgres-1.8 {create a connection, failure} {*}{
103
tdbc::postgres::connection create db -host rubbish.example.com
105
list $status $result $::errorCode
108
-result {1 {could not translate host name*} {TDBC GENERAL_ERROR HY000 POSTGRES *}}
111
test tdbc::postgres-1.9 {create a connection, successful} {*}{
114
tdbc::postgres::connection create ::db {*}$connFlags
118
catch {rename ::db {}}
123
#------------------------------------------------------------------------------
125
# The tests that follow all require a connection to a database.
127
if {![tcltest::testConstraint connect]} {
128
puts "tests requiring a db connection skipped."
133
tdbc::postgres::connection create ::db {*}$connFlags
134
catch {::db allrows {DROP TABLE people}}
136
#------------------------------------------------------------------------------
138
test tdbc::postgres-2.1 {prepare statement, wrong # args} {*}{
144
-result {wrong # args*}
147
test tdbc::postgres-2.2 {don't make a statement without a connection} {*}{
149
tdbc::postgres::statement create stmt rubbish moreRubbish
152
-result {rubbish does not refer to an object}
155
test tdbc::postgres-2.3 {don't make a statement without a connection} {*}{
157
tdbc::postgres::statement create stmt oo::class moreRubbish
160
-result {oo::class does not refer to a Postgres connection}
163
test tdbc::postgres-2.4 {semicolons in statements} {*}{
165
::db prepare {select foo from bar; select grill from quux}
168
-result {tdbc::postgres does not support semicolons in statements}
171
test tdbc::postgres-3.1 {prepare an invalid statement} {*}{
178
list $status $result $::errorCode
181
-result {1 {*syntax error*} {TDBC SYNTAX_ERROR* 42601 POSTGRES *}}
184
test tdbc::postgres-3.2 {prepare a valid statement} {*}{
186
set stmt [::db prepare {
188
idnum INTEGER PRIMARY KEY,
189
name VARCHAR(40) NOT NULL
196
catch [rename $stmt {}]
200
test tdbc::postgres-3.3 {execute a valid statement with no results} {*}{
202
set stmt [::db prepare {
204
idnum INTEGER PRIMARY KEY,
205
name VARCHAR(40) NOT NULL
208
set rs [$stmt execute]
209
list [expr {[$rs rowcount] <= 0}] [$rs columns] [$rs nextrow nothing]
216
set stmt [::db prepare {
219
set rs [$stmt execute]
226
test tdbc::postgres-3.4 {result set: wrong # args} {*}{
228
set stmt [::db prepare {
230
idnum INTEGER PRIMARY KEY,
231
name VARCHAR(40) NOT NULL
234
$stmt execute with extra args
238
-result {wrong # args*}
240
catch [rename $stmt {}]
244
test tdbc::postgres-3.5 {result set: trying to create against a non-object} {*}{
246
tdbc::postgres::resultset create rs nothing
249
-result {nothing does not refer to an object}
252
test tdbc::postgres-3.6 {result set: trying to create against a non-statement} {*}{
254
tdbc::postgres::resultset create rs db
257
-result {db does not refer to a Postgres statement}
260
#-------------------------------------------------------------------------------
262
# Following tests need a 'people' table in the database.
263
# They also need to use the InnoDB engine, because some of the test cases
264
# test transaction support.
266
set stmt [::db prepare {
268
idnum INTEGER PRIMARY KEY,
269
name VARCHAR(40) NOT NULL,
273
set rs [$stmt execute]
277
test tdbc::postgres-4.1 {execute an insert with no params} {*}{
279
set stmt [::db prepare {
280
INSERT INTO people(idnum, name, info) values(1, 'fred', 0)
282
set rs [$stmt execute]
283
list [$rs rowcount] [$rs columns] [$rs nextrow nothing]
290
set stmt [::db prepare {
293
set rs [$stmt execute]
300
test tdbc::postgres-4.2 {execute an insert with variable parameters} {*}{
302
set stmt [::db prepare {
303
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
305
$stmt paramtype idnum integer
306
$stmt paramtype name varchar 40
309
set rs [$stmt execute]
310
list [$rs rowcount] [$rs columns] [$rs nextrow nothing]
317
set stmt [::db prepare {
320
set rs [$stmt execute]
327
test tdbc::postgres-4.3 {execute an insert with dictionary parameters} {*}{
329
set stmt [::db prepare {
330
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
332
$stmt paramtype idnum integer
333
$stmt paramtype name varchar 40
334
set rs [$stmt execute {idnum 1 name fred}]
335
list [$rs rowcount] [$rs columns] [$rs nextrow nothing]
342
set stmt [::db prepare {
345
set rs [$stmt execute]
352
test tdbc::postgres-4.4 {bad dictionary} {*}{
354
set stmt [::db prepare {
355
INSERT INTO people(idnum, name) values(:idnum, :name)
357
$stmt paramtype idnum integer
358
$stmt paramtype name varchar 40
359
$stmt execute {idnum 1 name}
362
-result {missing value to go with key}
366
set stmt [::db prepare {
369
set rs [$stmt execute]
376
test tdbc::postgres-4.5 {missing parameter variable} {*}{
382
set stmt [::db prepare {
383
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
385
$stmt paramtype idnum integer
386
$stmt paramtype name varchar 40
392
-result {*violates not-null constraint*}
396
set stmt [::db prepare {
399
set rs [$stmt execute]
406
test tdbc::postgres-4.6 {missing parameter in dictionary} {*}{
409
set stmt [::db prepare {
410
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
412
$stmt paramtype idnum integer
413
$stmt paramtype name varchar 40
414
$stmt execute {name fred}
418
-result {*violates not-null constraint*}
422
set stmt [::db prepare {
425
set rs [$stmt execute]
432
test tdbc::postgres-4.7 {missing parameter - nullable} {*}{
435
set stmt [::db prepare {
436
INSERT INTO people(idnum, name, info) values(:idnum, :name, :info)
438
$stmt paramtype idnum integer
439
$stmt paramtype name varchar 40
440
$stmt paramtype info integer
441
set stmt2 [::db prepare {
442
SELECT name, info FROM people WHERE idnum = :idnum
444
$stmt2 paramtype idnum integer
447
set name "mr. gravel"
449
set rs [$stmt execute]
451
set rs [$stmt2 execute]
452
$rs nextrow -as dicts row
455
-result {name {mr. gravel}}
457
catch {rename $rs {}}
461
set stmt [::db prepare {
464
set rs [$stmt execute]
471
test tdbc::postgres-4.8 {missing parameter in dictionary - nullable} {*}{
473
set stmt [::db prepare {
474
INSERT INTO people(idnum, name, info) values(:idnum, :name, :info)
476
$stmt paramtype idnum integer
477
$stmt paramtype name varchar 40
478
$stmt paramtype info integer
479
set stmt2 [::db prepare {
480
SELECT name, info FROM people WHERE idnum = :idnum
482
$stmt2 paramtype idnum integer
485
set rs [$stmt execute {name {gary granite} idnum 200}]
487
set rs [$stmt2 execute {idnum 200}]
488
$rs nextrow -as dicts row
491
-result {name {gary granite}}
493
catch {rename $rs {}}
497
set stmt [::db prepare {
500
set rs [$stmt execute]
507
test tdbc::postgres-4.9 {two result sets open against the same statement} {*}{
509
set stmt [::db prepare {
510
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
512
$stmt paramtype idnum integer
513
$stmt paramtype name varchar 40
514
set rs1 [$stmt execute {idnum 1 name fred}]
515
set rs2 [$stmt execute {idnum 2 name wilma}]
516
list [$rs1 rowcount] [$rs1 columns] [$rs1 nextrow nothing] \
517
[$rs2 rowcount] [$rs2 columns] [$rs2 nextrow nothing]
519
-result {1 {} 0 1 {} 0}
525
set stmt [::db prepare {
528
set rs [$stmt execute]
535
test tdbc::postgres-4.10 {failed execution} {*}{
537
set stmt [::db prepare {
538
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
540
$stmt paramtype idnum integer
541
$stmt paramtype name varchar 40
542
set rs [$stmt execute {idnum 1 name fred}]
546
set status [catch {$stmt execute {idnum 1 name barney}} result]
547
list $status $::errorCode
551
set stmt [::db prepare {
554
set rs [$stmt execute]
559
-result {1 {TDBC CONSTRAINT_VIOLATION 23* POSTGRES *}}
562
test tdbc::postgres-5.1 {paramtype - too few args} {*}{
564
set stmt [::db prepare {
565
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
569
$stmt paramtype idnum
576
-result {wrong # args*}
579
test tdbc::postgres-5.2 {paramtype - just a direction} {*}{
581
set stmt [::db prepare {
582
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
586
$stmt paramtype idnum in
593
-result {wrong # args*}
596
test tdbc::postgres-5.3 {paramtype - bad type} {*}{
598
set stmt [::db prepare {
599
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
603
$stmt paramtype idnum rubbish
610
-result {bad SQL data type "rubbish":*}
613
test tdbc::postgres-5.4 {paramtype - bad scale} {*}{
615
set stmt [::db prepare {
616
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
620
$stmt paramtype idnum decimal rubbish
627
-result {expected integer but got "rubbish"}
630
test tdbc::postgres-5.5 {paramtype - bad precision} {*}{
632
set stmt [::db prepare {
633
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
637
$stmt paramtype idnum decimal 12 rubbish
644
-result {expected integer but got "rubbish"}
647
test tdbc::postgres-5.6 {paramtype - unknown parameter} {*}{
649
set stmt [::db prepare {
650
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
654
$stmt paramtype rubbish integer
661
-result {unknown parameter "rubbish":*}
664
test tdbc::postgres-6.1 {rowcount - wrong args} {*}{
666
set stmt [::db prepare {
667
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
669
$stmt paramtype idnum integer
670
$stmt paramtype name varchar 40
671
set rs [$stmt execute {idnum 1 name fred}]
679
set stmt [::db prepare {
682
set rs [$stmt execute]
688
-result "wrong \# args*"
692
#-------------------------------------------------------------------------------
694
# next tests require data in the database
697
set stmt [db prepare {
698
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
700
$stmt paramtype idnum integer
701
$stmt paramtype name varchar 40
703
foreach name {fred wilma pebbles barney betty bam-bam} {
704
set rs [$stmt execute]
711
#-------------------------------------------------------------------------------
713
test tdbc::postgres-7.1 {columns - bad args} {*}{
715
set stmt [::db prepare {
718
set rs [$stmt execute]
729
-result {wrong # args*}
732
test tdbc::postgres-7.2 {columns - get column names} {*}{
734
set stmt [::db prepare {
737
set rs [$stmt execute]
746
-result {idnum name info}
750
test tdbc::postgres-8.1 {nextrow - as dicts} {*}{
752
set stmt [::db prepare {
753
SELECT idnum, name FROM people ORDER BY idnum
755
set rs [$stmt execute]
760
while {[$rs nextrow -- row]} {
761
if {$idnum != [dict get $row idnum]} {
762
error [list bad idnum [dict get $row idnum] should be $idnum]
764
lappend names [dict get $row name]
773
-result {fred wilma pebbles barney betty bam-bam}
776
test tdbc::postgres-8.4 {anonymous columns - dicts} {*}{
778
set stmt [::db prepare {
779
SELECT COUNT(*), MAX(idnum) FROM people
781
set rs [$stmt execute]
793
-result {1 {* 6 * 6} 0}
796
test tdbc::postgres-8.5 {anonymous columns - lists} {*}{
798
set stmt [::db prepare {
799
SELECT COUNT(*), MAX(idnum) FROM people
801
set rs [$stmt execute]
804
list [$rs nextrow -as lists row] \
806
[$rs nextrow -as lists row]
815
test tdbc::postgres-8.2 {nextrow - as lists} {*}{
817
set stmt [::db prepare {
818
SELECT idnum, name FROM people ORDER BY idnum
820
set rs [$stmt execute]
825
while {[$rs nextrow -as lists -- row]} {
826
if {$idnum != [lindex $row 0]} {
827
error [list bad idnum [lindex $row 0] should be $idnum]
829
lappend names [lindex $row 1]
838
-result {fred wilma pebbles barney betty bam-bam}
846
test tdbc::postgres-8.3 {nextrow - bad cursor state} {*}{
848
set stmt [::db prepare {
849
SELECT idnum, name FROM people ORDER BY idnum
853
set rs [$stmt execute]
855
while {[$rs nextrow row]} {}
865
test tdbc::postgres-8.6 {null results - dicts} {*}{
867
set stmt [::db prepare {
868
SELECT idnum, name, info FROM people WHERE name = 'fred'
870
set rs [$stmt execute]
873
list [$rs nextrow row] $row [$rs nextrow row]
878
-result {1 {idnum 1 name fred} 0}
881
test tdbc::postgres-8.7 {null results - lists} {*}{
883
set stmt [::db prepare {
884
SELECT idnum, name, info FROM people WHERE name = 'fred'
886
set rs [$stmt execute]
889
list [$rs nextrow -as lists -- row] $row [$rs nextrow -as lists -- row]
894
-result {1 {1 fred {}} 0}
897
test tdbc::postgres-9.1 {rs foreach var script} {*}{
899
set stmt [::db prepare {
900
SELECT idnum, name FROM people WHERE name LIKE 'b%'
902
set rs [$stmt execute]
915
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
918
test tdbc::postgres-9.2 {stmt foreach var script} {*}{
920
set stmt [::db prepare {
921
SELECT idnum, name FROM people WHERE name LIKE 'b%'
935
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
938
test tdbc::postgres-9.3 {db foreach var sqlcode script} {*}{
942
SELECT idnum, name FROM people WHERE name LIKE 'b%'
948
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
951
test tdbc::postgres-9.4 {rs foreach -- var script} {*}{
953
set stmt [::db prepare {
954
SELECT idnum, name FROM people WHERE name LIKE 'b%'
956
set rs [$stmt execute]
969
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
972
test tdbc::postgres-9.5 {stmt foreach -- var script} {*}{
974
set stmt [::db prepare {
975
SELECT idnum, name FROM people WHERE name LIKE 'b%'
980
$stmt foreach -- row {
988
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
991
test tdbc::postgres-9.6 {db foreach -- var query script} {*}{
995
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1001
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1004
test tdbc::postgres-9.7 {rs foreach -- -as lists} {*}{
1006
set stmt [::db prepare {
1007
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1009
set rs [$stmt execute]
1013
$rs foreach -as lists row {
1022
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
1025
test tdbc::postgres-9.8 {stmt foreach -as lists} {*}{
1027
set stmt [::db prepare {
1028
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1033
$stmt foreach -as lists row {
1041
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
1044
test tdbc::postgres-9.9 {db foreach -as lists} {*}{
1047
db foreach -as lists row {
1048
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1054
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
1057
test tdbc::postgres-9.10 {rs foreach -as lists --} {*}{
1059
set stmt [::db prepare {
1060
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1062
set rs [$stmt execute]
1066
$rs foreach -as lists -- row {
1075
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
1078
test tdbc::postgres-9.11 {stmt foreach -as lists --} {*}{
1080
set stmt [::db prepare {
1081
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1086
$stmt foreach -as lists -- row {
1094
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
1097
test tdbc::postgres-9.12 {db foreach -as lists --} {*}{
1100
db foreach -as lists row {
1101
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1107
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
1110
test tdbc::postgres-9.13 {rs foreach -as lists -columnsvar c --} {*}{
1112
set stmt [::db prepare {
1113
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1115
set rs [$stmt execute]
1119
$rs foreach -as lists -columnsvar c -- row {
1120
foreach cn $c cv $row {
1121
lappend result $cn $cv
1130
-result {idnum 4 name barney idnum 5 name betty idnum 6 name bam-bam}
1133
test tdbc::postgres-9.14 {stmt foreach -as lists -columnsvar c --} {*}{
1135
set stmt [::db prepare {
1136
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1141
$stmt foreach -as lists -columnsvar c -- row {
1142
foreach cn $c cv $row {
1143
lappend result $cn $cv
1151
-result {idnum 4 name barney idnum 5 name betty idnum 6 name bam-bam}
1154
test tdbc::postgres-9.15 {db foreach -as lists -columnsvar c --} {*}{
1157
db foreach -as lists -columnsvar c -- row {
1158
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1160
foreach cn $c cv $row {
1161
lappend result $cn $cv
1166
-result {idnum 4 name barney idnum 5 name betty idnum 6 name bam-bam}
1169
test tdbc::postgres-9.16 {rs foreach / break out of loop} {*}{
1171
set stmt [::db prepare {
1172
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1174
set rs [$stmt execute]
1178
$rs foreach -as lists -- row {
1179
if {[lindex $row 1] eq {betty}} break
1188
-result {{4 barney {}}}
1191
test tdbc::postgres-9.17 {stmt foreach / break out of loop} {*}{
1193
set stmt [::db prepare {
1194
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1199
$stmt foreach -as lists -- row {
1200
if {[lindex $row 1] eq {betty}} break
1208
-result {{4 barney {}}}
1211
test tdbc::postgres-9.18 {db foreach / break out of loop} {*}{
1214
db foreach -as lists -- row {
1215
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1217
if {[lindex $row 1] eq {betty}} break
1222
-result {{4 barney {}}}
1225
test tdbc::postgres-9.19 {rs foreach / continue in loop} {*}{
1227
set stmt [::db prepare {
1228
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1230
set rs [$stmt execute]
1234
$rs foreach -as lists -- row {
1235
if {[lindex $row 1] eq {betty}} continue
1244
-result {{4 barney {}} {6 bam-bam {}}}
1247
test tdbc::postgres-9.20 {stmt foreach / continue in loop} {*}{
1249
set stmt [::db prepare {
1250
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1255
$stmt foreach -as lists -- row {
1256
if {[lindex $row 1] eq {betty}} continue
1264
-result {{4 barney {}} {6 bam-bam {}}}
1267
test tdbc::postgres-9.21 {db foreach / continue in loop} {*}{
1270
db foreach -as lists -- row {
1271
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
1273
if {[lindex $row 1] eq {betty}} continue
1278
-result {{4 barney {}} {6 bam-bam {}}}
1281
test tdbc::postgres-9.22 {rs foreach / return out of the loop} {*}{
1283
set stmt [::db prepare {
1284
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1286
set rs [$stmt execute]
1287
proc tdbcpostgres-9.22 {rs} {
1288
$rs foreach -as lists -- row {
1289
if {[lindex $row 1] eq {betty}} {
1290
return [lindex $row 0]
1297
tdbcpostgres-9.22 $rs
1300
rename tdbcpostgres-9.22 {}
1307
test tdbc::postgres-9.23 {stmt foreach / return out of the loop} {*}{
1309
set stmt [::db prepare {
1310
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1312
proc tdbcpostgres-9.23 {stmt} {
1313
$stmt foreach -as lists -- row {
1314
if {[lindex $row 1] eq {betty}} {
1315
return [lindex $row 0]
1322
tdbcpostgres-9.23 $stmt
1325
rename tdbcpostgres-9.23 {}
1331
test tdbc::postgres-9.24 {db foreach / return out of the loop} {*}{
1333
proc tdbcpostgres-9.24 {stmt} {
1334
db foreach -as lists -- row {
1335
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1337
if {[lindex $row 1] eq {betty}} {
1338
return [lindex $row 0]
1345
tdbcpostgres-9.24 $stmt
1348
rename tdbcpostgres-9.24 {}
1353
test tdbc::postgres-9.25 {rs foreach / error out of the loop} {*}{
1355
set stmt [::db prepare {
1356
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1358
set rs [$stmt execute]
1359
proc tdbcpostgres-9.25 {rs} {
1360
$rs foreach -as lists -- row {
1361
if {[lindex $row 1] eq {betty}} {
1362
error [lindex $row 0]
1369
tdbcpostgres-9.25 $rs
1372
rename tdbcpostgres-9.25 {}
1380
test tdbc::postgres-9.26 {stmt foreach - error out of the loop} {*}{
1382
set stmt [::db prepare {
1383
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1385
proc tdbcpostgres-9.26 {stmt} {
1386
$stmt foreach -as lists -- row {
1387
if {[lindex $row 1] eq {betty}} {
1388
error [lindex $row 0]
1395
tdbcpostgres-9.26 $stmt
1398
rename tdbcpostgres-9.26 {}
1405
test tdbc::postgres-9.27 {db foreach / error out of the loop} {*}{
1407
proc tdbcpostgres-9.27 {} {
1408
db foreach -as lists -- row {
1409
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1411
if {[lindex $row 1] eq {betty}} {
1412
error [lindex $row 0]
1422
rename tdbcpostgres-9.27 {}
1428
test tdbc::postgres-9.28 {rs foreach / unknown status from the loop} {*}{
1430
set stmt [::db prepare {
1431
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1433
set rs [$stmt execute]
1434
proc tdbcpostgres-9.28 {rs} {
1435
$rs foreach -as lists -- row {
1436
if {[lindex $row 1] eq {betty}} {
1437
return -code 666 -level 0 [lindex $row 0]
1444
tdbcpostgres-9.28 $rs
1447
rename tdbcpostgres-9.28 {}
1455
test tdbc::postgres-9.29 {stmt foreach / unknown status from the loop} {*}{
1457
set stmt [::db prepare {
1458
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1460
proc tdbcpostgres-9.29 {stmt} {
1461
$stmt foreach -as lists -- row {
1462
if {[lindex $row 1] eq {betty}} {
1463
return -code 666 -level 0 [lindex $row 0]
1470
tdbcpostgres-9.29 $stmt
1473
rename tdbcpostgres-9.29 {}
1480
test tdbc::postgres-9.30 {db foreach / unknown status from the loop} {*}{
1482
proc tdbcpostgres-9.30 {stmt} {
1483
db foreach -as lists -- row {
1484
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1486
if {[lindex $row 1] eq {betty}} {
1487
return -code 666 -level 0 [lindex $row 0]
1494
tdbcpostgres-9.30 $stmt
1497
rename tdbcpostgres-9.30 {}
1504
test tdbc::postgres-9.31 {stmt foreach / params in variables} {*}{
1506
set stmt [::db prepare {
1507
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1509
$stmt paramtype thePattern varchar 40
1522
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1525
test tdbc::postgres-9.32 {db foreach / params in variables} {*}{
1530
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1536
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1539
test tdbc::postgres-9.33 {stmt foreach / parameters in a dictionary} {*}{
1541
set stmt [::db prepare {
1542
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1544
$stmt paramtype thePattern varchar 40
1548
$stmt foreach row {thePattern b%} {
1556
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1559
test tdbc::postgres-9.34 {db foreach / parameters in a dictionary} {*}{
1563
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1569
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1572
test tdbc::postgres-9.35 {stmt foreach - variable not found} {*}{
1574
set stmt [::db prepare {
1575
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1577
$stmt paramtype thePattern varchar 40
1578
catch {unset thePattern}
1582
set thePattern(bogosity) {}
1595
test tdbc::postgres-9.36 {db foreach - variable not found} {*}{
1597
catch {unset thePattern}
1601
set thePattern(bogosity) {}
1603
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1615
test tdbc::postgres-9.37 {rs foreach - too few args} {*}{
1617
set stmt [::db prepare {
1618
SELECT idnum, name FROM people
1620
set rs [$stmt execute]
1630
-result {wrong # args*}
1634
test tdbc::postgres-9.38 {stmt foreach - too few args} {*}{
1636
set stmt [::db prepare {
1637
SELECT idnum, name FROM people
1647
-result {wrong # args*}
1651
test tdbc::postgres-9.39 {db foreach - too few args} {*}{
1654
SELECT idnum, name FROM people
1658
-result {wrong # args*}
1662
test tdbc::postgres-9.40 {rs foreach - too many args} {*}{
1664
set stmt [::db prepare {
1665
SELECT idnum, name FROM people
1667
set rs [$stmt execute]
1670
$rs foreach row do something
1677
-result {wrong # args*}
1681
test tdbc::postgres-9.41 {stmt foreach - too many args} {*}{
1683
set stmt [::db prepare {
1684
SELECT idnum, name FROM people
1688
$stmt foreach row do something else
1694
-result {wrong # args*}
1698
test tdbc::postgres-9.42 {db foreach - too many args} {*}{
1701
SELECT idnum, name FROM people
1705
-result {wrong # args*}
1709
test tdbc::postgres-10.1 {allrows - no args} {*}{
1711
set stmt [::db prepare {
1712
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1714
set rs [$stmt execute]
1723
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1726
test tdbc::postgres-10.2 {allrows - no args} {*}{
1728
set stmt [::db prepare {
1729
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1738
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1741
test tdbc::postgres-10.3 {allrows - no args} {*}{
1744
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1747
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1750
test tdbc::postgres-10.4 {allrows --} {*}{
1752
set stmt [::db prepare {
1753
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1755
set rs [$stmt execute]
1764
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1767
test tdbc::postgres-10.5 {allrows --} {*}{
1769
set stmt [::db prepare {
1770
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1779
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1782
test tdbc::postgres-10.6 {allrows --} {*}{
1785
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1788
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1791
test tdbc::postgres-10.7 {allrows -as lists} {*}{
1793
set stmt [::db prepare {
1794
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1796
set rs [$stmt execute]
1799
$rs allrows -as lists
1805
-result {{4 barney} {5 betty} {6 bam-bam}}
1808
test tdbc::postgres-10.8 {allrows -as lists} {*}{
1810
set stmt [::db prepare {
1811
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1815
$stmt allrows -as lists
1820
-result {{4 barney} {5 betty} {6 bam-bam}}
1823
test tdbc::postgres-10.9 {allrows -as lists} {*}{
1825
db allrows -as lists {
1826
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1829
-result {{4 barney} {5 betty} {6 bam-bam}}
1832
test tdbc::postgres-10.10 {allrows -as lists --} {*}{
1834
set stmt [::db prepare {
1835
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1837
set rs [$stmt execute]
1840
$rs allrows -as lists --
1846
-result {{4 barney} {5 betty} {6 bam-bam}}
1849
test tdbc::postgres-10.11 {allrows -as lists --} {*}{
1851
set stmt [::db prepare {
1852
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1856
$stmt allrows -as lists --
1861
-result {{4 barney} {5 betty} {6 bam-bam}}
1864
test tdbc::postgres-10.12 {allrows -as lists --} {*}{
1866
db allrows -as lists -- {
1867
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1870
-result {{4 barney} {5 betty} {6 bam-bam}}
1873
test tdbc::postgres-10.13 {allrows -as lists -columnsvar c} {*}{
1875
set stmt [::db prepare {
1876
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1878
set rs [$stmt execute]
1881
set result [$rs allrows -as lists -columnsvar c]
1888
-result {{idnum name} {{4 barney} {5 betty} {6 bam-bam}}}
1891
test tdbc::postgres-10.14 {allrows -as lists -columnsvar c} {*}{
1893
set stmt [::db prepare {
1894
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1898
set result [$stmt allrows -as lists -columnsvar c]
1904
-result {{idnum name} {{4 barney} {5 betty} {6 bam-bam}}}
1907
test tdbc::postgres-10.15 {allrows -as lists -columnsvar c} {*}{
1909
set result [db allrows -as lists -columnsvar c {
1910
SELECT idnum, name FROM people WHERE name LIKE 'b%'
1914
-result {{idnum name} {{4 barney} {5 betty} {6 bam-bam}}}
1917
test tdbc::postgres-10.16 {allrows - correct lexical scoping of variables} {*}{
1919
set stmt [::db prepare {
1920
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1922
$stmt paramtype thePattern varchar 40
1931
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1934
test tdbc::postgres-10.17 {allrows - parameters in a dictionary} {*}{
1936
set stmt [::db prepare {
1937
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1939
$stmt paramtype thePattern varchar 40
1942
$stmt allrows {thePattern b%}
1947
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1950
test tdbc::postgres-10.18 {allrows - parameters in a dictionary} {*}{
1953
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1956
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
1959
test tdbc::postgres-10.19 {allrows - variable not found} {*}{
1961
catch {unset thePattern}
1964
set thePattern(bogosity) {}
1966
SELECT idnum, name FROM people WHERE name LIKE :thePattern
1975
test tdbc::postgres-10.20 {allrows - too many args} {*}{
1977
set stmt [::db prepare {
1978
SELECT idnum, name FROM people
1982
$stmt allrows {} rubbish
1988
-result {wrong # args*}
1992
test tdbc::postgres-10.21 {bad -as} {*}{
1994
db allrows -as trash {
1995
SELECT idnum, name FROM people
1999
-result {bad variable type "trash": must be lists or dicts}
2002
test tdbc::postgres-11.1 {update - no rows} {*}{
2004
set stmt [::db prepare {
2005
UPDATE people SET info = 1 WHERE idnum > 6
2007
set rs [$stmt execute]
2019
test tdbc::postgres-11.2 {update - unique row} {*}{
2021
set stmt [::db prepare {
2022
UPDATE people SET info = 1 WHERE name = 'fred'
2026
set rs [$stmt execute]
2036
test tdbc::postgres-11.3 {update - multiple rows} {*}{
2038
set stmt [::db prepare {
2039
UPDATE people SET info = 1 WHERE name LIKE 'b%'
2043
set rs [$stmt execute]
2053
test tdbc::postgres-12.1 {delete - no rows} {*}{
2055
set stmt [::db prepare {
2056
DELETE FROM people WHERE name = 'nobody'
2060
set rs [$stmt execute]
2070
test tdbc::postgres-12.2 {delete - unique row} {*}{
2072
set stmt [::db prepare {
2073
DELETE FROM people WHERE name = 'fred'
2077
set rs [$stmt execute]
2087
test tdbc::postgres-12.3 {delete - multiple rows} {*}{
2089
set stmt [::db prepare {
2090
DELETE FROM people WHERE name LIKE 'b%'
2094
set rs [$stmt execute]
2104
test tdbc::postgres-13.1 {resultsets - no results} {*}{
2106
set stmt [::db prepare {
2107
SELECT name FROM people WHERE idnum = $idnum
2112
[llength [$stmt resultsets]] \
2113
[llength [::db resultsets]]
2121
test tdbc::postgres-13.2 {resultsets - various statements and results} {*}{
2123
for {set i 0} {$i < 6} {incr i} {
2124
set stmts($i) [::db prepare {
2125
SELECT name FROM people WHERE idnum = :idnum
2127
$stmts($i) paramtype idnum integer
2128
for {set j 0} {$j < $i} {incr j} {
2129
set resultsets($i,$j) [$stmts($i) execute [list idnum $j]]
2131
for {set j 1} {$j < $i} {incr j 2} {
2132
$resultsets($i,$j) close
2133
unset resultsets($i,$j)
2138
set x [list [llength [::db resultsets]]]
2139
for {set i 0} {$i < 6} {incr i} {
2140
lappend x [llength [$stmts($i) resultsets]]
2145
for {set i 0} {$i < 6} {incr i} {
2149
-result {9 0 1 1 2 2 3}
2152
#-------------------------------------------------------------------------------
2154
# next tests require a fresh database connection. Close the existing one down
2157
set stmt [db prepare {
2166
tdbc::postgres::connection create ::db {*}$::connFlags
2168
set stmt [db prepare {
2169
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
2171
$stmt paramtype idnum integer
2172
$stmt paramtype name varchar 40
2174
foreach name {fred wilma pebbles barney betty bam-bam} {
2175
set rs [$stmt execute]
2182
test tdbc::postgres-14.1 {begin transaction - wrong # args} {*}{
2184
::db begintransaction junk
2188
-result {wrong # args*}
2191
test tdbc::postgres-14.2 {commit - wrong # args} {*}{
2197
-result {wrong # args*}
2200
test tdbc::postgres-14.3 {rollback - wrong # args} {*}{
2206
-result {wrong # args*}
2209
test tdbc::postgres-14.4 {commit - not in transaction} {*}{
2211
list [catch {::db commit} result] $result $::errorCode
2214
-result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY010 POSTGRES *}}
2217
test tdbc::postgres-14.5 {rollback - not in transaction} {*}{
2219
list [catch {::db rollback} result] $result $::errorCode
2222
-result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY010 POSTGRES *}}
2225
test tdbc::postgres-14.6 {empty transaction} {*}{
2227
::db begintransaction
2233
test tdbc::postgres-14.7 {empty rolled-back transaction} {*}{
2235
::db begintransaction
2241
test tdbcpostgres-14.8 {rollback does not change database} {*}{
2243
::db begintransaction
2244
set stmt [::db prepare {DELETE FROM people WHERE name = 'fred'}]
2245
set rs [$stmt execute]
2246
while {[$rs nextrow trash]} {}
2250
set stmt [::db prepare {SELECT idnum FROM people WHERE name = 'fred'}]
2251
set id {changes still visible after rollback}
2252
set rs [$stmt execute]
2253
while {[$rs nextrow -as lists row]} {
2254
set id [lindex $row 0]
2263
test tdbc::postgres-14.9 {commit does change database} {*}{
2265
set stmt1 [db prepare {
2266
INSERT INTO people(idnum, name, info)
2267
VALUES(7, 'mr. gravel', 0)
2269
set stmt2 [db prepare {
2270
SELECT idnum FROM people WHERE name = 'mr. gravel'
2274
::db begintransaction
2275
set rs [$stmt1 execute]
2278
set rs [$stmt2 execute]
2279
while {[$rs nextrow -as lists row]} {
2280
set id [lindex $row 0]
2293
test tdbc::postgres-14.10 {nested transactions} {*}{
2295
::db begintransaction
2296
list [catch {::db begintransaction} result] $result $::errorCode
2299
catch {::db rollback}
2302
-result {1 {Postgres does not support nested transactions} {TDBC GENERAL_ERROR HYC00 POSTGRES *}}
2305
#------------------------------------------------------------------------------
2307
# Clean up database again for the next round.
2310
set stmt [db prepare {
2319
tdbc::postgres::connection create ::db {*}$::connFlags
2321
set stmt [db prepare {
2322
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
2324
$stmt paramtype idnum integer
2325
$stmt paramtype name varchar 40
2327
foreach name {fred wilma pebbles barney betty bam-bam} {
2328
set rs [$stmt execute]
2335
test tdbc::postgres-15.1 {successful (empty) transaction} {*}{
2344
test tdbc::postgres-15.2 {failing transaction does not get committed} {*}{
2346
set stmt1 [db prepare {
2347
DELETE FROM people WHERE name = 'fred'
2349
set stmt2 [db prepare {
2350
SELECT idnum FROM people WHERE name = 'fred'
2356
set rs [$stmt1 execute]
2358
error "abort the transaction"
2361
set id {failed transaction got committed}
2362
set rs [$stmt2 execute]
2363
while {[$rs nextrow -as lists row]} {
2364
set id [lindex $row 0]
2373
-result {{abort the transaction} 1}
2376
test tdbc::postgres-15.3 {successful transaction gets committed} {*}{
2378
set stmt1 [db prepare {
2379
INSERT INTO people(idnum, name, info)
2380
VALUES(7, 'mr. gravel', 0)
2382
set stmt2 [db prepare {
2383
SELECT idnum FROM people WHERE name = 'mr. gravel'
2388
set rs [$stmt1 execute]
2391
set rs [$stmt2 execute]
2392
while {[$rs nextrow -as lists row]} {
2393
set id [lindex $row 0]
2405
test tdbc::postgres-15.4 {break out of transaction commits it} {*}{
2407
set stmt1 [db prepare {
2408
INSERT INTO people(idnum, name, info)
2409
VALUES(8, 'gary granite', 0)
2411
set stmt2 [db prepare {
2412
SELECT idnum FROM people WHERE name = 'gary granite'
2418
set rs [$stmt1 execute]
2423
set rs [$stmt2 execute]
2424
while {[$rs nextrow -as lists row]} {
2425
set id [lindex $row 0]
2437
test tdbc::postgres-15.5 {continue in transaction commits it} {*}{
2439
set stmt1 [db prepare {
2440
INSERT INTO people(idnum, name, info)
2441
VALUES(9, 'hud rockstone', 0)
2443
set stmt2 [db prepare {
2444
SELECT idnum FROM people WHERE name = 'hud rockstone'
2448
for {set i 0} {$i < 1} {incr i} {
2450
set rs [$stmt1 execute]
2455
set rs [$stmt2 execute]
2456
while {[$rs nextrow -as lists row]} {
2457
set id [lindex $row 0]
2469
test tdbc::postgres-15.6 {return in transaction commits it} {*}{
2471
set stmt1 [db prepare {
2472
INSERT INTO people(idnum, name, info)
2473
VALUES(10, 'nelson stoneyfeller', 0)
2475
set stmt2 [db prepare {
2476
SELECT idnum FROM people WHERE name = 'nelson stoneyfeller'
2478
proc tdbcpostgres-15.6 {stmt1} {
2480
set rs [$stmt1 execute]
2487
tdbcpostgres-15.6 $stmt1
2488
set rs [$stmt2 execute]
2489
while {[$rs nextrow -as lists row]} {
2490
set id [lindex $row 0]
2498
rename tdbcpostgres-15.6 {}
2503
test tdbc::postgres-16.1 {database tables, wrong # args} {
2505
set dict [::db tables % rubbish]
2509
-result {wrong # args*}
2512
test tdbc::postgres-16.2 {database tables - empty set} {
2519
test tdbc::postgres-16.3 {enumerate database tables} {*}{
2521
set dict [::db tables]
2522
list [dict exists $dict people] [dict exists $dict property]
2527
test tdbc::postgres-16.4 {enumerate database tables} {*}{
2529
set dict [::db tables p%]
2530
list [dict exists $dict people] [dict exists $dict property]
2536
test tdbc::postgres-17.1 {database columns - wrong # args} {*}{
2538
set dict [::db columns people % rubbish]
2542
-result {wrong # args*}
2545
test tdbc::postgres-17.2 {database columns - no such table} {*}{
2547
::db columns rubbish
2551
-result {relation * does not exist}
2556
test tdbc::postgres-17.3 {database columns - no match pattern} {*}{
2559
dict for {colname attrs} [::db columns people] {
2560
lappend result $colname \
2561
[dict get $attrs type] \
2562
[expr {[dict exists $attrs precision] ?
2563
[dict get $attrs precision] : {NULL}}] \
2564
[expr {[dict exists $attrs scale] ?
2565
[dict get $attrs scale] : {NULL}}] \
2566
[dict get $attrs nullable]
2568
lsort -stride 5 $result
2571
-result {idnum integer * 0 0 info integer * 0 1 name varchar 40 *}
2574
# TODO: precision not a number of bytes?!
2575
# -result {idnum integer 11 0 0 info integer 11 0 1}
2577
test tdbc::postgres-17.4 {database columns - match pattern} {*}{
2578
-constraints !sqlite
2581
dict for {colname attrs} [::db columns people i%] {
2582
lappend result $colname \
2583
[dict get $attrs type] \
2584
[expr {[dict exists $attrs precision] ?
2585
[dict get $attrs precision] : {NULL}}] \
2586
[expr {[dict exists $attrs scale] ?
2587
[dict get $attrs scale] : {NULL}}] \
2588
[dict get $attrs nullable]
2590
lsort -stride 5 $result
2592
-result {idnum integer 32 0 0 info integer 32 0 1}
2595
test tdbc::postgres-18.1 {$statement params - excess arg} {*}{
2597
set s [::db prepare {
2598
SELECT name FROM people
2599
WHERE name LIKE :pattern
2602
$s paramtype minid numeric 10 0
2603
$s paramtype pattern varchar 40
2613
-result {wrong # args*}
2616
test tdbc::postgres-18.2 {$statement params - no params} {*}{
2618
set s [::db prepare {
2619
SELECT name FROM people
2631
test tdbc::postgres-18.3 {$statement params - try a few data types} {*}{
2633
set s [::db prepare {
2634
SELECT name FROM people
2635
WHERE name LIKE :pattern
2638
$s paramtype minid decimal 10 0
2639
$s paramtype pattern varchar 40
2644
[dict get $d minid direction] \
2645
[dict get $d minid type] \
2646
[dict get $d minid precision] \
2647
[dict get $d minid scale] \
2648
[dict get $d pattern direction] \
2649
[dict get $d pattern type] \
2650
[dict get $d pattern precision]
2655
-result {in decimal 10 0 in varchar 40}
2658
test tdbc::postgres-18.4 {$statement params - default param types} {
2660
set s [::db prepare {
2661
SELECT name FROM people
2662
WHERE name LIKE :pattern
2669
[dict get $d minid direction] \
2670
[dict get $d minid type] \
2671
[dict get $d minid precision] \
2672
[dict get $d minid scale] \
2673
[dict get $d pattern direction] \
2674
[dict get $d pattern type] \
2675
[dict get $d pattern precision] \
2676
[dict get $d pattern scale]
2681
-result {in integer 0 0 in text 0 0}
2684
test tdbc::postgres-18.5 {statement with parameter of indeterminate type} {
2686
set s [::db prepare {SELECT :foo::VARCHAR}]
2691
[dict get $d foo direction] \
2692
[dict get $d foo type] \
2693
[dict get $d foo precision] \
2694
[dict get $d foo scale]
2699
-result {in varchar 0 0}
2702
test tdbc::postgres-19.1 {$connection configure - no args} \
2704
::db configure -encoding UTF8
2711
-host * -hostaddr * -port * \
2712
-database * -user * -password * \
2713
-options {} -tty {} -service {} -timeout {} \
2714
-sslmode * -requiressl * -krbsrvname * \
2715
-encoding UTF8 -isolation readcommitted \
2718
test tdbc::postgres-19.2 {$connection configure - unknown arg} {*}{
2720
::db configure -junk
2724
-result "bad option *"
2727
test tdbc::postgres-19.3 {$connection configure - unknown arg} {*}{
2729
list [catch {::db configure -rubbish} result] $result $::errorCode
2732
-result {1 {bad option "-rubbish": must be *} {TCL LOOKUP INDEX option -rubbish}}
2735
test tdbc::postgres-19.4 {$connection configure - set unknown arg} {*}{
2737
list [catch {::db configure -rubbish rubbish} result] \
2738
$result $::errorCode
2741
-result {1 {bad option "-rubbish": must be *} {TCL LOOKUP INDEX option -rubbish}}
2744
test tdbc::postgres-19.5 {$connection configure - set inappropriate arg} {*}{
2746
list [catch {::db configure -host rubbish} result] \
2747
$result $::errorCode
2749
-result {1 {"-host" option cannot be changed dynamically} {TDBC GENERAL_ERROR HY000 POSTGRES -1}}
2752
test tdbc::postgres-19.6 {$connection configure - wrong # args} {*}{
2754
::db configure -parent . -junk
2758
-result "wrong # args*"
2761
test tdbc::postgres-19.9 {$connection configure - -encoding} {*}{
2763
::db configure -encoding UTF8
2766
::db configure -encoding
2772
test tdbc::postgres-19.10 {$connection configure - -isolation} {*}{
2774
::db configure -isolation junk
2778
-result {bad isolation level "junk"*}
2781
test tdbc::postgres-19.11 {$connection configure - -isolation} {*}{
2783
list [::db configure -isolation readuncommitted] \
2784
[::db configure -isolation] \
2785
[::db configure -isolation readcommitted] \
2786
[::db configure -isolation] \
2787
[::db configure -isolation serializable] \
2788
[::db configure -isolation] \
2789
[::db configure -isolation repeatableread] \
2790
[::db configure -isolation]
2792
-result {{} readuncommitted {} readcommitted {} serializable {} repeatableread}
2795
test tdbc::postgres-19.12 {$connection configure - -readonly set inappropriate arg } {*}{
2797
::db configure -readonly junk
2800
-result {expected boolean value but got "junk"}
2803
test tdbc::postgres-19.13 {$connection configure - -readonly} {*}{
2805
list [::db configure -readonly] \
2806
[::db configure -readonly 1] \
2807
[::db configure -readonly] \
2808
[::db configure -readonly 0] \
2809
[::db configure -readonly]
2811
-result {0 {} 1 {} 0}
2814
test tdbc::postgres-19.14 {$connection configure - -timeout} {*}{
2816
::db configure -timeout junk
2819
-result {"-timeout" option cannot be changed dynamically}
2823
test tdbc::postgres-19.15 {$connection configure - -db} {*}{
2825
::db configure -db information_schema
2828
-result {"-db" option cannot be changed dynamically}
2831
test tdbc::postgres-19.16 {$connection configure - -user} \
2833
::db configure -user nobody
2835
-returnCodes error \
2836
-result {"-user" option cannot be changed dynamically} \
2839
test tdbc::postgres-22.1 {duplicate column name} {*}{
2841
set stmt [::db prepare {
2842
SELECT a.idnum, b.idnum
2843
FROM people a, people b
2844
WHERE a.name = 'hud rockstone'
2847
set rs [$stmt execute]
2850
-result {idnum idnum#2}
2857
test tdbc::postgres-20.1 {bit values} {*}{
2859
catch {db allrows {DROP TABLE bittest}}
2861
CREATE TABLE bittest (
2865
db allrows {INSERT INTO bittest(bitstring) VALUES(b'11010001010110')}
2868
db allrows {SELECT bitstring FROM bittest}
2870
-result {{bitstring 11010001010110}}
2872
db allrows {DROP TABLE bittest}
2876
test tdbc::postgres-20.2 {direct value transfers} {*}{
2878
set bigtext [string repeat a 200]
2880
for {set i 1} {$i < 256} {incr i} {
2881
append bigbinary [format %c $i]
2883
catch {db allrows {DROP TABLE typetest}}
2885
CREATE TABLE typetest (
2889
xdouble1 DOUBLE PRECISION,
2890
xtimestamp1 TIMESTAMP,
2898
xvarc1 VARCHAR(256),
2902
set stmt [db prepare {
2903
INSERT INTO typetest(
2904
xsmall1, xint1, xfloat1,
2905
xdouble1, xtimestamp1, xbig1,
2906
xdate1, xtime1, xbit1,
2907
xdec1, xtext1, xvarb1,
2910
:xsmall1, :xint1, :xfloat1,
2911
:xdouble1, :xtimestamp1, :xbig1,
2912
:xdate1, :xtime1, :xbit1,
2913
:xdec1, :xtext1, :xvarb1,
2917
$stmt paramtype xsmall1 smallint
2918
$stmt paramtype xint1 integer
2919
$stmt paramtype xfloat1 float
2920
$stmt paramtype xdouble1 double
2921
$stmt paramtype xtimestamp1 timestamp
2922
$stmt paramtype xbig1 bigint
2923
$stmt paramtype xdate1 date
2924
$stmt paramtype xtime1 time
2925
$stmt paramtype xbit1 bit 14
2926
$stmt paramtype xdec1 decimal 10 0
2927
$stmt paramtype xtext1 text
2928
$stmt paramtype xvarb1 varbinary
2929
$stmt paramtype xvarc1 varchar
2930
$stmt paramtype xchar1 char 20
2938
set xtimestamp1 {2001-02-03 04:05:06}
2940
set xdate1 2001-02-03
2942
set xbit1 01101000101011
2945
set xvarb1 $bigbinary
2947
set xchar1 [string repeat a 20]
2949
db foreach row {select * from typetest} {
2951
xsmall1 xint1 xfloat1
2952
xdouble1 xtimestamp1 xbig1
2957
if {![dict exists $row $v]} {
2958
append trouble $v " did not appear in result set\n"
2959
} elseif {[set $v] != [dict get $row $v]} {
2960
append trouble [list $v is [dict get $row $v] \
2961
should be [set $v]] \n
2976
# Information schema tests require additional tables in the database.
2979
catch {::db allrows {DROP TABLE d}}
2980
catch {::db allrows {DROP TABLE c}}
2981
catch {::db allrows {DROP TABLE b}}
2982
catch {::db allrows {DROP TABLE a}}
2984
# The MyISAM engine doesn't track foreign key constraints, so force the
2985
# tables to be InnoDB.
2990
CONSTRAINT pk_a PRIMARY KEY(k1)
2998
CONSTRAINT pk_b PRIMARY KEY(k1, k2),
2999
CONSTRAINT fk_b1 FOREIGN KEY (k1) REFERENCES a(k1),
3000
CONSTRAINT fk_b2 FOREIGN KEY (k2) REFERENCES a(k1)
3008
CONSTRAINT pk_c PRIMARY KEY(p1, p2),
3009
CONSTRAINT fk_c1 FOREIGN KEY (p1) REFERENCES a(k1),
3010
CONSTRAINT fk_c2 FOREIGN KEY (p2) REFERENCES a(k1),
3011
CONSTRAINT fk_cpair FOREIGN KEY (p2,p1) REFERENCES b(k1,k2)
3021
test tdbc::postgres-23.1 {Primary keys - no arg} {*}{
3027
-result {wrong # args*}
3029
test tdbc::postgres-23.2 {Primary keys - no primary key} {*}{
3035
test tdbc::postgres-23.3 {Primary keys - simple primary key} {*}{
3038
foreach row [::db primarykeys a] {
3039
lappend result [dict get $row columnName] [dict get $row ordinalPosition]
3045
test tdbc::postgres-23.4 {Primary keys - compound primary key} {*}{
3048
foreach row [::db primarykeys b] {
3049
lappend result [dict get $row columnName] [dict get $row ordinalPosition]
3056
test tdbc::postgres-24.1 {Foreign keys - wrong # args} {*}{
3058
::db foreignkeys -wrong
3062
-result {wrong # args*}
3065
test tdbc::postgres-24.2 {Foreign keys - bad arg} {*}{
3067
::db foreignkeys -primary a -rubbish b
3071
-result {bad option "-rubbish"*}
3074
test tdbc::postgres-24.3 {Foreign keys - redundant arg} {*}{
3076
::db foreignkeys -primary a -primary b
3080
-result {duplicate option "primary"*}
3083
test tdbc::postgres-24.4 {Foreign keys - list all} \
3086
set wanted {fk_b1 {} fk_b2 {} fk_c1 {} fk_c2 {} fk_cpair {}}
3087
foreach row [::db foreignkeys] {
3088
if {[dict exists $wanted [dict get $row foreignConstraintName]]} {
3089
dict set result [dict get $row foreignConstraintName] \
3090
[dict get $row ordinalPosition] \
3091
[list [dict get $row foreignTable] \
3092
[dict get $row foreignColumn] \
3093
[dict get $row primaryTable] \
3094
[dict get $row primaryColumn]]
3097
lsort -index 0 -stride 2 $result
3100
fk_b1 {1 {b k1 a k1}} \
3101
fk_b2 {1 {b k2 a k1}} \
3102
fk_c1 {1 {c p1 a k1}} \
3103
fk_c2 {1 {c p2 a k1}} \
3104
fk_cpair {1 {c p2 b k1} 2 {c p1 b k2}}]
3106
test tdbc::postgres-24.5 {Foreign keys - -foreign} \
3109
set wanted {fk_b1 {} fk_b2 {} fk_c1 {} fk_c2 {} fk_cpair {}}
3110
foreach row [::db foreignkeys -foreign c] {
3111
if {[dict exists $wanted [dict get $row foreignConstraintName]]} {
3112
dict set result [dict get $row foreignConstraintName] \
3113
[dict get $row ordinalPosition] \
3114
[list [dict get $row foreignTable] \
3115
[dict get $row foreignColumn] \
3116
[dict get $row primaryTable] \
3117
[dict get $row primaryColumn]]
3120
lsort -index 0 -stride 2 $result
3123
fk_c1 {1 {c p1 a k1}} \
3124
fk_c2 {1 {c p2 a k1}} \
3125
fk_cpair {1 {c p2 b k1} 2 {c p1 b k2}}]
3127
test tdbc::postgres-24.6 {Foreign keys - -primary} \
3130
set wanted {fk_b1 {} fk_b2 {} fk_c1 {} fk_c2 {} fk_cpair {}}
3131
foreach row [::db foreignkeys -primary a] {
3132
if {[dict exists $wanted [dict get $row foreignConstraintName]]} {
3133
dict set result [dict get $row foreignConstraintName] \
3134
[dict get $row ordinalPosition] \
3135
[list [dict get $row foreignTable] \
3136
[dict get $row foreignColumn] \
3137
[dict get $row primaryTable] \
3138
[dict get $row primaryColumn]]
3141
lsort -index 0 -stride 2 $result
3144
fk_b1 {1 {b k1 a k1}} \
3145
fk_b2 {1 {b k2 a k1}} \
3146
fk_c1 {1 {c p1 a k1}} \
3147
fk_c2 {1 {c p2 a k1}}]
3149
test tdbc::postgres-24.7 {Foreign keys - -foreign and -primary} \
3152
set wanted {fk_b1 {} fk_b2 {} fk_c1 {} fk_c2 {} fk_cpair {}}
3153
foreach row [::db foreignkeys -foreign c -primary b] {
3154
if {[dict exists $wanted [dict get $row foreignConstraintName]]} {
3155
dict set result [dict get $row foreignConstraintName] \
3156
[dict get $row ordinalPosition] \
3157
[list [dict get $row foreignTable] \
3158
[dict get $row foreignColumn] \
3159
[dict get $row primaryTable] \
3160
[dict get $row primaryColumn]]
3163
lsort -index 0 -stride 2 $result
3165
-result [list fk_cpair {1 {c p2 b k1} 2 {c p1 b k2}}]
3167
test tdbc::postgres-30.0 {Multiple result sets} {*}{
3169
set stmt [::db prepare { }]
3172
set resultset [$stmt execute {}]
3178
-result {empty query}
3181
test tdbc::postgres-30.1 {Multiple result sets - but in reality only one} {*}{
3183
::db allrows {delete from people}
3184
set stmt [db prepare {
3185
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
3187
$stmt paramtype idnum integer
3188
$stmt paramtype name varchar 40
3190
foreach name {fred wilma pebbles barney betty bam-bam} {
3191
set rs [$stmt execute]
3198
set stmt [::db prepare {
3199
select idnum, name from people where name = :a
3202
set resultset [$stmt execute {a wilma}]
3207
while {[$resultset nextrow row]} {
3210
lappend rowsets $rows
3211
if {[$resultset nextresults] == 0} break
3215
rename $resultset {}
3221
-result {{{idnum 2 name wilma}}}
3224
#-------------------------------------------------------------------------------
3226
# Test cleanup. Drop tables and get rid of the test database.
3229
catch {::db allrows {DROP TABLE d}}
3230
catch {::db allrows {DROP TABLE c}}
3231
catch {::db allrows {DROP TABLE b}}
3232
catch {::db allrows {DROP TABLE a}}
3233
catch {::db allrows {DROP TABLE people}}
3235
catch {rename ::db {}}