compat_functions_test.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package pgserver
  2. import (
  3. "bufio"
  4. "testing"
  5. )
  6. func queryValue(t *testing.T, c *Connection, sql string) ([]string, string) {
  7. t.Helper()
  8. client := &countingConn{}
  9. c.conn = client
  10. c.writer = bufio.NewWriter(client)
  11. if err := c.handleMessage(&Message{Type: MsgQuery, Data: append([]byte(sql), 0)}); err != nil {
  12. t.Fatal(err)
  13. }
  14. messages := readAllMessages(t, client.bytes())
  15. if len(messages) > 0 && messages[0].Type == MsgErrorResponse {
  16. return nil, errorCode(messages[0])
  17. }
  18. for _, message := range messages {
  19. if message.Type == MsgDataRow {
  20. return dataRowValues(t, message), ""
  21. }
  22. }
  23. return nil, ""
  24. }
  25. func TestSmallPostgreSQLCompatibilityFunctions(t *testing.T) {
  26. c, _ := newDataConnection(t)
  27. if _, code := queryValue(t, c, "CREATE TABLE agg (v TEXT)"); code != "" {
  28. t.Fatal(code)
  29. }
  30. if _, code := queryValue(t, c, "INSERT INTO agg VALUES ('x'),('y'),('x')"); code != "" {
  31. t.Fatal(code)
  32. }
  33. for _, tc := range []struct{ sql, want string }{
  34. {"SELECT concat_ws('-', 'a', NULL, 'b')", "a-b"},
  35. {"SELECT concat_ws(NULL, 'a', 'b')", "<null>"},
  36. {"SELECT concat_ws('-', 'a')", "a"},
  37. {"SELECT json_array_length('[1,2,3]')", "3"},
  38. {"SELECT json_array_length('{\"a\":1}')", "0"},
  39. {"SELECT json_array_length('[1,[2,3]]', '$[1]')", "2"},
  40. {"SELECT json_array_length('{\"a\":[1,2]}', '$.a')", "2"},
  41. {"SELECT pg_backend_pid() = pg_backend_pid()", "true"},
  42. {"SELECT string_agg(v, ',') FROM agg", "x,y,x"},
  43. {"SELECT string_agg(DISTINCT v, ',') FROM agg", "x,y"},
  44. } {
  45. values, code := queryValue(t, c, tc.sql)
  46. if code != "" {
  47. t.Fatalf("%s: SQLSTATE %s", tc.sql, code)
  48. }
  49. if len(values) != 1 || values[0] != tc.want {
  50. t.Fatalf("%s: got %v want %s", tc.sql, values, tc.want)
  51. }
  52. }
  53. if values, code := queryValue(t, c, "SELECT json_array_length('not json')"); code == "" || len(values) != 0 {
  54. t.Fatalf("malformed JSON accepted: %v %s", values, code)
  55. }
  56. if values, code := queryValue(t, c, "SELECT string_agg('x', NULL)"); code != "" || len(values) != 1 || values[0] != "<null>" {
  57. t.Fatalf("NULL delimiter: %v %s", values, code)
  58. }
  59. if values, code := queryValue(t, c, "SELECT string_agg(NULL, ',')"); code != "" || len(values) != 1 || values[0] != "<null>" {
  60. t.Fatalf("NULL input: %v %s", values, code)
  61. }
  62. }