| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package exectest |
| |
| import ( |
| "errors" |
| "fmt" |
| "reflect" |
| "strings" |
| "testing" |
| "time" |
| |
| "v.io/syncbase/v23/syncbase" |
| "v.io/syncbase/v23/syncbase/nosql" |
| "v.io/syncbase/v23/syncbase/nosql/syncql" |
| tu "v.io/syncbase/v23/syncbase/testutil" |
| "v.io/v23/context" |
| "v.io/v23/vdl" |
| "v.io/v23/verror" |
| _ "v.io/x/ref/runtime/factories/generic" |
| ) |
| |
| var ctx *context.T |
| var db nosql.Database |
| var cleanup func() |
| |
| // In addition to populating store, populate these arrays to make |
| // specifying the wanted values in the tests easier. |
| type kv struct { |
| key string |
| value *vdl.Value |
| } |
| |
| var customerEntries []kv |
| var numbersEntries []kv |
| var fooEntries []kv |
| var keyIndexDataEntries []kv |
| |
| var t2015 time.Time |
| |
| var t2015_04 time.Time |
| var t2015_04_12 time.Time |
| var t2015_04_12_22 time.Time |
| var t2015_04_12_22_16 time.Time |
| var t2015_04_12_22_16_06 time.Time |
| |
| var t2015_07 time.Time |
| var t2015_07_01 time.Time |
| var t2015_07_01_01_23_45 time.Time |
| |
| func setup(t *testing.T) { |
| var sName string |
| ctx, sName, cleanup = tu.SetupOrDie(nil) |
| a := tu.CreateApp(t, ctx, syncbase.NewService(sName), "a") |
| db = tu.CreateNoSQLDatabase(t, ctx, a, "db") |
| customerTable := tu.CreateTable(t, ctx, db, "Customer") |
| numbersTable := tu.CreateTable(t, ctx, db, "Numbers") |
| fooTable := tu.CreateTable(t, ctx, db, "Foo") |
| keyIndexDataTable := tu.CreateTable(t, ctx, db, "KeyIndexData") |
| bigTable := tu.CreateTable(t, ctx, db, "BigTable") |
| |
| t20150122131101, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Jan 22 2015 13:11:01 -0800 PST") |
| t20150210161202, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Feb 10 2015 16:12:02 -0800 PST") |
| t20150311101303, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Mar 11 2015 10:13:03 -0700 PDT") |
| t20150317111404, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Mar 17 2015 11:14:04 -0700 PDT") |
| t20150317131505, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Mar 17 2015 13:15:05 -0700 PDT") |
| t20150412221606, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Apr 12 2015 22:16:06 -0700 PDT") |
| t20150413141707, _ := time.Parse("Jan 2 2006 15:04:05 -0700 MST", "Apr 13 2015 14:17:07 -0700 PDT") |
| |
| t2015, _ = time.Parse("2006 MST", "2015 PST") |
| |
| t2015_04, _ = time.Parse("Jan 2006 MST", "Apr 2015 PDT") |
| t2015_07, _ = time.Parse("Jan 2006 MST", "Jul 2015 PDT") |
| |
| t2015_04_12, _ = time.Parse("Jan 2 2006 MST", "Apr 12 2015 PDT") |
| t2015_07_01, _ = time.Parse("Jan 2 2006 MST", "Jul 01 2015 PDT") |
| |
| t2015_04_12_22, _ = time.Parse("Jan 2 2006 15 MST", "Apr 12 2015 22 PDT") |
| t2015_04_12_22_16, _ = time.Parse("Jan 2 2006 15:04 MST", "Apr 12 2015 22:16 PDT") |
| t2015_04_12_22_16_06, _ = time.Parse("Jan 2 2006 15:04:05 MST", "Apr 12 2015 22:16:06 PDT") |
| t2015_07_01_01_23_45, _ = time.Parse("Jan 2 2006 15:04:05 MST", "Jul 01 2015 01:23:45 PDT") |
| |
| k := "001" |
| c := Customer{"John Smith", 1, true, AddressInfo{"1 Main St.", "Palo Alto", "CA", "94303"}, CreditReport{Agency: CreditAgencyEquifax, Report: AgencyReportEquifaxReport{EquifaxCreditReport{'A'}}}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(c)}) |
| if err := customerTable.Put(ctx, k, c); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| k = "001001" |
| i := Invoice{1, 1000, t20150122131101, 42, AddressInfo{"1 Main St.", "Palo Alto", "CA", "94303"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "001002" |
| i = Invoice{1, 1003, t20150210161202, 7, AddressInfo{"2 Main St.", "Palo Alto", "CA", "94303"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "001003" |
| i = Invoice{1, 1005, t20150311101303, 88, AddressInfo{"3 Main St.", "Palo Alto", "CA", "94303"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "002" |
| c = Customer{"Bat Masterson", 2, true, AddressInfo{"777 Any St.", "Collins", "IA", "50055"}, CreditReport{Agency: CreditAgencyTransUnion, Report: AgencyReportTransUnionReport{TransUnionCreditReport{80}}}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(c)}) |
| if err := customerTable.Put(ctx, k, c); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "002001" |
| i = Invoice{2, 1001, t20150317111404, 166, AddressInfo{"777 Any St.", "collins", "IA", "50055"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "002002" |
| i = Invoice{2, 1002, t20150317131505, 243, AddressInfo{"888 Any St.", "collins", "IA", "50055"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "002003" |
| i = Invoice{2, 1004, t20150412221606, 787, AddressInfo{"999 Any St.", "collins", "IA", "50055"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "002004" |
| i = Invoice{2, 1006, t20150413141707, 88, AddressInfo{"101010 Any St.", "collins", "IA", "50055"}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(i)}) |
| if err := customerTable.Put(ctx, k, i); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "003" |
| c = Customer{"John Steed", 3, true, AddressInfo{"100 Queen St.", "New London", "CT", "06320"}, CreditReport{Agency: CreditAgencyExperian, Report: AgencyReportExperianReport{ExperianCreditReport{ExperianRatingGood}}}} |
| customerEntries = append(customerEntries, kv{k, vdl.ValueOf(c)}) |
| if err := customerTable.Put(ctx, k, c); err != nil { |
| t.Fatalf("customerTable.Put() failed: %v", err) |
| } |
| |
| k = "001" |
| n := Numbers{byte(12), uint16(1234), uint32(5678), uint64(999888777666), int16(9876), int32(876543), int64(128), float32(3.14159), float64(2.71828182846), complex64(123.0 + 7.0i), complex128(456.789 + 10.1112i)} |
| numbersEntries = append(numbersEntries, kv{k, vdl.ValueOf(n)}) |
| if err := numbersTable.Put(ctx, k, n); err != nil { |
| t.Fatalf("numbersTable.Put() failed: %v", err) |
| } |
| |
| k = "002" |
| n = Numbers{byte(9), uint16(99), uint32(999), uint64(9999999), int16(9), int32(99), int64(88), float32(1.41421356237), float64(1.73205080757), complex64(9.87 + 7.65i), complex128(4.32 + 1.0i)} |
| numbersEntries = append(numbersEntries, kv{k, vdl.ValueOf(n)}) |
| if err := numbersTable.Put(ctx, k, n); err != nil { |
| t.Fatalf("numbersTable.Put() failed: %v", err) |
| } |
| |
| k = "003" |
| n = Numbers{byte(210), uint16(210), uint32(210), uint64(210), int16(210), int32(210), int64(210), float32(210.0), float64(210.0), complex64(210.0 + 0.0i), complex128(210.0 + 0.0i)} |
| numbersEntries = append(numbersEntries, kv{k, vdl.ValueOf(n)}) |
| if err := numbersTable.Put(ctx, k, n); err != nil { |
| t.Fatalf("numbersTable.Put() failed: %v", err) |
| } |
| |
| k = "001" |
| f := FooType{BarType{BazType{"FooBarBaz", TitleOrValueTypeTitle{"Vice President"}}}} |
| fooEntries = append(fooEntries, kv{k, vdl.ValueOf(f)}) |
| if err := fooTable.Put(ctx, k, f); err != nil { |
| t.Fatalf("fooTable.Put() failed: %v", err) |
| } |
| |
| k = "002" |
| f = FooType{BarType{BazType{"BazBarFoo", TitleOrValueTypeValue{42}}}} |
| fooEntries = append(fooEntries, kv{k, vdl.ValueOf(f)}) |
| if err := fooTable.Put(ctx, k, f); err != nil { |
| t.Fatalf("fooTable.Put() failed: %v", err) |
| } |
| |
| k = "aaa" |
| kid := KeyIndexData{ |
| [4]string{"Fee", "Fi", "Fo", "Fum"}, |
| []string{"I", "smell", "the", "blood", "of", "an", "Englishman"}, |
| map[complex128]string{complex(1.1, 2.2): "Be he living, or be he dead"}, |
| map[string]struct{}{"I’ll grind his bones to mix my bread": {}}, |
| } |
| keyIndexDataEntries = append(keyIndexDataEntries, kv{k, vdl.ValueOf(kid)}) |
| if err := keyIndexDataTable.Put(ctx, k, kid); err != nil { |
| t.Fatalf("keyIndexDataTable.Put() failed: %v", err) |
| } |
| |
| for i := 100; i < 301; i++ { |
| k = fmt.Sprintf("%d", i) |
| b := BigData{k} |
| if err := bigTable.Put(ctx, k, b); err != nil { |
| t.Fatalf("bigTable.Put() failed: %v", err) |
| } |
| } |
| } |
| |
| type execSelectTest struct { |
| query string |
| headers []string |
| r [][]*vdl.Value |
| } |
| |
| type preExecFunctionTest struct { |
| query string |
| headers []string |
| } |
| |
| type execSelectErrorTest struct { |
| query string |
| err error |
| } |
| |
| func TestQueryExec(t *testing.T) { |
| setup(t) |
| defer cleanup() |
| basic := []execSelectTest{ |
| { |
| // Select values for all customer records. |
| "select v from Customer where Type(v) like \"%.Customer\"", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select values where v.InvoiceNum is nil |
| // Since InvoiceNum does not exist for Invoice, |
| // this will return just customers. |
| "select v from Customer where v.InvoiceNum is nil", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select values where v.InvoiceNum is nil |
| // or v.Name is nil This will select all customers |
| // with the former and all invoices with the latter. |
| // Hence, all records are returned. |
| "select v from Customer where v.InvoiceNum is nil or v.Name is nil", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| []*vdl.Value{customerEntries[1].value}, |
| []*vdl.Value{customerEntries[2].value}, |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| []*vdl.Value{customerEntries[6].value}, |
| []*vdl.Value{customerEntries[7].value}, |
| []*vdl.Value{customerEntries[8].value}, |
| []*vdl.Value{customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select values where v.InvoiceNum is nil |
| // and v.Name is nil. Expect nothing returned. |
| "select v from Customer where v.InvoiceNum is nil and v.Name is nil", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Select values where v.InvoiceNum is not nil |
| // This will return just invoices. |
| "select v from Customer where v.InvoiceNum is not nil", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[1].value}, |
| []*vdl.Value{customerEntries[2].value}, |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| []*vdl.Value{customerEntries[6].value}, |
| []*vdl.Value{customerEntries[7].value}, |
| []*vdl.Value{customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Select values where v.InvoiceNum is not nil |
| // or v.Name is not nil. All records are returned. |
| "select v from Customer where v.InvoiceNum is not nil or v.Name is not nil", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| []*vdl.Value{customerEntries[1].value}, |
| []*vdl.Value{customerEntries[2].value}, |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| []*vdl.Value{customerEntries[6].value}, |
| []*vdl.Value{customerEntries[7].value}, |
| []*vdl.Value{customerEntries[8].value}, |
| []*vdl.Value{customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select values where v.InvoiceNum is nil and v.Name is not nil. |
| // All customers are returned. |
| "select v from Customer where v.InvoiceNum is nil and v.Name is not nil", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select values where v.InvoiceNum is not nil |
| // and v.Name is not nil. Expect nothing returned. |
| "select v from Customer where v.InvoiceNum is not nil and v.Name is not nil", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Select keys & values for all customer records. |
| "select k, v from Customer where Type(v) like \"%.Customer\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), customerEntries[4].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[9].key), customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select keys & names for all customer records. |
| "select k, v.Name from Customer where Type(v) like \"%.Customer\"", |
| []string{"k", "v.Name"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), vdl.ValueOf("John Smith")}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), vdl.ValueOf("Bat Masterson")}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[9].key), vdl.ValueOf("John Steed")}, |
| }, |
| }, |
| { |
| // Select both customer and invoice records. |
| // Customer records have Id. |
| // Invoice records have CustId. |
| "select v.Id, v.CustId from Customer", |
| []string{"v.Id", "v.CustId"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(int64(1)), vdl.ValueOf(nil)}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(1))}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(1))}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(1))}, |
| []*vdl.Value{vdl.ValueOf(int64(2)), vdl.ValueOf(nil)}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(2))}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(2))}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(2))}, |
| []*vdl.Value{vdl.ValueOf(nil), vdl.ValueOf(int64(2))}, |
| []*vdl.Value{vdl.ValueOf(int64(3)), vdl.ValueOf(nil)}, |
| }, |
| }, |
| { |
| // Select keys & values fo all invoice records. |
| "select k, v from Customer where Type(v) like \"%.Invoice\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Select key, cust id, invoice number and amount for $88 invoices. |
| "select k, v.CustId as ID, v.InvoiceNum as InvoiceNumber, v.Amount as Amt from Customer where Type(v) like \"%.Invoice\" and v.Amount = 88", |
| []string{"k", "ID", "InvoiceNumber", "Amt"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), vdl.ValueOf(int64(1)), vdl.ValueOf(int64(1005)), vdl.ValueOf(int64(88))}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), vdl.ValueOf(int64(2)), vdl.ValueOf(int64(1006)), vdl.ValueOf(int64(88))}, |
| }, |
| }, |
| { |
| // Select keys & values for all records with a key prefix of "001". |
| "select k, v from Customer where k like \"001%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| }, |
| }, |
| { |
| // Select keys & values for all records with a key prefix of "002". |
| "select k, v from Customer where k like \"002%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), customerEntries[4].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Select keys & values for all records with NOT key prefix "002%". |
| "select k, v from Customer where k not like \"002%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[9].key), customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select keys & values for all records with NOT key prefix "002". |
| // Will be optimized to k <> "002" |
| "select k, v from Customer where k not like \"002\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[9].key), customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select keys & values for all records with a key prefix of "001". |
| // or a key prefix of "002". |
| "select k, v from Customer where k like \"001%\" or k like \"002%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), customerEntries[4].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Select keys & values for all records with a key prefix of "001". |
| // or a key prefix of "002". |
| "select k, v from Customer where k like \"002%\" or k like \"001%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), customerEntries[4].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Let's play with whitespace and mixed case. |
| " sElEcT k, v from \n Customer WhErE k lIkE \"002%\" oR k LiKe \"001%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), customerEntries[4].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Add in a like clause that accepts all strings. |
| " sElEcT k, v from \n Customer WhErE k lIkE \"002%\" oR k LiKe \"001%\" or k lIkE \"%\"", |
| []string{"k", "v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[0].key), customerEntries[0].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key), customerEntries[1].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key), customerEntries[2].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key), customerEntries[3].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[4].key), customerEntries[4].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key), customerEntries[5].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key), customerEntries[6].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key), customerEntries[7].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key), customerEntries[8].value}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[9].key), customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select id, name for customers whose last name is Masterson. |
| "select v.Id as ID, v.Name as Name from Customer where Type(v) like \"%.Customer\" and v.Name like \"%Masterson\"", |
| []string{"ID", "Name"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(int64(2)), vdl.ValueOf("Bat Masterson")}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City is "Collins" or type is Invoice. |
| "select v from Customer where v.Address.City = \"Collins\" or Type(v) like \"%.Invoice\"", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[1].value}, |
| []*vdl.Value{customerEntries[2].value}, |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| []*vdl.Value{customerEntries[6].value}, |
| []*vdl.Value{customerEntries[7].value}, |
| []*vdl.Value{customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City is "Collins" and v.InvoiceNum is not nil. |
| "select v from Customer where v.Address.City = \"Collins\" and v.InvoiceNum is not nil", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Select records where v.Address.City is "Collins" and v.InvoiceNum is nil. |
| "select v from Customer where v.Address.City = \"Collins\" and v.InvoiceNum is nil", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[4].value}, |
| }, |
| }, |
| { |
| // Select customer name for customer Id (i.e., key) "001". |
| "select v.Name as Name from Customer where Type(v) like \"%.Customer\" and k = \"001\"", |
| []string{"Name"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("John Smith")}, |
| }, |
| }, |
| { |
| // Select v where v.Credit.Report.EquifaxReport.Rating = 'A' |
| "select v from Customer where v.Credit.Report.EquifaxReport.Rating = 'A'", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| }, |
| }, |
| { |
| // Select v where v.AgencyRating = "Bad" |
| "select v from Customer where v.Credit.Report.EquifaxReport.Rating < 'A' or v.Credit.Report.ExperianReport.Rating = \"Bad\" or v.Credit.Report.TransUnionReport.Rating < 90", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[4].value}, |
| }, |
| }, |
| { |
| // Select records where v.Bar.Baz.Name = "FooBarBaz" |
| "select v from Foo where v.Bar.Baz.Name = \"FooBarBaz\"", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{fooEntries[0].value}, |
| }, |
| }, |
| { |
| // Select records where v.Bar.Baz.TitleOrValue.Value = 42 |
| "select v from Foo where v.Bar.Baz.TitleOrValue.Value = 42", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{fooEntries[1].value}, |
| }, |
| }, |
| { |
| // Select records where v.Bar.Baz.TitleOrValue.Title = "Vice President" |
| "select v from Foo where v.Bar.Baz.TitleOrValue.Title = \"Vice President\"", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{fooEntries[0].value}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" or type is Invoice. |
| // Limit 3 |
| "select v from Customer where v.Address.City = \"Collins\" or Type(v) like \"%.Invoice\" limit 3", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[1].value}, |
| []*vdl.Value{customerEntries[2].value}, |
| []*vdl.Value{customerEntries[3].value}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" or type is Invoice. |
| // Offset 5 |
| "select v from Customer where v.Address.City = \"Collins\" or Type(v) like \"%.Invoice\" offset 5", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[6].value}, |
| []*vdl.Value{customerEntries[7].value}, |
| []*vdl.Value{customerEntries[8].value}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" is "Mountain View". |
| "select v from Customer where v.Address.City = \"Mountain View\"", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" or type is Invoice. |
| // Offset 8 |
| "select v from Customer where v.Address.City = \"Collins\" or Type(v) like \"%.Invoice\" offset 8", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" or type is Invoice. |
| // Offset 23 |
| "select v from Customer where v.Address.City = \"Collins\" or Type(v) like \"%.Invoice\" offset 23", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" is 84 or type is Invoice. |
| // Limit 3 Offset 2 |
| "select v from Customer where v.Address.City = \"Collins\" or Type(v) like \"%.Invoice\" limit 3 offset 2", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" or (type is Invoice and v.InvoiceNum is not nil). |
| // Limit 3 Offset 2 |
| "select v from Customer where v.Address.City = \"Collins\" or (Type(v) like \"%.Invoice\" and v.InvoiceNum is not nil) limit 3 offset 2", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| }, |
| }, |
| { |
| // Select records where v.Address.City = "Collins" or (type is Invoice and v.InvoiceNum is nil). |
| // Limit 3 Offset 2 |
| "select v from Customer where v.Address.City = \"Collins\" or (Type(v) like \"%.Invoice\" and v.InvoiceNum is nil) limit 3 offset 2", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| // Test functions. |
| { |
| // Select invoice records where date is 2015-03-17 |
| "select v from Customer where Type(v) like \"%.Invoice\" and YMD(v.InvoiceDate, \"America/Los_Angeles\") = Date(\"2015-03-17 PDT\")", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[5].value}, |
| []*vdl.Value{customerEntries[6].value}, |
| }, |
| }, |
| { |
| // Now will always be > 2012, so all customer records will be returned. |
| "select v from Customer where Now() > Date(\"2012-03-17 PDT\")", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{customerEntries[0].value}, |
| []*vdl.Value{customerEntries[1].value}, |
| []*vdl.Value{customerEntries[2].value}, |
| []*vdl.Value{customerEntries[3].value}, |
| []*vdl.Value{customerEntries[4].value}, |
| []*vdl.Value{customerEntries[5].value}, |
| []*vdl.Value{customerEntries[6].value}, |
| []*vdl.Value{customerEntries[7].value}, |
| []*vdl.Value{customerEntries[8].value}, |
| []*vdl.Value{customerEntries[9].value}, |
| }, |
| }, |
| { |
| // Select April 2015 PT invoices. |
| // Note: this wouldn't work for March as daylight saving occurs March 8 |
| // and causes comparisons for those days to be off 1 hour. |
| // It would work to use UTC -- see next test. |
| "select k from Customer where YM(v.InvoiceDate, \"America/Los_Angeles\") = YM(Date(\"2015-04-01 PDT\"), \"America/Los_Angeles\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key)}, |
| }, |
| }, |
| { |
| // Select March 2015 UTC invoices. |
| "select k from Customer where YM(v.InvoiceDate, \"UTC\") = YM(Date(\"2015-03-01 UTC\"), \"UTC\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key)}, |
| }, |
| }, |
| { |
| // Select 2015 UTC invoices. |
| "select k from Customer where Y(v.InvoiceDate, \"UTC\") = Y(Date(\"2015-01-01 UTC\"), \"UTC\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[1].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[2].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[3].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key)}, |
| }, |
| }, |
| { |
| // Select the Mar 17 2015 11:14:04 America/Los_Angeles invoice. |
| "select k from Customer where v.InvoiceDate = DateTime(\"2015-03-17 11:14:04 PDT\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| }, |
| }, |
| { |
| // Select invoices in the minute Mar 17 2015 11:14 America/Los_Angeles invoice. |
| "select k from Customer where YMDHM(v.InvoiceDate, \"America/Los_Angeles\") = YMDHM(DateTime(\"2015-03-17 11:14:00 PDT\"), \"America/Los_Angeles\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| }, |
| }, |
| { |
| // Select invoices in the hour Mar 17 2015 11 hundred America/Los_Angeles invoice. |
| "select k from Customer where YMDH(v.InvoiceDate, \"America/Los_Angeles\") = YMDH(DateTime(\"2015-03-17 11:00:00 PDT\"), \"America/Los_Angeles\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| }, |
| }, |
| { |
| // Select invoices on the day Mar 17 2015 America/Los_Angeles invoice. |
| "select k from Customer where YMD(v.InvoiceDate, \"America/Los_Angeles\") = YMD(Date(\"2015-03-17 PDT\"), \"America/Los_Angeles\")", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key)}, |
| }, |
| }, |
| // Test string functions in where clause. |
| { |
| // Select invoices shipped to Any street -- using LowerCase. |
| "select k from Customer where Type(v) like \"%.Invoice\" and LowerCase(v.ShipTo.Street) like \"%any%\"", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key)}, |
| }, |
| }, |
| { |
| // Select invoices shipped to Any street -- using UpperCase. |
| "select k from Customer where Type(v) like \"%.Invoice\" and UpperCase(v.ShipTo.Street) like \"%ANY%\"", |
| []string{"k"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(customerEntries[5].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[6].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[7].key)}, |
| []*vdl.Value{vdl.ValueOf(customerEntries[8].key)}, |
| }, |
| }, |
| // Select clause functions. |
| // Date function |
| { |
| "select Date(\"2015-07-01 PDT\") from Customer", |
| []string{"Date"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01)}, |
| }, |
| }, |
| // DateTime function |
| { |
| "select DateTime(\"2015-07-01 01:23:45 PDT\") from Customer", |
| []string{"DateTime"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| []*vdl.Value{vdl.ValueOf(t2015_07_01_01_23_45)}, |
| }, |
| }, |
| // LowerCase function |
| { |
| "select LowerCase(v.Name) as name from Customer where Type(v) like \"%.Customer\"", |
| []string{"name"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("john smith")}, |
| []*vdl.Value{vdl.ValueOf("bat masterson")}, |
| []*vdl.Value{vdl.ValueOf("john steed")}, |
| }, |
| }, |
| // UpperCase function |
| { |
| "select UpperCase(v.Name) as NAME from Customer where Type(v) like \"%.Customer\"", |
| []string{"NAME"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("JOHN SMITH")}, |
| []*vdl.Value{vdl.ValueOf("BAT MASTERSON")}, |
| []*vdl.Value{vdl.ValueOf("JOHN STEED")}, |
| }, |
| }, |
| // YMDHMS function |
| { |
| "select k, YMDHMS(v.InvoiceDate, \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"002003\"", |
| []string{ |
| "k", |
| "YMDHMS", |
| }, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("002003"), vdl.ValueOf(t2015_04_12_22_16_06)}, |
| }, |
| }, |
| // YMDHM function |
| { |
| "select k, YMDHM(v.InvoiceDate, \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"002003\"", |
| []string{ |
| "k", |
| "YMDHM", |
| }, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("002003"), vdl.ValueOf(t2015_04_12_22_16)}, |
| }, |
| }, |
| // YMDH function |
| { |
| "select k, YMDH(v.InvoiceDate, \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"002003\"", |
| []string{ |
| "k", |
| "YMDH", |
| }, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("002003"), vdl.ValueOf(t2015_04_12_22)}, |
| }, |
| }, |
| // YMD function |
| { |
| "select k, YMD(v.InvoiceDate, \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"002003\"", |
| []string{ |
| "k", |
| "YMD", |
| }, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("002003"), vdl.ValueOf(t2015_04_12)}, |
| }, |
| }, |
| // YM function |
| { |
| "select k, YM(v.InvoiceDate, \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"002003\"", |
| []string{ |
| "k", |
| "YM", |
| }, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("002003"), vdl.ValueOf(t2015_04)}, |
| }, |
| }, |
| // Y function |
| { |
| "select k, Y(v.InvoiceDate, \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"001001\"", |
| []string{ |
| "k", |
| "Y", |
| }, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf("001001"), vdl.ValueOf(t2015)}, |
| }, |
| }, |
| // Nested functions |
| { |
| "select Y(YM(YMD(YMDH(YMDHM(YMDHMS(v.InvoiceDate, \"America/Los_Angeles\"), \"America/Los_Angeles\"), \"America/Los_Angeles\"), \"America/Los_Angeles\"), \"America/Los_Angeles\"), \"America/Los_Angeles\") from Customer where Type(v) like \"%.Invoice\" and k = \"001001\"", |
| []string{"Y"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{vdl.ValueOf(t2015)}, |
| }, |
| }, |
| // Bad arg to function. Expression is false. |
| { |
| "select v from Customer where Type(v) like \"%.Invoice\" and YMD(v.InvoiceDate, v.Foo) = v.InvoiceDate", |
| []string{"v"}, |
| [][]*vdl.Value{}, |
| }, |
| { |
| // Test that all numeric types can compare to an uint64 |
| "select v from Numbers where v.Ui64 = v.B and v.Ui64 = v.Ui16 and v.Ui64 = v.Ui32 and v.Ui64 = v.F64 and v.Ui64 = v.I16 and v.Ui64 = v.I32 and v.Ui64 = v.I64 and v.Ui64 = v.F32 and v.Ui64 = v.C64 and v.Ui64 = v.C128", |
| []string{"v"}, |
| [][]*vdl.Value{ |
| []*vdl.Value{numbersEntries[2].value}, |
| }, |
| }, |
| { |
| // array, list, map, set |
| "select v.A[2], v.L[6], v.M[Complex(1.1, 2.2)], v.S[\"I’ll grind his bones to mix my bread\"] from KeyIndexData", |
| []string{"v.A[2]", "v.L[6]", "v.M[Complex]", "v.S[I’ll grind his bones to mix my bread]"}, |
| [][]*vdl.Value{[]*vdl.Value{ |
| vdl.ValueOf("Fo"), |
| vdl.ValueOf("Englishman"), |
| vdl.ValueOf("Be he living, or be he dead"), |
| vdl.ValueOf(true), |
| }}, |
| }, |
| { |
| "select k, v.Key from BigTable where k < \"101\" or k = \"200\" or k like \"300%\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{svPair("100"), svPair("200"), svPair("300")}, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"10_\" or k like \"20_\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("100"), |
| svPair("101"), |
| svPair("102"), |
| svPair("103"), |
| svPair("104"), |
| svPair("105"), |
| svPair("106"), |
| svPair("107"), |
| svPair("108"), |
| svPair("109"), |
| svPair("200"), |
| svPair("201"), |
| svPair("202"), |
| svPair("203"), |
| svPair("204"), |
| svPair("205"), |
| svPair("206"), |
| svPair("207"), |
| svPair("208"), |
| svPair("209"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"_%9\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("109"), |
| svPair("119"), |
| svPair("129"), |
| svPair("139"), |
| svPair("149"), |
| svPair("159"), |
| svPair("169"), |
| svPair("179"), |
| svPair("189"), |
| svPair("199"), |
| svPair("209"), |
| svPair("219"), |
| svPair("229"), |
| svPair("239"), |
| svPair("249"), |
| svPair("259"), |
| svPair("269"), |
| svPair("279"), |
| svPair("289"), |
| svPair("299"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"__0\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("100"), |
| svPair("110"), |
| svPair("120"), |
| svPair("130"), |
| svPair("140"), |
| svPair("150"), |
| svPair("160"), |
| svPair("170"), |
| svPair("180"), |
| svPair("190"), |
| svPair("200"), |
| svPair("210"), |
| svPair("220"), |
| svPair("230"), |
| svPair("240"), |
| svPair("250"), |
| svPair("260"), |
| svPair("270"), |
| svPair("280"), |
| svPair("290"), |
| svPair("300"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"10%\" or k like \"20%\" or k like \"30%\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("100"), |
| svPair("101"), |
| svPair("102"), |
| svPair("103"), |
| svPair("104"), |
| svPair("105"), |
| svPair("106"), |
| svPair("107"), |
| svPair("108"), |
| svPair("109"), |
| svPair("200"), |
| svPair("201"), |
| svPair("202"), |
| svPair("203"), |
| svPair("204"), |
| svPair("205"), |
| svPair("206"), |
| svPair("207"), |
| svPair("208"), |
| svPair("209"), |
| svPair("300"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"1__\" and k like \"_2_\" and k like \"__3\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{svPair("123")}, |
| }, |
| { |
| "select k, v.Key from BigTable where (k > \"100\" and k < \"103\") or (k > \"205\" and k < \"208\")", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("101"), |
| svPair("102"), |
| svPair("206"), |
| svPair("207"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k <= \"100\" or k = \"101\" or k >= \"300\" or (k <> \"299\" and k not like \"300\" and k >= \"298\")", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("100"), |
| svPair("101"), |
| svPair("298"), |
| svPair("300"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"1%\" and k like \"%9\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{ |
| svPair("109"), |
| svPair("119"), |
| svPair("129"), |
| svPair("139"), |
| svPair("149"), |
| svPair("159"), |
| svPair("169"), |
| svPair("179"), |
| svPair("189"), |
| svPair("199"), |
| }, |
| }, |
| { |
| "select k, v.Key from BigTable where k like \"3%\" and k like \"30%\" and k like \"300%\"", |
| []string{"k", "v.Key"}, |
| [][]*vdl.Value{svPair("300")}, |
| }, |
| } |
| |
| for _, test := range basic { |
| headers, rs, err := db.Exec(ctx, test.query) |
| if err != nil { |
| t.Errorf("query: %s; got %v, want nil", test.query, err) |
| } else { |
| // Collect results. |
| r := [][]*vdl.Value{} |
| for rs.Advance() { |
| r = append(r, rs.Result()) |
| } |
| if !reflect.DeepEqual(test.r, r) { |
| t.Errorf("query: %s; got %v, want %v", test.query, r, test.r) |
| } |
| if !reflect.DeepEqual(test.headers, headers) { |
| t.Errorf("query: %s; got %v, want %v", test.query, headers, test.headers) |
| } |
| } |
| } |
| } |
| |
| func svPair(s string) []*vdl.Value { |
| v := vdl.ValueOf(s) |
| return []*vdl.Value{v, v} |
| } |
| |
| // Use Now to verify it is "pre" executed such that all the rows |
| // have the same time. |
| func TestPreExecFunctions(t *testing.T) { |
| setup(t) |
| defer cleanup() |
| basic := []preExecFunctionTest{ |
| { |
| "select Now() from Customer", |
| []string{ |
| "Now", |
| }, |
| }, |
| } |
| |
| for _, test := range basic { |
| headers, rs, err := db.Exec(ctx, test.query) |
| if err != nil { |
| t.Errorf("query: %s; got %v, want nil", test.query, err) |
| } else { |
| // Check that all results are identical. |
| // Collect results. |
| var last []*vdl.Value |
| for rs.Advance() { |
| result := rs.Result() |
| if last != nil && !reflect.DeepEqual(last, result) { |
| t.Errorf("query: %s; got %v, want %v", test.query, result, last) |
| } |
| last = result |
| } |
| if !reflect.DeepEqual(test.headers, headers) { |
| t.Errorf("query: %s; got %v, want %v", test.query, headers, test.headers) |
| } |
| } |
| } |
| } |
| |
| // TODO(jkline): More negative tests here (even though they are tested elsewhere)? |
| func TestExecErrors(t *testing.T) { |
| setup(t) |
| defer cleanup() |
| basic := []execSelectErrorTest{ |
| { |
| "select a from Customer", |
| syncql.NewErrInvalidSelectField(ctx, 7), |
| }, |
| { |
| "select v from Unknown", |
| // The following error text is dependent on the implementation of the query_db.Database interface. |
| syncql.NewErrTableCantAccess(ctx, 14, "Unknown", errors.New("exec_test.test:\"a/db\".Exec: Does not exist: $table:Unknown")), |
| }, |
| { |
| "select v from Customer offset -1", |
| // The following error text is dependent on implementation of Database. |
| syncql.NewErrExpected(ctx, 30, "positive integer literal"), |
| }, |
| } |
| |
| for _, test := range basic { |
| _, rs, err := db.Exec(ctx, test.query) |
| if err == nil { |
| err = rs.Err() |
| } |
| // Test both that the IDs compare and the text compares (since the offset needs to match). |
| // Note: This is a little tricky because the actual error message will contain the calling |
| // module. |
| wantPrefix := test.err.Error()[:strings.Index(test.err.Error(), ":")] |
| wantSuffix := test.err.Error()[len(wantPrefix)+1:] |
| if verror.ErrorID(err) != verror.ErrorID(test.err) || !strings.HasPrefix(err.Error(), wantPrefix) || !strings.HasSuffix(err.Error(), wantSuffix) { |
| t.Errorf("query: %s; got %v, want %v", test.query, err, test.err) |
| } |
| } |
| } |