示例#1
0
func newPrimaryIndex(b *bucket) (*primaryIndex, error) {
	ddoc := newPrimaryDDoc()
	meta := ast.NewFunctionCall("meta", ast.FunctionArgExpressionList{})
	mdid := ast.NewDotMemberOperator(meta, ast.NewProperty("id"))
	inst := primaryIndex{
		viewIndex{
			name:   PRIMARY_INDEX,
			using:  catalog.VIEW,
			on:     catalog.IndexKey{mdid},
			ddoc:   ddoc,
			bucket: b,
		},
	}

	err := inst.putDesignDoc()
	if err != nil {
		return nil, err
	}

	err = inst.WaitForIndex()
	if err != nil {
		return nil, err
	}

	return &inst, nil
}
示例#2
0
func TestUnnest(t *testing.T) {

	stubSource := NewStubSource(joinerTestData)

	joiner := NewUnnest(ast.NewProperty("children"), "INNER", "child")
	joiner.SetSource(stubSource)

	joinerItemChannel, _ := joiner.GetChannels()

	stopChannel := make(misc.StopChannel)
	go joiner.Run(stopChannel)

	count := 0
	for item := range joinerItemChannel {
		count++
		_, err := item.Path("name")
		if err != nil {
			t.Errorf("Expected to find field name")
		}
		_, err = item.Path("child")
		if err != nil {
			t.Errorf("Expected to find field child")
		}
	}

	if count != 4 {
		t.Errorf("Expected %d items, got %d", 4, count)
	}

}
示例#3
0
func TestOrderDescending(t *testing.T) {

	stubSource := NewStubSource(testData)

	order := NewOrder([]*ast.SortExpression{ast.NewSortExpression(ast.NewProperty("age"), false)}, []string{})
	order.SetSource(stubSource)

	orderItemChannel, _ := order.GetChannels()

	stopChannel := make(misc.StopChannel)
	go order.Run(stopChannel)

	count := 0
	for item := range orderItemChannel {

		val, err := item.Path("name")
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}
		value := val.Value()
		if count == 0 && value != "steve" {
			t.Errorf("expected steve, got %v", value)
		}
		if count == len(testData)-1 && value != "dustin" {
			t.Errorf("expected dustin, got %v", value)
		}
		count++
	}
}
示例#4
0
func TestProject(t *testing.T) {

	stubSource := NewStubSource(testData)

	project := NewProject(ast.ResultExpressionList{ast.NewResultExpressionWithAlias(ast.NewProperty("name"), "f_name")}, true)
	project.SetSource(stubSource)

	projectItemChannel, _ := project.GetChannels()

	stopChannel := make(misc.StopChannel)
	go project.Run(stopChannel)

	for item := range projectItemChannel {

		projection := item.GetAttachment("projection")
		projectionValue, ok := projection.(*dparval.Value)
		if !ok {
			t.Errorf("Expected item projection to be type Value")
		}
		_, err := projectionValue.Path("f_name")
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}
	}
}
示例#5
0
func newAllDocsIndex(b *bucket) *primaryIndex {
	meta := ast.NewFunctionCall("meta", ast.FunctionArgExpressionList{})
	mdid := ast.NewDotMemberOperator(meta, ast.NewProperty("id"))
	ddoc := designdoc{name: "", viewname: "_all_docs"}
	idx := primaryIndex{
		viewIndex{
			name:   ALLDOCS_INDEX,
			using:  catalog.VIEW,
			on:     catalog.IndexKey{mdid},
			ddoc:   &ddoc,
			bucket: b,
		},
	}
	return &idx
}
示例#6
0
func TestFilterSome(t *testing.T) {

	stubSource := NewStubSource(testData)

	filter := NewFilter(ast.NewGreaterThanOperator(ast.NewProperty("name"), ast.NewLiteralString("n")))
	filter.SetSource(stubSource)

	filterItemChannel, _ := filter.GetChannels()

	stopChannel := make(misc.StopChannel)
	go filter.Run(stopChannel)

	count := 0
	for _ = range filterItemChannel {
		count++
	}

	if count != 2 {
		t.Errorf("Expected %d items, got %d", 2, count)
	}

}
示例#7
0
func loadViewIndexes(b *bucket) ([]*catalog.Index, error) {

	rows, err := b.cbbucket.GetDDocs()
	if err != nil {
		return nil, err
	}

	inames := make([]string, 0, len(rows.Rows))
	for _, row := range rows.Rows {
		cdoc := row.DDoc
		id := cdoc.Meta["id"].(string)
		if !strings.HasPrefix(id, "_design/ddl_") {
			continue
		}
		iname := strings.TrimPrefix(id, "_design/ddl_")
		inames = append(inames, iname)
	}

	indexes := make([]*catalog.Index, 0, len(inames))
	for _, iname := range inames {
		ddname := "ddl_" + iname
		jdoc, err := getDesignDoc(b, ddname)
		if err != nil {
			return nil, err
		}
		jview, ok := jdoc.Views[iname]
		if !ok {
			return nil, errors.New("Missing view for index " + iname)
		}

		exprlist := make([]ast.Expression, 0, len(jdoc.IndexOn))

		for _, ser := range jdoc.IndexOn {
			// HACK - remove this when Unmarshall supports META()
			if iname == PRIMARY_INDEX {
				meta := ast.NewFunctionCall("meta", ast.FunctionArgExpressionList{})
				mdid := ast.NewDotMemberOperator(meta, ast.NewProperty("id"))
				exprlist = append(exprlist, mdid)
			} else {
				expr, err := ast.UnmarshalExpression([]byte(ser))
				if err != nil {
					return nil, errors.New("Cannot unmarshal expression for index " + iname)
				}
				exprlist = append(exprlist, expr)
			}
		}
		if len(exprlist) != len(jdoc.IndexOn) {
			continue
		}

		ddoc := designdoc{
			name:     ddname,
			viewname: iname,
			mapfn:    jview.Map,
			reducefn: jview.Reduce,
		}
		if ddoc.checksum() != jdoc.IndexChecksum {
			return nil, errors.New("Warning - checksum failed on index " + iname)
		}

		var index catalog.Index

		if iname == PRIMARY_INDEX {
			index = &primaryIndex{
				viewIndex{
					name:   iname,
					bucket: b,
					using:  catalog.VIEW,
					ddoc:   &ddoc,
					on:     exprlist,
				},
			}
			indexes = append(indexes, &index)
		} else {
			index = &viewIndex{
				name:   iname,
				bucket: b,
				using:  catalog.VIEW,
				ddoc:   &ddoc,
				on:     exprlist,
			}
			indexes = append(indexes, &index)
		}
	}

	return indexes, nil
}
示例#8
0
func TestParserASTOutput(t *testing.T) {

	tests := []struct {
		input  string
		output ast.Statement
	}{
		{"SELECT * FROM test WHERE true",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewStarResultExpression(),
				},
				Distinct: false,
				From:     &ast.From{Projection: ast.NewProperty("test")},
				Where:    ast.NewLiteralBool(true),
				Limit:    -1,
			},
		},
		{"SELECT * FROM :apool.test WHERE true",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewStarResultExpression(),
				},
				Distinct: false,
				From:     &ast.From{Pool: "apool", Projection: ast.NewProperty("test")},
				Where:    ast.NewLiteralBool(true),
				Limit:    -1,
			},
		},
		{"SELECT * FROM test ORDER BY foo",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewStarResultExpression(),
				},
				Distinct: false,
				From:     &ast.From{Projection: ast.NewProperty("test")},
				Where:    nil,
				OrderBy: []*ast.SortExpression{
					ast.NewSortExpression(ast.NewProperty("foo"), true),
				},
				Limit: -1,
			},
		},
		{"SELECT * FROM test LIMIT 10 OFFSET 3",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewStarResultExpression(),
				},
				Distinct: false,
				From:     &ast.From{Projection: ast.NewProperty("test")},
				Where:    nil,
				Limit:    10,
				Offset:   3,
			},
		},
		{"SELECT a FROM test",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewResultExpression(ast.NewProperty("a")),
				},
				Distinct: false,
				From:     &ast.From{Projection: ast.NewProperty("test")},
				Where:    nil,
				Limit:    -1,
			},
		},
		{"SELECT a FROM test t2",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewResultExpression(ast.NewProperty("a")),
				},
				Distinct: false,
				From:     &ast.From{Projection: ast.NewProperty("test"), As: "t2"},
				Where:    nil,
				Limit:    -1,
			},
		},
		{"SELECT 1+1*30 as steve",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"),
				},
				Distinct: false,
				From:     nil,
				Where:    nil,
				Limit:    -1,
			},
		},
		{"SELECT 1+1*30 steve",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"),
				},
				Distinct: false,
				From:     nil,
				Where:    nil,
				Limit:    -1,
			},
		},
		{"SELECT DISTINCT 1+1*30 as steve",
			&ast.SelectStatement{
				Select: ast.ResultExpressionList{
					ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"),
				},
				Distinct: true,
				From:     nil,
				Where:    nil,
				Limit:    -1,
			},
		},
		{"CREATE INDEX abv_idx ON beer-sample(abv) USING VIEW",
			&ast.CreateIndexStatement{
				Method: "view",
				Bucket: "beer-sample",
				Name:   "abv_idx",
				On:     ast.ExpressionList{ast.NewProperty("abv")},
			},
		},
		{"CREATE INDEX abv_idx ON beer-sample(abv) USING magic",
			&ast.CreateIndexStatement{
				Method: "magic",
				Bucket: "beer-sample",
				Name:   "abv_idx",
				On:     ast.ExpressionList{ast.NewProperty("abv")},
			},
		},
		{"CREATE INDEX abv_idx ON beer-sample(abv)",
			&ast.CreateIndexStatement{
				Method: "",
				Bucket: "beer-sample",
				Name:   "abv_idx",
				On:     ast.ExpressionList{ast.NewProperty("abv")},
			},
		},
		{"CREATE INDEX abv_idx ON :apool.beer-sample(abv) USING VIEW",
			&ast.CreateIndexStatement{
				Method: "view",
				Pool:   "apool",
				Bucket: "beer-sample",
				Name:   "abv_idx",
				On:     ast.ExpressionList{ast.NewProperty("abv")},
			},
		},
		{"CREATE INDEX abv_idx ON :apool.beer-sample(abv) USING magic",
			&ast.CreateIndexStatement{
				Method: "magic",
				Pool:   "apool",
				Bucket: "beer-sample",
				Name:   "abv_idx",
				On:     ast.ExpressionList{ast.NewProperty("abv")},
			},
		},
		{"CREATE INDEX abv_idx ON :apool.beer-sample(abv)",
			&ast.CreateIndexStatement{
				Method: "",
				Pool:   "apool",
				Bucket: "beer-sample",
				Name:   "abv_idx",
				On:     ast.ExpressionList{ast.NewProperty("abv")},
			},
		},
		{"DROP INDEX beer-sample.abv",
			&ast.DropIndexStatement{
				Bucket: "beer-sample",
				Name:   "abv",
			},
		},
		{"DROP INDEX :apool.beer-sample.abv",
			&ast.DropIndexStatement{
				Pool:   "apool",
				Bucket: "beer-sample",
				Name:   "abv",
			},
		},
	}

	n1qlParser := NewN1qlParser()

	for _, v := range tests {
		query, err := n1qlParser.Parse(v.input)
		if err != nil {
			t.Errorf("Valid Query Parse Failed: %v - %v", v, err)
		}

		if !reflect.DeepEqual(query, v.output) {
			t.Errorf("Expected %v, got %v", v.output, query)

			js, err := json.MarshalIndent(v.output, "", "  ")
			if err == nil {
				t.Logf("Expected %v", string(js))
			}

			js, err = json.MarshalIndent(query, "", "  ")
			if err == nil {
				t.Logf("Got %v", string(js))
			}

		}
	}

}