mirror of
https://github.com/chaisql/chai.git
synced 2025-09-26 19:51:21 +08:00
rename blob type to bytea
This commit is contained in:
@@ -57,9 +57,9 @@ func TestColumnConstraintsAdd(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Default value conversion, typed constraint, nextval with blob",
|
||||
"Default value conversion, typed constraint, nextval with bytea",
|
||||
[]*database.ColumnConstraint{{Column: "a", Type: types.TypeInteger}},
|
||||
database.ColumnConstraint{Column: "b", Type: types.TypeBlob, DefaultValue: expr.Constraint(&functions.NextVal{Expr: testutil.TextValue("seq")})},
|
||||
database.ColumnConstraint{Column: "b", Type: types.TypeBytea, DefaultValue: expr.Constraint(&functions.NextVal{Expr: testutil.TextValue("seq")})},
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
|
@@ -58,7 +58,7 @@ func (idx *Index) Set(vs []types.Value, key []byte) error {
|
||||
}
|
||||
|
||||
// append the key to the values
|
||||
values := append(vs, types.NewBlobValue(key))
|
||||
values := append(vs, types.NewByteaValue(key))
|
||||
|
||||
// create the key for the tree
|
||||
treeKey := tree.NewKey(values...)
|
||||
|
@@ -4,17 +4,17 @@ import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
func EncodeBlob(dst []byte, x []byte) []byte {
|
||||
func EncodeBytea(dst []byte, x []byte) []byte {
|
||||
// encode the length as a varint
|
||||
buf := make([]byte, binary.MaxVarintLen64+1)
|
||||
buf[0] = BlobValue
|
||||
buf[0] = ByteaValue
|
||||
n := binary.PutUvarint(buf[1:], uint64(len(x)))
|
||||
|
||||
dst = append(dst, buf[:n+1]...)
|
||||
return append(dst, x...)
|
||||
}
|
||||
|
||||
func DecodeBlob(b []byte) ([]byte, int) {
|
||||
func DecodeBytea(b []byte) ([]byte, int) {
|
||||
// skip type
|
||||
b = b[1:]
|
||||
// decode the length as a varint
|
||||
|
@@ -34,24 +34,24 @@ func TestEncodeDecodeText(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeDecodeBlob(t *testing.T) {
|
||||
a100 := append([]byte{encoding.BlobValue}, makeUvarint(100)...)
|
||||
func TestEncodeDecodeBytea(t *testing.T) {
|
||||
a100 := append([]byte{encoding.ByteaValue}, makeUvarint(100)...)
|
||||
a100 = append(a100, bytes.Repeat([]byte{'a'}, 100)...)
|
||||
tests := []struct {
|
||||
input []byte
|
||||
want []byte
|
||||
}{
|
||||
{[]byte{}, []byte{encoding.BlobValue, makeUvarint(0)[0]}},
|
||||
{[]byte{'a'}, []byte{encoding.BlobValue, makeUvarint(1)[0], 'a'}},
|
||||
{[]byte{}, []byte{encoding.ByteaValue, makeUvarint(0)[0]}},
|
||||
{[]byte{'a'}, []byte{encoding.ByteaValue, makeUvarint(1)[0], 'a'}},
|
||||
{bytes.Repeat([]byte{'a'}, 100), a100},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%v", test.input), func(t *testing.T) {
|
||||
got := encoding.EncodeBlob(nil, test.input)
|
||||
got := encoding.EncodeBytea(nil, test.input)
|
||||
require.Equal(t, test.want, got)
|
||||
|
||||
x, n := encoding.DecodeBlob(got)
|
||||
x, n := encoding.DecodeBytea(got)
|
||||
require.Equal(t, test.input, x)
|
||||
require.Equal(t, len(test.input)+len(makeUvarint(len(test.input)))+1, n)
|
||||
})
|
||||
|
@@ -57,7 +57,7 @@ func Skip(b []byte) int {
|
||||
return 5
|
||||
case Int64Value, Uint64Value, Float64Value, DESC_Int64Value, DESC_Uint64Value, DESC_Float64Value:
|
||||
return 9
|
||||
case TextValue, BlobValue, DESC_TextValue, DESC_BlobValue:
|
||||
case TextValue, ByteaValue, DESC_TextValue, DESC_ByteaValue:
|
||||
l, n := binary.Uvarint(b[1:])
|
||||
return n + int(l) + 1
|
||||
case ArrayValue, DESC_ArrayValue:
|
||||
@@ -193,7 +193,7 @@ func compareNonEmptyValues(t byte, a, b []byte) (cmp int, n int) {
|
||||
return bytes.Compare(a[1:3], b[1:3]), 3
|
||||
case Int8Value, Uint8Value:
|
||||
return bytes.Compare(a[1:2], b[1:2]), 2
|
||||
case TextValue, BlobValue:
|
||||
case TextValue, ByteaValue:
|
||||
l, n := binary.Uvarint(a[1:])
|
||||
n++
|
||||
enda := n + int(l)
|
||||
@@ -356,7 +356,7 @@ func abbreviatedValue(key []byte) uint64 {
|
||||
}
|
||||
x := DecodeUint64(key[1:])
|
||||
return uint64(x) >> 24
|
||||
case TextValue, BlobValue:
|
||||
case TextValue, ByteaValue:
|
||||
var abbv uint64
|
||||
l, n := binary.Uvarint(key[1:])
|
||||
n++
|
||||
|
@@ -82,7 +82,7 @@ func TestCompare(t *testing.T) {
|
||||
{`("a")`, `("aa")`, -1},
|
||||
{`("aaaa")`, `("aab")`, -1},
|
||||
|
||||
// blob
|
||||
// bytea
|
||||
{`("\xaa")`, `("\xaa")`, 0},
|
||||
{`("\xab")`, `("\xaa")`, 1},
|
||||
{`("\xaa")`, `("\xab")`, -1},
|
||||
@@ -238,11 +238,11 @@ func TestAbbreviatedKey(t *testing.T) {
|
||||
{`(1, "abcdefghijkl` + strings.Repeat("m", 100) + `")`, 1<<48 | uint64(encoding.TextValue)<<40 | uint64('a')<<32 | uint64('b')<<24 | uint64('c')<<16 | uint64('d')<<8 | uint64('e')},
|
||||
{`(1, "abcdefghijkl` + strings.Repeat("m", 10000) + `")`, 1<<48 | uint64(encoding.TextValue)<<40 | uint64('a')<<32 | uint64('b')<<24 | uint64('c')<<16 | uint64('d')<<8 | uint64('e')},
|
||||
|
||||
// blob
|
||||
{`(1, "\xab")`, 1<<48 | uint64(encoding.BlobValue)<<40 | uint64(0xab)<<32},
|
||||
{`(1, "\xabcdefabcdef")`, 1<<48 | uint64(encoding.BlobValue)<<40 | uint64(0xab)<<32 | uint64(0xcd)<<24 | uint64(0xef)<<16 | uint64(0xab)<<8 | uint64(0xcd)},
|
||||
{`(1, "\xabcdefabcdef` + strings.Repeat("c", 100) + `")`, 1<<48 | uint64(encoding.BlobValue)<<40 | uint64(0xab)<<32 | uint64(0xcd)<<24 | uint64(0xef)<<16 | uint64(0xab)<<8 | uint64(0xcd)},
|
||||
{`(1, "\xabcdefabcdef` + strings.Repeat("c", 1000) + `")`, 1<<48 | uint64(encoding.BlobValue)<<40 | uint64(0xab)<<32 | uint64(0xcd)<<24 | uint64(0xef)<<16 | uint64(0xab)<<8 | uint64(0xcd)},
|
||||
// bytea
|
||||
{`(1, "\xab")`, 1<<48 | uint64(encoding.ByteaValue)<<40 | uint64(0xab)<<32},
|
||||
{`(1, "\xabcdefabcdef")`, 1<<48 | uint64(encoding.ByteaValue)<<40 | uint64(0xab)<<32 | uint64(0xcd)<<24 | uint64(0xef)<<16 | uint64(0xab)<<8 | uint64(0xcd)},
|
||||
{`(1, "\xabcdefabcdef` + strings.Repeat("c", 100) + `")`, 1<<48 | uint64(encoding.ByteaValue)<<40 | uint64(0xab)<<32 | uint64(0xcd)<<24 | uint64(0xef)<<16 | uint64(0xab)<<8 | uint64(0xcd)},
|
||||
{`(1, "\xabcdefabcdef` + strings.Repeat("c", 1000) + `")`, 1<<48 | uint64(encoding.ByteaValue)<<40 | uint64(0xab)<<32 | uint64(0xcd)<<24 | uint64(0xef)<<16 | uint64(0xab)<<8 | uint64(0xcd)},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@@ -54,7 +54,7 @@ const (
|
||||
// 101 to 105: 5 types are free
|
||||
|
||||
// Binary
|
||||
BlobValue byte = 103
|
||||
ByteaValue byte = 103
|
||||
|
||||
// 104 to 109: 6 types are free
|
||||
|
||||
@@ -74,7 +74,7 @@ const (
|
||||
// DESC_ prefix means that the value is encoded in reverse order.
|
||||
DESC_ObjectValue byte = 255 - ObjectValue
|
||||
DESC_ArrayValue byte = 255 - ArrayValue
|
||||
DESC_BlobValue byte = 255 - BlobValue
|
||||
DESC_ByteaValue byte = 255 - ByteaValue
|
||||
DESC_TextValue byte = 255 - TextValue
|
||||
DESC_Float64Value byte = 255 - Float64Value
|
||||
DESC_Uint64Value byte = 255 - Uint64Value
|
||||
|
@@ -23,7 +23,7 @@
|
||||
'text'
|
||||
|
||||
> typeof('\xAA')
|
||||
'blob'
|
||||
'bytea'
|
||||
|
||||
> typeof(NULL)
|
||||
'null'
|
||||
|
@@ -69,7 +69,7 @@ func (s *RollbackSegment) Apply(b *pebble.Batch) error {
|
||||
}
|
||||
|
||||
// append the key to the buffer
|
||||
s.buf = encoding.EncodeBlob(s.buf, key)
|
||||
s.buf = encoding.EncodeBytea(s.buf, key)
|
||||
|
||||
err = b.Set(s.buf, v, nil)
|
||||
if err != nil {
|
||||
@@ -114,7 +114,7 @@ func (s *RollbackSegment) Rollback() error {
|
||||
k = k[n:]
|
||||
|
||||
// get the key
|
||||
uk, _ := encoding.DecodeBlob(k)
|
||||
uk, _ := encoding.DecodeBytea(k)
|
||||
v, err := it.ValueAndErr()
|
||||
|
||||
if bytes.Equal(v, tombStone) {
|
||||
|
@@ -119,7 +119,7 @@ func marshalText(dst *bytes.Buffer, v types.Value) error {
|
||||
case types.TypeText:
|
||||
dst.WriteString(strconv.Quote(types.AsString(v)))
|
||||
return nil
|
||||
case types.TypeBlob:
|
||||
case types.TypeBytea:
|
||||
src := types.AsByteSlice(v)
|
||||
dst.WriteString("\"\\x")
|
||||
_, _ = hex.NewEncoder(dst).Write(src)
|
||||
|
@@ -86,9 +86,9 @@ func NewValue(x any) (types.Value, error) {
|
||||
if v == nil {
|
||||
return types.NewNullValue(), nil
|
||||
}
|
||||
return types.NewBlobValue(*v), nil
|
||||
return types.NewByteaValue(*v), nil
|
||||
case []byte:
|
||||
return types.NewBlobValue(v), nil
|
||||
return types.NewByteaValue(v), nil
|
||||
case *string:
|
||||
if v == nil {
|
||||
return types.NewNullValue(), nil
|
||||
|
@@ -407,7 +407,7 @@ func (rs *Rows) Next(dest []driver.Value) error {
|
||||
cp := make([]byte, len(s))
|
||||
copy(cp, s)
|
||||
dest[i] = string(cp)
|
||||
case types.TypeBlob:
|
||||
case types.TypeBytea:
|
||||
// Make a copy of the byte slice to avoid issues with re-use.
|
||||
b := types.AsByteSlice(v)
|
||||
cp := make([]byte, len(b))
|
||||
|
@@ -221,7 +221,7 @@ func (p *Parser) parseUnaryExpr(allowed ...scanner.Token) (expr.Expr, error) {
|
||||
return expr.PositionalParam(pp), nil
|
||||
case scanner.STRING:
|
||||
if strings.HasPrefix(lit, `\x`) {
|
||||
blob, err := hex.DecodeString(lit[2:])
|
||||
bytea, err := hex.DecodeString(lit[2:])
|
||||
if err != nil {
|
||||
if bt, ok := err.(hex.InvalidByteError); ok {
|
||||
return nil, fmt.Errorf("invalid hexadecimal digit: %c", bt)
|
||||
@@ -229,7 +229,7 @@ func (p *Parser) parseUnaryExpr(allowed ...scanner.Token) (expr.Expr, error) {
|
||||
|
||||
return nil, err
|
||||
}
|
||||
return expr.LiteralValue{Value: types.NewBlobValue(blob)}, nil
|
||||
return expr.LiteralValue{Value: types.NewByteaValue(bytea)}, nil
|
||||
}
|
||||
return expr.LiteralValue{Value: types.NewTextValue(lit)}, nil
|
||||
case scanner.NUMBER:
|
||||
@@ -361,8 +361,8 @@ func (p *Parser) parseIdentList() ([]string, error) {
|
||||
func (p *Parser) parseType() (types.Type, error) {
|
||||
tok, pos, lit := p.ScanIgnoreWhitespace()
|
||||
switch tok {
|
||||
case scanner.TYPEBLOB, scanner.TYPEBYTES:
|
||||
return types.TypeBlob, nil
|
||||
case scanner.TYPEBYTEA, scanner.TYPEBYTES:
|
||||
return types.TypeBytea, nil
|
||||
case scanner.TYPEBOOL, scanner.TYPEBOOLEAN:
|
||||
return types.TypeBoolean, nil
|
||||
case scanner.TYPEREAL:
|
||||
|
@@ -35,9 +35,9 @@ func TestParserExpr(t *testing.T) {
|
||||
{"double quoted string", `"10.0"`, testutil.TextValue("10.0"), false},
|
||||
{"single quoted string", "'-10.0'", testutil.TextValue("-10.0"), false},
|
||||
|
||||
// blobs
|
||||
{"blob as hex string", `'\xff'`, testutil.BlobValue([]byte{255}), false},
|
||||
{"invalid blob hex string", `'\xzz'`, nil, true},
|
||||
// byteas
|
||||
{"bytea as hex string", `'\xff'`, testutil.ByteaValue([]byte{255}), false},
|
||||
{"invalid bytea hex string", `'\xzz'`, nil, true},
|
||||
|
||||
// parentheses
|
||||
{"parentheses: empty", "()", nil, true},
|
||||
|
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
// Code heavily inspired by the influxdata/influxql repository
|
||||
// https://github.com/influxdata/influxql/blob/57f403b00b124eb900835c0c944e9b60d848db5e/scanner.go#L12
|
||||
// https://github.com/influxdata/influxql/bytea/57f403b00b124eb900835c0c944e9b60d848db5e/scanner.go#L12
|
||||
|
||||
func init() {
|
||||
keywords = make(map[string]Token)
|
||||
|
@@ -145,7 +145,7 @@ const (
|
||||
|
||||
// Types
|
||||
TYPEBIGINT
|
||||
TYPEBLOB
|
||||
TYPEBYTEA
|
||||
TYPEBOOL
|
||||
TYPEBOOLEAN
|
||||
TYPEBYTES
|
||||
@@ -287,7 +287,7 @@ var tokens = [...]string{
|
||||
WRITE: "WRITE",
|
||||
|
||||
TYPEBIGINT: "BIGINT",
|
||||
TYPEBLOB: "BLOB",
|
||||
TYPEBYTEA: "BYTEA",
|
||||
TYPEBOOL: "BOOL",
|
||||
TYPEBOOLEAN: "BOOLEAN",
|
||||
TYPEBYTES: "BYTES",
|
||||
|
@@ -218,7 +218,7 @@ func (it *TempTreeSortIterator) iterateOnStream() error {
|
||||
}
|
||||
}
|
||||
|
||||
tk := tree.NewKey(v, types.NewTextValue(r.TableName()), types.NewBlobValue(encKey), types.NewBigintValue(counter))
|
||||
tk := tree.NewKey(v, types.NewTextValue(r.TableName()), types.NewByteaValue(encKey), types.NewBigintValue(counter))
|
||||
|
||||
counter++
|
||||
|
||||
|
@@ -158,7 +158,7 @@ func (it *UnionIterator) iterateOnStream(s *Stream) error {
|
||||
}
|
||||
|
||||
key := tree.NewKey(row.Flatten(r)...)
|
||||
buf, err = types.EncodeValuesAsKey(buf, types.NewBlobValue(encKey), types.NewTextValue(tableName))
|
||||
buf, err = types.EncodeValuesAsKey(buf, types.NewByteaValue(encKey), types.NewTextValue(tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -48,9 +48,9 @@ func TextValue(v string) expr.LiteralValue {
|
||||
return expr.LiteralValue{Value: types.NewTextValue(v)}
|
||||
}
|
||||
|
||||
// BlobValue creates a literal value of type Blob.
|
||||
func BlobValue(v []byte) expr.LiteralValue {
|
||||
return expr.LiteralValue{Value: types.NewBlobValue(v)}
|
||||
// ByteaValue creates a literal value of type bytea.
|
||||
func ByteaValue(v []byte) expr.LiteralValue {
|
||||
return expr.LiteralValue{Value: types.NewByteaValue(v)}
|
||||
}
|
||||
|
||||
func ExprList(t testing.TB, s string) expr.LiteralExprList {
|
||||
|
@@ -164,12 +164,12 @@ func TestTreeIterateOnRange(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// keys: [blob, blob] * 100
|
||||
// keys: [bytea, bytea] * 100
|
||||
for i := int32(0); i < 10; i++ {
|
||||
for j := 0; j < 10; j++ {
|
||||
keys = append(keys, tree.NewKey(
|
||||
types.NewBlobValue([]byte(fmt.Sprintf("bar%d", i))),
|
||||
types.NewBlobValue([]byte(fmt.Sprintf("baz%d", j))),
|
||||
types.NewByteaValue([]byte(fmt.Sprintf("bar%d", i))),
|
||||
types.NewByteaValue([]byte(fmt.Sprintf("baz%d", j))),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -280,19 +280,19 @@ func TestTreeIterateOnRange(t *testing.T) {
|
||||
{"<= bar3 desc", nil, tree.NewKey(types.NewTextValue("bar3")), false, 160, 200, tree.SortOrder(0).SetDesc(0)},
|
||||
{"< bar3 desc", nil, tree.NewKey(types.NewTextValue("bar3")), true, 170, 200, tree.SortOrder(0).SetDesc(0)},
|
||||
|
||||
// blob
|
||||
{"= bar3", tree.NewKey(types.NewBlobValue([]byte("bar3"))), tree.NewKey(types.NewBlobValue([]byte("bar3"))), false, 1330, 1340, 0},
|
||||
{">= bar3", tree.NewKey(types.NewBlobValue([]byte("bar3"))), nil, false, 1330, 1400, 0},
|
||||
{"> bar3", tree.NewKey(types.NewBlobValue([]byte("bar3"))), nil, true, 1340, 1400, 0},
|
||||
{"<= bar3", nil, tree.NewKey(types.NewBlobValue([]byte("bar3"))), false, 1300, 1340, 0},
|
||||
{"< bar3", nil, tree.NewKey(types.NewBlobValue([]byte("bar3"))), true, 1300, 1330, 0},
|
||||
// bytea
|
||||
{"= bar3", tree.NewKey(types.NewByteaValue([]byte("bar3"))), tree.NewKey(types.NewByteaValue([]byte("bar3"))), false, 1330, 1340, 0},
|
||||
{">= bar3", tree.NewKey(types.NewByteaValue([]byte("bar3"))), nil, false, 1330, 1400, 0},
|
||||
{"> bar3", tree.NewKey(types.NewByteaValue([]byte("bar3"))), nil, true, 1340, 1400, 0},
|
||||
{"<= bar3", nil, tree.NewKey(types.NewByteaValue([]byte("bar3"))), false, 1300, 1340, 0},
|
||||
{"< bar3", nil, tree.NewKey(types.NewByteaValue([]byte("bar3"))), true, 1300, 1330, 0},
|
||||
|
||||
// blob desc
|
||||
{"= bar3 desc", tree.NewKey(types.NewBlobValue([]byte("bar3"))), tree.NewKey(types.NewBlobValue([]byte("bar3"))), false, 60, 70, tree.SortOrder(0).SetDesc(0)},
|
||||
{">= bar3 desc", tree.NewKey(types.NewBlobValue([]byte("bar3"))), nil, false, 0, 70, tree.SortOrder(0).SetDesc(0)},
|
||||
{"> bar3 desc", tree.NewKey(types.NewBlobValue([]byte("bar3"))), nil, true, 0, 60, tree.SortOrder(0).SetDesc(0)},
|
||||
{"<= bar3 desc", nil, tree.NewKey(types.NewBlobValue([]byte("bar3"))), false, 60, 100, tree.SortOrder(0).SetDesc(0)},
|
||||
{"< bar3 desc", nil, tree.NewKey(types.NewBlobValue([]byte("bar3"))), true, 70, 100, tree.SortOrder(0).SetDesc(0)},
|
||||
// bytea desc
|
||||
{"= bar3 desc", tree.NewKey(types.NewByteaValue([]byte("bar3"))), tree.NewKey(types.NewByteaValue([]byte("bar3"))), false, 60, 70, tree.SortOrder(0).SetDesc(0)},
|
||||
{">= bar3 desc", tree.NewKey(types.NewByteaValue([]byte("bar3"))), nil, false, 0, 70, tree.SortOrder(0).SetDesc(0)},
|
||||
{"> bar3 desc", tree.NewKey(types.NewByteaValue([]byte("bar3"))), nil, true, 0, 60, tree.SortOrder(0).SetDesc(0)},
|
||||
{"<= bar3 desc", nil, tree.NewKey(types.NewByteaValue([]byte("bar3"))), false, 60, 100, tree.SortOrder(0).SetDesc(0)},
|
||||
{"< bar3 desc", nil, tree.NewKey(types.NewByteaValue([]byte("bar3"))), true, 70, 100, tree.SortOrder(0).SetDesc(0)},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@@ -9,62 +9,62 @@ import (
|
||||
"github.com/cockroachdb/errors"
|
||||
)
|
||||
|
||||
var _ TypeDefinition = BlobTypeDef{}
|
||||
var _ TypeDefinition = ByteaTypeDef{}
|
||||
|
||||
type BlobTypeDef struct{}
|
||||
type ByteaTypeDef struct{}
|
||||
|
||||
func (BlobTypeDef) New(v any) Value {
|
||||
return NewBlobValue(v.([]byte))
|
||||
func (ByteaTypeDef) New(v any) Value {
|
||||
return NewByteaValue(v.([]byte))
|
||||
}
|
||||
|
||||
func (BlobTypeDef) Type() Type {
|
||||
return TypeBlob
|
||||
func (ByteaTypeDef) Type() Type {
|
||||
return TypeBytea
|
||||
}
|
||||
|
||||
func (BlobTypeDef) Decode(src []byte) (Value, int) {
|
||||
x, n := encoding.DecodeBlob(src)
|
||||
return NewBlobValue(x), n
|
||||
func (ByteaTypeDef) Decode(src []byte) (Value, int) {
|
||||
x, n := encoding.DecodeBytea(src)
|
||||
return NewByteaValue(x), n
|
||||
}
|
||||
|
||||
func (BlobTypeDef) IsComparableWith(other Type) bool {
|
||||
return other == TypeBlob
|
||||
func (ByteaTypeDef) IsComparableWith(other Type) bool {
|
||||
return other == TypeBytea
|
||||
}
|
||||
|
||||
func (BlobTypeDef) IsIndexComparableWith(other Type) bool {
|
||||
return other == TypeBlob
|
||||
func (ByteaTypeDef) IsIndexComparableWith(other Type) bool {
|
||||
return other == TypeBytea
|
||||
}
|
||||
|
||||
var _ Value = NewBlobValue(nil)
|
||||
var _ Value = NewByteaValue(nil)
|
||||
|
||||
type BlobValue []byte
|
||||
type ByteaValue []byte
|
||||
|
||||
// NewBlobValue returns a SQL BLOB value.
|
||||
func NewBlobValue(x []byte) BlobValue {
|
||||
return BlobValue(x)
|
||||
// NewByteaValue returns a SQL BYTEA value.
|
||||
func NewByteaValue(x []byte) ByteaValue {
|
||||
return ByteaValue(x)
|
||||
}
|
||||
|
||||
func (v BlobValue) V() any {
|
||||
func (v ByteaValue) V() any {
|
||||
return []byte(v)
|
||||
}
|
||||
|
||||
func (v BlobValue) Type() Type {
|
||||
return TypeBlob
|
||||
func (v ByteaValue) Type() Type {
|
||||
return TypeBytea
|
||||
}
|
||||
|
||||
func (v BlobValue) TypeDef() TypeDefinition {
|
||||
return BlobTypeDef{}
|
||||
func (v ByteaValue) TypeDef() TypeDefinition {
|
||||
return ByteaTypeDef{}
|
||||
}
|
||||
|
||||
func (v BlobValue) IsZero() (bool, error) {
|
||||
func (v ByteaValue) IsZero() (bool, error) {
|
||||
return v == nil, nil
|
||||
}
|
||||
|
||||
func (v BlobValue) String() string {
|
||||
func (v ByteaValue) String() string {
|
||||
t, _ := v.MarshalText()
|
||||
return string(t)
|
||||
}
|
||||
|
||||
func (v BlobValue) MarshalText() ([]byte, error) {
|
||||
func (v ByteaValue) MarshalText() ([]byte, error) {
|
||||
var dst bytes.Buffer
|
||||
dst.WriteString("\"\\x")
|
||||
_, _ = hex.NewEncoder(&dst).Write(v)
|
||||
@@ -72,7 +72,7 @@ func (v BlobValue) MarshalText() ([]byte, error) {
|
||||
return dst.Bytes(), nil
|
||||
}
|
||||
|
||||
func (v BlobValue) MarshalJSON() ([]byte, error) {
|
||||
func (v ByteaValue) MarshalJSON() ([]byte, error) {
|
||||
dst := make([]byte, base64.StdEncoding.EncodedLen(len(v))+2)
|
||||
dst[0] = '"'
|
||||
dst[len(dst)-1] = '"'
|
||||
@@ -80,17 +80,17 @@ func (v BlobValue) MarshalJSON() ([]byte, error) {
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func (v BlobValue) Encode(dst []byte) ([]byte, error) {
|
||||
return encoding.EncodeBlob(dst, v), nil
|
||||
func (v ByteaValue) Encode(dst []byte) ([]byte, error) {
|
||||
return encoding.EncodeBytea(dst, v), nil
|
||||
}
|
||||
|
||||
func (v BlobValue) EncodeAsKey(dst []byte) ([]byte, error) {
|
||||
return encoding.EncodeBlob(dst, v), nil
|
||||
func (v ByteaValue) EncodeAsKey(dst []byte) ([]byte, error) {
|
||||
return encoding.EncodeBytea(dst, v), nil
|
||||
}
|
||||
|
||||
func (v BlobValue) CastAs(target Type) (Value, error) {
|
||||
func (v ByteaValue) CastAs(target Type) (Value, error) {
|
||||
switch target {
|
||||
case TypeBlob:
|
||||
case TypeBytea:
|
||||
return v, nil
|
||||
case TypeText:
|
||||
return NewTextValue(base64.StdEncoding.EncodeToString([]byte(v))), nil
|
||||
@@ -99,52 +99,52 @@ func (v BlobValue) CastAs(target Type) (Value, error) {
|
||||
return nil, errors.Errorf("cannot cast %s as %s", v.Type(), target)
|
||||
}
|
||||
|
||||
func (v BlobValue) EQ(other Value) (bool, error) {
|
||||
if other.Type() != TypeBlob {
|
||||
func (v ByteaValue) EQ(other Value) (bool, error) {
|
||||
if other.Type() != TypeBytea {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return bytes.Equal([]byte(v), AsByteSlice(other)), nil
|
||||
}
|
||||
|
||||
func (v BlobValue) GT(other Value) (bool, error) {
|
||||
func (v ByteaValue) GT(other Value) (bool, error) {
|
||||
t := other.Type()
|
||||
if t != TypeBlob {
|
||||
if t != TypeBytea {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return bytes.Compare([]byte(v), AsByteSlice(other)) > 0, nil
|
||||
}
|
||||
|
||||
func (v BlobValue) GTE(other Value) (bool, error) {
|
||||
func (v ByteaValue) GTE(other Value) (bool, error) {
|
||||
t := other.Type()
|
||||
if t != TypeBlob {
|
||||
if t != TypeBytea {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return bytes.Compare([]byte(v), AsByteSlice(other)) >= 0, nil
|
||||
}
|
||||
|
||||
func (v BlobValue) LT(other Value) (bool, error) {
|
||||
func (v ByteaValue) LT(other Value) (bool, error) {
|
||||
t := other.Type()
|
||||
if t != TypeBlob {
|
||||
if t != TypeBytea {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return bytes.Compare([]byte(v), AsByteSlice(other)) < 0, nil
|
||||
}
|
||||
|
||||
func (v BlobValue) LTE(other Value) (bool, error) {
|
||||
func (v ByteaValue) LTE(other Value) (bool, error) {
|
||||
t := other.Type()
|
||||
if t != TypeBlob {
|
||||
if t != TypeBytea {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return bytes.Compare([]byte(v), AsByteSlice(other)) <= 0, nil
|
||||
}
|
||||
|
||||
func (v BlobValue) Between(a, b Value) (bool, error) {
|
||||
if a.Type() != TypeBlob || b.Type() != TypeBlob {
|
||||
func (v ByteaValue) Between(a, b Value) (bool, error) {
|
||||
if a.Type() != TypeBytea || b.Type() != TypeBytea {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ func TestCastAs(t *testing.T) {
|
||||
doubleV := types.NewDoubleValue(10.5)
|
||||
tsV := types.NewTimestampValue(now)
|
||||
textV := types.NewTextValue("foo")
|
||||
blobV := types.NewBlobValue([]byte("asdine"))
|
||||
byteaV := types.NewByteaValue([]byte("asdine"))
|
||||
|
||||
check := func(t *testing.T, targetType types.Type, tests []test) {
|
||||
t.Helper()
|
||||
@@ -50,7 +50,7 @@ func TestCastAs(t *testing.T) {
|
||||
{textV, nil, true},
|
||||
{types.NewTextValue("true"), boolV, false},
|
||||
{types.NewTextValue("false"), types.NewBooleanValue(false), false},
|
||||
{blobV, nil, true},
|
||||
{byteaV, nil, true},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestCastAs(t *testing.T) {
|
||||
{textV, nil, true},
|
||||
{types.NewTextValue("10"), integerV, false},
|
||||
{types.NewTextValue("10.5"), integerV, false},
|
||||
{blobV, nil, true},
|
||||
{byteaV, nil, true},
|
||||
{types.NewDoubleValue(math.MaxInt64 + 1), nil, true},
|
||||
})
|
||||
})
|
||||
@@ -76,7 +76,7 @@ func TestCastAs(t *testing.T) {
|
||||
{textV, nil, true},
|
||||
{types.NewTextValue("10"), types.NewDoubleValue(10), false},
|
||||
{types.NewTextValue("10.5"), doubleV, false},
|
||||
{blobV, nil, true},
|
||||
{byteaV, nil, true},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -86,7 +86,7 @@ func TestCastAs(t *testing.T) {
|
||||
{integerV, nil, true},
|
||||
{doubleV, nil, true},
|
||||
{types.NewTextValue(now.Format(time.RFC3339Nano)), tsV, false},
|
||||
{blobV, nil, true},
|
||||
{byteaV, nil, true},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -96,18 +96,18 @@ func TestCastAs(t *testing.T) {
|
||||
{integerV, types.NewTextValue("10"), false},
|
||||
{doubleV, types.NewTextValue("10.5"), false},
|
||||
{textV, textV, false},
|
||||
{blobV, types.NewTextValue(`YXNkaW5l`), false},
|
||||
{byteaV, types.NewTextValue(`YXNkaW5l`), false},
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("blob", func(t *testing.T) {
|
||||
check(t, types.TypeBlob, []test{
|
||||
t.Run("bytea", func(t *testing.T) {
|
||||
check(t, types.TypeBytea, []test{
|
||||
{boolV, nil, true},
|
||||
{integerV, nil, true},
|
||||
{doubleV, nil, true},
|
||||
{types.NewTextValue("YXNkaW5l"), types.NewBlobValue([]byte{0x61, 0x73, 0x64, 0x69, 0x6e, 0x65}), false},
|
||||
{types.NewTextValue("YXNkaW5l"), types.NewByteaValue([]byte{0x61, 0x73, 0x64, 0x69, 0x6e, 0x65}), false},
|
||||
{types.NewTextValue("not base64"), nil, true},
|
||||
{blobV, blobV, false},
|
||||
{byteaV, byteaV, false},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@@ -57,8 +57,8 @@ func toText(t testing.TB, x string) types.Value {
|
||||
return types.NewTextValue(x)
|
||||
}
|
||||
|
||||
func toBlob(t testing.TB, x string) types.Value {
|
||||
return types.NewBlobValue([]byte(x))
|
||||
func tobytea(t testing.TB, x string) types.Value {
|
||||
return types.NewByteaValue([]byte(x))
|
||||
}
|
||||
|
||||
var now = time.Now().Format(time.RFC3339Nano)
|
||||
@@ -180,23 +180,23 @@ func TestCompare(t *testing.T) {
|
||||
{"<=", "a", "b", true, toText},
|
||||
{"<=", "b", "b", true, toText},
|
||||
|
||||
// blob
|
||||
{"=", "b", "a", false, toBlob},
|
||||
{"=", "b", "b", true, toBlob},
|
||||
{"!=", "b", "a", true, toBlob},
|
||||
{"!=", "b", "b", false, toBlob},
|
||||
{">", "b", "a", true, toBlob},
|
||||
{">", "a", "b", false, toBlob},
|
||||
{">", "b", "b", false, toBlob},
|
||||
{">=", "b", "a", true, toBlob},
|
||||
{">=", "a", "b", false, toBlob},
|
||||
{">=", "b", "b", true, toBlob},
|
||||
{"<", "b", "a", false, toBlob},
|
||||
{"<", "a", "b", true, toBlob},
|
||||
{"<", "b", "b", false, toBlob},
|
||||
{"<=", "b", "a", false, toBlob},
|
||||
{"<=", "a", "b", true, toBlob},
|
||||
{"<=", "b", "b", true, toBlob},
|
||||
// bytea
|
||||
{"=", "b", "a", false, tobytea},
|
||||
{"=", "b", "b", true, tobytea},
|
||||
{"!=", "b", "a", true, tobytea},
|
||||
{"!=", "b", "b", false, tobytea},
|
||||
{">", "b", "a", true, tobytea},
|
||||
{">", "a", "b", false, tobytea},
|
||||
{">", "b", "b", false, tobytea},
|
||||
{">=", "b", "a", true, tobytea},
|
||||
{">=", "a", "b", false, tobytea},
|
||||
{">=", "b", "b", true, tobytea},
|
||||
{"<", "b", "a", false, tobytea},
|
||||
{"<", "a", "b", true, tobytea},
|
||||
{"<", "b", "b", false, tobytea},
|
||||
{"<=", "b", "a", false, tobytea},
|
||||
{"<=", "a", "b", true, tobytea},
|
||||
{"<=", "b", "b", true, tobytea},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@@ -18,7 +18,7 @@ var encodedTypeToTypeDefs = map[byte]TypeDefinition{
|
||||
encoding.Uint64Value: BigintTypeDef{},
|
||||
encoding.Float64Value: DoubleTypeDef{},
|
||||
encoding.TextValue: TextTypeDef{},
|
||||
encoding.BlobValue: BlobTypeDef{},
|
||||
encoding.ByteaValue: ByteaTypeDef{},
|
||||
}
|
||||
|
||||
func DecodeValue(b []byte) (v Value, n int) {
|
||||
|
@@ -28,7 +28,7 @@ func (TextTypeDef) Decode(src []byte) (Value, int) {
|
||||
}
|
||||
|
||||
func (TextTypeDef) IsComparableWith(other Type) bool {
|
||||
return other == TypeNull || other == TypeText || other == TypeBoolean || other == TypeInteger || other == TypeBigint || other == TypeDouble || other == TypeTimestamp || other == TypeBlob
|
||||
return other == TypeNull || other == TypeText || other == TypeBoolean || other == TypeInteger || other == TypeBigint || other == TypeDouble || other == TypeTimestamp || other == TypeBytea
|
||||
}
|
||||
|
||||
func (t TextTypeDef) IsIndexComparableWith(other Type) bool {
|
||||
@@ -124,14 +124,14 @@ func (v TextValue) CastAs(target Type) (Value, error) {
|
||||
return nil, fmt.Errorf(`cannot cast %q as timestamp: %w`, v.V(), err)
|
||||
}
|
||||
return NewTimestampValue(t), nil
|
||||
case TypeBlob:
|
||||
case TypeBytea:
|
||||
s := string(v)
|
||||
b, err := base64.StdEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewBlobValue(b), nil
|
||||
return NewByteaValue(b), nil
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("cannot cast %s as %s", v.Type(), target)
|
||||
|
@@ -27,7 +27,7 @@ const (
|
||||
TypeDouble
|
||||
TypeTimestamp
|
||||
TypeText
|
||||
TypeBlob
|
||||
TypeBytea
|
||||
)
|
||||
|
||||
func (t Type) Def() TypeDefinition {
|
||||
@@ -46,8 +46,8 @@ func (t Type) Def() TypeDefinition {
|
||||
return TimestampTypeDef{}
|
||||
case TypeText:
|
||||
return TextTypeDef{}
|
||||
case TypeBlob:
|
||||
return BlobTypeDef{}
|
||||
case TypeBytea:
|
||||
return ByteaTypeDef{}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -67,8 +67,8 @@ func (t Type) String() string {
|
||||
return "double"
|
||||
case TypeTimestamp:
|
||||
return "timestamp"
|
||||
case TypeBlob:
|
||||
return "blob"
|
||||
case TypeBytea:
|
||||
return "bytea"
|
||||
case TypeText:
|
||||
return "text"
|
||||
}
|
||||
@@ -92,8 +92,8 @@ func (t Type) MinEnctype() byte {
|
||||
return encoding.Int64Value
|
||||
case TypeText:
|
||||
return encoding.TextValue
|
||||
case TypeBlob:
|
||||
return encoding.BlobValue
|
||||
case TypeBytea:
|
||||
return encoding.ByteaValue
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported type %v", t))
|
||||
}
|
||||
@@ -115,8 +115,8 @@ func (t Type) MinEnctypeDesc() byte {
|
||||
return encoding.DESC_Uint64Value
|
||||
case TypeText:
|
||||
return encoding.DESC_TextValue
|
||||
case TypeBlob:
|
||||
return encoding.DESC_BlobValue
|
||||
case TypeBytea:
|
||||
return encoding.DESC_ByteaValue
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported type %v", t))
|
||||
}
|
||||
@@ -138,8 +138,8 @@ func (t Type) MaxEnctype() byte {
|
||||
return encoding.Uint64Value + 1
|
||||
case TypeText:
|
||||
return encoding.TextValue + 1
|
||||
case TypeBlob:
|
||||
return encoding.BlobValue + 1
|
||||
case TypeBytea:
|
||||
return encoding.ByteaValue + 1
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported type %v", t))
|
||||
}
|
||||
@@ -159,8 +159,8 @@ func (t Type) MaxEnctypeDesc() byte {
|
||||
return encoding.DESC_Int64Value + 1
|
||||
case TypeText:
|
||||
return encoding.DESC_TextValue + 1
|
||||
case TypeBlob:
|
||||
return encoding.DESC_BlobValue + 1
|
||||
case TypeBytea:
|
||||
return encoding.DESC_ByteaValue + 1
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported type %v", t))
|
||||
}
|
||||
|
@@ -83,7 +83,7 @@ func AsString(v Value) string {
|
||||
}
|
||||
|
||||
func AsByteSlice(v Value) []byte {
|
||||
bv, ok := v.(BlobValue)
|
||||
bv, ok := v.(ByteaValue)
|
||||
if !ok {
|
||||
return v.V().([]byte)
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func (v *ValueScanner) Scan(src any) error {
|
||||
case bool:
|
||||
v.V = NewBooleanValue(t)
|
||||
case []byte:
|
||||
v.V = NewBlobValue(t)
|
||||
v.V = NewByteaValue(t)
|
||||
case string:
|
||||
v.V = NewTextValue(t)
|
||||
case time.Time:
|
||||
|
@@ -57,7 +57,7 @@ func TestValueMarshalJSON(t *testing.T) {
|
||||
expected string
|
||||
}{
|
||||
{"null", types.NewNullValue(), "null"},
|
||||
{"blob", types.NewBlobValue([]byte("bar")), `"YmFy"`},
|
||||
{"bytea", types.NewByteaValue([]byte("bar")), `"YmFy"`},
|
||||
{"string", types.NewTextValue("bar"), `"bar"`},
|
||||
{"bool", types.NewBooleanValue(true), "true"},
|
||||
{"int", types.NewIntegerValue(10), "10"},
|
||||
|
@@ -102,15 +102,15 @@ CREATE TABLE test(pk INT PRIMARY KEY, a DOUBLE DEFAULT pk());
|
||||
-- error:
|
||||
|
||||
-- test: incompatible expr
|
||||
CREATE TABLE test(pk INT PRIMARY KEY, a BLOB DEFAULT 1 + 4 / 4);
|
||||
CREATE TABLE test(pk INT PRIMARY KEY, a BYTEA DEFAULT 1 + 4 / 4);
|
||||
-- error:
|
||||
|
||||
-- test: forbidden tokens: AND
|
||||
CREATE TABLE test(pk INT PRIMARY KEY, a BLOB DEFAULT 1 AND 1);
|
||||
CREATE TABLE test(pk INT PRIMARY KEY, a BYTEA DEFAULT 1 AND 1);
|
||||
-- error:
|
||||
|
||||
-- test: forbidden tokens: path
|
||||
CREATE TABLE test(pk INT PRIMARY KEY, a BLOB DEFAULT b);
|
||||
CREATE TABLE test(pk INT PRIMARY KEY, a BYTEA DEFAULT b);
|
||||
-- error:
|
||||
|
||||
-- test: DEFAULT nextval sequence
|
||||
|
@@ -38,13 +38,13 @@ SELECT name, sql FROM __chai_catalog WHERE type = "table" AND name = "test";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: BLOB
|
||||
CREATE TABLE test (pk INT PRIMARY KEY, a BLOB);
|
||||
-- test: BYTEA
|
||||
CREATE TABLE test (pk INT PRIMARY KEY, a BYTEA);
|
||||
SELECT name, sql FROM __chai_catalog WHERE type = "table" AND name = "test";
|
||||
/* result:
|
||||
{
|
||||
"name": "test",
|
||||
"sql": "CREATE TABLE test (pk INTEGER NOT NULL, a BLOB, CONSTRAINT test_pk PRIMARY KEY (pk))"
|
||||
"sql": "CREATE TABLE test (pk INTEGER NOT NULL, a BYTEA, CONSTRAINT test_pk PRIMARY KEY (pk))"
|
||||
}
|
||||
*/
|
||||
|
||||
|
@@ -16,7 +16,7 @@ INSERT INTO testpk (bar, foo) VALUES (1, 2);
|
||||
-- test: insert with types constraints
|
||||
CREATE TABLE test_tc(
|
||||
b bool, db double,
|
||||
i bigint, bb blob, byt bytes,
|
||||
i bigint, bb bytea, byt bytes,
|
||||
t text primary key
|
||||
);
|
||||
INSERT INTO test_tc (i, db, b, bb, byt, t) VALUES (10000000000, 21.21, true, "YmxvYlZhbHVlCg==", "Ynl0ZXNWYWx1ZQ==", "text");
|
||||
@@ -26,7 +26,7 @@ SELECT * FROM test_tc;
|
||||
"b": true,
|
||||
"db": 21.21,
|
||||
"i": 10000000000,
|
||||
"bb": CAST("YmxvYlZhbHVlCg==" AS BLOB),
|
||||
"bb": CAST("YmxvYlZhbHVlCg==" AS BYTEA),
|
||||
"byt": CAST("Ynl0ZXNWYWx1ZQ==" AS BYTES),
|
||||
"t": "text"
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ CREATE TABLE test(
|
||||
b double,
|
||||
c boolean,
|
||||
d text,
|
||||
e blob
|
||||
e bytea
|
||||
);
|
||||
|
||||
INSERT INTO test VALUES
|
||||
@@ -1053,7 +1053,7 @@ SELECT * FROM test WHERE d NOT IN ("a", "c");
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob =
|
||||
-- test: bytea =
|
||||
SELECT * FROM test WHERE e = "\xaa";
|
||||
/* result:
|
||||
{
|
||||
@@ -1066,7 +1066,7 @@ SELECT * FROM test WHERE e = "\xaa";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob !=
|
||||
-- test: bytea !=
|
||||
SELECT * FROM test WHERE e != "\xaa";
|
||||
/* result:
|
||||
{
|
||||
@@ -1095,7 +1095,7 @@ SELECT * FROM test WHERE e != "\xaa";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob >
|
||||
-- test: bytea >
|
||||
SELECT * FROM test WHERE e > "\xaa";
|
||||
/* result:
|
||||
{
|
||||
@@ -1124,7 +1124,7 @@ SELECT * FROM test WHERE e > "\xaa";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob >=
|
||||
-- test: bytea >=
|
||||
SELECT * FROM test WHERE e >= "\xaa";
|
||||
/* result:
|
||||
{
|
||||
@@ -1161,7 +1161,7 @@ SELECT * FROM test WHERE e >= "\xaa";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob <
|
||||
-- test: bytea <
|
||||
SELECT * FROM test WHERE e < "\xac";
|
||||
/* result:
|
||||
{
|
||||
@@ -1182,7 +1182,7 @@ SELECT * FROM test WHERE e < "\xac";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob <=
|
||||
-- test: bytea <=
|
||||
SELECT * FROM test WHERE e <= "\xac";
|
||||
/* result:
|
||||
{
|
||||
@@ -1211,7 +1211,7 @@ SELECT * FROM test WHERE e <= "\xac";
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob IN
|
||||
-- test: bytea IN
|
||||
SELECT * FROM test WHERE e IN ("\xaa", "\xac");
|
||||
/* result:
|
||||
{
|
||||
@@ -1232,7 +1232,7 @@ SELECT * FROM test WHERE e IN ("\xaa", "\xac");
|
||||
}
|
||||
*/
|
||||
|
||||
-- test: blob NOT IN
|
||||
-- test: bytea NOT IN
|
||||
SELECT * FROM test WHERE e NOT IN ("\xaa", "\xac");
|
||||
/* result:
|
||||
{
|
||||
|
@@ -11,8 +11,8 @@ true
|
||||
> CAST (1 AS TEXT)
|
||||
'1'
|
||||
|
||||
! CAST (1 AS BLOB)
|
||||
'cannot cast integer as blob'
|
||||
! CAST (1 AS BYTEA)
|
||||
'cannot cast integer as bytea'
|
||||
|
||||
-- test: source(DOUBLE)
|
||||
> CAST (1.1 AS DOUBLE)
|
||||
@@ -27,8 +27,8 @@ true
|
||||
> CAST (1.1 AS TEXT)
|
||||
'1.1'
|
||||
|
||||
! CAST (1.1 AS BLOB)
|
||||
'cannot cast double as blob'
|
||||
! CAST (1.1 AS BYTEA)
|
||||
'cannot cast double as bytea'
|
||||
|
||||
-- test: source(BOOL)
|
||||
> CAST (true AS BOOL)
|
||||
@@ -46,8 +46,8 @@ true
|
||||
> CAST (true AS TEXT)
|
||||
'true'
|
||||
|
||||
! CAST (true AS BLOB)
|
||||
'cannot cast boolean as blob'
|
||||
! CAST (true AS BYTEA)
|
||||
'cannot cast boolean as bytea'
|
||||
|
||||
-- test: source(TEXT)
|
||||
> CAST ('a' AS TEXT)
|
||||
@@ -77,18 +77,18 @@ false
|
||||
|
||||
! CAST ('falSe' AS BOOL)
|
||||
|
||||
> CAST ('YXNkaW5l' AS BLOB)
|
||||
> CAST ('YXNkaW5l' AS BYTEA)
|
||||
'\x617364696e65'
|
||||
|
||||
-- test: source(BLOB)
|
||||
> CAST ('\xAF' AS BLOB)
|
||||
-- test: source(BYTEA)
|
||||
> CAST ('\xAF' AS BYTEA)
|
||||
'\xAF'
|
||||
|
||||
! CAST ('\xAF' AS INT)
|
||||
'cannot cast blob as integer'
|
||||
'cannot cast bytea as integer'
|
||||
|
||||
! CAST ('\xAF' AS DOUBLE)
|
||||
'cannot cast blob as double'
|
||||
'cannot cast bytea as double'
|
||||
|
||||
> CAST ('\x617364696e65' AS TEXT)
|
||||
'YXNkaW5l'
|
||||
|
@@ -85,13 +85,13 @@ false
|
||||
> typeof("hello")
|
||||
'text'
|
||||
|
||||
-- test: literals/blobs
|
||||
-- test: literals/byteas
|
||||
|
||||
> '\xFF'
|
||||
'\xFF'
|
||||
|
||||
> typeof('\xFF')
|
||||
'blob'
|
||||
'bytea'
|
||||
|
||||
! '\xhello'
|
||||
'invalid hexadecimal digit: h'
|
||||
|
Reference in New Issue
Block a user