github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/table/scanner/scan_raw.go (about)

     1  package scanner
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
    12  
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/decimal"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/types"
    15  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
    16  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    17  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xstring"
    18  )
    19  
    20  type rawConverter struct {
    21  	*valueScanner
    22  }
    23  
    24  func (s *rawConverter) String() (v []byte) {
    25  	s.unwrap()
    26  
    27  	return s.bytes()
    28  }
    29  
    30  func (s *rawConverter) HasItems() bool {
    31  	return s.hasItems()
    32  }
    33  
    34  func (s *rawConverter) HasNextItem() bool {
    35  	return s.hasItems() && s.nextItem < len(s.row.GetItems())
    36  }
    37  
    38  func (s *rawConverter) Path() string {
    39  	var buf bytes.Buffer
    40  	_, _ = s.WritePathTo(&buf)
    41  
    42  	return buf.String()
    43  }
    44  
    45  func (s *rawConverter) WritePathTo(w io.Writer) (n int64, err error) {
    46  	for sp := 0; sp < s.stack.size(); sp++ {
    47  		if sp > 0 {
    48  			var m int
    49  			m, err = io.WriteString(w, ".")
    50  			if err != nil {
    51  				return n, xerrors.WithStackTrace(err)
    52  			}
    53  			n += int64(m)
    54  		}
    55  		x := s.stack.get(sp)
    56  		s := x.name
    57  		if s == "" {
    58  			s = strconv.Itoa(x.i)
    59  		}
    60  		var m int
    61  		m, err = io.WriteString(w, s)
    62  		if err != nil {
    63  			return n, xerrors.WithStackTrace(err)
    64  		}
    65  		n += int64(m)
    66  	}
    67  
    68  	return n, nil
    69  }
    70  
    71  func (s *rawConverter) Type() types.Type {
    72  	return s.getType()
    73  }
    74  
    75  func (s *rawConverter) Bool() (v bool) {
    76  	if s.Err() != nil {
    77  		return
    78  	}
    79  	s.unwrap()
    80  
    81  	return s.bool()
    82  }
    83  
    84  func (s *rawConverter) Int8() (v int8) {
    85  	if s.Err() != nil {
    86  		return
    87  	}
    88  	s.unwrap()
    89  
    90  	return s.int8()
    91  }
    92  
    93  func (s *rawConverter) Uint8() (v uint8) {
    94  	if s.Err() != nil {
    95  		return
    96  	}
    97  	s.unwrap()
    98  
    99  	return s.uint8()
   100  }
   101  
   102  func (s *rawConverter) Int16() (v int16) {
   103  	if s.Err() != nil {
   104  		return
   105  	}
   106  	s.unwrap()
   107  
   108  	return s.int16()
   109  }
   110  
   111  func (s *rawConverter) Uint16() (v uint16) {
   112  	if s.Err() != nil {
   113  		return
   114  	}
   115  	s.unwrap()
   116  
   117  	return s.uint16()
   118  }
   119  
   120  func (s *rawConverter) Int32() (v int32) {
   121  	if s.Err() != nil {
   122  		return
   123  	}
   124  	s.unwrap()
   125  
   126  	return s.int32()
   127  }
   128  
   129  func (s *rawConverter) Uint32() (v uint32) {
   130  	if s.Err() != nil {
   131  		return
   132  	}
   133  	s.unwrap()
   134  
   135  	return s.uint32()
   136  }
   137  
   138  func (s *rawConverter) Int64() (v int64) {
   139  	if s.Err() != nil {
   140  		return
   141  	}
   142  	s.unwrap()
   143  
   144  	return s.int64()
   145  }
   146  
   147  func (s *rawConverter) Uint64() (v uint64) {
   148  	if s.Err() != nil {
   149  		return
   150  	}
   151  	s.unwrap()
   152  
   153  	return s.uint64()
   154  }
   155  
   156  func (s *rawConverter) Float() (v float32) {
   157  	if s.Err() != nil {
   158  		return
   159  	}
   160  	s.unwrap()
   161  
   162  	return s.float()
   163  }
   164  
   165  func (s *rawConverter) Double() (v float64) {
   166  	if s.Err() != nil {
   167  		return
   168  	}
   169  	s.unwrap()
   170  
   171  	return s.double()
   172  }
   173  
   174  func (s *rawConverter) Date() (v time.Time) {
   175  	s.unwrap()
   176  
   177  	return value.DateToTime(s.uint32())
   178  }
   179  
   180  func (s *rawConverter) Datetime() (v time.Time) {
   181  	s.unwrap()
   182  
   183  	return value.DatetimeToTime(s.uint32())
   184  }
   185  
   186  func (s *rawConverter) Timestamp() (v time.Time) {
   187  	s.unwrap()
   188  
   189  	return value.TimestampToTime(s.uint64())
   190  }
   191  
   192  func (s *rawConverter) Interval() (v time.Duration) {
   193  	s.unwrap()
   194  
   195  	return value.IntervalToDuration(s.int64())
   196  }
   197  
   198  func (s *rawConverter) TzDate() (v time.Time) {
   199  	s.unwrap()
   200  	if s.isNull() {
   201  		return
   202  	}
   203  	src, err := value.TzDateToTime(s.text())
   204  	if err != nil {
   205  		_ = s.errorf(0, "rawConverter.TzDate(): %w", err)
   206  	}
   207  
   208  	return src
   209  }
   210  
   211  func (s *rawConverter) TzDatetime() (v time.Time) {
   212  	s.unwrap()
   213  	if s.isNull() {
   214  		return
   215  	}
   216  	src, err := value.TzDatetimeToTime(s.text())
   217  	if err != nil {
   218  		_ = s.errorf(0, "rawConverter.TzDatetime(): %w", err)
   219  	}
   220  
   221  	return src
   222  }
   223  
   224  func (s *rawConverter) TzTimestamp() (v time.Time) {
   225  	s.unwrap()
   226  	if s.isNull() {
   227  		return
   228  	}
   229  	src, err := value.TzTimestampToTime(s.text())
   230  	if err != nil {
   231  		_ = s.errorf(0, "rawConverter.TzTimestamp(): %w", err)
   232  	}
   233  
   234  	return src
   235  }
   236  
   237  func (s *rawConverter) UTF8() (v string) {
   238  	if s.Err() != nil {
   239  		return
   240  	}
   241  	s.unwrap()
   242  
   243  	return s.text()
   244  }
   245  
   246  func (s *rawConverter) YSON() (v []byte) {
   247  	s.unwrap()
   248  
   249  	return s.bytes()
   250  }
   251  
   252  func (s *rawConverter) JSON() (v []byte) {
   253  	s.unwrap()
   254  
   255  	return xstring.ToBytes(s.text())
   256  }
   257  
   258  func (s *rawConverter) JSONDocument() (v []byte) {
   259  	s.unwrap()
   260  
   261  	return xstring.ToBytes(s.text())
   262  }
   263  
   264  func (s *rawConverter) UUID() (v [16]byte) {
   265  	if s.Err() != nil {
   266  		return
   267  	}
   268  	s.unwrap()
   269  
   270  	return s.uint128()
   271  }
   272  
   273  func (s *rawConverter) DyNumber() (v string) {
   274  	if s.Err() != nil {
   275  		return
   276  	}
   277  	s.unwrap()
   278  
   279  	return s.text()
   280  }
   281  
   282  func (s *rawConverter) Any() interface{} {
   283  	return s.any()
   284  }
   285  
   286  // Value returns current item under scan as value
   287  func (s *rawConverter) Value() value.Value {
   288  	if s.Err() != nil {
   289  		return nil
   290  	}
   291  	s.unwrap()
   292  
   293  	return s.value()
   294  }
   295  
   296  func (s *rawConverter) AssertType(t types.Type) bool {
   297  	return s.assertCurrentTypeIs(t)
   298  }
   299  
   300  func (s *rawConverter) Null() {
   301  	if s.Err() != nil || !s.assertCurrentTypeNullable() {
   302  		return
   303  	}
   304  	s.null()
   305  }
   306  
   307  func (s *rawConverter) IsNull() bool {
   308  	if s.Err() != nil {
   309  		return false
   310  	}
   311  
   312  	return s.isNull()
   313  }
   314  
   315  func (s *rawConverter) IsOptional() bool {
   316  	if s.Err() != nil {
   317  		return false
   318  	}
   319  
   320  	return s.isCurrentTypeOptional()
   321  }
   322  
   323  // --------non-primitive---------
   324  
   325  func (s *rawConverter) ListIn() (size int) {
   326  	if s.Err() != nil {
   327  		return 0
   328  	}
   329  	x := s.stack.current()
   330  	if s.assertTypeList(x.t) != nil {
   331  		return s.itemsIn()
   332  	}
   333  
   334  	return 0
   335  }
   336  
   337  func (s *rawConverter) ListItem(i int) {
   338  	if s.Err() != nil {
   339  		return
   340  	}
   341  	p := s.stack.parent()
   342  	if !s.itemsBoundsCheck(p.v.GetItems(), i) {
   343  		return
   344  	}
   345  	if t := s.assertTypeList(p.t); t != nil {
   346  		s.stack.set(item{
   347  			i: i,
   348  			t: t.ListType.GetItem(),
   349  			v: p.v.GetItems()[i],
   350  		})
   351  	}
   352  }
   353  
   354  func (s *rawConverter) ListOut() {
   355  	if s.Err() != nil {
   356  		return
   357  	}
   358  	p := s.stack.parent()
   359  	if t := s.assertTypeList(p.t); t != nil {
   360  		s.itemsOut()
   361  	}
   362  }
   363  
   364  func (s *rawConverter) TupleIn() (size int) {
   365  	if s.Err() != nil {
   366  		return 0
   367  	}
   368  	x := s.stack.current()
   369  	if s.assertTypeTuple(x.t) != nil {
   370  		return s.itemsIn()
   371  	}
   372  
   373  	return 0
   374  }
   375  
   376  func (s *rawConverter) TupleItem(i int) {
   377  	if s.Err() != nil {
   378  		return
   379  	}
   380  	p := s.stack.parent()
   381  	if !s.itemsBoundsCheck(p.v.GetItems(), i) {
   382  		return
   383  	}
   384  	if t := s.assertTypeTuple(p.t); t != nil {
   385  		s.stack.set(item{
   386  			i: i,
   387  			t: t.TupleType.GetElements()[i],
   388  			v: p.v.GetItems()[i],
   389  		})
   390  	}
   391  }
   392  
   393  func (s *rawConverter) TupleOut() {
   394  	if s.Err() != nil {
   395  		return
   396  	}
   397  	p := s.stack.parent()
   398  	if t := s.assertTypeTuple(p.t); t != nil {
   399  		s.itemsOut()
   400  	}
   401  }
   402  
   403  func (s *rawConverter) StructIn() (size int) {
   404  	if s.Err() != nil {
   405  		return 0
   406  	}
   407  	x := s.stack.current()
   408  	if s.assertTypeStruct(x.t) != nil {
   409  		return s.itemsIn()
   410  	}
   411  
   412  	return 0
   413  }
   414  
   415  func (s *rawConverter) StructField(i int) (name string) {
   416  	if s.Err() != nil {
   417  		return
   418  	}
   419  	p := s.stack.parent()
   420  	if !s.itemsBoundsCheck(p.v.GetItems(), i) {
   421  		return
   422  	}
   423  	if t := s.assertTypeStruct(p.t); t != nil {
   424  		m := t.StructType.GetMembers()[i]
   425  		name = m.GetName()
   426  		s.stack.set(item{
   427  			name: m.GetName(),
   428  			i:    i,
   429  			t:    m.GetType(),
   430  			v:    p.v.GetItems()[i],
   431  		})
   432  	}
   433  
   434  	return
   435  }
   436  
   437  func (s *rawConverter) StructOut() {
   438  	if s.Err() != nil {
   439  		return
   440  	}
   441  	p := s.stack.parent()
   442  	if t := s.assertTypeStruct(p.t); t != nil {
   443  		s.itemsOut()
   444  	}
   445  }
   446  
   447  func (s *rawConverter) DictIn() (size int) {
   448  	if s.Err() != nil {
   449  		return 0
   450  	}
   451  	x := s.stack.current()
   452  	if s.assertTypeDict(x.t) != nil {
   453  		return s.pairsIn()
   454  	}
   455  
   456  	return 0
   457  }
   458  
   459  func (s *rawConverter) DictKey(i int) {
   460  	if s.Err() != nil {
   461  		return
   462  	}
   463  	p := s.stack.parent()
   464  	if !s.pairsBoundsCheck(p.v.GetPairs(), i) {
   465  		return
   466  	}
   467  	if t := s.assertTypeDict(p.t); t != nil {
   468  		s.stack.set(item{
   469  			i: i,
   470  			t: t.DictType.GetKey(),
   471  			v: p.v.GetPairs()[i].GetKey(),
   472  		})
   473  	}
   474  }
   475  
   476  func (s *rawConverter) DictPayload(i int) {
   477  	if s.Err() != nil {
   478  		return
   479  	}
   480  	p := s.stack.parent()
   481  	if !s.pairsBoundsCheck(p.v.GetPairs(), i) {
   482  		return
   483  	}
   484  	if t := s.assertTypeDict(p.t); t != nil {
   485  		s.stack.set(item{
   486  			i: i,
   487  			t: t.DictType.GetPayload(),
   488  			v: p.v.GetPairs()[i].GetPayload(),
   489  		})
   490  	}
   491  }
   492  
   493  func (s *rawConverter) DictOut() {
   494  	if s.Err() != nil {
   495  		return
   496  	}
   497  	p := s.stack.parent()
   498  	if t := s.assertTypeDict(p.t); t != nil {
   499  		s.pairsOut()
   500  	}
   501  }
   502  
   503  func (s *rawConverter) Variant() (name string, index uint32) {
   504  	if s.Err() != nil {
   505  		return
   506  	}
   507  	x := s.stack.current()
   508  	t := s.assertTypeVariant(x.t)
   509  	if t == nil {
   510  		return
   511  	}
   512  	v, index := s.variant()
   513  	if v == nil {
   514  		return
   515  	}
   516  	name, typ := s.unwrapVariantType(t, index)
   517  	s.stack.scanItem.v = nil
   518  	s.stack.set(item{
   519  		name: name,
   520  		i:    int(index),
   521  		t:    typ,
   522  		v:    v,
   523  	})
   524  
   525  	return name, index
   526  }
   527  
   528  func (s *rawConverter) Unwrap() {
   529  	if s.Err() != nil {
   530  		return
   531  	}
   532  	x := s.stack.current()
   533  	t := s.assertTypeOptional(x.t)
   534  	if t == nil {
   535  		return
   536  	}
   537  	v := x.v
   538  	if isOptional(t.OptionalType.GetItem()) {
   539  		v = s.unwrapValue()
   540  	}
   541  	s.stack.enter()
   542  	s.stack.set(item{
   543  		name: "*",
   544  		t:    t.OptionalType.GetItem(),
   545  		v:    v,
   546  	})
   547  }
   548  
   549  func (s *rawConverter) Decimal(t types.Type) (v [16]byte) {
   550  	if s.Err() != nil {
   551  		return
   552  	}
   553  	s.unwrap()
   554  	if !s.assertCurrentTypeDecimal(t) {
   555  		return
   556  	}
   557  
   558  	return s.uint128()
   559  }
   560  
   561  func (s *rawConverter) UnwrapDecimal() decimal.Decimal {
   562  	if s.Err() != nil {
   563  		return decimal.Decimal{}
   564  	}
   565  	s.unwrap()
   566  	d := s.assertTypeDecimal(s.stack.current().t)
   567  	if d == nil {
   568  		return decimal.Decimal{}
   569  	}
   570  
   571  	return decimal.Decimal{
   572  		Bytes:     s.uint128(),
   573  		Precision: d.DecimalType.GetPrecision(),
   574  		Scale:     d.DecimalType.GetScale(),
   575  	}
   576  }
   577  
   578  func (s *rawConverter) IsDecimal() bool {
   579  	if s.Err() != nil {
   580  		return false
   581  	}
   582  
   583  	return s.isCurrentTypeDecimal()
   584  }
   585  
   586  func isEqualDecimal(d *Ydb.DecimalType, t types.Type) bool {
   587  	w := t.(*types.Decimal)
   588  
   589  	return d.GetPrecision() == w.Precision() && d.GetScale() == w.Scale()
   590  }
   591  
   592  func (s *rawConverter) isCurrentTypeDecimal() bool {
   593  	c := s.stack.current()
   594  	_, ok := c.t.GetType().(*Ydb.Type_DecimalType)
   595  
   596  	return ok
   597  }
   598  
   599  func (s *rawConverter) unwrapVariantType(typ *Ydb.Type_VariantType, index uint32) (name string, t *Ydb.Type) {
   600  	i := int(index)
   601  	switch x := typ.VariantType.GetType().(type) {
   602  	case *Ydb.VariantType_TupleItems:
   603  		if i >= len(x.TupleItems.GetElements()) {
   604  			_ = s.errorf(0, "unimplemented")
   605  
   606  			return
   607  		}
   608  
   609  		return "", x.TupleItems.GetElements()[i]
   610  
   611  	case *Ydb.VariantType_StructItems:
   612  		if i >= len(x.StructItems.GetMembers()) {
   613  			_ = s.errorf(0, "unimplemented")
   614  
   615  			return
   616  		}
   617  		m := x.StructItems.GetMembers()[i]
   618  
   619  		return m.GetName(), m.GetType()
   620  
   621  	default:
   622  		panic("unexpected variant items types")
   623  	}
   624  }
   625  
   626  func (s *rawConverter) variant() (v *Ydb.Value, index uint32) {
   627  	v = s.unwrapValue()
   628  	if v == nil {
   629  		return
   630  	}
   631  	x := s.stack.current() // Is not nil if unwrapValue succeeded.
   632  	index = x.v.GetVariantIndex()
   633  
   634  	return
   635  }
   636  
   637  func (s *rawConverter) itemsIn() int {
   638  	x := s.stack.current()
   639  	if x.isEmpty() {
   640  		return -1
   641  	}
   642  	s.stack.enter()
   643  
   644  	return len(x.v.GetItems())
   645  }
   646  
   647  func (s *rawConverter) itemsOut() {
   648  	s.stack.leave()
   649  }
   650  
   651  func (s *rawConverter) itemsBoundsCheck(xs []*Ydb.Value, i int) bool {
   652  	return s.boundsCheck(len(xs), i)
   653  }
   654  
   655  func (s *rawConverter) pairsIn() int {
   656  	x := s.stack.current()
   657  	if x.isEmpty() {
   658  		return -1
   659  	}
   660  	s.stack.enter()
   661  
   662  	return len(x.v.GetPairs())
   663  }
   664  
   665  func (s *rawConverter) pairsOut() {
   666  	s.stack.leave()
   667  }
   668  
   669  func (s *rawConverter) pairsBoundsCheck(xs []*Ydb.ValuePair, i int) bool {
   670  	return s.boundsCheck(len(xs), i)
   671  }
   672  
   673  func (s *rawConverter) boundsCheck(n, i int) bool {
   674  	if i < 0 || n <= i {
   675  		s.boundsError(n, i)
   676  
   677  		return false
   678  	}
   679  
   680  	return true
   681  }
   682  
   683  func (s *valueScanner) assertTypeOptional(typ *Ydb.Type) (t *Ydb.Type_OptionalType) {
   684  	x := typ.GetType()
   685  	if t, _ = x.(*Ydb.Type_OptionalType); t == nil {
   686  		s.typeError(x, t)
   687  	}
   688  
   689  	return
   690  }
   691  
   692  func (s *rawConverter) assertCurrentTypeNullable() bool {
   693  	c := s.stack.current()
   694  	if isOptional(c.t) {
   695  		return true
   696  	}
   697  	p := s.stack.parent()
   698  	if isOptional(p.t) {
   699  		return true
   700  	}
   701  	_ = s.errorf(
   702  		1,
   703  		"not nullable types at %q: %s (%d %s %s)",
   704  		s.Path(),
   705  		s.Type(),
   706  		s.stack.size(),
   707  		c.t,
   708  		p.t,
   709  	)
   710  
   711  	return false
   712  }
   713  
   714  func (s *rawConverter) assertCurrentTypeIs(t types.Type) bool {
   715  	c := s.stack.current()
   716  	act := types.TypeFromYDB(c.t)
   717  	if !types.Equal(act, t) {
   718  		_ = s.errorf(
   719  			1,
   720  			"unexpected types at %q %s: %s; want %s",
   721  			s.Path(),
   722  			s.Type(),
   723  			act,
   724  			t,
   725  		)
   726  
   727  		return false
   728  	}
   729  
   730  	return true
   731  }
   732  
   733  func (s *rawConverter) assertCurrentTypeDecimal(t types.Type) bool {
   734  	d := s.assertTypeDecimal(s.stack.current().t)
   735  	if d == nil {
   736  		return false
   737  	}
   738  	if !isEqualDecimal(d.DecimalType, t) {
   739  		s.decimalTypeError(t)
   740  
   741  		return false
   742  	}
   743  
   744  	return true
   745  }
   746  
   747  func (s *rawConverter) assertTypeList(typ *Ydb.Type) (t *Ydb.Type_ListType) {
   748  	x := typ.GetType()
   749  	if t, _ = x.(*Ydb.Type_ListType); t == nil {
   750  		s.typeError(x, t)
   751  	}
   752  
   753  	return
   754  }
   755  
   756  func (s *rawConverter) assertTypeTuple(typ *Ydb.Type) (t *Ydb.Type_TupleType) {
   757  	x := typ.GetType()
   758  	if t, _ = x.(*Ydb.Type_TupleType); t == nil {
   759  		s.typeError(x, t)
   760  	}
   761  
   762  	return
   763  }
   764  
   765  func (s *rawConverter) assertTypeStruct(typ *Ydb.Type) (t *Ydb.Type_StructType) {
   766  	x := typ.GetType()
   767  	if t, _ = x.(*Ydb.Type_StructType); t == nil {
   768  		s.typeError(x, t)
   769  	}
   770  
   771  	return
   772  }
   773  
   774  func (s *rawConverter) assertTypeDict(typ *Ydb.Type) (t *Ydb.Type_DictType) {
   775  	x := typ.GetType()
   776  	if t, _ = x.(*Ydb.Type_DictType); t == nil {
   777  		s.typeError(x, t)
   778  	}
   779  
   780  	return
   781  }
   782  
   783  func (s *rawConverter) assertTypeDecimal(typ *Ydb.Type) (t *Ydb.Type_DecimalType) {
   784  	x := typ.GetType()
   785  	if t, _ = x.(*Ydb.Type_DecimalType); t == nil {
   786  		s.typeError(x, t)
   787  	}
   788  
   789  	return
   790  }
   791  
   792  func (s *rawConverter) assertTypeVariant(typ *Ydb.Type) (t *Ydb.Type_VariantType) {
   793  	x := typ.GetType()
   794  	if t, _ = x.(*Ydb.Type_VariantType); t == nil {
   795  		s.typeError(x, t)
   796  	}
   797  
   798  	return
   799  }
   800  
   801  func (s *rawConverter) boundsError(n, i int) {
   802  	_ = s.errorf(
   803  		1, "index out of range: %d; have %d",
   804  		i, n,
   805  	)
   806  }
   807  
   808  func (s *rawConverter) decimalTypeError(t types.Type) {
   809  	_ = s.errorf(
   810  		1, "unexpected decimal types at %q %s: want %s",
   811  		s.Path(), s.getType(), t,
   812  	)
   813  }
   814  
   815  func nameIface(v interface{}) string {
   816  	if v == nil {
   817  		return "nil"
   818  	}
   819  	t := reflect.TypeOf(v)
   820  	s := t.String()
   821  	s = strings.TrimPrefix(s, "*Ydb.Value_")
   822  	s = strings.TrimSuffix(s, "valueType")
   823  	s = strings.TrimPrefix(s, "*Ydb.Type_")
   824  	s = strings.TrimSuffix(s, "Type")
   825  
   826  	return s
   827  }