added type support for looker; added intercept for yellowfin typelen query

This commit is contained in:
Todd Gruben 2021-09-29 11:16:10 -05:00
parent c4a348724e
commit 1a068cf0e2
3 changed files with 66 additions and 6 deletions

View file

@ -32,6 +32,7 @@ import (
"github.com/molecula/featurebase/v2/pg/message"
"github.com/molecula/featurebase/v2/sql"
"github.com/molecula/featurebase/v2/vprint"
"github.com/pkg/errors"
"vitess.io/vitess/go/vt/sqlparser"
)
@ -269,6 +270,7 @@ const (
pgSelect1 PgType = 'h'
pgSchema PgType = 'i'
pgBegin PgType = 'j'
pgTypeLen PgType = 'k'
)
type Portal struct {
@ -298,6 +300,8 @@ func (p *Portal) Bind() {
var lookPQL = regexp.MustCompile(`\[.*\].*\)\z`)
const POSTGRESLENSQL = `SELECT t.typlen FROM pg_catalog.pg_type t, pg_catalog.pg_namespace n WHERE t.typnamespace=n.oid AND t.typname='name' AND n.nspname='pg_catalog'`
func (p *Portal) Parse(data []byte) {
p.queryStart = time.Now()
queryStr := string(bytes.Trim(data, "\x00"))
@ -336,6 +340,10 @@ func (p *Portal) Parse(data []byte) {
if strings.Contains(strings.ToLower(query.SQL), "select 1") {
p.pgspecial = pgSelect1
p.Name = "SELECT"
} else if strings.Contains(queryStr, POSTGRESLENSQL) {
vprint.VV("YELLOWFIN Len")
p.pgspecial = pgTypeLen
p.Name = "SELECT"
} else {
switch query.SQLType {
case sql.SQLTypeSet:
@ -565,6 +573,16 @@ func (p *Portal) Execute() (shouldTerminate bool, queryReady bool, err error) {
case pgBegin:
p.Name = "BEGIN"
case pgTypeLen:
rowDescription, e := p.Encoder.EncodeColumn("typelen", int32(21), 2)
if e != nil {
err = e
return
}
p.Add(rowDescription)
mesg := "64"
dataRow, _ := p.Encoder.TextRow(mesg)
p.Add(dataRow)
}
//maybe add in the number of items in select clause

View file

@ -20,18 +20,26 @@ import "github.com/molecula/featurebase/v2/pg/message"
type Type struct {
// I am not entirely sure what should be in here long term.
// For now, I am just going to leave it like this.
id int32
Id int32
Typelen int16
}
// TypeCharoid is a postgres type for text.
var TypeCharoid = Type{id: 18}
// found in postgres source src/include/catalog/pg_type.h
var TypeCharoid = Type{Id: 18, Typelen: -1}
var TypeNAMEOID = Type{Id: 19, Typelen: 64}
var TypeINT4OID = Type{Id: 23, Typelen: 4}
var TypeTEXTOID = Type{Id: 25, Typelen: -1}
var TypeFLOAT8OID = Type{Id: 701, Typelen: 8}
// TypeData is a type containing raw postgres wire type information.
/*
type TypeData struct {
TypeID int32
TypeLen int16
TypeModifier int32
}
*/
// TypeEngine is a system for managing types.
// This is necessary for compound types like arrays which need ID generation.
@ -45,9 +53,32 @@ type PrimitiveTypeEngine struct{}
// TranslateType translates a type to a column description.
func (pte PrimitiveTypeEngine) TranslateType(t Type) (message.ColumnDescription, error) {
var TypeLen int16
var TypeID int32
switch t {
case TypeCharoid:
TypeID = TypeCharoid.Id
TypeLen = TypeCharoid.Typelen
case TypeNAMEOID:
TypeID = TypeNAMEOID.Id
TypeLen = TypeNAMEOID.Typelen
case TypeINT4OID:
TypeID = TypeINT4OID.Id
TypeLen = TypeINT4OID.Typelen
case TypeTEXTOID:
TypeID = TypeTEXTOID.Id
TypeLen = TypeTEXTOID.Typelen
case TypeFLOAT8OID:
TypeID = TypeFLOAT8OID.Id
TypeLen = TypeFLOAT8OID.Typelen
//case
default: // treat like TypeCharoid:
TypeID = TypeCharoid.Id
TypeLen = TypeCharoid.Typelen
}
return message.ColumnDescription{
TypeID: t.id, // just charoid for now; as far as I can tell most implementations do not really use this
TypeLen: -1, // vdsm had 4. . . but the spec says this should be negative
TypeID: TypeID,
TypeLen: TypeLen,
TypeModifier: -1,
Mode: 0, // send as text
}, nil

View file

@ -28,6 +28,7 @@ import (
pilosa "github.com/molecula/featurebase/v2"
"github.com/molecula/featurebase/v2/logger"
"github.com/molecula/featurebase/v2/pg"
"github.com/molecula/featurebase/v2/sql2"
//"github.com/molecula/featurebase/v2/pg"
"github.com/molecula/featurebase/v2/pql"
@ -336,6 +337,15 @@ func pgWriteGroupCount(w pg.QueryResultWriter, counts *pilosa.GroupCounts) error
return nil
}
// TODO(twg) move this to a better area
func getPgType(sql2type string) pg.Type {
ret := pg.TypeCharoid
switch sql2type {
case sql2.DataTypeInt:
ret = pg.TypeINT4OID
}
return ret
}
func pgWriteStmtRows(w pg.QueryResultWriter, rows *pilosa.StmtRows) error {
//TODO(twg) writeHeader
//TODO(twg) writeColumns
@ -348,9 +358,10 @@ func pgWriteStmtRows(w pg.QueryResultWriter, rows *pilosa.StmtRows) error {
//TODO (twg) types:=rows.Types()
headers := make([]pg.ColumnInfo, len(columns))
for i, column := range columns {
pgType := getPgType(column.Type)
headers[i] = pg.ColumnInfo{
Name: column.Name,
Type: pg.TypeCharoid, //TODO(twg) types[i]
Type: pgType,
}
}
err := w.WriteHeader(headers...)
@ -481,7 +492,7 @@ func pgWriteResult(w pg.QueryResultWriter, result interface{}) error {
return pgWriteGroupCount(w, result)
case pb.ToRowser: // we should avoid protobuf where we can...
return pgWriteRowser(w, result)
case *pilosa.StmtRows: // we should avoid protobuf where we can...
case *pilosa.StmtRows:
return pgWriteStmtRows(w, result)
case uint64:
err := w.WriteHeader(pg.ColumnInfo{