Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into taylor/diff-schema
Browse files Browse the repository at this point in the history
  • Loading branch information
tbantle22 committed Oct 2, 2024
2 parents 3904c7c + 7872cb9 commit 1e96f68
Show file tree
Hide file tree
Showing 19 changed files with 500 additions and 152 deletions.
10 changes: 9 additions & 1 deletion postgres/parser/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -6032,8 +6032,12 @@ set_session_or_local_cmd:
| set_role

generic_set_single_config:
name '.' name to_or_eq var_list
{
$$.val = &tree.SetVar{Namespace: $1, Name: $3, Values: $5.exprs()}
}
// var_value includes DEFAULT expr
name to_or_eq var_list
| name to_or_eq var_list
{
$$.val = &tree.SetVar{Name: $1, Values: $3.exprs()}
}
Expand Down Expand Up @@ -6283,6 +6287,10 @@ show_session_stmt:

session_var:
IDENT
| IDENT '.' IDENT
{
$$ = $1 + "." + $3
}
// Although ALL, SESSION_USER and DATABASE are identifiers for the
// purpose of SHOW, they lex as separate token types, so they need
// separate rules.
Expand Down
16 changes: 15 additions & 1 deletion postgres/parser/pgdate/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package pgdate

import (
"strings"
"unicode"
"unicode/utf8"
)
Expand Down Expand Up @@ -144,14 +145,27 @@ func chunk(s string, buf []stringChunk) (int, string) {
return true
}

maybeJulian := strings.HasPrefix(strings.ToLower(s), "j")

lastSeenDigit := false
lastSeenLetter := false
for offset, r := range s {
if unicode.IsDigit(r) || unicode.IsLetter(r) {
isDigit := unicode.IsDigit(r)
isLetter := unicode.IsLetter(r)
if isDigit || isLetter {
if (isDigit && lastSeenLetter && !maybeJulian) || (isLetter && lastSeenDigit) {
if !flush() {
return -1, ""
}
}
if matchStart >= matchEnd {
matchStart = offset
}
// We're guarded by IsDigit() || IsLetter() above, so
// RuneLen() should always return a reasonable value.
matchEnd = offset + utf8.RuneLen(r)
lastSeenDigit = isDigit
lastSeenLetter = isLetter
} else if !flush() {
return -1, ""
}
Expand Down
7 changes: 4 additions & 3 deletions postgres/parser/sem/tree/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ var _ Statement = &SetVar{}

// SetVar represents a SET or RESET <configuration_param> statement.
type SetVar struct {
IsLocal bool
Name string
Values Exprs
IsLocal bool
Name string
Namespace string
Values Exprs
// FromCurrent is used for SET clauses in CREATE statements only.
FromCurrent bool
}
Expand Down
32 changes: 22 additions & 10 deletions server/ast/set_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func nodeSetVar(node *tree.SetVar) (vitess.Statement, error) {
dbName = strings.TrimPrefix(strings.TrimSuffix(dbName, "`"), "`")
return &vitess.Use{DBName: vitess.NewTableIdent(dbName)}, nil
}
if !config.IsValidPostgresConfigParameter(node.Name) && !config.IsValidDoltConfigParameter(node.Name) {
if node.Namespace == "" && !config.IsValidPostgresConfigParameter(node.Name) && !config.IsValidDoltConfigParameter(node.Name) {
return nil, fmt.Errorf(`ERROR: unrecognized configuration parameter "%s"`, node.Name)
}
if node.IsLocal {
Expand All @@ -63,14 +63,26 @@ func nodeSetVar(node *tree.SetVar) (vitess.Statement, error) {
return nil, err
}
}
setStmt := &vitess.Set{
Exprs: vitess.SetVarExprs{&vitess.SetVarExpr{
Scope: vitess.SetScope_Session,
Name: &vitess.ColName{
Name: vitess.NewColIdent(node.Name),
},
Expr: expr,
}},

if node.Namespace == "" {
return &vitess.Set{
Exprs: vitess.SetVarExprs{&vitess.SetVarExpr{
Scope: vitess.SetScope_Session,
Name: &vitess.ColName{
Name: vitess.NewColIdent(node.Name),
},
Expr: expr,
}},
}, nil
} else {
return &vitess.Set{
Exprs: vitess.SetVarExprs{&vitess.SetVarExpr{
Scope: vitess.SetScope_User,
Name: &vitess.ColName{
Name: vitess.NewColIdent(fmt.Sprintf("%s.%s", node.Namespace, node.Name)),
},
Expr: expr,
}},
}, nil
}
return setStmt, nil
}
46 changes: 35 additions & 11 deletions server/ast/show_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,42 @@ func nodeShowVar(node *tree.ShowVar) (vitess.Statement, error) {

// TODO: this is a temporary way to get the param value for the current implementation
// need better way to get these info
s := &vitess.Select{
SelectExprs: vitess.SelectExprs{
&vitess.AliasedExpr{
Expr: &vitess.ColName{
Name: vitess.NewColIdent("@@session." + node.Name),
Qualifier: vitess.TableName{},
// We treat namespaced variables (e.g. myvar.myvalue) as user variables.
// See set_var.go
isUserVar := strings.Index(node.Name, ".") > 0
if isUserVar {
varName := vitess.NewColIdent(node.Name)
return &vitess.Select{
SelectExprs: vitess.SelectExprs{
&vitess.AliasedExpr{
Expr: &vitess.FuncExpr{
Name: vitess.NewColIdent("current_setting"),
Exprs: []vitess.SelectExpr{
&vitess.AliasedExpr{
Expr: &vitess.SQLVal{Type: vitess.StrVal, Val: []byte(node.Name)},
},
},
},
StartParsePos: 7,
EndParsePos: 7 + len(varName.String()),
As: varName,
},
StartParsePos: 7,
EndParsePos: 17 + len(node.Name),
As: vitess.NewColIdent(node.Name),
},
},
}, nil
} else {
varName := vitess.NewColIdent("@@session." + node.Name)
return &vitess.Select{
SelectExprs: vitess.SelectExprs{
&vitess.AliasedExpr{
Expr: &vitess.ColName{
Name: varName,
Qualifier: vitess.TableName{},
},
StartParsePos: 7,
EndParsePos: 7 + len(varName.String()),
As: varName,
},
},
}, nil
}
return s, nil
}
19 changes: 18 additions & 1 deletion server/doltgres_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/base64"
"fmt"
"io"
"os"
"regexp"
"runtime/trace"
"sync"
Expand All @@ -38,6 +39,16 @@ import (
pgtypes "github.com/dolthub/doltgresql/server/types"
)

var printErrorStackTraces = false

const PrintErrorStackTracesEnvKey = "DOLTGRES_PRINT_ERROR_STACK_TRACES"

func init() {
if _, ok := os.LookupEnv(PrintErrorStackTracesEnvKey); ok {
printErrorStackTraces = true
}
}

// Result represents a query result.
type Result struct {
Fields []pgproto3.FieldDescription `json:"fields"`
Expand Down Expand Up @@ -109,6 +120,9 @@ func (h *DoltgresHandler) ComPrepareParsed(ctx context.Context, c *mysql.Conn, q

analyzed, err := h.e.PrepareParsedQuery(sqlCtx, query, query, parsed)
if err != nil {
if printErrorStackTraces {
fmt.Printf("unable to prepare query: %+v\n", err)
}
logrus.WithField("query", query).Errorf("unable to prepare query: %s", err.Error())
err := sql.CastSQLError(err)
return nil, nil, err
Expand Down Expand Up @@ -218,6 +232,9 @@ func (h *DoltgresHandler) doQuery(ctx context.Context, c *mysql.Conn, query stri

schema, rowIter, qFlags, err := queryExec(sqlCtx, query, parsed, analyzedPlan)
if err != nil {
if printErrorStackTraces {
fmt.Printf("error running query: %+v\n", err)
}
sqlCtx.GetLogger().WithError(err).Warn("error running query")
return err
}
Expand Down Expand Up @@ -451,7 +468,7 @@ func (h *DoltgresHandler) resultForDefaultIter(ctx *sql.Context, schema sql.Sche
// and calls |callback| to give them to vitess.
eg.Go(func() error {
defer pan2err()
//defer cancelF()
// defer cancelF()
defer wg.Done()
for {
if r == nil {
Expand Down
59 changes: 59 additions & 0 deletions server/functions/current_setting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2024 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 functions

import (
"fmt"

"github.com/dolthub/go-mysql-server/sql"

"github.com/dolthub/doltgresql/server/functions/framework"
pgtypes "github.com/dolthub/doltgresql/server/types"
)

// initAsin registers the functions to the catalog.
func initCurrentSetting() {
framework.RegisterFunction(current_setting)
}

// asin_float64 represents the PostgreSQL function of the same name, taking the same parameters.
var current_setting = framework.Function1{
Name: "current_setting",
Return: pgtypes.Text, // TODO: it would be nice to support non-text values as well, but this is all postgres supports
Parameters: [1]pgtypes.DoltgresType{pgtypes.Text},
Strict: true,
Callable: func(ctx *sql.Context, _ [2]pgtypes.DoltgresType, val1 any) (any, error) {
s := val1.(string)
_, variable, err := ctx.GetUserVariable(ctx, s)
if err != nil {
return nil, err
}

if variable != nil {
return variable, nil
}

variable, err = ctx.GetSessionVariable(ctx, s)
if err != nil {
return nil, fmt.Errorf("unrecognized configuration parameter %s", s)
}

if variable != nil {
return variable, nil
}

return nil, fmt.Errorf("unrecognized configuration parameter %s", s)
},
}
3 changes: 3 additions & 0 deletions server/functions/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func Init() {
initCotd()
initCurrentDatabase()
initCurrentSchema()
initCurrentSetting()
initCurrentSchemas()
initDegrees()
initDiv()
Expand Down Expand Up @@ -94,6 +95,7 @@ func Init() {
initPgTotalRelationSize()
initPi()
initPower()
initQuoteIdent()
initRadians()
initRandom()
initRepeat()
Expand Down Expand Up @@ -122,6 +124,7 @@ func Init() {
initToRegclass()
initToRegproc()
initToRegtype()
initTranslate()
initTrimScale()
initTrunc()
initTxidCurrent()
Expand Down
41 changes: 41 additions & 0 deletions server/functions/quote_ident.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 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 functions

import (
"fmt"
"strings"

"github.com/dolthub/go-mysql-server/sql"

"github.com/dolthub/doltgresql/server/functions/framework"
pgtypes "github.com/dolthub/doltgresql/server/types"
)

// initQuoteIdent registers the functions to the catalog.
func initQuoteIdent() {
framework.RegisterFunction(quote_ident_text)
}

// quote_ident_text represents the PostgreSQL function of the same name, taking the same parameters.
var quote_ident_text = framework.Function1{
Name: "quote_ident",
Return: pgtypes.Text,
Parameters: [1]pgtypes.DoltgresType{pgtypes.Text},
Strict: true,
Callable: func(ctx *sql.Context, _ [2]pgtypes.DoltgresType, val any) (any, error) {
return fmt.Sprintf(`"%s"`, strings.Replace(val.(string), "\"", "\"\"", -1)), nil
},
}
Loading

0 comments on commit 1e96f68

Please sign in to comment.