8000 Multi statement mode doesn't handle procedures correctly · Issue #28 · dolthub/driver · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Multi statement mode doesn't handle procedures correctly #28
Closed
@arvidfm

Description

@arvidfm

The driver naively splits multi-statement queries by ;, which doesn't match how Vitess and GMS process the queries: In particular, procedure definitions are not parsed as a single statement, and DELIMITER statements are not respected.

Additionally, the driver processes multi-statement queries by executing the statements directly in Prepare, which is unexpected behaviour.

Demonstration of the issue; the below yields the error Error 1105: syntax error at position 42 near '1' when running the last query, but works correctly if connecting to a Dolt server using the MySQL driver:

package main

import (
	"context"
	"database/sql"
	"net/url"
	"os"

	_ "github.com/dolthub/driver"
)

func main() {
	dir := must(os.MkdirTemp("", "dolt-test-db-*"))
	defer os.RemoveAll(dir)

	params := url.Values{
		"database": []string{"testdb"}, "multistatements": []string{"true"},
		"commitname": []string{"a"}, "commitemail": []string{"a@a.com"}}
	dsn := url.URL{Scheme: "file", Path: dir, RawQuery: params.Encode()}
	db := must(sql.Open("dolt", dsn.String()))

	ctx := context.Background()
	must(db.ExecContext(ctx, "CREATE DATABASE testdb"))
	must(db.ExecContext(ctx, "COMMIT")) // workaround for implicit transactions not being committed

	must(db.ExecContext(ctx, `
CREATE PROCEDURE myproc()
BEGIN
	SELECT 1;
END;

CALL myproc();
`))
}

func must[T any](t T, err error) T {
	if err != nil {
		panic(err)
	}
	return t
}

I had a quick look at it myself, but it wasn't obvious what the best approach would be - perhaps the easiest would be to implement ExecContext and QueryContext and move the multi-statement processing there, maybe using MysqlParser from GMS to split the queries and calling QueryWithBindings for each, if prepared multi-statement queries aren't a requirement? (They don't seem to be supported by MySQL anyway.) Would be nice if the result also implemented driver.RowsNextResultSet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0