#!/usr/bin/env bats load $BATS_TEST_DIRNAME/helper/common.bash setup() { setup_common export DOLT_DBNAME_REPLACE="true" dolt sql < 0;" [ "$status" -eq "1" ] [[ "$output" =~ "violation" ]] || false run dolt sql -q "SELECT * FROM test" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "pk,v1" ]] || false [[ "$output" =~ "1,1" ]] || false [[ "$output" =~ "4,4" ]] || false [[ "$output" =~ "5,5" ]] || false [[ ! "$output" =~ "2,2" ]] || false [[ ! "$output" =~ "3,3" ]] || false [[ "${#lines[@]}" = "4" ]] || false run dolt sql -q "SELECT * FROM test2" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "pk" ]] || false [[ "$output" =~ "4" ]] || false [[ "${#lines[@]}" = "2" ]] || false run dolt sql -q "REPLACE INTO test VALUES (1,7), (4,8), (5,9);" [ "$status" -eq "1" ] [[ "$output" =~ "violation" ]] || false run dolt sql -q "SELECT * FROM test" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "pk,v1" ]] || false [[ "$output" =~ "1,1" ]] || false [[ "$output" =~ "4,4" ]] || false [[ "$output" =~ "5,5" ]] || false [[ ! "$output" =~ "2,2" ]] || false [[ ! "$output" =~ "3,3" ]] || false [[ "${#lines[@]}" = "4" ]] || false run dolt sql -q "SELECT * FROM test2" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "pk" ]] || false [[ "$output" =~ "4" ]] || false [[ "${#lines[@]}" = "2" ]] || false } @test "sql: select from multiple tables" { run dolt sql -q "select pk,pk1,pk2 from one_pk,two_pk" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 20 ] run dolt sql -q "select pk,pk1,pk2 from one_pk,two_pk where one_pk.c1=two_pk.c1" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 8 ] run dolt sql -q "select pk,pk1,pk2,one_pk.c1 as foo,two_pk.c1 as bar from one_pk,two_pk where one_pk.c1=two_pk.c1" [ "$status" -eq 0 ] [[ "$output" =~ foo ]] || false [[ "$output" =~ bar ]] || false [ "${#lines[@]}" -eq 8 ] # check information_schema.STATISTICS table # TODO: caridnality here are all 0's as it's not supported yet run dolt sql -q "select * from information_schema.STATISTICS;" -r csv [[ "$output" =~ "has_datetimes,0,dolt_repo_$$,PRIMARY,1,pk,A,0,,,\"\",BTREE,\"\",\"\",YES," ]] || false [[ "$output" =~ "one_pk,0,dolt_repo_$$,PRIMARY,1,pk,A,0,,,\"\",BTREE,\"\",\"\",YES," ]] || false [[ "$output" =~ "two_pk,0,dolt_repo_$$,PRIMARY,1,pk1,A,0,,,\"\",BTREE,\"\",\"\",YES," ]] || false [[ "$output" =~ "two_pk,0,dolt_repo_$$,PRIMARY,2,pk2,A,0,,,\"\",BTREE,\"\",\"\",YES," ]] || false skip "ALTER VIEW is unsupported" # check cardinality on information_schema.STATISTICS table run dolt sql -q "select table_name, column_name, cardinality from information_schema.STATISTICS;" -r csv [[ "$output" =~ "has_datetimes,pk,1" ]] || false [[ "$output" =~ "one_pk,pk,4" ]] || false [[ "$output" =~ "two_pk,pk1,2" ]] || false [[ "$output" =~ "two_pk,pk2,4" ]] || false } @test "sql: AS OF queries" { dolt add . dolt commit -m "Initial main commit" --date "2020-03-01T12:00:00Z" main_commit=`dolt log | head -n1 | cut -d' ' -f2` dolt sql -q "update one_pk set c1 = c1 + 1" dolt sql -q "drop table two_pk" dolt checkout -b new_branch dolt add . dolt commit -m "Updated a table, dropped a table" --date "2020-03-01T13:00:00Z" new_commit=`dolt log | head -n1 | cut -d' ' -f2` run dolt sql -r csv -q "select pk,c1 from one_pk order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,1" ]] || false [[ "$output" =~ "1,11" ]] || false [[ "$output" =~ "2,21" ]] || false [[ "$output" =~ "3,31" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of 'main' order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of '$main_commit' order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false run dolt sql -r csv -q "select count(*) from two_pk as of 'main'" [ $status -eq 0 ] [[ "$output" =~ "4" ]] || false run dolt sql -r csv -q "select count(*) from two_pk as of '$main_commit'" [ $status -eq 0 ] [[ "$output" =~ "4" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of 'HEAD~' order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of 'new_branch^' order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false dolt checkout main run dolt sql -r csv -q "select pk,c1 from one_pk as of 'new_branch' order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,1" ]] || false [[ "$output" =~ "1,11" ]] || false [[ "$output" =~ "2,21" ]] || false [[ "$output" =~ "3,31" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of '$new_commit' order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,1" ]] || false [[ "$output" =~ "1,11" ]] || false [[ "$output" =~ "2,21" ]] || false [[ "$output" =~ "3,31" ]] || false dolt checkout new_branch run dolt sql -r csv -q "select pk,c1 from one_pk as of CONVERT('2020-03-01 12:00:00', DATETIME) order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of CONVERT('2020-03-01 12:15:00', DATETIME) order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of CONVERT('2020-03-01 13:00:00', DATETIME) order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,1" ]] || false [[ "$output" =~ "1,11" ]] || false [[ "$output" =~ "2,21" ]] || false [[ "$output" =~ "3,31" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of CONVERT('2020-03-01 13:15:00', DATETIME) order by c1" [ $status -eq 0 ] [[ "$output" =~ "0,1" ]] || false [[ "$output" =~ "1,11" ]] || false [[ "$output" =~ "2,21" ]] || false [[ "$output" =~ "3,31" ]] || false run dolt sql -r csv -q "select pk,c1 from one_pk as of CONVERT('2020-03-01 11:59:59', DATETIME) order by c1" [ $status -eq 1 ] [[ "$output" =~ "not found" ]] || false } @test "sql: output formats" { dolt sql < out.parquet run parquet cat out.parquet [ "$status" -eq 0 ] [[ "$output" =~ '{"a": 1, "b": 1.5, "c": "1", "d": 1577836800000000}' ]] || false [[ "$output" =~ '{"a": 2, "b": 2.5, "c": "2", "d": 1580601600000000}' ]] || false [[ "$output" =~ '{"a": 3, "b": null, "c": "3", "d": 1583193600000000}' ]] || false [[ "$output" =~ '{"a": 4, "b": 4.5, "c": null, "d": 1585958400000000}' ]] || false [[ "$output" =~ '{"a": 5, "b": 5.5, "c": "5", "d": null}' ]] || false [ "${#lines[@]}" -eq 5 ] run dolt sql -r parquet -q "select @@character_set_client" [ $status -eq 0 ] [[ "$output" =~ "utf8mb4" ]] || false } @test "sql: empty output exports properly" { dolt sql < out.parquet run parquet cat out.parquet [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 0 ] } @test "sql: output for escaped longtext exports properly" { dolt sql < out.parquet run parquet cat out.parquet [ $status -eq 0 ] [[ "$output" =~ '{"a": 1, "v": "{\"key\": \"value\"}"}' ]] || false [[ "$output" =~ '{"a": 2, "v": "\"Hello\""}' ]] || false } @test "sql: ambiguous column name" { run dolt sql -q "select pk,pk1,pk2 from one_pk,two_pk where c1=0" [ "$status" -eq 1 ] [[ "$output" =~ "ambiguous column name \"c1\", it's present in all these tables: [two_pk one_pk]" ]] || false } @test "sql: select with and and or clauses" { run dolt sql -q "select pk,pk1,pk2 from one_pk,two_pk where pk=0 and pk1=0 or pk2=1" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 13 ] } @test "sql: select the same column twice using column aliases" { run dolt sql -q "select pk,c1 as foo,c1 as bar from one_pk" [ "$status" -eq 0 ] [[ ! "$output" =~ "NULL" ]] || false [[ "$output" =~ "foo" ]] || false [[ "$output" =~ "bar" ]] || false } @test "sql: select same column twice using table aliases" { run dolt sql -q "select foo.pk,foo.c1,bar.c1 from one_pk as foo, one_pk as bar" [ "$status" -eq 0 ] [[ ! "$output" =~ "NULL" ]] || false [[ "$output" =~ "c1" ]] || false } @test "sql: select ambiguous column using table aliases" { run dolt sql -q "select pk,foo.c1,bar.c1 from one_pk as foo, one_pk as bar" [ "$status" -eq 1 ] [[ "$output" =~ "ambiguous" ]] || false } @test "sql: basic inner join" { run dolt sql -q "select pk,pk1,pk2 from one_pk join two_pk on one_pk.c1=two_pk.c1 order by pk" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 8 ] first_join_output=$output run dolt sql -q "select pk,pk1,pk2 from two_pk join one_pk on one_pk.c1=two_pk.c1 order by pk" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 8 ] [ "$output" = "$first_join_output" ] run dolt sql -q "select pk,pk1,pk2 from one_pk join two_pk on one_pk.c1=two_pk.c1 where pk=1 order by pk" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 5 ] run dolt sql -q "select pk,pk1,pk2,one_pk.c1 as foo,two_pk.c1 as bar from one_pk join two_pk on one_pk.c1=two_pk.c1 order by pk" [ "$status" -eq 0 ] [[ "$output" =~ foo ]] || false [[ "$output" =~ bar ]] || false [ "${#lines[@]}" -eq 8 ] run dolt sql -q "select pk,pk1,pk2,one_pk.c1 as foo,two_pk.c1 as bar from one_pk join two_pk on one_pk.c1=two_pk.c1 where one_pk.c1=10 order by pk" [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "10" ]] || false } @test "sql: select two tables and join to one" { run dolt sql -q "select op.pk,pk1,pk2 from one_pk,two_pk join one_pk as op on op.pk=pk1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 20 ] } @test "sql: non unique table alias" { run dolt sql -q "select pk from one_pk,one_pk" [ $status -eq 1 ] } @test "sql: is null and is not null statements" { dolt sql -q "insert into one_pk (pk,c1,c2) values (11,0,0)" run dolt sql -q "select pk from one_pk where c3 is null" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "11" ]] || false run dolt sql -q "select pk from one_pk where c3 is not null" [ $status -eq 0 ] [ "${#lines[@]}" -eq 8 ] [[ ! "$output" =~ "11" ]] || false } @test "sql: addition and subtraction" { dolt sql -q "insert into one_pk (pk,c1,c2,c3,c4,c5) values (11,0,5,10,15,20)" run dolt sql -q "select pk from one_pk where c2-c1>=5" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "11" ]] || false run dolt sql -q "select pk from one_pk where c3-c2-c1>=5" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "11" ]] || false run dolt sql -q "select pk from one_pk where c2+c1<=5" [ $status -eq 0 ] [ "${#lines[@]}" -eq 6 ] [[ "$output" =~ "0" ]] || false [[ "$output" =~ "11" ]] || false } @test "sql: order by and limit" { run dolt sql -q "select * from one_pk order by pk limit 1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ " 0 " ]] || false [[ ! "$output" =~ " 10 " ]] || false run dolt sql -q "select * from one_pk order by pk limit 0,1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ " 0 " ]] || false [[ ! "$output" =~ " 10 " ]] || false run dolt sql -q "select * from one_pk order by pk limit 1,1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ " 10 " ]] || false [[ ! "$output" =~ " 0 " ]] || false run dolt sql -q "select * from one_pk order by pk limit 1,0" [ $status -eq 0 ] [ "${#lines[@]}" -eq 0 ] [[ ! "$output" =~ " 0 " ]] || false run dolt sql -q "select * from one_pk order by pk desc limit 1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "30" ]] || false [[ ! "$output" =~ "10" ]] || false run dolt sql -q "select * from two_pk order by pk1, pk2 desc limit 1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "10" ]] || false run dolt sql -q "select pk,c2 from one_pk order by c1 limit 1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "0" ]] || false [[ ! "$output" =~ "10" ]] || false run dolt sql -q "select * from one_pk,two_pk order by pk1,pk2,pk limit 1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "0" ]] || false [[ ! "$output" =~ "10" ]] || false dolt sql -q "select * from one_pk join two_pk order by pk1,pk2,pk limit 1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "0" ]] || false [[ ! "$output" =~ "10" ]] || false run dolt sql -q "select * from one_pk order by limit 1" [ $status -eq 1 ] run dolt sql -q "select * from one_pk order by bad limit 1" [ $status -eq 1 ] [[ "$output" =~ "column \"bad\" could not be found" ]] || false run dolt sql -q "select * from one_pk order pk by limit" [ $status -eq 1 ] } @test "sql: limit less than zero" { run dolt sql -q "select * from one_pk order by pk limit -1" [ $status -eq 1 ] [[ "$output" =~ "syntax error" ]] || false run dolt sql -q "select * from one_pk order by pk limit -2" [ $status -eq 1 ] [[ "$output" =~ "syntax error" ]] || false run dolt sql -q "select * from one_pk order by pk limit -1,1" [ $status -eq 1 ] [[ "$output" =~ "syntax error" ]] || false } @test "sql: addition on both left and right sides of comparison operator" { dolt sql -q "insert into one_pk (pk,c1,c2,c3,c4,c5) values (11,5,5,10,15,20)" run dolt sql -q "select pk from one_pk where c2+c1<=5+5" [ $status -eq 0 ] [ "${#lines[@]}" -eq 6 ] [[ "$output" =~ 0 ]] || false [[ "$output" =~ 11 ]] || false } @test "sql: select with in list" { run dolt sql -q "select pk from one_pk where c1 in (10,20)" [ $status -eq 0 ] [ "${#lines[@]}" -eq 6 ] [[ "$output" =~ "1" ]] || false [[ "$output" =~ "2" ]] || false run dolt sql -q "select pk from one_pk where c1 in (11,21)" [ $status -eq 0 ] [ "${#lines[@]}" -eq 0 ] run dolt sql -q "select pk from one_pk where c1 not in (10,20)" [ $status -eq 0 ] [ "${#lines[@]}" -eq 6 ] [[ "$output" =~ "0" ]] || false [[ "$output" =~ "3" ]] || false run dolt sql -q "select pk from one_pk where c1 not in (10,20) and c1 in (30)" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "3" ]] || false } @test "sql: parser does not support empty list" { run dolt sql -q "select pk from one_pk where c1 not in ()" [ $status -eq 1 ] [[ "$output" =~ "Error parsing SQL" ]] || false } @test "sql: addition in join statement" { run dolt sql -q "select * from one_pk join two_pk on pk1-pk>0 and pk2<1" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "$output" =~ "20" ]] || false } @test "sql: leave off table name in select" { dolt sql -q "insert into one_pk (pk,c1,c2) values (11,0,0)" run dolt sql -q "select pk where c3 is null" [ $status -eq 1 ] [[ "$output" =~ "column \"c3\" could not be found in any table in scope" ]] || false } @test "sql: show tables" { run dolt sql -q "show tables" [ $status -eq 0 ] echo ${#lines[@]} [ "${#lines[@]}" -eq 7 ] [[ "$output" =~ "one_pk" ]] || false [[ "$output" =~ "two_pk" ]] || false [[ "$output" =~ "has_datetimes" ]] || false } @test "sql: show tables AS OF" { dolt add .; dolt commit -m 'commit tables' dolt sql < decoy/config.json # Not doing this cd ../ results in the teardown method failing on # a skip, not sure why. It's not part of the actual test cd ../ skip "This results in a panic right now" run dolt sql -q "show databases" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "information_schema" ]] || false [[ ! "$output" =~ "decoy" ]] || false } @test "sql: set head ref session var" { dolt add .; dolt commit -m 'commit tables' dolt checkout -b feature-branch dolt checkout main run dolt sql -q "select @@dolt_repo_$$_head_ref;" [ "$status" -eq 0 ] [[ "$output" =~ 'refs/heads/main' ]] || false dolt sql < |" ]] || false } @test "sql: drop table" { dolt sql -q "drop table one_pk" run dolt ls [[ ! "$output" =~ "one_pk" ]] || false run dolt sql -q "drop table poop" [ $status -eq 1 ] [[ "$output" =~ "table not found: poop" ]] || false } @test "sql: replace count" { skip "right now we always count a replace as a delete and insert when we shouldn't" dolt sql -q "CREATE TABLE test(pk BIGINT PRIMARY KEY, v BIGINT);" run dolt sql -q "REPLACE INTO test VALUES (1, 1);" [ $status -eq 0 ] [[ "${lines[3]}" =~ " 1 " ]] || false run dolt sql -q "REPLACE INTO test VALUES (1, 2);" [ $status -eq 0 ] [[ "${lines[3]}" =~ " 2 " ]] || false } @test "sql: unix_timestamp function" { run dolt sql -q "SELECT UNIX_TIMESTAMP(NOW()) FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] } @test "sql: select union all" { run dolt sql -r csv -q "SELECT 2+2 FROM dual UNION ALL SELECT 2+2 FROM dual UNION ALL SELECT 2+3 FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 4 ] } @test "sql: select union" { run dolt sql -r csv -q "SELECT 2+2 FROM dual UNION SELECT 2+2 FROM dual UNION SELECT 2+3 FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 3 ] run dolt sql -r csv -q "SELECT 2+2 FROM dual UNION DISTINCT SELECT 2+2 FROM dual UNION SELECT 2+3 FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 3 ] run dolt sql -r csv -q "(SELECT 2+2 FROM dual UNION DISTINCT SELECT 2+2 FROM dual) UNION SELECT 2+3 FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 3 ] run dolt sql -r csv -q "SELECT 2+2 FROM dual UNION DISTINCT (SELECT 2+2 FROM dual UNION SELECT 2+3 FROM dual);" [ $status -eq 0 ] [ "${#lines[@]}" -eq 3 ] } @test "sql: greatest/least with a timestamp" { run dolt sql -q "SELECT GREATEST(NOW(), DATE_ADD(NOW(), INTERVAL 2 DAY)) FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] run dolt sql -q "SELECT LEAST(NOW(), DATE_ADD(NOW(), INTERVAL 2 DAY)) FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] } @test "sql: greatest with converted null" { run dolt sql -q "SELECT GREATEST(CAST(NOW() AS CHAR), CAST(NULL AS CHAR)) FROM dual;" [ $status -eq 0 ] [ "${#lines[@]}" -eq 5 ] [[ "${lines[3]}" =~ " NULL " ]] || false } @test "sql: date_format function" { dolt sql -q "select date_format(date_created, '%Y-%m-%d') from has_datetimes" } @test "sql: DATE_ADD and DATE_SUB in where clause" { run dolt sql -q "select * from has_datetimes where date_created > DATE_SUB('2020-02-18 00:00:00', INTERVAL 2 DAY)" [ $status -eq 0 ] [[ "$output" =~ "17 " ]] || false run dolt sql -q "select * from has_datetimes where date_created > DATE_ADD('2020-02-14 00:00:00', INTERVAL 2 DAY)" [ $status -eq 0 ] [[ "$output" =~ "17 " ]] || false } @test "sql: update a datetime column" { dolt sql -q "insert into has_datetimes (pk) values (1)" run dolt sql -q "update has_datetimes set date_created='2020-02-11 00:00:00' where pk=1" [ $status -eq 0 ] [[ ! "$output" =~ "Expected GetField expression" ]] || false } @test "sql: group by statements" { dolt sql -q "insert into one_pk (pk,c1,c2,c3,c4,c5) values (4,0,0,0,0,0),(5,0,0,0,0,0)" run dolt sql -q "select max(pk) from one_pk group by c1" [ $status -eq 0 ] [[ "$output" =~ " 5 " ]] || false [[ ! "$output" =~ " 4 " ]] || false run dolt sql -q "select max(pk), min(c2) from one_pk group by c1" [ $status -eq 0 ] [[ "$output" =~ " 5 " ]] || false [[ "$output" =~ " 0 " ]] || false [[ ! "$output" =~ " 4 " ]] || false run dolt sql -r csv -q "select max(pk),c2 from one_pk group by c1" [ $status -eq 0 ] [[ "$output" =~ "5,0" ]] || false [[ "$output" =~ "1,10" ]] || false [[ "$output" =~ "2,20" ]] || false [[ "$output" =~ "3,30" ]] || false } @test "sql: substr() and cast() functions" { run dolt sql -q "select substr(cast(date_created as char), 1, 4) from has_datetimes" [ $status -eq 0 ] [[ "$output" =~ " 2020 " ]] || false [[ ! "$output" =~ "17" ]] || false } @test "sql: divide by zero does not panic" { run dolt sql -q "select 1/0 from dual" [ $status -eq 0 ] echo $output [[ "$output" =~ "NULL" ]] || false [[ ! "$output" =~ "panic: " ]] || false run dolt sql -q "select 1.0/0.0 from dual" [ $status -eq 0 ] [[ "$output" =~ "NULL" ]] || false [[ ! "$output" =~ "panic: " ]] || false run dolt sql -q "select 1 div 0 from dual" [ $status -eq 0 ] [[ "$output" =~ "NULL" ]] || false [[ ! "$output" =~ "panic: " ]] || false } @test "sql: delete all rows in table" { run dolt sql < m THEN SET s = 'greater'; ELSE SET s = 'less'; END IF; SET s = CONCAT('is ', s, ' than'); END IF; SET s = CONCAT(n, ' ', s, ' ', m, '.'); SELECT s; END; //" run dolt sql -q "CALL p1('', 1, 1)" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "1 equals 1." ]] || false [[ "${#lines[@]}" = "2" ]] || false run dolt sql -q "CALL p1('', 2, 1)" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "2 is greater than 1." ]] || false [[ "${#lines[@]}" = "2" ]] || false run dolt sql -q "CALL p1('', 1, 2)" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "1 is less than 2." ]] || false [[ "${#lines[@]}" = "2" ]] || false run dolt sql -q "SELECT * FROM dolt_procedures" -r=csv [ "$status" -eq "0" ] [[ "$output" =~ "name,create_stmt,created_at,modified_at" ]] || false # Just the beginning portion is good enough, we don't need to test the timestamps as they change [[ "$output" =~ 'p1,"CREATE PROCEDURE p1(s VARCHAR(200), N DOUBLE, m DOUBLE)' ]] || false [[ "${#lines[@]}" = "14" ]] || false } @test "sql: stored procedures show and delete" { dolt sql < script.sql < ../dont_read.txt echo "should be able to read this" > ./do_read.txt run dolt sql -q "select load_file('../dont_read.txt')"; [ "$status" -eq 0 ] [[ "$output" =~ "NULL" ]] || false [[ "$output" != "should not be able to read this" ]] || false run dolt sql -q "select load_file('./do_read.txt')"; [ "$status" -eq 0 ] [[ "$output" =~ "should be able to read this" ]] || false } @test "sql: ignore an empty .dolt directory" { mkdir empty_dir cd empty_dir mkdir .dolt dolt sql -q "select 1" # If there is a zombie lock file, sql should delete it. echo "42:3306:aebf244e-0693-4c36-8b2d-6eb0dfa4fe2d" > .dolt/sql-server.lock} dolt sql -q "select 1" [[ ! -f .dolt/sql-server.lock ]] || false }