| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- package parser
- import (
- "strings"
- "testing"
- "github.com/danfragoso/pizzasql-next/pkg/lexer"
- )
- func parseNotifySQL(t *testing.T, sql string) (Statement, error) {
- t.Helper()
- return New(lexer.New(sql)).Parse()
- }
- func TestParseListen(t *testing.T) {
- stmt, err := parseNotifySQL(t, `LISTEN orders`)
- if err != nil {
- t.Fatal(err)
- }
- listen, ok := stmt.(*ListenStmt)
- if !ok || listen.Channel != "orders" {
- t.Fatalf("unexpected statement: %#v", stmt)
- }
- quoted, err := parseNotifySQL(t, `LISTEN "Mixed Case"`)
- if err != nil {
- t.Fatal(err)
- }
- if quoted.(*ListenStmt).Channel != "Mixed Case" {
- t.Fatalf("quoted channel = %q", quoted.(*ListenStmt).Channel)
- }
- }
- func TestParseUnlisten(t *testing.T) {
- stmt, err := parseNotifySQL(t, `UNLISTEN orders`)
- if err != nil {
- t.Fatal(err)
- }
- unlisten := stmt.(*UnlistenStmt)
- if unlisten.All || unlisten.Channel != "orders" {
- t.Fatalf("unexpected unlisten: %#v", unlisten)
- }
- all, err := parseNotifySQL(t, `UNLISTEN *`)
- if err != nil {
- t.Fatal(err)
- }
- if !all.(*UnlistenStmt).All {
- t.Fatal("expected UNLISTEN *")
- }
- }
- func TestParseNotify(t *testing.T) {
- stmt, err := parseNotifySQL(t, `NOTIFY orders, 'created'`)
- if err != nil {
- t.Fatal(err)
- }
- notify := stmt.(*NotifyStmt)
- if notify.Channel != "orders" || notify.Payload != "created" {
- t.Fatalf("unexpected notify: %#v", notify)
- }
- empty, err := parseNotifySQL(t, `NOTIFY orders`)
- if err != nil {
- t.Fatal(err)
- }
- if empty.(*NotifyStmt).Payload != "" {
- t.Fatalf("payload = %q, want empty", empty.(*NotifyStmt).Payload)
- }
- escaped, err := parseNotifySQL(t, `NOTIFY orders, 'it''s here'`)
- if err != nil {
- t.Fatal(err)
- }
- if escaped.(*NotifyStmt).Payload != "it's here" {
- t.Fatalf("payload = %q", escaped.(*NotifyStmt).Payload)
- }
- }
- func TestParseNotifyPayloadLimit(t *testing.T) {
- payload := strings.Repeat("a", 8000)
- if _, err := parseNotifySQL(t, `NOTIFY ch, '`+payload+`'`); err != nil {
- t.Fatalf("8000-byte payload rejected: %v", err)
- }
- if _, err := parseNotifySQL(t, `NOTIFY ch, '`+payload+`a'`); err == nil {
- t.Fatal("expected 8001-byte payload to be rejected")
- }
- }
- func TestParseChannelNameLimit(t *testing.T) {
- channel := strings.Repeat("a", 63)
- if _, err := parseNotifySQL(t, `LISTEN `+channel); err != nil {
- t.Fatalf("63-byte channel rejected: %v", err)
- }
- if _, err := parseNotifySQL(t, `LISTEN `+channel+`a`); err == nil {
- t.Fatal("expected 64-byte channel to be rejected")
- }
- }
- func TestParseNotifyInvalid(t *testing.T) {
- for _, sql := range []string{
- `LISTEN`,
- `UNLISTEN`,
- `NOTIFY ch,`,
- `NOTIFY ch, 42`,
- `NOTIFY ch 'payload'`,
- `LISTEN 42`,
- } {
- if _, err := parseNotifySQL(t, sql); err == nil {
- t.Errorf("expected %q to fail", sql)
- }
- }
- }
- func TestNotifyIsNotReservedAsColumnName(t *testing.T) {
- stmt, err := parseNotifySQL(t, `SELECT notify, listen FROM events`)
- if err != nil {
- t.Fatalf("contextual keywords should remain usable as columns: %v", err)
- }
- sel := stmt.(*SelectStmt)
- if len(sel.Columns) != 2 {
- t.Fatalf("columns = %d, want 2", len(sel.Columns))
- }
- }
|