Skip to content

Commit

Permalink
colexec: add JSONFetchVal operator for vectorized engine
Browse files Browse the repository at this point in the history
Previously, the vectorized engine had no support for JSONFetchVal
operator. This commit added JSONFetchVal operator.
In this commit, I added BytesFamily into compatible canonical type
family group of DatumVecCanonicalTypeFamily. Then I declared
JSONFetchVal as supported binary operator and registered output
type of JSONFetchVal to generate operators.

Release note (sql change): Vectorized engine now support JSONFetchVal(->) operator.
  • Loading branch information
yongyanglai committed Jun 4, 2020
1 parent a18b32f commit 67d55a0
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 9 deletions.
25 changes: 21 additions & 4 deletions pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ var compatibleCanonicalTypeFamilies = map[types.Family][]types.Family{
typeconv.DatumVecCanonicalTypeFamily,
types.BoolFamily,
types.IntervalFamily,
types.BytesFamily,
}, numericCanonicalTypeFamilies...,
),
}
Expand Down Expand Up @@ -159,11 +160,18 @@ func registerBinOpOutputTypes() {
{types.BytesFamily, anyWidth, types.BytesFamily, anyWidth}: types.Bytes,
{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}: types.Any,
}

binOpOutputTypes[tree.JSONFetchVal] = map[typePair]*types.T{
{typeconv.DatumVecCanonicalTypeFamily, anyWidth, types.BytesFamily, anyWidth}: types.Any,
}
for _, intWidth := range supportedWidthsByCanonicalTypeFamily[types.IntFamily] {
binOpOutputTypes[tree.JSONFetchVal][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, types.IntFamily, intWidth}] = types.Any
}
}

func populateBinOpOverloads() {
registerBinOpOutputTypes()
for _, op := range []tree.BinaryOperator{tree.Plus, tree.Minus, tree.Mult, tree.Div, tree.Concat} {
for _, op := range []tree.BinaryOperator{tree.Plus, tree.Minus, tree.Mult, tree.Div, tree.Concat, tree.JSONFetchVal} {
ob := &overloadBase{
kind: binaryOverload,
Name: execgen.BinaryOpName[op],
Expand Down Expand Up @@ -623,7 +631,7 @@ func (c datumCustomizer) getBinOpAssignFunc() assignFunc {
// convertNativeToDatum returns a string that converts nativeElem to a
// tree.Datum that is stored in local variable named datumElemVarName.
func convertNativeToDatum(
canonicalTypeFamily types.Family, nativeElem, datumElemVarName string,
op tree.BinaryOperator, canonicalTypeFamily types.Family, nativeElem, datumElemVarName string,
) string {
var runtimeConversion string
switch canonicalTypeFamily {
Expand All @@ -639,6 +647,15 @@ func convertNativeToDatum(
runtimeConversion = fmt.Sprintf("tree.DDecimal{Decimal: %s}", nativeElem)
case types.IntervalFamily:
runtimeConversion = fmt.Sprintf("tree.DInterval{Duration: %s}", nativeElem)
case types.BytesFamily:
// TODO(yuzefovich): figure out a better way to perform type resolution
// for types that have the same physical representation.
switch op {
case tree.JSONFetchVal:
runtimeConversion = fmt.Sprintf("tree.DString(%s)", nativeElem)
default:
runtimeConversion = fmt.Sprintf("tree.DBytes(%s)", nativeElem)
}
default:
colexecerror.InternalError(fmt.Sprintf("unexpected canonical type family: %s", canonicalTypeFamily))
}
Expand All @@ -653,7 +670,7 @@ func (c datumNonDatumCustomizer) getBinOpAssignFunc() assignFunc {
return func(op *lastArgWidthOverload, targetElem, leftElem, rightElem, targetCol, leftCol, rightCol string) string {
const rightDatumElem = "_nonDatumArgAsDatum"
prelude := convertNativeToDatum(
op.lastArgTypeOverload.CanonicalTypeFamily, rightElem, rightDatumElem,
op.BinOp, op.lastArgTypeOverload.CanonicalTypeFamily, rightElem, rightDatumElem,
)
return executeBinOpOnDatums(
prelude, targetElem,
Expand All @@ -673,7 +690,7 @@ func (c nonDatumDatumCustomizer) getBinOpAssignFunc() assignFunc {
%s
%s := &coldataext.Datum{Datum: %s}
`,
convertNativeToDatum(c.leftCanonicalTypeFamily, leftElem, leftDatumElem),
convertNativeToDatum(op.BinOp, c.leftCanonicalTypeFamily, leftElem, leftDatumElem),
leftColdataExtDatum, leftDatumElem,
)
return executeBinOpOnDatums(
Expand Down
11 changes: 6 additions & 5 deletions pkg/sql/colexec/execgen/supported_bin_cmp_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import "github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
// BinaryOpName is a mapping from all binary operators that are supported by
// the vectorized engine to their names.
var BinaryOpName = map[tree.BinaryOperator]string{
tree.Plus: "Plus",
tree.Minus: "Minus",
tree.Mult: "Mult",
tree.Div: "Div",
tree.Concat: "Concat",
tree.Plus: "Plus",
tree.Minus: "Minus",
tree.Mult: "Mult",
tree.Div: "Div",
tree.Concat: "Concat",
tree.JSONFetchVal: "JSONFetchVal",
}

// ComparisonOpName is a mapping from all comparison operators that are
Expand Down
105 changes: 105 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/vectorize_overloads
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,111 @@ NULL
11
1111

statement ok
INSERT
INTO many_types
VALUES (
NULL,
NULL,
NULL,
NULL,
2,
2,
2,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'[1, "hello", {"a": ["foo", {"b": 3}]}]',
NULL,
NULL
)

query T
EXPLAIN (VEC) SELECT _json -> _int2 FROM many_types
----
└ Node 1
└ *colexec.projJSONFetchValDatumInt16Op
└ *colexec.colBatchScan

query T
SELECT _json -> _int2 FROM many_types
----
NULL
NULL
NULL
{"a": ["foo", {"b": 3}]}

query T
EXPLAIN (VEC) SELECT _json -> _int4 FROM many_types
----
└ Node 1
└ *colexec.projJSONFetchValDatumInt32Op
└ *colexec.colBatchScan

query T
SELECT _json -> _int4 FROM many_types
----
NULL
NULL
NULL
{"a": ["foo", {"b": 3}]}

query T
EXPLAIN (VEC) SELECT _json -> _int FROM many_types
----
└ Node 1
└ *colexec.projJSONFetchValDatumInt64Op
└ *colexec.colBatchScan

query T
SELECT _json -> _int FROM many_types
----
NULL
NULL
NULL
{"a": ["foo", {"b": 3}]}

query T
EXPLAIN (VEC) SELECT _json -> 2 FROM many_types
----
└ Node 1
└ *colexec.projJSONFetchValDatumInt64ConstOp
└ *colexec.colBatchScan

query T
SELECT _json -> 2 FROM many_types
----
NULL
{"a": ["foo", {"b": 3}]}
{"b": ["bar", {"c": 4}]}
{"a": ["foo", {"b": 3}]}

query T
EXPLAIN (VEC) SELECT _json -> 2 -> 'a' FROM many_types
----
└ Node 1
└ *colexec.projJSONFetchValDatumBytesConstOp
└ *colexec.projJSONFetchValDatumInt64ConstOp
└ *colexec.colBatchScan

query T
SELECT _json -> 2 -> 'a' FROM many_types
----
NULL
["foo", {"b": 3}]
NULL
["foo", {"b": 3}]


# Make sure we fall back to row engine when we have a mixed-type expression
# with dates.
Expand Down

0 comments on commit 67d55a0

Please sign in to comment.