chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
# Tests that we can successfully load the french towns dataset into Doltgres
|
||||
# https://github.com/morenoh149/postgresDBSamples/blob/master/french-towns-communes-francaises/french-towns-communes-francaises.sql
|
||||
@test 'dataloading: tabular import, french towns dataset' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/french-towns-communes-francaises.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 26" ]] || false
|
||||
[[ "$output" =~ "COPY 100" ]] || false
|
||||
[[ "$output" =~ "COPY 36684" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
[[ ! "$output" =~ "is not yet supported" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from Regions;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "26" ]] || false
|
||||
run query_server -c "SELECT count(*) from Departments;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "100" ]] || false
|
||||
run query_server -c "SELECT count(*) from Towns;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "36684" ]] || false
|
||||
|
||||
# Spot check a row from each table
|
||||
run query_server -c "SELECT * from Regions where id=21;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "21 | 74 | 87085 | Limousin" ]] || false
|
||||
run query_server -c "SELECT * from Departments where id=42;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "42 | 41 | 41018 | 24 | Loir-et-Cher" ]] || false
|
||||
run query_server -c "SELECT * from Towns where id=420;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "420 | 001 | | Abbécourt | 02" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load data dump files with windows line endings.
|
||||
@test 'dataloading: tabular import, windows line endings' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/windows-line-endings.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 26" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from Regions;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "26" ]] || false
|
||||
|
||||
# Spot check a row
|
||||
run query_server -c "SELECT * from Regions where id=21;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "21 | 74 | 87085 | Limousin" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load tabular data dump files that contain a header
|
||||
@test 'dataloading: tabular import, with header' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/tab-load-with-header.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 3" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from Regions;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
|
||||
# Check the inserted rows
|
||||
run query_server -c "SELECT * from Regions;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 01 | 97105 | Guadeloupe" ]] || false
|
||||
[[ "$output" =~ "2 | 02 | 97209 | Martinique" ]] || false
|
||||
[[ "$output" =~ "3 | 03 | 97302 | Guyane" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load tabular data dump files that contain quoted column names
|
||||
@test 'dataloading: tabular import, with quoted column names' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/tab-load-with-quoted-column-names.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 3" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from Regions;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
|
||||
# Check the inserted rows
|
||||
run query_server -c "SELECT * from Regions;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 01 | 97105 | Guadeloupe" ]] || false
|
||||
[[ "$output" =~ "2 | 02 | 97209 | Martinique" ]] || false
|
||||
[[ "$output" =~ "3 | 03 | 97302 | Guyane" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load tabular data dump files that do not explicitly manage the session's transaction.
|
||||
@test 'dataloading: tabular import, no explicit tx management' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/tab-load-with-no-tx-control.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 3" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the inserted rows
|
||||
run query_server -c "SELECT * FROM test_info ORDER BY id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "4 | string for 4 | 1" ]] || false
|
||||
[[ "$output" =~ "5 | string for 5 | 0" ]] || false
|
||||
[[ "$output" =~ "6 | string for 6 | 0" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load tabular data dump files that specify a delimiter.
|
||||
@test "dataloading: tabular import, delimiter='|', no explicit tx management" {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/tab-load-with-delimiter-no-tx-control.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 3" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the inserted rows
|
||||
run query_server -c "SELECT * FROM test_info ORDER BY id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "4 | string for 4 | 1" ]] || false
|
||||
[[ "$output" =~ "5 | string for 5 | 0" ]] || false
|
||||
[[ "$output" =~ "6 | string for 6 | 0" ]] || false
|
||||
}
|
||||
|
||||
# Tests loading in data via different CSV data files.
|
||||
@test 'dataloading: csv import' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/csv-load-basic-cases.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 9" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from tbl1;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "9" ]] || false
|
||||
|
||||
# Assert the data was loaded correctly
|
||||
run query_server -c "SELECT * from tbl1 order by pk;"
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 17 ]
|
||||
[[ "$output" =~ "1 | green | " ]] || false
|
||||
[[ "$output" =~ "2 | blue | a +" ]] || false
|
||||
[[ "$output" =~ " | | q +" ]] || false
|
||||
[[ "$output" =~ " | | u +" ]] || false
|
||||
[[ "$output" =~ " | | a" ]] || false
|
||||
[[ "$output" =~ "3 | brown |" ]] || false
|
||||
[[ "$output" =~ "4 | NULL | NULL" ]] || false
|
||||
[[ "$output" =~ "5 | ? |" ]] || false
|
||||
[[ "$output" =~ "6 | foo +| baz" ]] || false
|
||||
# NOTE: \. has to be escaped as \\\\.
|
||||
[[ "$output" =~ " | \\\\. +|" ]] || false
|
||||
[[ "$output" =~ " | bar |" ]] || false
|
||||
[[ "$output" =~ "7 | | ' '" ]] || false
|
||||
[[ "$output" =~ "8 | |" ]] || false
|
||||
[[ "$output" =~ "9 | | ''" ]] || false
|
||||
|
||||
# Assert NULL values were properly identified
|
||||
run query_server -c "SELECT * from tbl1 where c2 is NULL;"
|
||||
[[ "$output" =~ " 1 | green | " ]] || false
|
||||
[[ "$output" =~ " 3 | brown | " ]] || false
|
||||
run query_server -c "SELECT * from tbl1 where c1 is NULL;"
|
||||
[ "${#lines[@]}" -eq 4 ]
|
||||
[[ "$output" =~ " 9 | | ''" ]] || false
|
||||
}
|
||||
|
||||
# Tests loading in CSV data that includes a header row.
|
||||
@test 'dataloading: csv import with header' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/csv-load-with-header.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 9" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from tbl1;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "9" ]] || false
|
||||
}
|
||||
|
||||
# Tests loading in data via a CSV data file that is large enough to be split across multiple chunks.
|
||||
@test 'dataloading: csv import across multiple chunks' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/csv-load-multi-chunk.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 100" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from tbl1;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "100" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load CSV data dump files that do not explicitly manage the session's transaction.
|
||||
@test 'dataloading: csv import, no explicit tx management' {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/csv-load-with-no-tx-control.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 3" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the inserted rows
|
||||
run query_server -c "SELECT * FROM test_info ORDER BY id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "4 | string for 4 | 1" ]] || false
|
||||
[[ "$output" =~ "5 | string for 5 | 0" ]] || false
|
||||
[[ "$output" =~ "6 | string for 6 | 0" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load CSV data dump files that do not explicitly manage the session's transaction.
|
||||
@test "dataloading: csv import, delimiter='|', no explicit tx management" {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/psv-load-with-no-tx-control.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 3" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the inserted rows
|
||||
run query_server -c "SELECT * FROM test_info ORDER BY id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "4 | string for 4 | 1" ]] || false
|
||||
[[ "$output" =~ "5 | string for 5 | 0" ]] || false
|
||||
[[ "$output" =~ "6 | string for 6 | 0" ]] || false
|
||||
}
|
||||
|
||||
# Tests that we can load CSV data dump files using Postgres' legacy syntax
|
||||
@test "dataloading: csv import, legacy syntax" {
|
||||
# Import the data dump and assert the expected output
|
||||
run query_server -f $BATS_TEST_DIRNAME/dataloading/csv-load-with-legacy-syntax.sql
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "COPY 9" ]] || false
|
||||
[[ ! "$output" =~ "ERROR" ]] || false
|
||||
|
||||
# Check the row count of imported tables
|
||||
run query_server -c "SELECT count(*) from tbl1;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "9" ]] || false
|
||||
|
||||
# Spot check a row
|
||||
run query_server -c "SELECT * FROM tbl1 WHERE pk=3 and c2 IS NULL;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ " 3 | brown | " ]] || false
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE tbl1 (pk int primary key, c1 varchar(100), c2 varchar(250));
|
||||
|
||||
COPY tbl1 FROM STDIN (FORMAT CSV);
|
||||
1,green,
|
||||
2,"blue","a
|
||||
q
|
||||
u
|
||||
a"
|
||||
3,"brown",
|
||||
4,"NULL",NULL
|
||||
5,"?",""
|
||||
6,"foo
|
||||
\\.
|
||||
bar","baz"
|
||||
7, ,' '
|
||||
8," ",""
|
||||
9,,''
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,109 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE tbl1 (pk int primary key, c1 varchar(100), c2 varchar(250));
|
||||
|
||||
COPY tbl1 FROM STDIN (FORMAT CSV);
|
||||
0,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
1,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
2,foo,barbazbashbarbazbashbarbazbash
|
||||
3,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
4,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
5,foo,barbazbashbarbazbashbarbazbash
|
||||
6,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
7,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
8,foo,barbazbashbarbazbashbarbazbash
|
||||
9,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
10,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
11,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
12,foo,barbazbashbarbazbashbarbazbash
|
||||
13,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
14,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
15,foo,barbazbashbarbazbashbarbazbash
|
||||
16,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
17,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
18,foo,barbazbashbarbazbashbarbazbash
|
||||
19,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
20,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
21,foo,barbazbashbarbazbashbarbazbash
|
||||
22,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
23,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
24,foo,barbazbashbarbazbashbarbazbash
|
||||
25,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
26,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
27,foo,barbazbashbarbazbashbarbazbash
|
||||
28,foo,barbazbashbarbazbashbarbazbashbarbazbash
|
||||
29,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
30,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
31,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
32,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
33,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
34,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
35,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
36,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
37,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
38,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
39,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
40,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
41,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
42,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
43,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
44,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
45,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
46,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
47,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
48,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
49,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
50,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
51,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
52,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
53,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
54,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
55,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
56,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
57,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
58,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
59,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
60,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
61,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
62,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
63,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
64,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
65,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
66,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
67,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
68,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
69,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
70,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
71,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
72,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
73,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
74,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
75,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
76,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
77,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
78,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
79,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
80,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
81,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
82,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
83,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
84,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
85,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
86,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
87,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
88,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
89,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
90,foo,"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
345678901234567"
|
||||
91,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
92,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
93,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
94,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
95,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
96,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
97,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
98,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
99,foo,barbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbashbarbazbash
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,23 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE tbl1 (pk int primary key, c1 varchar(100), c2 varchar(250));
|
||||
|
||||
COPY tbl1 FROM STDIN (FORMAT CSV, HEADER TRUE);
|
||||
pk,c1,c2
|
||||
1,green,
|
||||
2,"blue","a
|
||||
q
|
||||
u
|
||||
a"
|
||||
3,"brown",
|
||||
4,"NULL",NULL
|
||||
5,"?",""
|
||||
6,"foo
|
||||
\\.
|
||||
bar","baz"
|
||||
7, ,' '
|
||||
8," ",""
|
||||
9,,''
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,24 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE tbl1 (pk int primary key, c1 varchar(100), c2 varchar(250));
|
||||
|
||||
-- NOTE: This is legacy syntax, but still in use and still supported by PostgreSQL
|
||||
COPY tbl1 FROM STDIN CSV, HEADER;
|
||||
pk,c1,c2
|
||||
1,green,
|
||||
2,"blue","a
|
||||
q
|
||||
u
|
||||
a"
|
||||
3,"brown",
|
||||
4,"NULL",NULL
|
||||
5,"?",""
|
||||
6,"foo
|
||||
\\.
|
||||
bar","baz"
|
||||
7, ,' '
|
||||
8," ",""
|
||||
9,,''
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE test (pk int primary key);
|
||||
INSERT INTO test VALUES (0), (1);
|
||||
|
||||
CREATE TABLE test_info (id int, info varchar(255), test_pk int, primary key(id), foreign key (test_pk) references test(pk));
|
||||
|
||||
COPY test_info FROM STDIN (FORMAT CSV, HEADER TRUE);
|
||||
id,info,test_pk
|
||||
4,string for 4,1
|
||||
5,string for 5,0
|
||||
6,string for 6,0
|
||||
\.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE test (pk int primary key);
|
||||
INSERT INTO test VALUES (0), (1);
|
||||
|
||||
CREATE TABLE test_info (id int, info varchar(255), test_pk int, primary key(id), foreign key (test_pk) references test(pk));
|
||||
|
||||
COPY test_info FROM STDIN (FORMAT CSV, HEADER TRUE, DELIMITER '|');
|
||||
id|info|test_pk
|
||||
4|string for 4|1
|
||||
5|string for 5|0
|
||||
6|string for 6|0
|
||||
\.
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE test (pk int primary key);
|
||||
INSERT INTO test VALUES (0), (1);
|
||||
|
||||
CREATE TABLE test_info (id int, info varchar(255), test_pk int, primary key(id), foreign key (test_pk) references test(pk));
|
||||
|
||||
COPY test_info FROM STDIN WITH (DELIMITER '|', HEADER);
|
||||
id|info|test_pk
|
||||
4|string for 4|1
|
||||
5|string for 5|0
|
||||
6|string for 6|0
|
||||
\.
|
||||
@@ -0,0 +1,17 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE Regions (
|
||||
id SERIAL UNIQUE NOT NULL,
|
||||
code VARCHAR(4) UNIQUE NOT NULL,
|
||||
capital VARCHAR(10) NOT NULL,
|
||||
name VARCHAR(255) UNIQUE NOT NULL
|
||||
);
|
||||
|
||||
COPY regions (id, code, capital, name) FROM stdin WITH (HEADER);
|
||||
id code capital name
|
||||
1 01 97105 Guadeloupe
|
||||
2 02 97209 Martinique
|
||||
3 03 97302 Guyane
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE test (pk int primary key);
|
||||
INSERT INTO test VALUES (0), (1);
|
||||
|
||||
CREATE TABLE test_info (id int, info varchar(255), test_pk int, primary key(id), foreign key (test_pk) references test(pk));
|
||||
|
||||
COPY test_info FROM STDIN WITH (HEADER);
|
||||
id info test_pk
|
||||
4 string for 4 1
|
||||
5 string for 5 0
|
||||
6 string for 6 0
|
||||
\.
|
||||
@@ -0,0 +1,16 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE Regions (
|
||||
"Id" SERIAL UNIQUE NOT NULL,
|
||||
"Code" VARCHAR(4) UNIQUE NOT NULL,
|
||||
"Capital" VARCHAR(10) NOT NULL,
|
||||
"Name" VARCHAR(255) UNIQUE NOT NULL
|
||||
);
|
||||
|
||||
COPY regions ("Id", "Code", "Capital", "Name") FROM stdin;
|
||||
1 01 97105 Guadeloupe
|
||||
2 02 97209 Martinique
|
||||
3 03 97302 Guyane
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,48 @@
|
||||
BEGIN;
|
||||
|
||||
-- Database schema / Schéma de la base de données
|
||||
|
||||
-- Regions / Régions
|
||||
CREATE TABLE Regions (
|
||||
id SERIAL UNIQUE NOT NULL,
|
||||
code VARCHAR(4) UNIQUE NOT NULL,
|
||||
capital VARCHAR(10) NOT NULL, -- REFERENCES Towns (code),
|
||||
-- TODO: TEXT columns do not work correctly in Doltgres yet
|
||||
-- name TEXT UNIQUE NOT NULL
|
||||
name VARCHAR(255) UNIQUE NOT NULL
|
||||
);
|
||||
|
||||
SET client_encoding = 'utf-8';
|
||||
SET check_function_bodies = false;
|
||||
SET search_path = public, pg_catalog;
|
||||
|
||||
COPY regions (id, code, capital, name) FROM stdin;
|
||||
1 01 97105 Guadeloupe
|
||||
2 02 97209 Martinique
|
||||
3 03 97302 Guyane
|
||||
4 04 97411 La Réunion
|
||||
5 11 75056 Île-de-France
|
||||
6 21 51108 Champagne-Ardenne
|
||||
7 22 80021 Picardie
|
||||
8 23 76540 Haute-Normandie
|
||||
9 24 45234 Centre
|
||||
10 25 14118 Basse-Normandie
|
||||
11 26 21231 Bourgogne
|
||||
12 31 59350 Nord-Pas-de-Calais
|
||||
13 41 57463 Lorraine
|
||||
14 42 67482 Alsace
|
||||
15 43 25056 Franche-Comté
|
||||
16 52 44109 Pays de la Loire
|
||||
17 53 35238 Bretagne
|
||||
18 54 86194 Poitou-Charentes
|
||||
19 72 33063 Aquitaine
|
||||
20 73 31555 Midi-Pyrénées
|
||||
21 74 87085 Limousin
|
||||
22 82 69123 Rhône-Alpes
|
||||
23 83 63113 Auvergne
|
||||
24 91 34172 Languedoc-Roussillon
|
||||
25 93 13055 Provence-Alpes-Côte d'Azur
|
||||
26 94 2A004 Corse
|
||||
\.
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,430 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'doltgres: --help' {
|
||||
# just a smoke test
|
||||
doltgres --help
|
||||
}
|
||||
|
||||
@test 'doltgres: --config-help' {
|
||||
# just a smoke test
|
||||
doltgres --config-help
|
||||
}
|
||||
|
||||
@test 'doltgres: no arguments' {
|
||||
PORT=5432
|
||||
mkdir test-home
|
||||
# TODO: DOLT_ROOT_PATH behavior overrides the HOME behavior, which is confusing and not
|
||||
# applicable to Doltgres, fix it
|
||||
HOME=test-home DOLTGRES_DATA_DIR='' DOLT_ROOT_PATH='' doltgres > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
# databases should get created in home/doltgres/databases by default
|
||||
[ -d test-home/doltgres/databases/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: data-dir param' {
|
||||
PORT=5432
|
||||
DOLTGRES_DATA_DIR=fake doltgres --data-dir test > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
[ -d test/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: data dir in env var' {
|
||||
PORT=5432
|
||||
DOLTGRES_DATA_DIR=test doltgres > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
[ -d test/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: implicit config.yaml' {
|
||||
PORT=5434
|
||||
|
||||
cat > config.yaml <<EOF
|
||||
log_level: info
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
user:
|
||||
name: "postgres"
|
||||
password: "password"
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: $PORT
|
||||
read_timeout_millis: 28800000
|
||||
write_timeout_millis: 28800000
|
||||
|
||||
data_dir: test
|
||||
EOF
|
||||
|
||||
doltgres > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
[ -d test/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: config.yaml without data dir' {
|
||||
PORT=5434
|
||||
|
||||
cat > config.yaml <<EOF
|
||||
log_level: info
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
user:
|
||||
name: "postgres"
|
||||
password: "password"
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: $PORT
|
||||
read_timeout_millis: 28800000
|
||||
write_timeout_millis: 28800000
|
||||
|
||||
EOF
|
||||
|
||||
mkdir test-home
|
||||
HOME=test-home DOLTGRES_DATA_DIR='' DOLT_ROOT_PATH='' doltgres --config config.yaml > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
[ -d test-home/doltgres/databases/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: config file override with explicit config.yaml' {
|
||||
PORT=5434
|
||||
|
||||
cat > config-test.yaml <<EOF
|
||||
log_level: info
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
user:
|
||||
name: "postgres"
|
||||
password: "password"
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: $PORT
|
||||
read_timeout_millis: 28800000
|
||||
write_timeout_millis: 28800000
|
||||
|
||||
data_dir: test
|
||||
EOF
|
||||
|
||||
# The only supported override right now is the data dir, add more here as we add more overrides
|
||||
doltgres --config config-test.yaml --data-dir local-override > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
[ ! -d test/postgres ]
|
||||
[ -d local-override/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: config file override with implicit config.yaml' {
|
||||
PORT=5434
|
||||
|
||||
cat > config.yaml <<EOF
|
||||
log_level: info
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
user:
|
||||
name: "postgres"
|
||||
password: "password"
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: $PORT
|
||||
read_timeout_millis: 28800000
|
||||
write_timeout_millis: 28800000
|
||||
|
||||
data_dir: test
|
||||
EOF
|
||||
|
||||
# The only supported override right now is the data dir, add more here as we add more overrides
|
||||
doltgres --data-dir local-override > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
[ ! -d test/postgres ]
|
||||
[ -d local-override/postgres ]
|
||||
}
|
||||
|
||||
@test 'doltgres: config file' {
|
||||
PORT=$( definePORT )
|
||||
CONFIG=$( defineCONFIG $PORT )
|
||||
echo "$CONFIG" > config.yaml
|
||||
|
||||
cat config.yaml
|
||||
start_sql_server_with_args -config config.yaml > log.txt 2>&1
|
||||
|
||||
run cat log.txt
|
||||
[[ ! "$output" =~ "Author identity unknown" ]] || false
|
||||
[ -d "postgres" ]
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
}
|
||||
|
||||
@test 'doltgres: config file with all options' {
|
||||
PORT=$( definePORT )
|
||||
cat > config.yaml <<EOF
|
||||
log_level: info
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
user:
|
||||
name: "postgres"
|
||||
password: "password"
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: $PORT
|
||||
read_timeout_millis: 28800000
|
||||
write_timeout_millis: 28800000
|
||||
tls_key: null
|
||||
tls_cert: null
|
||||
require_secure_transport: null
|
||||
allow_cleartext_passwords: null
|
||||
|
||||
performance:
|
||||
query_parallelism: null
|
||||
|
||||
data_dir: .
|
||||
|
||||
cfg_dir: .doltcfg
|
||||
|
||||
metrics:
|
||||
labels: {}
|
||||
host: null
|
||||
port: -1
|
||||
|
||||
remotesapi: {}
|
||||
|
||||
privilege_file: .doltcfg/privileges.db
|
||||
|
||||
auth_file: .doltcfg/auth.db
|
||||
|
||||
branch_control_file: .doltcfg/branch_control.db
|
||||
|
||||
user_session_vars: []
|
||||
|
||||
jwks: []
|
||||
EOF
|
||||
|
||||
cat config.yaml
|
||||
|
||||
start_sql_server_with_args -config config.yaml
|
||||
|
||||
query_server -c "create table t1 (a int primary key, b int)"
|
||||
query_server -c "insert into t1 values (1,2)"
|
||||
|
||||
run query_server -c "select * from t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
run test -f ".doltcfg/auth.db"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test 'doltgres: DOLTGRES_DATA_DIR set to current dir' {
|
||||
[ ! -d "postgres" ]
|
||||
export DOLTGRES_DATA_DIR="$(pwd)"
|
||||
start_sql_server > log.txt 2>&1
|
||||
|
||||
run cat log.txt
|
||||
[[ ! "$output" =~ "Author identity unknown" ]] || false
|
||||
[ -d "postgres" ]
|
||||
|
||||
run query_server -c "\l"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "postgres" ]] || false
|
||||
}
|
||||
|
||||
@test 'doltgres: user name and pass via env' {
|
||||
export DOLTGRES_USER="myuser"
|
||||
export DOLTGRES_PASSWORD="mypass"
|
||||
|
||||
[ ! -d "auth.db" ]
|
||||
|
||||
start_sql_server "" log.txt myuser mypass
|
||||
cat log.txt
|
||||
|
||||
# db matches user name since DOLTGRES_DB was not set
|
||||
query_server_for_user_and_pass myuser mypass myuser -c "create table myTable (a int);"
|
||||
|
||||
run query_server_for_user_and_pass myuser mypass myuser -c "insert into mytable values (1), (2)"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "INSERT" ]] || false
|
||||
|
||||
run query_server_for_user_and_pass postgres password myuser -c "insert into mytable values (1), (2)"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test 'doltgres: default db via env' {
|
||||
[ ! -d "auth.db" ]
|
||||
|
||||
start_sql_server mydb log.txt myuser
|
||||
cat log.txt
|
||||
|
||||
query_server_for_user_and_pass myuser password mydb -c "create table myTable (a int);"
|
||||
|
||||
run query_server_for_user_and_pass myuser password mydb -c "insert into mytable values (1), (2)"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "INSERT" ]] || false
|
||||
|
||||
run query_server_for_user_and_pass postgres password mydb -c "insert into mytable values (1), (2)"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
query_server_for_user_and_pass() {
|
||||
user=$1
|
||||
pass=$2
|
||||
db=$3
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
|
||||
nativevar PGPASSWORD "$pass" /w
|
||||
psql -U "$user" -h localhost -p $PORT "$@" $db
|
||||
}
|
||||
|
||||
# Test for https://github.com/dolthub/doltgresql/issues/1863
|
||||
@test 'doltgres: connection to non-existent database fails' {
|
||||
start_sql_server
|
||||
|
||||
# Connecting to the default postgres database should work
|
||||
run query_server -c "SELECT 1"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Connecting to a non-existent database should fail
|
||||
nativevar PGPASSWORD "password" /w
|
||||
run psql -U postgres -h localhost -p $PORT -c "SELECT 1" nonexistent_db
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "does not exist" ]] || false
|
||||
}
|
||||
|
||||
@test 'doltgres: CREATE SCHEMA works on valid database' {
|
||||
start_sql_server
|
||||
|
||||
# CREATE SCHEMA should work on a valid database
|
||||
run query_server -c "CREATE SCHEMA test_schema_bats"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Verify schema was created
|
||||
run query_server -c "SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'test_schema_bats'"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "test_schema_bats" ]] || false
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'foreign-keys: survives restarts' {
|
||||
PORT=$( definePORT )
|
||||
|
||||
# stopping the server undefines the port, so save it
|
||||
port=$PORT
|
||||
mkdir test-home
|
||||
|
||||
CONFIG=$( defineCONFIG $PORT )
|
||||
echo "$CONFIG" > config.yaml
|
||||
|
||||
doltgres > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
cat server.out
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
query_server -c "create table parent (a int primary key, b int)"
|
||||
query_server -c "insert into parent values (1,2)"
|
||||
query_server -c "create table child (c int primary key, d int, foreign key (d) references public.parent(a))"
|
||||
query_server -c "insert into child values (2,1)"
|
||||
|
||||
stop_sql_server
|
||||
|
||||
PORT=$port
|
||||
doltgres > server.out 2>&1 &
|
||||
SERVER_PID=$!
|
||||
run wait_for_connection $PORT 7500
|
||||
|
||||
run query_server -c "insert into child values (100,100)"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "violation" ]] || false
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
query_server <<SQL
|
||||
CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 SMALLINT);
|
||||
INSERT INTO test1 VALUES (1, 2), (6, 7);
|
||||
SQL
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
|
||||
@test 'pgcatalog: tables do not include data from other databases' {
|
||||
run query_server --csv -c "SELECT current_database();"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "current_database" ]] || false
|
||||
[[ "$output" =~ "postgres" ]] || false
|
||||
[ "${#lines[@]}" -eq 2 ]
|
||||
|
||||
run query_server --csv -c "SELECT attname FROM pg_catalog.pg_attribute WHERE attname = 'pk' and attrelid not in (select oid from pg_catalog.pg_class where left(relname, 5) = 'dolt_');"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "attname" ]] || false
|
||||
[[ "$output" =~ "pk" ]] || false
|
||||
[ "${#lines[@]}" -eq 2 ]
|
||||
|
||||
run query_server --csv -c "SELECT relname FROM pg_catalog.pg_class WHERE relname = 'test1';"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "relname" ]] || false
|
||||
[[ "$output" =~ "test1" ]] || false
|
||||
[ "${#lines[@]}" -eq 2 ]
|
||||
|
||||
run query_server -c "CREATE DATABASE newdb;"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run query_server_for_db newdb --csv -c "SELECT current_database();"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "current_database" ]] || false
|
||||
[[ "$output" =~ "newdb" ]] || false
|
||||
[ "${#lines[@]}" -eq 2 ]
|
||||
|
||||
run query_server_for_db newdb --csv -c "SELECT attname FROM pg_catalog.pg_attribute WHERE attname = 'pk';"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "attname" ]] || false
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
|
||||
run query_server_for_db newdb --csv -c "SELECT relname FROM pg_catalog.pg_class WHERE relname = 'test1';"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "relname" ]] || false
|
||||
[ "${#lines[@]}" -eq 1 ]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
query_server <<SQL
|
||||
CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 SMALLINT);
|
||||
CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 INTEGER, v2 SMALLINT);
|
||||
INSERT INTO test1 VALUES (1, 2), (6, 7);
|
||||
INSERT INTO test2 VALUES (3, 4, 5), (8, 9, 0);
|
||||
CREATE VIEW testview AS SELECT * FROM test1;
|
||||
SQL
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'psql-commands: \l' {
|
||||
run query_server -c "\l"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "postgres" ]] || false
|
||||
}
|
||||
|
||||
@test 'psql-commands: \dt' {
|
||||
run query_server --csv -c "\dt"
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "public,test1,table,postgres" ]] || false
|
||||
[[ "$output" =~ "public,test2,table,postgres" ]] || false
|
||||
}
|
||||
|
||||
@test 'psql-commands: \dt table' {
|
||||
run query_server --csv -c "\dt test2"
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "public,test2,table,postgres" ]] || false
|
||||
[ "${#lines[@]}" -eq 2 ]
|
||||
}
|
||||
|
||||
@test 'psql-commands: \d' {
|
||||
run query_server --csv -c "\d"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "public,test1,table,postgres" ]] || false
|
||||
[[ "$output" =~ "public,test2,table,postgres" ]] || false
|
||||
[[ "$output" =~ "public,testview,view,postgres" ]] || false
|
||||
}
|
||||
|
||||
@test 'psql-commands: \d table' {
|
||||
skip "this command has not yet been implemented"
|
||||
}
|
||||
|
||||
@test 'psql-commands: \dn' {
|
||||
run query_server --csv -c "\dn"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "dolt,postgres" ]] || false
|
||||
[[ "$output" =~ "public,postgres" ]] || false
|
||||
[ "${#lines[@]}" -eq 3 ]
|
||||
}
|
||||
|
||||
@test 'psql-commands: \df' {
|
||||
run query_server -c "\df"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "0 rows" ]] || false
|
||||
}
|
||||
|
||||
@test 'psql-commands: \dv' {
|
||||
run query_server --csv -c "\dv"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "public,testview,view,postgres" ]] || false
|
||||
[ "${#lines[@]}" -eq 2 ]
|
||||
}
|
||||
|
||||
@test 'psql-commands: \du' {
|
||||
skip "users have not yet been implemented"
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
# This test exercises the push/pull/clone workflow across two independent Doltgres server
|
||||
# processes, each with its own data directory, coordinating only through a shared
|
||||
# file-system remote.
|
||||
@test 'remotes-file-system: clone from a fresh server, then push/pull round-trip data, a sequence, an enum type, and a function' {
|
||||
mkdir remote
|
||||
REMOTE_URL="file://$(pwd)/remote"
|
||||
|
||||
# --- Server A: seed a table, a sequence, a custom enum type, and a user-defined function --
|
||||
# (all serialized at the Doltgres layer, not the Dolt layer -- see core/rootobject) -- commit,
|
||||
# and push to the file-system remote ---
|
||||
mkdir serverA
|
||||
cd serverA
|
||||
start_sql_server
|
||||
query_server <<SQL
|
||||
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
|
||||
CREATE FUNCTION double_it(x INT) RETURNS INT AS \$\$ BEGIN RETURN x * 2; END; \$\$ LANGUAGE plpgsql;
|
||||
CREATE TABLE items (id INT PRIMARY KEY, label TEXT NOT NULL, feeling mood);
|
||||
INSERT INTO items VALUES (1, 'apple', 'happy'), (2, 'banana', 'sad');
|
||||
CREATE SEQUENCE counter START 100 INCREMENT 50;
|
||||
SELECT nextval('counter'); -- advances to 100
|
||||
SELECT dolt_commit('-Am', 'seed items, counter, mood type, and double_it function');
|
||||
SELECT dolt_remote('add', 'origin', '$REMOTE_URL');
|
||||
SELECT dolt_push('origin', 'main');
|
||||
SQL
|
||||
stop_sql_server
|
||||
cd ..
|
||||
|
||||
# --- Server B: an entirely separate, freshly-started server with its own data directory;
|
||||
# it shares no process, session, or in-memory state with server A. Clone from the remote. ---
|
||||
mkdir serverB
|
||||
cd serverB
|
||||
start_sql_server
|
||||
query_server -c "SELECT dolt_clone('$REMOTE_URL', 'cloned');"
|
||||
|
||||
# The enum type definition itself (not just data using it) must have transferred. Checked as
|
||||
# separate substrings (rather than one "id | label | feeling" string) because psql's tuples-only
|
||||
# output pads each column to its widest value ("apple" pads out to match "banana"'s width), so
|
||||
# the exact spacing between columns isn't stable across rows.
|
||||
run query_server_for_db cloned -t -c "SELECT id, label, feeling::text FROM items ORDER BY id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | apple" ]] || false
|
||||
[[ "$output" =~ "happy" ]] || false
|
||||
[[ "$output" =~ "2 | banana" ]] || false
|
||||
[[ "$output" =~ "sad" ]] || false
|
||||
|
||||
# The user-defined function must also be callable post-clone.
|
||||
run query_server_for_db cloned -c "SELECT double_it(21);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "42" ]] || false
|
||||
|
||||
# Must reflect server A's current value (100), not reset to the sequence's start value. Read
|
||||
# via pg_sequences rather than calling nextval() here, since nextval() itself writes the
|
||||
# sequence's current value and would leave the clone with an uncommitted change, which the
|
||||
# pull below would then reject with "cannot merge with uncommitted changes".
|
||||
run query_server_for_db cloned -c "SELECT last_value FROM pg_sequences WHERE sequencename = 'counter';"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "100" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
cd ..
|
||||
|
||||
# --- Back on server A: advance the table (using the enum type again) and the sequence
|
||||
# further, and push again ---
|
||||
cd serverA
|
||||
start_sql_server
|
||||
query_server <<SQL
|
||||
INSERT INTO items VALUES (3, 'cherry', 'ok');
|
||||
SELECT nextval('counter'); -- advances to 150
|
||||
SELECT dolt_commit('-Am', 'add cherry and advance counter');
|
||||
SELECT dolt_push('origin', 'main');
|
||||
SQL
|
||||
stop_sql_server
|
||||
cd ..
|
||||
|
||||
# --- Back on server B (also restarted fresh): pull the update into the clone ---
|
||||
cd serverB
|
||||
start_sql_server
|
||||
run query_server_for_db cloned -c "SELECT dolt_pull('origin');"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run query_server_for_db cloned -t -c "SELECT id, label, feeling::text FROM items ORDER BY id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | apple" ]] || false
|
||||
[[ "$output" =~ "happy" ]] || false
|
||||
[[ "$output" =~ "2 | banana" ]] || false
|
||||
[[ "$output" =~ "sad" ]] || false
|
||||
[[ "$output" =~ "3 | cherry" ]] || false
|
||||
[[ "$output" =~ "ok" ]] || false
|
||||
|
||||
# The function keeps working after an incremental pull too, not just right after clone.
|
||||
run query_server_for_db cloned -c "SELECT double_it(10);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "20" ]] || false
|
||||
|
||||
# The pull must have carried server A's advanced current value (150), not left the clone's own.
|
||||
run query_server_for_db cloned -c "SELECT last_value FROM pg_sequences WHERE sequencename = 'counter';"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "150" ]] || false
|
||||
|
||||
# No further pull happens after this, so it's now safe to call nextval() directly: must
|
||||
# continue from 150 (next is 200), proving the synced state drives future values correctly too.
|
||||
run query_server_for_db cloned -c "SELECT nextval('counter');"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "200" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
cd ..
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
log_level: debug
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
user:
|
||||
name: "postgres"
|
||||
password: "password"
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: 5433
|
||||
read_timeout_millis: 28800000
|
||||
write_timeout_millis: 28800000
|
||||
|
||||
data_dir: .
|
||||
|
||||
cfg_dir: .doltcfg
|
||||
|
||||
metrics:
|
||||
labels: {}
|
||||
host: null
|
||||
port: -1
|
||||
|
||||
postgres_replication:
|
||||
postgres_server_address: 127.0.0.1
|
||||
postgres_user: postgres
|
||||
postgres_password: password
|
||||
postgres_database: postgres
|
||||
postgres_port: 5432
|
||||
slot_name: doltgres_slot
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
# tests are run without setting doltgres config user.name and user.email
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'replication: test postgres connection' {
|
||||
if [[ ! -v "RUN_DOLTGRES_REPLICATION_TESTS" ]]; then
|
||||
skip "RUN_DOLTGRES_REPLICATION_TESTS not set, skipping"
|
||||
fi
|
||||
|
||||
# setup the postgres primary
|
||||
postgres_primary_query "drop table if exists t1"
|
||||
postgres_primary_query "create table t1 (a int primary key, b int)"
|
||||
postgres_primary_query "DROP PUBLICATION IF EXISTS doltgres_slot"
|
||||
postgres_primary_query "CREATE PUBLICATION doltgres_slot FOR TABLE t1"
|
||||
run postgres_primary_query "DROP_REPLICATION_SLOT doltgres_slot" # ignore errors if the slot doesn't exist
|
||||
postgres_primary_query "CREATE_REPLICATION_SLOT doltgres_slot LOGICAL pgoutput"
|
||||
|
||||
# This host may have a history, and we don't want to start replicating from the beginning of
|
||||
# history, just from the current WAL position. So seed that state here.
|
||||
LSN=$(postgres_primary_query "SELECT pg_current_wal_lsn()" -t)
|
||||
|
||||
if [[ ! -d ./.doltcfg ]]; then
|
||||
mkdir ./.doltcfg
|
||||
fi
|
||||
echo $LSN > ./.doltcfg/pg_wal_location
|
||||
|
||||
cat ./.doltcfg/pg_wal_location
|
||||
|
||||
cp "$BATS_TEST_DIRNAME/replication-config.yaml" "$BATS_TMPDIR/dolt-repo-$$"
|
||||
PORT=5433
|
||||
start_sql_server_with_args "-config=replication-config.yaml"
|
||||
|
||||
# Create the table that already exists on the primary before doing any inserts on the primary
|
||||
query_server postgres -c "create table public.t1 (a int primary key, b int)"
|
||||
|
||||
# this insert on the primary should now replicate to the replica
|
||||
postgres_primary_query "insert into t1 values (1, 2)"
|
||||
sleep 1
|
||||
|
||||
query_server postgres -c "select * from public.t1" -t
|
||||
run query_server postgres -c "select * from public.t1" -t
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1 | 2" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
}
|
||||
|
||||
postgres_primary_query() {
|
||||
PGPASSWORD="password" psql -U "postgres" -h 127.0.0.1 -p 5432 "dbname=postgres replication=database" -c "$@" doltgres
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'root-objects: dolt_add, dolt_branch, dolt_checkout, dolt_commit, dolt_reset' {
|
||||
query_server <<SQL
|
||||
CREATE SEQUENCE test;
|
||||
SELECT setval('test', 10);
|
||||
SQL
|
||||
run query_server -c "SELECT nextval('test');"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "11" ]] || false
|
||||
|
||||
query_server -c "SELECT dolt_add('test');"
|
||||
run query_server -c "SELECT length(dolt_commit('-m', 'initial')::text);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "34" ]] || false
|
||||
|
||||
query_server -c "SELECT dolt_branch('other');"
|
||||
query_server -c "SELECT setval('test', 20);"
|
||||
query_server -c "SELECT dolt_add('.');"
|
||||
run query_server -c "SELECT length(dolt_commit('-m', 'next')::text);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "34" ]] || false
|
||||
|
||||
run query_server -c "SELECT nextval('test');"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "21" ]] || false
|
||||
|
||||
run query_server <<SQL
|
||||
SELECT dolt_checkout('other');
|
||||
SELECT nextval('test');
|
||||
SQL
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "12" ]] || false
|
||||
}
|
||||
|
||||
@test 'root-objects: start and stop' {
|
||||
query_server <<SQL
|
||||
CREATE SEQUENCE test;
|
||||
SELECT setval('test', 10);
|
||||
SQL
|
||||
run query_server -c "SELECT nextval('test');"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "11" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
start_sql_server
|
||||
query_server -c "SELECT dolt_add('test');"
|
||||
run query_server -c "SELECT length(dolt_commit('-m', 'initial')::text);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "34" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
start_sql_server
|
||||
query_server -c "SELECT dolt_branch('other');"
|
||||
query_server -c "SELECT setval('test', 20);"
|
||||
query_server -c "SELECT dolt_add('.');"
|
||||
run query_server -c "SELECT length(dolt_commit('-m', 'next')::text);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "34" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
start_sql_server
|
||||
run query_server -c "SELECT nextval('test');"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "21" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
start_sql_server
|
||||
run query_server <<SQL
|
||||
SELECT dolt_checkout('other');
|
||||
SELECT nextval('test');
|
||||
SQL
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "12" ]] || false
|
||||
}
|
||||
|
||||
@test 'root-objects: \d does not break' {
|
||||
query_server <<SQL
|
||||
CREATE TABLE "t" ("id" SERIAL);
|
||||
SQL
|
||||
run query_server -c "\d"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "sequence" ]] || false
|
||||
|
||||
stop_sql_server
|
||||
start_sql_server
|
||||
run query_server -c "\d"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "sequence" ]] || false
|
||||
}
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
script_dir=$(dirname "$0")
|
||||
cd $script_dir/../
|
||||
|
||||
ERRORS_FOUND=0
|
||||
for FILENAME_WITH_EXT in *.bats; do
|
||||
FILENAME=${FILENAME_WITH_EXT%".bats"}
|
||||
while read -r LINE; do
|
||||
if [[ ! "$LINE" =~ "@test \"$FILENAME:" ]] && [[ -n "$LINE" ]]; then
|
||||
TESTNAME=$(echo "$LINE" | cut -d'"' -f 2)
|
||||
echo -e "ERROR: test \"$TESTNAME\" in \"$FILENAME_WITH_EXT\" must start with \"$FILENAME:\" in the title"
|
||||
ERRORS_FOUND=1
|
||||
fi
|
||||
done <<< $(grep '@test "' "$FILENAME_WITH_EXT")
|
||||
while read -r LINE; do
|
||||
if [[ ! "$LINE" =~ "@test '$FILENAME:" ]] && [[ -n "$LINE" ]]; then
|
||||
TESTNAME=$(echo "$LINE" | cut -d"'" -f 2)
|
||||
echo -e "ERROR: test \"$TESTNAME\" in \"$FILENAME_WITH_EXT\" must start with \"$FILENAME:\" in the title"
|
||||
ERRORS_FOUND=1
|
||||
fi
|
||||
done <<< $(grep "@test '" "$FILENAME_WITH_EXT")
|
||||
done
|
||||
if [[ $ERRORS_FOUND -eq 1 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
@@ -0,0 +1,72 @@
|
||||
load setup/windows-compat
|
||||
load setup/query-server-common
|
||||
|
||||
if [ -z "$BATS_TMPDIR" ]; then
|
||||
export BATS_TMPDIR=$HOME/batstmp/
|
||||
mkdir $BATS_TMPDIR
|
||||
fi
|
||||
|
||||
nativebatsdir() { echo `nativepath $BATS_TEST_DIRNAME/$1`; }
|
||||
batshelper() { echo `nativebatsdir helper/$1`; }
|
||||
|
||||
setup_common() {
|
||||
psql --version
|
||||
|
||||
export PATH=$PATH:~/go/bin
|
||||
cd $BATS_TMPDIR
|
||||
|
||||
# remove directory if exists
|
||||
# reruns recycle pids
|
||||
rm -rf "dolt-repo-$$"
|
||||
|
||||
# Append the directory name with the pid of the calling process so
|
||||
# multiple tests can be run in parallel on the same machine
|
||||
mkdir "dolt-repo-$$"
|
||||
cd "dolt-repo-$$"
|
||||
nativevar DOLTGRES_DATA_DIR "$(pwd)" /p
|
||||
|
||||
if [ -z "$DOLT_TEST_RETRIES" ]; then
|
||||
export BATS_TEST_RETRIES="$DOLT_TEST_RETRIES"
|
||||
fi
|
||||
}
|
||||
|
||||
teardown_common() {
|
||||
# rm -rf can fail with a "directory not empty" error in some cases. This seems to be a misleading
|
||||
# error message; the real error is that a file is still in use. Instead of waiting longer for
|
||||
# any processes to finish, we just ignore any error removing temp files and use 'true' as the last
|
||||
# command in this function to ensure that teardown_common doesn't fail a test just because we
|
||||
# couldn't delete any temporary test files.
|
||||
stop_sql_server
|
||||
rm -rf "$BATS_TMPDIR/dolt-repo-$$"
|
||||
true
|
||||
}
|
||||
|
||||
query_server() {
|
||||
nativevar PGPASSWORD "password" /w
|
||||
psql -U "${SQL_USER:-postgres}" -h localhost -p $PORT "$@" postgres
|
||||
}
|
||||
|
||||
query_server_for_db() {
|
||||
nativevar PGPASSWORD "password" /w
|
||||
local db_name=${1:-postgres}
|
||||
shift
|
||||
psql -U "${SQL_USER:-postgres}" -h localhost -p $PORT "$@" $db_name
|
||||
}
|
||||
|
||||
log_status_eq() {
|
||||
if ! [ "$status" -eq $1 ]; then
|
||||
echo "status: expected $1, received $status"
|
||||
printf "output:\n$output"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
log_output_has() {
|
||||
if ! [[ "$output" =~ $1 ]]; then
|
||||
echo "output did not have $1"
|
||||
printf "output:\n$output"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
nativevar DOLT_ROOT_PATH $BATS_TMPDIR/config-$$ /p
|
||||
@@ -0,0 +1,144 @@
|
||||
SERVER_REQS_INSTALLED="FALSE"
|
||||
SERVER_PID=""
|
||||
DEFAULT_DB=""
|
||||
PASSWORD=""
|
||||
USERNAME=""
|
||||
|
||||
# wait_for_connection(<PORT>, <TIMEOUT IN MS>) attempts to connect to the sql-server at the specified
|
||||
# port on localhost, using the $SQL_USER (or 'postgres' if unspecified) as the user name, and trying once
|
||||
# per second until the millisecond timeout is reached. If a connection is successfully established,
|
||||
# this function returns 0. If a connection was not able to be established within the timeout period,
|
||||
# this function returns 1.
|
||||
wait_for_connection() {
|
||||
port=$1
|
||||
timeout=$2
|
||||
end_time=$((SECONDS+($timeout/1000)))
|
||||
USERNAME="${USERNAME:=postgres}"
|
||||
PASSWORD="${PASSWORD:=password}"
|
||||
|
||||
nativevar PGPASSWORD "$PASSWORD" /w
|
||||
|
||||
while [ $SECONDS -lt $end_time ]; do
|
||||
run psql -U $USERNAME -h localhost -p $port -c "SELECT 1;" $DEFAULT_DB
|
||||
if [ $status -eq 0 ]; then
|
||||
echo "Connected successfully!"
|
||||
return 0
|
||||
else
|
||||
echo "$output"
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Failed to connect to database $DEFAULT_DB on port $port within $timeout ms."
|
||||
return 1
|
||||
}
|
||||
|
||||
start_sql_server() {
|
||||
DEFAULT_DB="$1"
|
||||
logFile=$2
|
||||
USERNAME=$3
|
||||
PASSWORD=$4
|
||||
|
||||
if [ -n "$DEFAULT_DB" ]; then
|
||||
nativevar DOLTGRES_DB "$DEFAULT_DB" /w
|
||||
fi
|
||||
|
||||
if [ -n "$PASSWORD" ]; then
|
||||
nativevar PGPASSWORD "password" /w
|
||||
nativevar DOLTGRES_PASSWORD "$PASSWORD" /w
|
||||
else
|
||||
nativevar PGPASSWORD "$PASSWORD" /w
|
||||
PASSWORD="password"
|
||||
fi
|
||||
|
||||
if [ -n "$USERNAME" ]; then
|
||||
nativevar DOLTGRES_USER "$USERNAME" /w
|
||||
if [ -z "$DEFAULT_DB" ]; then
|
||||
DEFAULT_DB="$USERNAME"
|
||||
fi
|
||||
else
|
||||
USERNAME="postgres"
|
||||
fi
|
||||
|
||||
DEFAULT_DB="${DEFAULT_DB:=postgres}"
|
||||
|
||||
PORT=$( definePORT )
|
||||
CONFIG=$( defineCONFIG $PORT )
|
||||
echo "$CONFIG" > config.yaml
|
||||
if [[ $logFile ]]
|
||||
then
|
||||
doltgres -data-dir=. -config=config.yaml> $logFile 2>&1 &
|
||||
else
|
||||
doltgres -data-dir=. -config=config.yaml &
|
||||
fi
|
||||
SERVER_PID=$!
|
||||
wait_for_connection $PORT 7500
|
||||
}
|
||||
|
||||
# like start_sql_server, but the second argument is a string with all arguments to doltgres. The
|
||||
# port argument is handled separately: if the variable $PORT is not defined and the --port argument
|
||||
# is not included in the argument list, a random port is chosen for $PORT and the argument --port is
|
||||
# appended to the argument list.
|
||||
start_sql_server_with_args() {
|
||||
DEFAULT_DB=""
|
||||
nativevar DEFAULT_DB "$DEFAULT_DB" /w
|
||||
nativevar PGPASSWORD "password" /w
|
||||
|
||||
echo "running doltgres $@"
|
||||
doltgres "$@" &
|
||||
SERVER_PID=$!
|
||||
wait_for_connection $PORT 7500
|
||||
}
|
||||
|
||||
# stop_sql_server stops the SQL server. For cases where it's important
|
||||
# to wait for the process to exit after the kill signal (e.g. waiting
|
||||
# for an async replication push), pass 1.
|
||||
# kill the process if it's still running
|
||||
stop_sql_server() {
|
||||
# Clean up any mysql.sock file in the default, global location
|
||||
if [ -f "/tmp/mysql.sock" ]; then rm -f /tmp/mysql.sock; fi
|
||||
if [ -f "/tmp/postgres.sock" ]; then rm -f /tmp/mysql.sock; fi
|
||||
if [ -f "/tmp/dolt.$PORT.sock" ]; then rm -f /tmp/dolt.$PORT.sock; fi
|
||||
|
||||
wait=$1
|
||||
if [ ! -z "$SERVER_PID" ]; then
|
||||
# ignore failures of kill command in the case the server is already dead
|
||||
run kill $SERVER_PID
|
||||
if [ $wait ]; then
|
||||
while ps -p $SERVER_PID > /dev/null; do
|
||||
sleep .1;
|
||||
done
|
||||
fi;
|
||||
fi
|
||||
SERVER_PID=
|
||||
PORT=
|
||||
}
|
||||
|
||||
definePORT() {
|
||||
for i in {0..99}
|
||||
do
|
||||
port=$((RANDOM % 4096 + 2048))
|
||||
# nc (netcat) returns 0 when it _can_ connect to a port (therefore in use), 1 otherwise.
|
||||
run nc -z localhost $port
|
||||
if [ "$status" -eq 1 ]; then
|
||||
echo $port
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
defineCONFIG() {
|
||||
PORT=$1
|
||||
cat <<EOF
|
||||
log_level: debug
|
||||
|
||||
behavior:
|
||||
read_only: false
|
||||
disable_client_multi_statements: false
|
||||
dolt_transaction_commit: false
|
||||
|
||||
listener:
|
||||
host: localhost
|
||||
port: $PORT
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
nativepath() { echo "$1"; }
|
||||
nativevar() { eval export "$1"="$2"; }
|
||||
skiponwindows() { :; }
|
||||
|
||||
IS_WINDOWS=${IS_WINDOWS:-false}
|
||||
WINDOWS_BASE_DIR=${WINDOWS_BASE_DIR:-/mnt/c}
|
||||
|
||||
if [ -d "$WINDOWS_BASE_DIR"/Windows/System32 ] || [ "$IS_WINDOWS" == true ]; then
|
||||
IS_WINDOWS=true
|
||||
if [ ! -d "$WINDOWS_BASE_DIR"/batstmp ]; then
|
||||
mkdir "$WINDOWS_BASE_DIR"/batstmp
|
||||
fi
|
||||
BATS_TMPDIR=`TMPDIR="$WINDOWS_BASE_DIR"/batstmp mktemp -d -t dolt-bats-tests-XXXXXX`
|
||||
export BATS_TMPDIR
|
||||
nativepath() {
|
||||
wslpath -w "$1"
|
||||
}
|
||||
nativevar() {
|
||||
eval export "$1"="$2"
|
||||
export WSLENV="$WSLENV:$1$3"
|
||||
}
|
||||
skiponwindows() {
|
||||
skip "$1"
|
||||
}
|
||||
fi
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'types: boolean type' {
|
||||
query_server <<SQL
|
||||
CREATE TABLE t_boolean (id INTEGER primary key, v1 BOOLEAN);
|
||||
INSERT INTO t_boolean VALUES (1, 'true'), (2, 'false');
|
||||
SQL
|
||||
|
||||
run query_server --csv -c "SELECT * FROM t_boolean;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1,t" ]] || false
|
||||
[[ "$output" =~ "2,f" ]] || false
|
||||
}
|
||||
|
||||
@test 'types: boolean array type' {
|
||||
query_server <<SQL
|
||||
CREATE TABLE t_boolean_array (id INTEGER primary key, v1 BOOLEAN[]);
|
||||
INSERT INTO t_boolean_array VALUES (1, ARRAY[true, false]), (2, ARRAY[false, true]), (3, ARRAY[true, true]), (4, ARRAY[false, false]), (5, ARRAY[true]), (6, ARRAY[false]);
|
||||
SQL
|
||||
|
||||
run query_server --csv -c "SELECT * FROM t_boolean_array;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ '1,"{t,f}"' ]] || false
|
||||
[[ "$output" =~ '2,"{f,t}"' ]] || false
|
||||
[[ "$output" =~ '3,"{t,t}"' ]] || false
|
||||
[[ "$output" =~ '4,"{f,f}"' ]] || false
|
||||
[[ "$output" =~ '5,{t}' ]] || false
|
||||
[[ "$output" =~ '6,{f}' ]] || false
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test 'values: mixed int and decimal' {
|
||||
# Integer first, then decimal - should resolve to numeric
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1),(2.01),(3)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2.01" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: decimal first then int' {
|
||||
# Decimal first, then integers - should resolve to numeric
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1.01),(2),(3)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1.01" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: SUM with mixed types' {
|
||||
# SUM should work directly now that VALUES has correct type
|
||||
run query_server -t -c "SELECT SUM(n) FROM (VALUES(1),(2.01),(3)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "6.01" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: multiple columns mixed types' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1, 'a'), (2.5, 'b')) v(num, str);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "a" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "b" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: SUM with explicit cast' {
|
||||
run query_server -t -c "SELECT SUM(n::numeric) FROM (VALUES(1),(2.01),(3)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "6.01" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: MIN and MAX with mixed types' {
|
||||
run query_server -t -c "SELECT MIN(n), MAX(n) FROM (VALUES(1),(2.5),(3),(0.5)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "0.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: GROUP BY with mixed types' {
|
||||
run query_server -t -c "SELECT n, COUNT(*) FROM (VALUES(1),(2.5),(1),(3.5),(2.5)) v(n) GROUP BY n ORDER BY n;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "3.5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: SUM GROUP BY with mixed types' {
|
||||
run query_server -t -c "SELECT category, SUM(amount) FROM (VALUES('a', 1),('b', 2.5),('a', 3),('b', 4.5)) v(category, amount) GROUP BY category ORDER BY category;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "a" ]] || false
|
||||
[[ "$output" =~ "4" ]] || false
|
||||
[[ "$output" =~ "b" ]] || false
|
||||
[[ "$output" =~ "7.0" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: DISTINCT with mixed types' {
|
||||
run query_server -t -c "SELECT DISTINCT n FROM (VALUES(1),(2.5),(1),(2.5),(3)) v(n) ORDER BY n;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: ORDER BY with mixed types' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(3),(1.5),(2),(4.5)) v(n) ORDER BY n;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1.5" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "4.5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: ORDER BY DESC with mixed types' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(3),(1.5),(2),(4.5)) v(n) ORDER BY n DESC;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "4.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
[[ "$output" =~ "1.5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: LIMIT with mixed types' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1),(2.5),(3),(4.5),(5)) v(n) LIMIT 3;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
! [[ "$output" =~ "4.5" ]] || false
|
||||
! [[ "$output" =~ " 5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: WHERE filter with mixed types' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1),(2.5),(3),(4.5),(5)) v(n) WHERE n > 2;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "4.5" ]] || false
|
||||
[[ "$output" =~ "5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: NULLs with mixed types' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1),(NULL),(2.5)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: all same type no cast needed' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1),(2),(3)) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: all string literals' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES('a'),('b'),('c')) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "a" ]] || false
|
||||
[[ "$output" =~ "b" ]] || false
|
||||
[[ "$output" =~ "c" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: string concatenation' {
|
||||
run query_server -t -c "SELECT n || '!' FROM (VALUES('hello'),('world')) v(n);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "hello!" ]] || false
|
||||
[[ "$output" =~ "world!" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: type mismatch bool and int errors' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(true),(1),(false)) v(n);"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "cannot be matched" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: JOIN with same types' {
|
||||
run query_server -t -c "SELECT a.n, b.label FROM (VALUES(1),(2),(3)) a(n) JOIN (VALUES(1, 'one'),(2, 'two'),(3, 'three')) b(id, label) ON a.n = b.id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "one" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
[[ "$output" =~ "two" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "three" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: JOIN with mixed types' {
|
||||
run query_server -t -c "SELECT a.n, b.label FROM (VALUES(1),(2.5),(3)) a(n) JOIN (VALUES(1, 'one'),(3, 'three')) b(id, label) ON a.n = b.id;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "one" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "three" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: CTE with mixed types' {
|
||||
run query_server -t -c "WITH nums AS (SELECT * FROM (VALUES(1),(2.5),(3)) v(n)) SELECT * FROM nums;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: CTE SUM with mixed types' {
|
||||
run query_server -t -c "WITH nums AS (SELECT * FROM (VALUES(1),(2.5),(3)) v(n)) SELECT SUM(n) FROM nums;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "6.5" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: multi-column partial cast' {
|
||||
# Only second column needs cast, first stays int
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1, 10),(2, 20.5),(3, 30)) v(a, b);"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "10" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
[[ "$output" =~ "20.5" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "30" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: combined GROUP BY ORDER BY LIMIT' {
|
||||
run query_server -t -c "SELECT n, COUNT(*) as cnt FROM (VALUES(1),(2.5),(1),(2.5),(3),(1)) v(n) GROUP BY n ORDER BY cnt DESC LIMIT 2;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
[[ "$output" =~ "2.5" ]] || false
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
}
|
||||
|
||||
@test 'values: combined WHERE ORDER BY LIMIT' {
|
||||
run query_server -t -c "SELECT * FROM (VALUES(1),(2.5),(3),(4.5),(5)) v(n) WHERE n > 1 ORDER BY n DESC LIMIT 2;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "5" ]] || false
|
||||
[[ "$output" =~ "4.5" ]] || false
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/setup/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
start_sql_server
|
||||
query_server <<SQL
|
||||
CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 SMALLINT);
|
||||
CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 INTEGER, v2 SMALLINT);
|
||||
INSERT INTO test1 VALUES (1, 2), (6, 7);
|
||||
INSERT INTO test2 VALUES (3, 4, 5), (8, 9, 0);
|
||||
CREATE VIEW testview AS SELECT * FROM test1;
|
||||
SQL
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
# Function to extract and verify the first line (column name)
|
||||
verify_column_name() {
|
||||
local output=$1
|
||||
local expected_column_name=$2
|
||||
|
||||
# Extract the first line and trim leading and trailing whitespace
|
||||
local first_line=$(echo "$output" | head -n 1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
|
||||
# Verify the first line matches the expected column name
|
||||
[ "$first_line" = "$expected_column_name" ] || return 1
|
||||
}
|
||||
|
||||
@test 'workbench-commands: version' {
|
||||
run query_server -c "SELECT version();"
|
||||
[ "$status" -eq 0 ]
|
||||
# Ensure the column name is 'version' and not 'version()'
|
||||
verify_column_name "$output" "version"
|
||||
[[ "$output" =~ "PostgreSQL 15.5" ]] || false
|
||||
}
|
||||
|
||||
@test 'workbench-commands: current_schema' {
|
||||
run query_server -c "SELECT * FROM current_schema()"
|
||||
[ "$status" -eq 0 ]
|
||||
verify_column_name "$output" "current_schema"
|
||||
[[ "$output" =~ "public" ]] || false
|
||||
|
||||
run query_server <<SQL
|
||||
CREATE SCHEMA test_schema;
|
||||
SET search_path TO test_schema;
|
||||
SELECT * FROM current_schema();
|
||||
SQL
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "test_schema" ]] || false
|
||||
}
|
||||
|
||||
@test 'workbench-commands: current_database' {
|
||||
run query_server -c "SELECT * FROM current_database();"
|
||||
[ "$status" -eq 0 ]
|
||||
verify_column_name "$output" "current_database"
|
||||
[[ "$output" =~ "postgres" ]] || false
|
||||
|
||||
run query_server -c "CREATE DATABASE newdb;"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run query_server_for_db newdb -c "SELECT * FROM current_database()"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "newdb" ]] || false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user