Skip to content

Commit cd418fe

Browse files
Return detailed C* error for USE query. More test comments
1 parent bd60d74 commit cd418fe

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

parser/lexer_test.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,15 @@ func TestLexerIdentifiers(t *testing.T) {
8686
{`"system"`, tkIdentifier, "system"},
8787
{`"system"`, tkIdentifier, "system"},
8888
{`"System"`, tkIdentifier, "System"},
89-
{`""""`, tkIdentifier, "\""},
90-
{`""""""`, tkIdentifier, "\"\""},
91-
{`"A"""""`, tkIdentifier, "A\"\""},
92-
{`"""A"""`, tkIdentifier, "\"A\""},
93-
{`"""""A"`, tkIdentifier, "\"\"A"},
89+
// below test verify correct escaping double quote character as per CQL definition:
90+
// identifier ::= unquoted_identifier | quoted_identifier
91+
// unquoted_identifier ::= re('[a-zA-Z][link:[a-zA-Z0-9]]*')
92+
// quoted_identifier ::= '"' (any character where " can appear if doubled)+ '"'
93+
{`""""`, tkIdentifier, "\""}, // outermost quotes indicate quoted string, inner two double quotes shall be treated as single quote
94+
{`""""""`, tkIdentifier, "\"\""}, // same as above, but 4 inner quotes result in 2 quotes
95+
{`"A"""""`, tkIdentifier, "A\"\""}, // outermost quotes indicate quoted string, 4 quotes after A result in 2 quotes
96+
{`"""A"""`, tkIdentifier, "\"A\""}, // outermost quotes indicate quoted string, 2 quotes before and after A result in single quotes
97+
{`"""""A"`, tkIdentifier, "\"\"A"}, // analogical to previous tests
9498
{`";`, tkInvalid, ""},
9599
{`"""`, tkIdentifier, ""},
96100
}

proxy/proxy.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,14 @@ func (c *client) interceptSystemQuery(hdr *frame.Header, stmt interface{}) {
812812
}
813813
case *parser.UseStatement:
814814
if _, err := c.proxy.maybeCreateSession(hdr.Version, s.Keyspace); err != nil {
815-
c.send(hdr, &message.ServerError{ErrorMessage: "Proxy unable to create new session for keyspace"})
815+
var cqlError *proxycore.CqlError
816+
switch {
817+
case errors.As(err, &cqlError):
818+
errMsg := cqlError.Message
819+
c.send(hdr, errMsg)
820+
default:
821+
c.send(hdr, &message.ServerError{ErrorMessage: "Proxy unable to create new session for keyspace"})
822+
}
816823
} else {
817824
c.keyspace = s.Keyspace
818825
// We might have received a quoted keyspace name in the UseStatement so remove any

proxy/proxy_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,37 @@ func TestProxy_UseKeyspace(t *testing.T) {
219219
}
220220
}
221221

222+
func TestProxy_UseKeyspace_Error(t *testing.T) {
223+
ctx, cancel := context.WithCancel(context.Background())
224+
tester, proxyContactPoint, err := setupProxyTest(ctx, 1, proxycore.MockRequestHandlers{
225+
primitive.OpCodeQuery: func(cl *proxycore.MockClient, frm *frame.Frame) message.Message {
226+
qry := frm.Body.Message.(*message.Query)
227+
if qry.Query == "USE non_existing" {
228+
return &message.ServerError{
229+
ErrorMessage: "Keyspace 'non_existing' does not exist",
230+
}
231+
}
232+
return cl.InterceptQuery(frm.Header, frm.Body.Message.(*message.Query))
233+
}})
234+
defer func() {
235+
cancel()
236+
tester.shutdown()
237+
}()
238+
require.NoError(t, err)
239+
240+
cl := connectTestClient(t, ctx, proxyContactPoint)
241+
242+
resp, err := cl.SendAndReceive(ctx, frame.NewFrame(primitive.ProtocolVersion4, 0, &message.Query{Query: "USE non_existing"}))
243+
require.NoError(t, err)
244+
245+
assert.Equal(t, primitive.OpCodeError, resp.Header.OpCode)
246+
res, ok := resp.Body.Message.(*message.ServerError)
247+
require.True(t, ok)
248+
// make sure that CQL Proxy returns the same error of 'USE keyspace' command
249+
// as backend C* cluster has and does not wrap it inside a custom one
250+
assert.Equal(t, "Keyspace 'non_existing' does not exist", res.ErrorMessage)
251+
}
252+
222253
func TestProxy_NegotiateProtocolV5(t *testing.T) {
223254
ctx, cancel := context.WithCancel(context.Background())
224255
tester, proxyContactPoint, err := setupProxyTest(ctx, 1, nil)

0 commit comments

Comments
 (0)