本文整理匯總了Golang中github.com/cockroachdb/cockroach/pkg/sql/parser.MakeDBool函數的典型用法代碼示例。如果您正苦於以下問題:Golang MakeDBool函數的具體用法?Golang MakeDBool怎麽用?Golang MakeDBool使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了MakeDBool函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: golangFillQueryArguments
// golangFillQueryArguments populates the placeholder map with
// types and values from an array of Go values.
// TODO: This does not support arguments of the SQL 'Date' type, as there is not
// an equivalent type in Go's standard library. It's not currently needed by any
// of our internal tables.
func golangFillQueryArguments(pinfo *parser.PlaceholderInfo, args []interface{}) {
pinfo.Clear()
for i, arg := range args {
k := fmt.Sprint(i + 1)
if arg == nil {
pinfo.SetValue(k, parser.DNull)
continue
}
// A type switch to handle a few explicit types with special semantics:
// - Datums are passed along as is.
// - Time datatypes get special representation in the database.
var d parser.Datum
switch t := arg.(type) {
case parser.Datum:
d = t
case time.Time:
d = parser.MakeDTimestamp(t, time.Microsecond)
case time.Duration:
d = &parser.DInterval{Duration: duration.Duration{Nanos: t.Nanoseconds()}}
case *inf.Dec:
dd := &parser.DDecimal{}
dd.Set(t)
d = dd
}
if d == nil {
// Handle all types which have an underlying type that can be stored in the
// database.
// Note: if this reflection becomes a performance concern in the future,
// commonly used types could be added explicitly into the type switch above
// for a performance gain.
val := reflect.ValueOf(arg)
switch val.Kind() {
case reflect.Bool:
d = parser.MakeDBool(parser.DBool(val.Bool()))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
d = parser.NewDInt(parser.DInt(val.Int()))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
d = parser.NewDInt(parser.DInt(val.Uint()))
case reflect.Float32, reflect.Float64:
d = parser.NewDFloat(parser.DFloat(val.Float()))
case reflect.String:
d = parser.NewDString(val.String())
case reflect.Slice:
// Handle byte slices.
if val.Type().Elem().Kind() == reflect.Uint8 {
d = parser.NewDBytes(parser.DBytes(val.Bytes()))
}
}
if d == nil {
panic(fmt.Sprintf("unexpected type %T", arg))
}
}
pinfo.SetValue(k, d)
}
}
示例2: DecodeTableValue
// DecodeTableValue decodes a value encoded by EncodeTableValue.
func DecodeTableValue(a *DatumAlloc, valType parser.Type, b []byte) (parser.Datum, []byte, error) {
_, dataOffset, _, typ, err := encoding.DecodeValueTag(b)
if err != nil {
return nil, b, err
}
if typ == encoding.Null {
return parser.DNull, b[dataOffset:], nil
}
switch valType {
case parser.TypeBool:
var x bool
b, x, err = encoding.DecodeBoolValue(b)
// No need to chunk allocate DBool as MakeDBool returns either
// parser.DBoolTrue or parser.DBoolFalse.
return parser.MakeDBool(parser.DBool(x)), b, err
case parser.TypeInt:
var i int64
b, i, err = encoding.DecodeIntValue(b)
return a.NewDInt(parser.DInt(i)), b, err
case parser.TypeFloat:
var f float64
b, f, err = encoding.DecodeFloatValue(b)
return a.NewDFloat(parser.DFloat(f)), b, err
case parser.TypeDecimal:
var d *inf.Dec
b, d, err = encoding.DecodeDecimalValue(b)
dd := a.NewDDecimal(parser.DDecimal{})
dd.Set(d)
return dd, b, err
case parser.TypeString:
var data []byte
b, data, err = encoding.DecodeBytesValue(b)
return a.NewDString(parser.DString(data)), b, err
case parser.TypeBytes:
var data []byte
b, data, err = encoding.DecodeBytesValue(b)
return a.NewDBytes(parser.DBytes(data)), b, err
case parser.TypeDate:
var i int64
b, i, err = encoding.DecodeIntValue(b)
return a.NewDDate(parser.DDate(i)), b, err
case parser.TypeTimestamp:
var t time.Time
b, t, err = encoding.DecodeTimeValue(b)
return a.NewDTimestamp(parser.DTimestamp{Time: t}), b, err
case parser.TypeTimestampTZ:
var t time.Time
b, t, err = encoding.DecodeTimeValue(b)
return a.NewDTimestampTZ(parser.DTimestampTZ{Time: t}), b, err
case parser.TypeInterval:
var d duration.Duration
b, d, err = encoding.DecodeDurationValue(b)
return a.NewDInterval(parser.DInterval{Duration: d}), b, err
default:
return nil, nil, errors.Errorf("TODO(pmattis): decoded index value: %s", valType)
}
}
示例3: simplifyAndExpr
func simplifyAndExpr(n *parser.AndExpr) (parser.TypedExpr, bool) {
// a AND b AND c AND d -> [a, b, c, d]
equivalent := true
exprs := splitAndExpr(n, nil)
for i := range exprs {
var equiv bool
exprs[i], equiv = simplifyExpr(exprs[i])
if !equiv {
equivalent = false
}
if isKnownFalseOrNull(exprs[i]) {
return parser.MakeDBool(false), equivalent
}
}
// Simplifying exprs might have transformed one of the elements into an AND
// expression.
texprs, exprs := exprs, nil
for _, e := range texprs {
exprs = splitAndExpr(e, exprs)
}
// Loop over the expressions looking for simplifications.
//
// TODO(pmattis): This is O(n^2) in the number of expressions. Could be
// optimized by sorting the expressions based on the variables they contain.
outer:
for i := len(exprs) - 1; i >= 0; i-- {
for j := i - 1; j >= 0; j-- {
var equiv bool
exprs[j], exprs[i], equiv = simplifyOneAndExpr(exprs[j], exprs[i])
if !equiv {
equivalent = false
}
if isKnownFalseOrNull(exprs[j]) {
return exprs[j], equivalent
}
if isKnownTrue(exprs[i]) {
exprs[i] = nil
}
if exprs[i] == nil {
// We found a simplification. Strip off the expression that is now nil
// and continue the outer loop.
n := len(exprs) - 1
exprs[i] = exprs[n]
exprs = exprs[:n]
continue outer
}
}
}
// Reform the AND expressions.
return joinAndExprs(exprs), equivalent
}
示例4: ShowColumns
// ShowColumns of a table.
// Privileges: Any privilege on table.
// Notes: postgres does not have a SHOW COLUMNS statement.
// mysql only returns columns you have privileges on.
func (p *planner) ShowColumns(n *parser.ShowColumns) (planNode, error) {
tn, err := n.Table.NormalizeWithDatabaseName(p.session.Database)
if err != nil {
return nil, err
}
desc, err := p.mustGetTableDesc(tn)
if err != nil {
return nil, err
}
if err := p.anyPrivilege(desc); err != nil {
return nil, err
}
columns := ResultColumns{
{Name: "Field", Typ: parser.TypeString},
{Name: "Type", Typ: parser.TypeString},
{Name: "Null", Typ: parser.TypeBool},
{Name: "Default", Typ: parser.TypeString},
}
return &delayedNode{
p: p,
name: "SHOW COLUMNS FROM " + tn.String(),
columns: columns,
constructor: func(p *planner) (planNode, error) {
v := p.newContainerValuesNode(columns, 0)
for i, col := range desc.Columns {
defaultExpr := parser.DNull
if e := desc.Columns[i].DefaultExpr; e != nil {
defaultExpr = parser.NewDString(*e)
}
newRow := parser.DTuple{
parser.NewDString(desc.Columns[i].Name),
parser.NewDString(col.Type.SQLString()),
parser.MakeDBool(parser.DBool(desc.Columns[i].Nullable)),
defaultExpr,
}
if err := v.rows.AddRow(newRow); err != nil {
v.rows.Close()
return nil, err
}
}
return v, nil
},
}, nil
}
示例5: RandDatum
// RandDatum generates a random Datum of the given type.
// If null is true, the datum can be DNull.
func RandDatum(rng *rand.Rand, typ ColumnType_Kind, null bool) parser.Datum {
if null && rng.Intn(10) == 0 {
return parser.DNull
}
switch typ {
case ColumnType_BOOL:
return parser.MakeDBool(rng.Intn(2) == 1)
case ColumnType_INT:
return parser.NewDInt(parser.DInt(rng.Int63()))
case ColumnType_FLOAT:
return parser.NewDFloat(parser.DFloat(rng.NormFloat64()))
case ColumnType_DECIMAL:
d := &parser.DDecimal{}
d.Dec.SetScale(inf.Scale(rng.Intn(40) - 20))
d.Dec.SetUnscaled(rng.Int63())
return d
case ColumnType_DATE:
return parser.NewDDate(parser.DDate(rng.Intn(10000)))
case ColumnType_TIMESTAMP:
return &parser.DTimestamp{Time: time.Unix(rng.Int63n(1000000), rng.Int63n(1000000))}
case ColumnType_INTERVAL:
return &parser.DInterval{Duration: duration.Duration{Months: rng.Int63n(1000),
Days: rng.Int63n(1000),
Nanos: rng.Int63n(1000000),
}}
case ColumnType_STRING:
// Generate a random ASCII string.
p := make([]byte, rng.Intn(10))
for i := range p {
p[i] = byte(1 + rng.Intn(127))
}
return parser.NewDString(string(p))
case ColumnType_BYTES:
p := make([]byte, rng.Intn(10))
_, _ = rng.Read(p)
return parser.NewDBytes(parser.DBytes(p))
case ColumnType_TIMESTAMPTZ:
return &parser.DTimestampTZ{Time: time.Unix(rng.Int63n(1000000), rng.Int63n(1000000))}
case ColumnType_INT_ARRAY:
// TODO(cuongdo): we don't support for persistence of arrays yet
return parser.DNull
default:
panic(fmt.Sprintf("invalid type %s", typ))
}
}
示例6: MakePrimaryIndexKey
// MakePrimaryIndexKey creates a key prefix that corresponds to a table row
// (in the primary index); it is intended for tests.
//
// The value types must match the primary key columns (or a prefix of them);
// supported types are: - Datum
// - bool (converts to DBool)
// - int (converts to DInt)
// - string (converts to DString)
func MakePrimaryIndexKey(desc *TableDescriptor, vals ...interface{}) (roachpb.Key, error) {
index := &desc.PrimaryIndex
if len(vals) > len(index.ColumnIDs) {
return nil, errors.Errorf("got %d values, PK has %d columns", len(vals), len(index.ColumnIDs))
}
datums := make([]parser.Datum, len(vals))
for i, v := range vals {
switch v := v.(type) {
case bool:
datums[i] = parser.MakeDBool(parser.DBool(v))
case int:
datums[i] = parser.NewDInt(parser.DInt(v))
case string:
datums[i] = parser.NewDString(v)
case parser.Datum:
datums[i] = v
default:
return nil, errors.Errorf("unexpected value type %T", v)
}
// Check that the value type matches.
colID := index.ColumnIDs[i]
for _, c := range desc.Columns {
if c.ID == colID {
if t := DatumTypeToColumnKind(datums[i].ResolvedType()); t != c.Type.Kind {
return nil, errors.Errorf("column %d of type %s, got value of type %s", i, c.Type.Kind, t)
}
break
}
}
}
// Create the ColumnID to index in datums slice map needed by
// MakeIndexKeyPrefix.
colIDToRowIndex := make(map[ColumnID]int)
for i := range vals {
colIDToRowIndex[index.ColumnIDs[i]] = i
}
keyPrefix := MakeIndexKeyPrefix(desc, index.ID)
key, _, err := EncodeIndexKey(desc, index, colIDToRowIndex, datums, keyPrefix)
if err != nil {
return nil, err
}
return roachpb.Key(key), nil
}
示例7: simplifyExpr
// simplifyExpr transforms an expression such that it contains only expressions
// involving IndexedVars that can be used for index selection. If an expression is
// encountered that cannot be used for index selection (e.g. "func(val)") that
// part of the expression tree is considered to evaluate to true, possibly
// rendering the entire expression as true. Additionally, various
// normalizations are performed on comparison expressions. For example:
//
// (a < 1 AND a < 2) -> (a < 1)
// (a < 1 AND a > 2) -> false
// (a > 1 OR a < 2) -> true
// (a > 1 OR func(b)) -> true
//
// Note that simplification is not normalization. Normalization as performed by
// parser.NormalizeExpr returns an expression that is equivalent to the
// original. Simplification can return an expression with parts of the
// expression tree stripped out.
//
// Returns false for equivalent if the resulting expression is not equivalent
// to the original. This occurs for expressions which are currently not handled
// by simplification.
func simplifyExpr(e parser.TypedExpr) (simplified parser.TypedExpr, equivalent bool) {
if e == parser.DNull {
return e, true
}
switch t := e.(type) {
case *parser.NotExpr:
return simplifyNotExpr(t)
case *parser.AndExpr:
return simplifyAndExpr(t)
case *parser.OrExpr:
return simplifyOrExpr(t)
case *parser.ComparisonExpr:
return simplifyComparisonExpr(t)
case *parser.IndexedVar, *parser.DBool:
return e, true
}
// We don't know how to simplify expressions that fall through to here, so
// consider this part of the expression true.
return parser.MakeDBool(true), false
}
示例8: makePrefixRange
func makePrefixRange(prefix parser.DString, datum parser.TypedExpr, complete bool) parser.TypedExpr {
if complete {
return parser.NewTypedComparisonExpr(
parser.EQ,
datum,
&prefix,
)
}
if len(prefix) == 0 {
return parser.MakeDBool(true)
}
return parser.NewTypedAndExpr(
parser.NewTypedComparisonExpr(
parser.GE,
datum,
&prefix,
),
parser.NewTypedComparisonExpr(
parser.LT,
datum,
parser.NewDString(string(roachpb.Key(prefix).PrefixEnd())),
),
)
}
示例9:
COLUMN_NAME STRING NOT NULL DEFAULT '',
"COLLATION" STRING NOT NULL DEFAULT '',
CARDINALITY INT NOT NULL DEFAULT 0,
DIRECTION STRING NOT NULL DEFAULT '',
STORING BOOL NOT NULL DEFAULT FALSE
);`,
populate: func(p *planner, addRow func(...parser.Datum) error) error {
return forEachTableDesc(p,
func(db *sqlbase.DatabaseDescriptor, table *sqlbase.TableDescriptor) error {
appendRow := func(index *sqlbase.IndexDescriptor, colName string, sequence int,
direction string, isStored bool) error {
return addRow(
defString, // table_catalog
parser.NewDString(db.GetName()), // table_schema
parser.NewDString(table.GetName()), // table_name
parser.MakeDBool(parser.DBool(index.Unique)), // non_unique
parser.NewDString(db.GetName()), // index_schema
parser.NewDString(index.Name), // index_name
parser.NewDInt(parser.DInt(sequence)), // seq_in_index
parser.NewDString(colName), // column_name
parser.DNull, // collation
parser.DNull, // cardinality
parser.NewDString(direction), // direction
parser.MakeDBool(parser.DBool(isStored)), // storing
)
}
return forEachIndexInTable(table, func(index *sqlbase.IndexDescriptor) error {
sequence := 1
for i, col := range index.ColumnNames {
// We add a row for each column of index.
示例10: simplifyOneOrExpr
func simplifyOneOrExpr(left, right parser.TypedExpr) (parser.TypedExpr, parser.TypedExpr, bool) {
lcmp, ok := left.(*parser.ComparisonExpr)
if !ok {
return left, right, true
}
rcmp, ok := right.(*parser.ComparisonExpr)
if !ok {
return left, right, true
}
lcmpLeft, lcmpRight := lcmp.TypedLeft(), lcmp.TypedRight()
rcmpLeft, rcmpRight := rcmp.TypedLeft(), rcmp.TypedRight()
if !isDatum(lcmpRight) || !isDatum(rcmpRight) {
return parser.MakeDBool(true), nil, false
}
if !varEqual(lcmpLeft, rcmpLeft) {
return left, right, true
}
if lcmp.Operator == parser.IsNot || rcmp.Operator == parser.IsNot {
switch lcmp.Operator {
case parser.Is:
if lcmpRight == parser.DNull && rcmpRight == parser.DNull {
// a IS NULL OR a IS NOT NULL
return parser.MakeDBool(true), nil, true
}
case parser.IsNot:
if lcmpRight == parser.DNull {
switch rcmp.Operator {
case parser.Is:
if rcmpRight == parser.DNull {
// a IS NOT NULL OR a IS NULL
return parser.MakeDBool(true), nil, true
}
case parser.IsNot:
if rcmpRight == parser.DNull {
// a IS NOT NULL OR a IS NOT NULL
return left, nil, true
}
}
}
}
return left, right, true
}
if lcmp.Operator == parser.In || rcmp.Operator == parser.In {
left, right = simplifyOneOrInExpr(lcmp, rcmp)
return left, right, true
}
if reflect.TypeOf(lcmpRight) != reflect.TypeOf(rcmpRight) {
allowCmp := false
switch lcmp.Operator {
case parser.EQ, parser.NE, parser.GT, parser.GE, parser.LT, parser.LE:
switch rcmp.Operator {
case parser.EQ, parser.NE, parser.GT, parser.GE, parser.LT, parser.LE:
// Break, permitting heterogeneous comparison.
allowCmp = true
}
}
if !allowCmp {
// If the types of the left and right datums are different, no
// simplification is possible.
return left, right, true
}
}
ldatum := lcmpRight.(parser.Datum)
rdatum := rcmpRight.(parser.Datum)
cmp := ldatum.Compare(rdatum)
// Determine which expression to use when either expression (left or right)
// is valid as a return value but their types are different. The reason
// to prefer a comparison between a column value and a datum of the same
// type is that it makes index constraint construction easier.
either := lcmp
if !ldatum.ResolvedType().Equal(rdatum.ResolvedType()) {
switch ta := lcmpLeft.(type) {
case *parser.IndexedVar:
if ta.ResolvedType().Equal(rdatum.ResolvedType()) {
either = rcmp
}
}
}
// TODO(pmattis): Figure out how to generate this logic.
switch lcmp.Operator {
case parser.EQ:
switch rcmp.Operator {
case parser.EQ:
// a = x OR a = y
if cmp == 0 {
// x = y
return either, nil, true
} else if cmp == 1 {
// x > y
ldatum, rdatum = rdatum, ldatum
}
return parser.NewTypedComparisonExpr(
parser.In,
lcmpLeft,
//.........這裏部分代碼省略.........
示例11: dumpTable
//.........這裏部分代碼省略.........
// pk holds the last values of the fetched primary keys
var pk []driver.Value
q := fmt.Sprintf(bs, "")
for {
rows, err := conn.Query(q, pk)
if err != nil {
return err
}
cols := rows.Columns()
pkcols := cols[:len(index)]
cols = cols[len(index):]
inserts := make([][]string, 0, limit)
i := 0
for i < limit {
vals := make([]driver.Value, len(cols)+len(pkcols))
if err := rows.Next(vals); err == io.EOF {
break
} else if err != nil {
return err
}
if pk == nil {
q = fmt.Sprintf(bs, wbuf.String())
}
pk = vals[:len(index)]
vals = vals[len(index):]
ivals := make([]string, len(vals))
// Values need to be correctly encoded for INSERT statements in a text file.
for si, sv := range vals {
switch t := sv.(type) {
case nil:
ivals[si] = "NULL"
case bool:
ivals[si] = parser.MakeDBool(parser.DBool(t)).String()
case int64:
ivals[si] = parser.NewDInt(parser.DInt(t)).String()
case float64:
ivals[si] = parser.NewDFloat(parser.DFloat(t)).String()
case string:
ivals[si] = parser.NewDString(t).String()
case []byte:
switch ct := coltypes[cols[si]]; ct {
case "INTERVAL":
ivals[si] = fmt.Sprintf("'%s'", t)
case "BYTES":
ivals[si] = parser.NewDBytes(parser.DBytes(t)).String()
default:
// STRING and DECIMAL types can have optional length
// suffixes, so only examine the prefix of the type.
if strings.HasPrefix(coltypes[cols[si]], "STRING") {
ivals[si] = parser.NewDString(string(t)).String()
} else if strings.HasPrefix(coltypes[cols[si]], "DECIMAL") {
ivals[si] = string(t)
} else {
panic(errors.Errorf("unknown []byte type: %s, %v: %s", t, cols[si], coltypes[cols[si]]))
}
}
case time.Time:
var d parser.Datum
ct := coltypes[cols[si]]
switch ct {
case "DATE":
d = parser.NewDDateFromTime(t, time.UTC)
case "TIMESTAMP":
d = parser.MakeDTimestamp(t, time.Nanosecond)
case "TIMESTAMP WITH TIME ZONE":
示例12: simplifyComparisonExpr
func simplifyComparisonExpr(n *parser.ComparisonExpr) (parser.TypedExpr, bool) {
// NormalizeExpr will have left comparisons in the form "<var> <op>
// <datum>" unless they could not be simplified further in which case
// simplifyExpr cannot handle them. For example, "lower(a) = 'foo'"
left, right := n.TypedLeft(), n.TypedRight()
if isVar(left) && isDatum(right) {
if right == parser.DNull {
switch n.Operator {
case parser.IsNotDistinctFrom:
switch left.(type) {
case *parser.IndexedVar:
// Transform "a IS NOT DISTINCT FROM NULL" into "a IS NULL".
return parser.NewTypedComparisonExpr(
parser.Is,
left,
right,
), true
}
case parser.IsDistinctFrom:
switch left.(type) {
case *parser.IndexedVar:
// Transform "a IS DISTINCT FROM NULL" into "a IS NOT NULL".
return parser.NewTypedComparisonExpr(
parser.IsNot,
left,
right,
), true
}
case parser.Is, parser.IsNot:
switch left.(type) {
case *parser.IndexedVar:
// "a IS {,NOT} NULL" can be used during index selection to restrict
// the range of scanned keys.
return n, true
}
default:
// All of the remaining comparison operators have the property that when
// comparing to NULL they evaluate to NULL (see evalComparisonOp). NULL is
// not the same as false, but in the context of a WHERE clause, NULL is
// considered not-true which is the same as false.
return parser.MakeDBool(false), true
}
}
switch n.Operator {
case parser.EQ:
// Translate "(a, b) = (1, 2)" to "(a, b) IN ((1, 2))".
switch left.(type) {
case *parser.Tuple:
return parser.NewTypedComparisonExpr(
parser.In,
left,
&parser.DTuple{right.(parser.Datum)},
), true
}
return n, true
case parser.NE, parser.GE, parser.LE:
return n, true
case parser.GT:
// This simplification is necessary so that subsequent transformation of
// > constraint to >= can use Datum.Next without concern about whether a
// next value exists. Note that if the variable (n.Left) is NULL, this
// comparison would evaluate to NULL which is equivalent to false for a
// boolean expression.
if right.(parser.Datum).IsMax() {
return parser.MakeDBool(false), true
}
return n, true
case parser.LT:
// Note that if the variable is NULL, this would evaluate to NULL which
// would equivalent to false for a boolean expression.
if right.(parser.Datum).IsMin() {
return parser.MakeDBool(false), true
}
return n, true
case parser.In, parser.NotIn:
tuple := *right.(*parser.DTuple)
if len(tuple) == 0 {
return parser.MakeDBool(false), true
}
return n, true
case parser.Like:
// a LIKE 'foo%' -> a >= "foo" AND a < "fop"
if d, ok := right.(*parser.DString); ok {
if i := strings.IndexAny(string(*d), "_%"); i >= 0 {
return makePrefixRange((*d)[:i], left, false), false
}
return makePrefixRange(*d, left, true), false
}
// TODO(pmattis): Support parser.DBytes?
case parser.SimilarTo:
// a SIMILAR TO "foo.*" -> a >= "foo" AND a < "fop"
if d, ok := right.(*parser.DString); ok {
pattern := parser.SimilarEscape(string(*d))
if re, err := regexp.Compile(pattern); err == nil {
prefix, complete := re.LiteralPrefix()
return makePrefixRange(parser.DString(prefix), left, complete), false
}
}
// TODO(pmattis): Support parser.DBytes?
//.........這裏部分代碼省略.........
示例13: doEval
func (s *subquery) doEval() (parser.Datum, error) {
var result parser.Datum
switch s.execMode {
case execModeExists:
// For EXISTS expressions, all we want to know is if there is at least one
// result.
next, err := s.plan.Next()
s.plan.Close()
if s.err = err; err != nil {
return result, err
}
if next {
result = parser.MakeDBool(true)
}
if result == nil {
result = parser.MakeDBool(false)
}
case execModeAllRows:
fallthrough
case execModeAllRowsNormalized:
var rows parser.DTuple
next, err := s.plan.Next()
for ; next; next, err = s.plan.Next() {
values := s.plan.Values()
switch len(values) {
case 1:
// This seems hokey, but if we don't do this then the subquery expands
// to a tuple of tuples instead of a tuple of values and an expression
// like "k IN (SELECT foo FROM bar)" will fail because we're comparing
// a single value against a tuple.
rows = append(rows, values[0])
default:
// The result from plan.Values() is only valid until the next call to
// plan.Next(), so make a copy.
valuesCopy := make(parser.DTuple, len(values))
copy(valuesCopy, values)
rows = append(rows, &valuesCopy)
}
}
s.plan.Close()
if s.err = err; err != nil {
return result, err
}
if s.execMode == execModeAllRowsNormalized {
rows.Normalize()
}
result = &rows
case execModeOneRow:
result = parser.DNull
hasRow, err := s.plan.Next()
if s.err = err; err != nil {
s.plan.Close()
return result, err
}
if !hasRow {
s.plan.Close()
} else {
values := s.plan.Values()
switch len(values) {
case 1:
result = values[0]
default:
valuesCopy := make(parser.DTuple, len(values))
copy(valuesCopy, values)
result = &valuesCopy
}
another, err := s.plan.Next()
s.plan.Close()
if s.err = err; err != nil {
return result, err
}
if another {
s.err = fmt.Errorf("more than one row returned by a subquery used as an expression")
return result, s.err
}
}
}
return result, nil
}
示例14:
addColumn := func(column *sqlbase.ColumnDescriptor, attRelID parser.Datum, colNum int) error {
colTyp := column.Type.ToDatumType()
return addRow(
attRelID, // attrelid
parser.NewDString(column.Name), // attname
typOid(colTyp), // atttypid
zeroVal, // attstattarget
typLen(colTyp), // attlen
parser.NewDInt(parser.DInt(colNum)), // attnum
zeroVal, // attndims
negOneVal, // attcacheoff
negOneVal, // atttypmod
parser.DNull, // attbyval (see pg_type.typbyval)
parser.DNull, // attstorage
parser.DNull, // attalign
parser.MakeDBool(parser.DBool(!column.Nullable)), // attnotnull
parser.MakeDBool(parser.DBool(column.DefaultExpr != nil)), // atthasdef
parser.MakeDBool(false), // attisdropped
parser.MakeDBool(true), // attislocal
zeroVal, // attinhcount
parser.DNull, // attacl
parser.DNull, // attoptions
parser.DNull, // attfdwoptions
)
}
// Columns for table.
colNum := 0
if err := forEachColumnInTable(table, func(column *sqlbase.ColumnDescriptor) error {
colNum++
tableID := h.TableOid(db, table)
示例15: RandDatum
// RandDatum generates a random Datum of the given type.
// If null is true, the datum can be DNull.
func RandDatum(rng *rand.Rand, typ ColumnType, null bool) parser.Datum {
if null && rng.Intn(10) == 0 {
return parser.DNull
}
switch typ.Kind {
case ColumnType_BOOL:
return parser.MakeDBool(rng.Intn(2) == 1)
case ColumnType_INT:
return parser.NewDInt(parser.DInt(rng.Int63()))
case ColumnType_FLOAT:
return parser.NewDFloat(parser.DFloat(rng.NormFloat64()))
case ColumnType_DECIMAL:
d := &parser.DDecimal{}
d.Dec.SetScale(inf.Scale(rng.Intn(40) - 20))
d.Dec.SetUnscaled(rng.Int63())
return d
case ColumnType_DATE:
return parser.NewDDate(parser.DDate(rng.Intn(10000)))
case ColumnType_TIMESTAMP:
return &parser.DTimestamp{Time: time.Unix(rng.Int63n(1000000), rng.Int63n(1000000))}
case ColumnType_INTERVAL:
return &parser.DInterval{Duration: duration.Duration{Months: rng.Int63n(1000),
Days: rng.Int63n(1000),
Nanos: rng.Int63n(1000000),
}}
case ColumnType_STRING:
// Generate a random ASCII string.
p := make([]byte, rng.Intn(10))
for i := range p {
p[i] = byte(1 + rng.Intn(127))
}
return parser.NewDString(string(p))
case ColumnType_BYTES:
p := make([]byte, rng.Intn(10))
_, _ = rng.Read(p)
return parser.NewDBytes(parser.DBytes(p))
case ColumnType_TIMESTAMPTZ:
return &parser.DTimestampTZ{Time: time.Unix(rng.Int63n(1000000), rng.Int63n(1000000))}
case ColumnType_COLLATEDSTRING:
if typ.Locale == nil {
panic("locale is required for COLLATEDSTRING")
}
// Generate a random Unicode string.
var buf bytes.Buffer
n := rng.Intn(10)
for i := 0; i < n; i++ {
var r rune
for {
r = rune(rng.Intn(unicode.MaxRune + 1))
if !unicode.Is(unicode.C, r) {
break
}
}
buf.WriteRune(r)
}
return parser.NewDCollatedString(buf.String(), *typ.Locale, &parser.CollationEnvironment{})
case ColumnType_INT_ARRAY:
// TODO(cuongdo): we don't support for persistence of arrays yet
return parser.DNull
default:
panic(fmt.Sprintf("invalid type %s", typ.String()))
}
}