Skip to content

Commit

Permalink
Merge pull request #57 from dolthub/zachmu/exprs
Browse files Browse the repository at this point in the history
Better type handling in harness, support COUNT(*) expressions and CAST
  • Loading branch information
zachmu authored Nov 28, 2023
2 parents e0f8ccf + dba2cda commit 5da75fd
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 38 deletions.
38 changes: 8 additions & 30 deletions server/ast/column_table_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ package ast

import (
"fmt"
"strconv"

vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
"github.com/dolthub/doltgresql/postgres/parser/types"
)

// nodeColumnTableDef handles *tree.ColumnTableDef nodes.
Expand All @@ -40,32 +38,12 @@ func nodeColumnTableDef(node *tree.ColumnTableDef) (_ *vitess.ColumnDefinition,
if node.Family.Create || len(node.Family.Name) > 0 {
return nil, fmt.Errorf("FAMILY is not yet supported")
}
var columnTypeName string
var columnTypeLength *vitess.SQLVal
var columnTypeScale *vitess.SQLVal
switch columnType := node.Type.(type) {
case *tree.ArrayTypeReference:
return nil, fmt.Errorf("array types are not yet supported")
case *tree.OIDTypeReference:
return nil, fmt.Errorf("referencing types by their OID is not yet supported")
case *tree.UnresolvedObjectName:
return nil, fmt.Errorf("type declaration format is not yet supported")
case *types.GeoMetadata:
return nil, fmt.Errorf("geometry types are not yet supported")
case *types.T:
columnTypeName = columnType.SQLStandardName()
switch columnType.Family() {
case types.DecimalFamily:
columnTypeLength = vitess.NewIntVal([]byte(strconv.Itoa(int(columnType.Precision()))))
columnTypeScale = vitess.NewIntVal([]byte(strconv.Itoa(int(columnType.Scale()))))
case types.JsonFamily:
columnTypeName = "JSON"
case types.StringFamily:
columnTypeLength = vitess.NewIntVal([]byte(strconv.Itoa(int(columnType.Width()))))
case types.TimestampFamily:
columnTypeName = columnType.Name()
}

typeParams, err := nodeResolvableTypeReference(node.Type)
if err != nil {
return nil, err
}

var isNull vitess.BoolVal
var isNotNull vitess.BoolVal
switch node.Nullable.Nullability {
Expand Down Expand Up @@ -126,13 +104,13 @@ func nodeColumnTableDef(node *tree.ColumnTableDef) (_ *vitess.ColumnDefinition,
return &vitess.ColumnDefinition{
Name: vitess.NewColIdent(string(node.Name)),
Type: vitess.ColumnType{
Type: columnTypeName,
Type: typeParams.name,
Null: isNull,
NotNull: isNotNull,
Autoincrement: vitess.BoolVal(node.IsSerial),
Default: defaultExpr,
Length: columnTypeLength,
Scale: columnTypeScale,
Length: typeParams.length,
Scale: typeParams.scale,
KeyOpt: keyOpt,
ForeignKeyDef: fkDef,
GeneratedExpr: generated,
Expand Down
35 changes: 30 additions & 5 deletions server/ast/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,37 @@ func nodeExpr(node tree.Expr) (vitess.Expr, error) {
Else: else_,
}, nil
case *tree.CastExpr:
//TODO: finish the implementation
expr, err := nodeExpr(node.Expr)
if err != nil {
return nil, err
}

switch node.SyntaxMode {
case tree.CastExplicit:
// only acceptable cast type
case tree.CastShort:
return nil, fmt.Errorf("TYPECAST is not yet supported")
case tree.CastPrepend:
return nil, fmt.Errorf("typed literals are not yet supported")
default:
return nil, fmt.Errorf("unknown cast syntax")
}

params, err := nodeResolvableTypeReference(node.Type)
if err != nil {
return nil, err
}

return &vitess.ConvertExpr{
Name: "",
Expr: nil,
Type: nil,
}, fmt.Errorf("CAST is not yet supported")
Name: "CAST",
Expr: expr,
Type: &vitess.ConvertType{
Type: params.name,
Length: params.length,
Scale: params.scale,
Charset: "", // TODO
},
}, nil
case *tree.CoalesceExpr:
return nil, fmt.Errorf("COALESCE is not yet supported")
case *tree.CollateExpr:
Expand Down
4 changes: 2 additions & 2 deletions server/ast/func_expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func nodeFuncExpr(node *tree.FuncExpr) (*vitess.FuncExpr, error) {
if node.Filter != nil {
return nil, fmt.Errorf("function filters are not yet supported")
}
if node.AggType != tree.GeneralAgg {
return nil, fmt.Errorf("function aggregation is not yet supported")
if node.AggType == tree.OrderedSetAgg {
return nil, fmt.Errorf("WITHIN GROUP is not yet supported")
}
if len(node.OrderBy) > 0 {
return nil, fmt.Errorf("function ORDER BY is not yet supported")
Expand Down
70 changes: 70 additions & 0 deletions server/ast/resolvable_type_reference.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2023 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ast

import (
"fmt"
"strconv"

vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
"github.com/dolthub/doltgresql/postgres/parser/types"
)

type typeParams struct {
name string
length *vitess.SQLVal
scale *vitess.SQLVal
}

func nodeResolvableTypeReference(typ tree.ResolvableTypeReference) (*typeParams, error) {
if typ == nil {
return nil, nil
}

var columnTypeName string
var columnTypeLength *vitess.SQLVal
var columnTypeScale *vitess.SQLVal
switch columnType := typ.(type) {
case *tree.ArrayTypeReference:
return nil, fmt.Errorf("array types are not yet supported")
case *tree.OIDTypeReference:
return nil, fmt.Errorf("referencing types by their OID is not yet supported")
case *tree.UnresolvedObjectName:
return nil, fmt.Errorf("type declaration format is not yet supported")
case *types.GeoMetadata:
return nil, fmt.Errorf("geometry types are not yet supported")
case *types.T:
columnTypeName = columnType.SQLStandardName()
switch columnType.Family() {
case types.DecimalFamily:
columnTypeLength = vitess.NewIntVal([]byte(strconv.Itoa(int(columnType.Precision()))))
columnTypeScale = vitess.NewIntVal([]byte(strconv.Itoa(int(columnType.Scale()))))
case types.JsonFamily:
columnTypeName = "JSON"
case types.StringFamily:
columnTypeLength = vitess.NewIntVal([]byte(strconv.Itoa(int(columnType.Width()))))
case types.TimestampFamily:
columnTypeName = columnType.Name()
}
}

return &typeParams{
name: columnTypeName,
length: columnTypeLength,
scale: columnTypeScale,
}, nil
}
2 changes: 1 addition & 1 deletion testing/logictest/harness/doltgres_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func columns(rows *sql.Rows) (string, []interface{}, error) {
colVal := sql.NullString{}
columns = append(columns, &colVal)
sb.WriteString("T")
case "DECIMAL", "DOUBLE", "FLOAT":
case "DECIMAL", "DOUBLE", "FLOAT", "FLOAT8", "NUMERIC":
colVal := sql.NullFloat64{}
columns = append(columns, &colVal)
sb.WriteString("R")
Expand Down

0 comments on commit 5da75fd

Please sign in to comment.