Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for protocol v3 and add QuerySQL and ExecuteSQL client methods #328

Merged
merged 6 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions errors_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const (
UnknownUserError = edgedb.UnknownUserError
UnknownDatabaseError = edgedb.UnknownDatabaseError
UnknownParameterError = edgedb.UnknownParameterError
DeprecatedScopingError = edgedb.DeprecatedScopingError
SchemaError = edgedb.SchemaError
SchemaDefinitionError = edgedb.SchemaDefinitionError
InvalidDefinitionError = edgedb.InvalidDefinitionError
Expand Down Expand Up @@ -102,6 +103,9 @@ const (
AuthenticationError = edgedb.AuthenticationError
AvailabilityError = edgedb.AvailabilityError
BackendUnavailableError = edgedb.BackendUnavailableError
ServerOfflineError = edgedb.ServerOfflineError
UnknownTenantError = edgedb.UnknownTenantError
ServerBlockedError = edgedb.ServerBlockedError
BackendError = edgedb.BackendError
UnsupportedBackendFeatureError = edgedb.UnsupportedBackendFeatureError
ClientError = edgedb.ClientError
Expand Down
2 changes: 2 additions & 0 deletions internal/client/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type idPair struct {
}

type queryKey struct {
lang Language
cmd string
fmt Format
expCard Cardinality
Expand All @@ -76,6 +77,7 @@ type queryKey struct {

func makeKey(q *query) queryKey {
return queryKey{
lang: q.lang,
cmd: q.cmd,
fmt: q.fmt,
expCard: q.expCard,
Expand Down
46 changes: 46 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,52 @@ func (p *Client) QuerySingleJSON(
return firstError(err, p.release(conn, err))
}

// QuerySQL runs a SQL query and returns the results.
func (p *Client) QuerySQL(
ctx context.Context,
cmd string,
out interface{},
args ...interface{},
) error {
conn, err := p.acquire(ctx)
if err != nil {
return err
}

err = runQuery(
ctx, conn, "QuerySQL", cmd, out, args, p.state, p.warningHandler)
return firstError(err, p.release(conn, err))
}

// ExecuteSQL executes a SQL command (or commands).
func (p *Client) ExecuteSQL(
ctx context.Context,
cmd string,
args ...interface{},
) error {
conn, err := p.acquire(ctx)
if err != nil {
return err
}

q, err := newQuery(
"ExecuteSQL",
cmd,
args,
conn.capabilities1pX(),
copyState(p.state),
nil,
true,
p.warningHandler,
)
if err != nil {
return err
}

err = conn.scriptFlow(ctx, q)
return firstError(err, p.release(conn, err))
}

// Tx runs an action in a transaction retrying failed actions
// if they might succeed on a subsequent attempt.
//
Expand Down
58 changes: 58 additions & 0 deletions internal/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,64 @@ func TestQuerySingleJSONMissingResult(t *testing.T) {
"the \"out\" argument must be *[]byte or *OptionalBytes, got *string")
}

func TestQuerySQL(t *testing.T) {
ctx := context.Background()

var version int64
err := client.QuerySingle(ctx, "SELECT sys::get_version().major", &version)
assert.NoError(t, err)

if version >= 6 {
err = client.ExecuteSQL(ctx, "select 1")
assert.NoError(t, err)

var result []struct {
Col1 int32 `edgedb:"col~1"`
}
err = client.QuerySQL(ctx, "select 1", &result)
assert.NoError(t, err)
assert.Equal(t, int32(1), result[0].Col1)

type res2 struct {
Foo int32 `edgedb:"foo"`
Bar int32 `edgedb:"bar"`
}
var result2 []res2
err = client.QuerySQL(ctx, "select 1 AS foo, 2 AS bar", &result2)
assert.NoError(t, err)
assert.Equal(t, []res2{
{
Foo: 1,
Bar: 2,
},
}, result2)

var result3 []struct {
Col1 int64 `edgedb:"col~1"`
}
err = client.QuerySQL(ctx, "select 1 + $1::int8", &result3, int64(41))
assert.NoError(t, err)
assert.Equal(t, int64(42), result3[0].Col1)
} else {
var res []interface{}
err = client.QuerySQL(ctx, "select 1", &res)
assert.EqualError(
t, err,
"edgedb.UnsupportedFeatureError: "+
"the server does not support SQL queries, "+
"upgrade to 6.0 or newer",
)

err = client.ExecuteSQL(ctx, "select 1")
assert.EqualError(
t, err,
"edgedb.UnsupportedFeatureError: "+
"the server does not support SQL queries, "+
"upgrade to 6.0 or newer",
)
}
}

// TODO: return when session_idle_timeout changes
// will be reflected at connection creation

Expand Down
3 changes: 2 additions & 1 deletion internal/client/connutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ var (
`^(\w(?:-?\w)*)$`,
)
cloudInstanceNameRe = regexp.MustCompile(
`^([A-Za-z0-9_\-](?:-?[A-Za-z_0-9\-])*)/([A-Za-z0-9](?:-?[A-Za-z0-9])*)$`,
`^([A-Za-z0-9_\-](?:-?[A-Za-z_0-9\-])*)/` +
`([A-Za-z0-9](?:-?[A-Za-z0-9])*)$`,
)
domainLabelMaxLength = 63
crcTable *crc16.Table = crc16.MakeTable(crc16.CRC16_XMODEM)
Expand Down
3 changes: 2 additions & 1 deletion internal/client/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ var (
defaultConcurrency = max(4, runtime.NumCPU())

protocolVersionMin = protocolVersion0p13
protocolVersionMax = protocolVersion2p0
protocolVersionMax = protocolVersion3p0
protocolVersion0p13 = internal.ProtocolVersion{Major: 0, Minor: 13}
protocolVersion1p0 = internal.ProtocolVersion{Major: 1, Minor: 0}
protocolVersion2p0 = internal.ProtocolVersion{Major: 2, Minor: 0}
protocolVersion3p0 = internal.ProtocolVersion{Major: 3, Minor: 0}

capabilitiesSessionConfig uint64 = 0x2
capabilitiesTransaction uint64 = 0x4
Expand Down
14 changes: 14 additions & 0 deletions internal/client/edgedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ func (c *protocolConnection) isClosed() bool {
}

func (c *protocolConnection) scriptFlow(ctx context.Context, q *query) error {
if q.lang == SQL && c.protocolVersion.LT(protocolVersion3p0) {
return &unsupportedFeatureError{
msg: "the server does not support SQL queries, " +
"upgrade to 6.0 or newer",
}
}

r, err := c.acquireReader(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -210,6 +217,13 @@ func (c *protocolConnection) granularFlow(
ctx context.Context,
q *query,
) error {
if q.lang == SQL && c.protocolVersion.LT(protocolVersion3p0) {
return &unsupportedFeatureError{
msg: "the server does not support SQL queries, " +
"upgrade to 6.0 or newer",
}
}

r, err := c.acquireReader(ctx)
if err != nil {
return err
Expand Down
Loading
Loading