本文整理汇总了Golang中github.com/pingcap/tidb/util/types.NewIntDatum函数的典型用法代码示例。如果您正苦于以下问题:Golang NewIntDatum函数的具体用法?Golang NewIntDatum怎么用?Golang NewIntDatum使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NewIntDatum函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: TestEvalIsNull
func (s *testEvalSuite) TestEvalIsNull(c *C) {
colID := int64(1)
xevaluator := NewEvaluator(new(variable.StatementContext))
xevaluator.Row[colID] = types.NewIntDatum(100)
null, trueAns, falseAns := types.Datum{}, types.NewIntDatum(1), types.NewIntDatum(0)
cases := []struct {
expr *tipb.Expr
result types.Datum
}{
{
expr: buildExpr(tipb.ExprType_IsNull, types.NewStringDatum("abc")),
result: falseAns,
},
{
expr: buildExpr(tipb.ExprType_IsNull, null),
result: trueAns,
},
{
expr: buildExpr(tipb.ExprType_IsNull, types.NewIntDatum(0)),
result: falseAns,
},
}
for _, ca := range cases {
result, err := xevaluator.Eval(ca.expr)
c.Assert(err, IsNil)
c.Assert(result.Kind(), Equals, ca.result.Kind())
cmp, err := result.CompareDatum(xevaluator.sc, ca.result)
c.Assert(err, IsNil)
c.Assert(cmp, Equals, 0)
}
}
开发者ID:pingcap,项目名称:tidb,代码行数:31,代码来源:eval_test.go
示例2: TestSleep
func (s *testEvaluatorSuite) TestSleep(c *C) {
defer testleak.AfterTest(c)()
ctx := mock.NewContext()
sessVars := ctx.GetSessionVars()
// non-strict model
sessVars.StrictSQLMode = false
d := make([]types.Datum, 1)
ret, err := builtinSleep(d, ctx)
c.Assert(err, IsNil)
c.Assert(ret, DeepEquals, types.NewIntDatum(0))
d[0].SetInt64(-1)
ret, err = builtinSleep(d, ctx)
c.Assert(err, IsNil)
c.Assert(ret, DeepEquals, types.NewIntDatum(0))
// for error case under the strict model
sessVars.StrictSQLMode = true
d[0].SetNull()
_, err = builtinSleep(d, ctx)
c.Assert(err, NotNil)
d[0].SetFloat64(-2.5)
_, err = builtinSleep(d, ctx)
c.Assert(err, NotNil)
// strict model
d[0].SetFloat64(0.5)
start := time.Now()
ret, err = builtinSleep(d, ctx)
c.Assert(err, IsNil)
c.Assert(ret, DeepEquals, types.NewIntDatum(0))
sub := time.Since(start)
c.Assert(sub.Nanoseconds(), GreaterEqual, int64(0.5*1e9))
}
开发者ID:pingcap,项目名称:tidb,代码行数:34,代码来源:evaluator_test.go
示例3: TestEvaluatedFlag
func (s *testEvaluatorSuite) TestEvaluatedFlag(c *C) {
l := ast.NewValueExpr(int64(1))
r := ast.NewValueExpr(int64(2))
b := &ast.BinaryOperationExpr{L: l, R: r, Op: opcode.Plus}
ast.SetFlag(b)
c.Assert(ast.IsPreEvaluable(b), Equals, true)
d, err := Eval(s.ctx, b)
c.Assert(ast.IsEvaluated(b), Equals, true)
c.Assert(err, IsNil)
c.Assert(d, testutil.DatumEquals, types.NewIntDatum(3))
funcCall := &ast.FuncCallExpr{
FnName: model.NewCIStr("abs"),
Args: []ast.ExprNode{ast.NewValueExpr(int(-1))},
}
b = &ast.BinaryOperationExpr{L: funcCall, R: r, Op: opcode.Plus}
ast.ResetEvaluatedFlag(b)
ast.SetFlag(b)
c.Assert(ast.IsPreEvaluable(b), Equals, true)
d, err = Eval(s.ctx, b)
c.Assert(ast.IsEvaluated(b), Equals, false)
c.Assert(err, IsNil)
c.Assert(d, testutil.DatumEquals, types.NewIntDatum(3))
rf := &ast.ResultField{Expr: ast.NewValueExpr(int64(1))}
colExpr := &ast.ColumnNameExpr{Refer: rf}
b = &ast.BinaryOperationExpr{L: colExpr, R: r, Op: opcode.Plus}
ast.ResetEvaluatedFlag(b)
ast.SetFlag(b)
c.Assert(ast.IsPreEvaluable(b), Equals, false)
d, err = Eval(s.ctx, b)
c.Assert(ast.IsEvaluated(b), Equals, false)
c.Assert(err, IsNil)
c.Assert(d, testutil.DatumEquals, types.NewIntDatum(3))
}
开发者ID:pingcap,项目名称:tidb,代码行数:35,代码来源:evaluator_test.go
示例4: TestEvalIf
func (s *testEvalSuite) TestEvalIf(c *C) {
colID := int64(1)
xevaluator := NewEvaluator(new(variable.StatementContext))
xevaluator.Row[colID] = types.NewIntDatum(100)
trueCond, falseCond, null := types.NewIntDatum(1), types.NewIntDatum(0), types.Datum{}
expr1, expr2 := types.NewStringDatum("expr1"), types.NewStringDatum("expr2")
cases := []struct {
expr *tipb.Expr
result types.Datum
}{
{
expr: buildExpr(tipb.ExprType_If,
trueCond, types.NewStringDatum("expr1"), types.NewStringDatum("expr2")),
result: expr1,
},
{
expr: buildExpr(tipb.ExprType_If,
falseCond, types.NewStringDatum("expr1"), types.NewStringDatum("expr2")),
result: expr2,
},
{
expr: buildExpr(tipb.ExprType_If,
null, types.NewStringDatum("expr1"), types.NewStringDatum("expr2")),
result: expr2,
},
{
expr: buildExpr(tipb.ExprType_If,
trueCond, null, types.NewStringDatum("expr2")),
result: null,
},
{
expr: buildExpr(tipb.ExprType_If,
falseCond, types.NewStringDatum("expr1"), null),
result: null,
},
{
expr: buildExpr(tipb.ExprType_If,
trueCond, types.NewStringDatum("expr1"), types.NewStringDatum("expr2")),
result: expr1,
},
{
expr: buildExpr(tipb.ExprType_If, buildExpr(tipb.ExprType_If, trueCond, null, trueCond),
buildExpr(tipb.ExprType_If, trueCond, expr1, expr2),
buildExpr(tipb.ExprType_If, falseCond, expr1, expr2)),
result: expr2,
},
}
for _, ca := range cases {
result, err := xevaluator.Eval(ca.expr)
c.Assert(err, IsNil)
c.Assert(result.Kind(), Equals, ca.result.Kind())
cmp, err := result.CompareDatum(xevaluator.sc, ca.result)
c.Assert(err, IsNil)
c.Assert(cmp, Equals, 0)
}
}
开发者ID:pingcap,项目名称:tidb,代码行数:56,代码来源:eval_control_funcs_test.go
示例5: TestFromUnixTime
func (s *testEvaluatorSuite) TestFromUnixTime(c *C) {
defer testleak.AfterTest(c)()
tbl := []struct {
isDecimal bool
integralPart int64
fractionalPart int64
decimal float64
format string
ansLen int
}{
{false, 1451606400, 0, 0, "", 19},
{true, 1451606400, 123456000, 1451606400.123456, "", 26},
{true, 1451606400, 999999000, 1451606400.999999, "", 26},
{true, 1451606400, 999999900, 1451606400.9999999, "", 19},
{false, 1451606400, 0, 0, "%Y %D %M %h:%i:%s %x", 19},
{true, 1451606400, 123456000, 1451606400.123456, "%Y %D %M %h:%i:%s %x", 26},
{true, 1451606400, 999999000, 1451606400.999999, "%Y %D %M %h:%i:%s %x", 26},
{true, 1451606400, 999999900, 1451606400.9999999, "%Y %D %M %h:%i:%s %x", 19},
}
for _, t := range tbl {
var timestamp types.Datum
if !t.isDecimal {
timestamp.SetInt64(t.integralPart)
} else {
timestamp.SetFloat64(t.decimal)
}
// result of from_unixtime() is dependent on specific time zone.
unixTime := time.Unix(t.integralPart, t.fractionalPart).Round(time.Microsecond).String()[:t.ansLen]
if len(t.format) == 0 {
v, err := builtinFromUnixTime([]types.Datum{timestamp}, s.ctx)
c.Assert(err, IsNil)
ans := v.GetMysqlTime()
c.Assert(ans.String(), Equals, unixTime)
} else {
format := types.NewStringDatum(t.format)
v, err := builtinFromUnixTime([]types.Datum{timestamp, format}, s.ctx)
c.Assert(err, IsNil)
result, err := builtinDateFormat([]types.Datum{types.NewStringDatum(unixTime), format}, s.ctx)
c.Assert(err, IsNil)
c.Assert(v.GetString(), Equals, result.GetString())
}
}
v, err := builtinFromUnixTime([]types.Datum{types.NewIntDatum(-12345)}, s.ctx)
c.Assert(err, IsNil)
c.Assert(v.Kind(), Equals, types.KindNull)
_, err = builtinFromUnixTime([]types.Datum{types.NewIntDatum(math.MaxInt32 + 1)}, s.ctx)
c.Assert(err, IsNil)
c.Assert(v.Kind(), Equals, types.KindNull)
}
开发者ID:pingcap,项目名称:tidb,代码行数:52,代码来源:builtin_time_test.go
示例6: evalIsNull
func (e *Evaluator) evalIsNull(expr *tipb.Expr) (types.Datum, error) {
if len(expr.Children) != 1 {
return types.Datum{}, ErrInvalid.Gen("ISNULL need 1 operand, got %d", len(expr.Children))
}
d, err := e.Eval(expr.Children[0])
if err != nil {
return types.Datum{}, errors.Trace(err)
}
if d.IsNull() {
return types.NewIntDatum(1), nil
}
return types.NewIntDatum(0), nil
}
开发者ID:pingcap,项目名称:tidb,代码行数:13,代码来源:eval.go
示例7: evalGT
func (e *Evaluator) evalGT(expr *tipb.Expr) (types.Datum, error) {
cmp, err := e.compareTwoChildren(expr)
if err != nil {
return types.Datum{}, errors.Trace(err)
}
if cmp == compareResultNull {
return types.Datum{}, nil
} else if cmp > 0 {
return types.NewIntDatum(1), nil
} else {
return types.NewIntDatum(0), nil
}
}
开发者ID:XuHuaiyu,项目名称:tidb,代码行数:13,代码来源:eval.go
示例8: evalNullEQ
func (e *Evaluator) evalNullEQ(expr *tipb.Expr) (types.Datum, error) {
left, right, err := e.evalTwoChildren(expr)
if err != nil {
return types.Datum{}, errors.Trace(err)
}
cmp, err := left.CompareDatum(right)
if err != nil {
return types.Datum{}, errors.Trace(err)
}
if cmp == 0 {
return types.NewIntDatum(1), nil
}
return types.NewIntDatum(0), nil
}
开发者ID:XuHuaiyu,项目名称:tidb,代码行数:14,代码来源:eval.go
示例9: HashCode
// HashCode implements Expression interface.
func (col *Column) HashCode() []byte {
if len(col.hashcode) != 0 {
return col.hashcode
}
col.hashcode, _ = codec.EncodeValue(col.hashcode, types.NewStringDatum(col.FromID), types.NewIntDatum(int64(col.Position)))
return col.hashcode
}
开发者ID:pingcap,项目名称:tidb,代码行数:8,代码来源:column.go
示例10: handleRowData
// handleRowData deals with raw row data:
// 1. Decodes row from raw byte slice.
// 2. Checks if it fit where condition.
// 3. Update aggregate functions.
// returns true if got a row.
func (rs *localRegion) handleRowData(ctx *selectContext, handle int64, value []byte) (bool, error) {
columns := ctx.sel.TableInfo.Columns
values, err := rs.getRowData(value, ctx.colTps)
if err != nil {
return false, errors.Trace(err)
}
// Fill handle and null columns.
for _, col := range columns {
if col.GetPkHandle() {
var handleDatum types.Datum
if mysql.HasUnsignedFlag(uint(col.Flag)) {
// PK column is Unsigned
handleDatum = types.NewUintDatum(uint64(handle))
} else {
handleDatum = types.NewIntDatum(handle)
}
handleData, err1 := codec.EncodeValue(nil, handleDatum)
if err1 != nil {
return false, errors.Trace(err1)
}
values[col.GetColumnId()] = handleData
} else {
_, ok := values[col.GetColumnId()]
if !ok {
if mysql.HasNotNullFlag(uint(col.GetFlag())) {
return false, errors.New("Miss column")
}
values[col.GetColumnId()] = []byte{codec.NilFlag}
}
}
}
return rs.valuesToRow(ctx, handle, values)
}
开发者ID:jmptrader,项目名称:tidb,代码行数:38,代码来源:local_region.go
示例11: builtinSleep
// See http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_sleep
func builtinSleep(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
if ctx == nil {
return d, errors.Errorf("Missing context when evalue builtin")
}
sessVars := variable.GetSessionVars(ctx)
if args[0].IsNull() {
if sessVars.StrictSQLMode {
return d, errors.New("Incorrect arguments to sleep.")
}
d.SetInt64(0)
return
}
// processing argument is negative
zero := types.NewIntDatum(0)
ret, err := args[0].CompareDatum(zero)
if err != nil {
return d, errors.Trace(err)
}
if ret == -1 {
if sessVars.StrictSQLMode {
return d, errors.New("Incorrect arguments to sleep.")
}
d.SetInt64(0)
return
}
// TODO: consider it's interrupted using KILL QUERY from other session, or
// interrupted by time out.
duration := time.Duration(args[0].GetFloat64() * float64(time.Second.Nanoseconds()))
time.Sleep(duration)
d.SetInt64(0)
return
}
开发者ID:XuHuaiyu,项目名称:tidb,代码行数:35,代码来源:builtin_other.go
示例12: evalWhereForRow
func (rs *localRegion) evalWhereForRow(ctx *selectContext, h int64, row map[int64][]byte) (bool, error) {
if ctx.sel.Where == nil {
return true, nil
}
for colID, col := range ctx.whereColumns {
if col.GetPkHandle() {
ctx.eval.Row[colID] = types.NewIntDatum(h)
} else {
data := row[colID]
ft := xapi.FieldTypeFromPBColumn(col)
datum, err := tablecodec.DecodeColumnValue(data, ft)
if err != nil {
return false, errors.Trace(err)
}
ctx.eval.Row[colID] = datum
}
}
result, err := ctx.eval.Eval(ctx.sel.Where)
if err != nil {
return false, errors.Trace(err)
}
if result.IsNull() {
return false, nil
}
boolResult, err := result.ToBool()
if err != nil {
return false, errors.Trace(err)
}
return boolResult == 1, nil
}
开发者ID:yubobo,项目名称:tidb,代码行数:30,代码来源:local_region.go
示例13: likeToScalarFunc
func (er *expressionRewriter) likeToScalarFunc(v *ast.PatternLikeExpr) {
l := len(er.ctxStack)
function := er.notToScalarFunc(v.Not, ast.Like, v.Type,
er.ctxStack[l-2], er.ctxStack[l-1], &expression.Constant{Value: types.NewIntDatum(int64(v.Escape))})
er.ctxStack = er.ctxStack[:l-2]
er.ctxStack = append(er.ctxStack, function)
}
开发者ID:yuyongwei,项目名称:tidb,代码行数:7,代码来源:expression_rewriter.go
示例14: TestEvalCoalesce
func (s *testEvalSuite) TestEvalCoalesce(c *C) {
colID := int64(1)
row := make(map[int64]types.Datum)
row[colID] = types.NewIntDatum(100)
xevaluator := &Evaluator{Row: row}
nullDatum := types.Datum{}
nullDatum.SetNull()
notNullDatum := types.NewStringDatum("not-null")
cases := []struct {
expr *tipb.Expr
result types.Datum
}{
{
expr: buildExpr(tipb.ExprType_Coalesce, nullDatum, nullDatum, nullDatum),
result: nullDatum,
},
{
expr: buildExpr(tipb.ExprType_Coalesce, nullDatum, notNullDatum, nullDatum),
result: notNullDatum,
},
{
expr: buildExpr(tipb.ExprType_Coalesce, nullDatum, notNullDatum, types.NewStringDatum("not-null-2"), nullDatum),
result: notNullDatum,
},
}
for _, ca := range cases {
result, err := xevaluator.Eval(ca.expr)
c.Assert(err, IsNil)
c.Assert(result.Kind(), Equals, ca.result.Kind())
cmp, err := result.CompareDatum(xevaluator.sc, ca.result)
c.Assert(err, IsNil)
c.Assert(cmp, Equals, 0)
}
}
开发者ID:pingcap,项目名称:tidb,代码行数:34,代码来源:eval_other_funcs_test.go
示例15: addUpdateBinlog
func (t *Table) addUpdateBinlog(ctx context.Context, h int64, old []types.Datum, newValue []byte, colIDs []int64) error {
mutation := t.getMutation(ctx)
hasPK := false
if t.meta.PKIsHandle {
hasPK = true
} else {
for _, idx := range t.meta.Indices {
if idx.Primary {
hasPK = true
break
}
}
}
var bin []byte
if hasPK {
handleData, _ := codec.EncodeValue(nil, types.NewIntDatum(h))
bin = append(handleData, newValue...)
} else {
oldData, err := tablecodec.EncodeRow(old, colIDs)
if err != nil {
return errors.Trace(err)
}
bin = append(oldData, newValue...)
}
mutation.UpdatedRows = append(mutation.UpdatedRows, bin)
mutation.Sequence = append(mutation.Sequence, binlog.MutationType_Update)
return nil
}
开发者ID:pingcap,项目名称:tidb,代码行数:28,代码来源:tables.go
示例16: IterRecords
// IterRecords implements table.Table IterRecords interface.
func (t *Table) IterRecords(ctx context.Context, startKey kv.Key, cols []*table.Column,
fn table.RecordIterFunc) error {
txn, err := ctx.GetTxn(false)
if err != nil {
return errors.Trace(err)
}
it, err := txn.Seek(startKey)
if err != nil {
return errors.Trace(err)
}
defer it.Close()
if !it.Valid() {
return nil
}
log.Debugf("startKey:%q, key:%q, value:%q", startKey, it.Key(), it.Value())
colMap := make(map[int64]*types.FieldType)
for _, col := range cols {
colMap[col.ID] = &col.FieldType
}
prefix := t.RecordPrefix()
for it.Valid() && it.Key().HasPrefix(prefix) {
// first kv pair is row lock information.
// TODO: check valid lock
// get row handle
handle, err := tablecodec.DecodeRowKey(it.Key())
if err != nil {
return errors.Trace(err)
}
rowMap, err := tablecodec.DecodeRow(it.Value(), colMap)
if err != nil {
return errors.Trace(err)
}
data := make([]types.Datum, 0, len(cols))
for _, col := range cols {
if col.IsPKHandleColumn(t.Meta()) {
data = append(data, types.NewIntDatum(handle))
} else {
data = append(data, rowMap[col.ID])
}
}
more, err := fn(handle, data, cols)
if !more || err != nil {
return errors.Trace(err)
}
rk := t.RecordKey(handle)
err = kv.NextUntil(it, util.RowKeyPrefixFilter(rk))
if err != nil {
return errors.Trace(err)
}
}
return nil
}
开发者ID:pingcap,项目名称:tidb,代码行数:58,代码来源:tables.go
示例17: TestTable
func (s *testStatisticsSuite) TestTable(c *C) {
tblInfo := &model.TableInfo{
ID: 1,
}
columns := []*model.ColumnInfo{
{
ID: 2,
FieldType: *types.NewFieldType(mysql.TypeLonglong),
},
}
tblInfo.Columns = columns
timestamp := int64(10)
bucketCount := int64(256)
sc := new(variable.StatementContext)
t, err := NewTable(sc, tblInfo, timestamp, s.count, bucketCount, [][]types.Datum{s.samples})
c.Check(err, IsNil)
col := t.Columns[0]
count, err := col.EqualRowCount(sc, types.NewIntDatum(1000))
c.Check(err, IsNil)
c.Check(count, Equals, int64(2))
count, err = col.LessRowCount(sc, types.NewIntDatum(2000))
c.Check(err, IsNil)
c.Check(count, Equals, int64(19955))
count, err = col.BetweenRowCount(sc, types.NewIntDatum(3000), types.NewIntDatum(3500))
c.Check(err, IsNil)
c.Check(count, Equals, int64(5075))
str := t.String()
log.Debug(str)
c.Check(len(str), Greater, 0)
tpb, err := t.ToPB()
c.Check(err, IsNil)
data, err := proto.Marshal(tpb)
c.Check(err, IsNil)
ntpb := &TablePB{}
err = proto.Unmarshal(data, ntpb)
c.Check(err, IsNil)
nt, err := TableFromPB(tblInfo, ntpb)
c.Check(err, IsNil)
c.Check(nt.String(), Equals, str)
}
开发者ID:pingcap,项目名称:tidb,代码行数:43,代码来源:statistics_test.go
示例18: likeToScalarFunc
func (er *expressionRewriter) likeToScalarFunc(v *ast.PatternLikeExpr) {
l := len(er.ctxStack)
er.checkArgsOneColumn(er.ctxStack[l-2:]...)
if er.err != nil {
return
}
function := er.notToExpression(v.Not, ast.Like, &v.Type,
er.ctxStack[l-2], er.ctxStack[l-1], &expression.Constant{Value: types.NewIntDatum(int64(v.Escape))})
er.ctxStack = er.ctxStack[:l-2]
er.ctxStack = append(er.ctxStack, function)
}
开发者ID:pingcap,项目名称:tidb,代码行数:11,代码来源:expression_rewriter.go
示例19: TestCutKey
func (s *testTableCodecSuite) TestCutKey(c *C) {
colIDs := []int64{1, 2, 3}
values := []types.Datum{types.NewIntDatum(1), types.NewBytesDatum([]byte("abc")), types.NewFloat64Datum(5.5)}
handle := types.NewIntDatum(100)
values = append(values, handle)
encodedValue, err := codec.EncodeKey(nil, values...)
c.Assert(err, IsNil)
tableID := int64(4)
indexID := int64(5)
indexKey := EncodeIndexSeekKey(tableID, indexID, encodedValue)
valuesMap, handleBytes, err := CutIndexKey(indexKey, colIDs)
c.Assert(err, IsNil)
for i, colID := range colIDs {
valueBytes := valuesMap[colID]
var val types.Datum
_, val, _ = codec.DecodeOne(valueBytes)
c.Assert(val, DeepEquals, values[i])
}
_, handleVal, _ := codec.DecodeOne(handleBytes)
c.Assert(handleVal, DeepEquals, types.NewIntDatum(100))
}
开发者ID:pingcap,项目名称:tidb,代码行数:21,代码来源:tablecodec_test.go
示例20: TestPseudoTable
func (s *testStatisticsSuite) TestPseudoTable(c *C) {
ti := &model.TableInfo{}
ti.Columns = append(ti.Columns, &model.ColumnInfo{
ID: 1,
FieldType: *types.NewFieldType(mysql.TypeLonglong),
})
tbl := PseudoTable(ti)
c.Assert(tbl.Count, Greater, int64(0))
c.Assert(tbl.TS, Greater, int64(0))
col := tbl.Columns[0]
c.Assert(col.ID, Greater, int64(0))
c.Assert(col.NDV, Greater, int64(0))
count, err := col.LessRowCount(types.NewIntDatum(100))
c.Assert(err, IsNil)
c.Assert(count, Equals, int64(3333))
count, err = col.EqualRowCount(types.NewIntDatum(1000))
c.Assert(err, IsNil)
c.Assert(count, Equals, int64(1000))
count, err = col.BetweenRowCount(types.NewIntDatum(1000), types.NewIntDatum(5000))
c.Assert(err, IsNil)
c.Assert(count, Equals, int64(2500))
}
开发者ID:XuHuaiyu,项目名称:tidb,代码行数:22,代码来源:statistics_test.go
注:本文中的github.com/pingcap/tidb/util/types.NewIntDatum函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论