Skip to content

Commit 8e614fc

Browse files
craig[bot]otan
andcommitted
106131: pgrepl: parse replication statements + handle IDENTIFY_SYSTEM r=cucaroach a=otan Informs: cockroachdb#105130 ## pgwire: ban extended protocol with REPLICATION protocol In line with PostgreSQL, we prohibit the use of the extended protocol when the replication protocol is in effect. Release note: None ## pgrepl: implement IDENTIFY_SYSTEM command This commit implements IDENTIFY_SYSTEM in the replication protocol, which is used to retrieve metadata about replication state. Most of this commit involves changing assumptions throughout the codebase there is 1 parser - there is 2 if replication mode is enabled. We've also had to change the parser to return `statements.Statement` instead of `pgrepltree.ReplicationStatement` for compatibility with `parser.Parse...`. I've left the `LSN` fields as placeholders for now as we finalise on what we'll eventually call it. Release note: None ## sql: no-op SHOW SYNTAX in replication mode Currently on the CLI, the command must parse on the server for it to run. For replication related commands, we have not implemented `SHOW SYNTAX` yet. This is a bit of effort and seems outside the scope of what we want for now. For now, handle replication commands by no-oping them. Release note: None Co-authored-by: Oliver Tan <[email protected]>
2 parents e5d064d + 1cd0a2a commit 8e614fc

29 files changed

+488
-15
lines changed

pkg/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,7 @@ GO_TARGETS = [
19021902
"//pkg/sql/parser:parser",
19031903
"//pkg/sql/parser:parser_test",
19041904
"//pkg/sql/pgrepl/lsn:lsn",
1905+
"//pkg/sql/pgrepl/lsnutil:lsnutil",
19051906
"//pkg/sql/pgrepl/pgreplparser:pgreplparser",
19061907
"//pkg/sql/pgrepl/pgreplparser:pgreplparser_test",
19071908
"//pkg/sql/pgrepl/pgrepltree:pgrepltree",

pkg/acceptance/generated_cli_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#! /usr/bin/env expect -f
2+
3+
source [file join [file dirname $argv0] common.tcl]
4+
5+
start_server $argv
6+
7+
start_test "Ensure that replication mode works as expected in the sql shell"
8+
9+
# Spawn a sql shell.
10+
spawn /bin/bash
11+
12+
send "$argv sql --url `cat server_url`'\&replication=database' -e 'IDENTIFY_SYSTEM'\r"
13+
eexpect "(1 row)"
14+
15+
send_eof
16+
eexpect eof
17+
18+
end_test
19+
20+
stop_server $argv

pkg/sql/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ go_library(
127127
"grant_revoke_system.go",
128128
"grant_role.go",
129129
"group.go",
130+
"identify_system.go",
130131
"index_backfiller.go",
131132
"index_join.go",
132133
"index_split_scatter.go",
@@ -442,6 +443,9 @@ go_library(
442443
"//pkg/sql/paramparse",
443444
"//pkg/sql/parser",
444445
"//pkg/sql/parser/statements",
446+
"//pkg/sql/pgrepl/lsn",
447+
"//pkg/sql/pgrepl/lsnutil",
448+
"//pkg/sql/pgrepl/pgrepltree",
445449
"//pkg/sql/pgwire/pgcode",
446450
"//pkg/sql/pgwire/pgerror",
447451
"//pkg/sql/pgwire/pgnotice",

pkg/sql/catalog/colinfo/result_columns.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,11 @@ const RangesExtraRenders = `
344344
coalesce((crdb_internal.range_stats(start_key)->>'range_key_bytes')::INT, 0) +
345345
coalesce((crdb_internal.range_stats(start_key)->>'range_val_bytes')::INT, 0) AS range_size
346346
`
347+
348+
// IdentifySystemColumns is the schema for IDENTIFY_SYSTEM.
349+
var IdentifySystemColumns = ResultColumns{
350+
{Name: "systemid", Typ: types.String},
351+
{Name: "timeline", Typ: types.Int4},
352+
{Name: "xlogpos", Typ: types.String},
353+
{Name: "dbname", Typ: types.String},
354+
}

pkg/sql/delegate/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ go_library(
5353
"//pkg/sql/oidext",
5454
"//pkg/sql/opt/cat",
5555
"//pkg/sql/parser",
56+
"//pkg/sql/pgrepl/pgreplparser",
5657
"//pkg/sql/pgwire/pgcode",
5758
"//pkg/sql/pgwire/pgerror",
5859
"//pkg/sql/privilege",
5960
"//pkg/sql/roleoption",
6061
"//pkg/sql/sem/catconstants",
6162
"//pkg/sql/sem/eval",
6263
"//pkg/sql/sem/tree",
64+
"//pkg/sql/sessiondatapb",
6365
"//pkg/sql/sqlerrors",
6466
"//pkg/sql/sqltelemetry",
6567
"//pkg/sql/syntheticprivilege",

pkg/sql/delegate/show_syntax.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import (
1818
"github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo"
1919
"github.com/cockroachdb/cockroach/pkg/sql/lexbase"
2020
"github.com/cockroachdb/cockroach/pkg/sql/parser"
21+
"github.com/cockroachdb/cockroach/pkg/sql/pgrepl/pgreplparser"
2122
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
23+
"github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb"
2224
)
2325

2426
// delegateShowSyntax implements SHOW SYNTAX. This statement is usually handled
@@ -41,6 +43,16 @@ func (d *delegator) delegateShowSyntax(n *tree.ShowSyntax) (tree.Statement, erro
4143
colinfo.ShowSyntaxColumns[0].Name, colinfo.ShowSyntaxColumns[1].Name,
4244
)
4345

46+
// For replication based statements, return nothing for now.
47+
if d.evalCtx.SessionData().ReplicationMode != sessiondatapb.ReplicationMode_REPLICATION_MODE_DISABLED &&
48+
pgreplparser.IsReplicationProtocolCommand(n.Statement) {
49+
return d.parse(fmt.Sprintf(
50+
`SELECT '' AS %s, '' AS %s FROM generate_series(0, -1) x`,
51+
colinfo.ShowSyntaxColumns[0].Name,
52+
colinfo.ShowSyntaxColumns[1].Name,
53+
))
54+
}
55+
4456
comma := ""
4557
// TODO(knz): in the call below, reportErr is nil although we might
4658
// want to be able to capture (and report) these errors as well.

pkg/sql/exec_util.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,6 +2152,7 @@ type SessionArgs struct {
21522152
User username.SQLUsername
21532153
IsSuperuser bool
21542154
IsSSL bool
2155+
ReplicationMode sessiondatapb.ReplicationMode
21552156
SystemIdentity username.SQLUsername
21562157
SessionDefaults SessionDefaults
21572158
CustomOptionSessionDefaults SessionDefaults

pkg/sql/identify_system.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2023 The Cockroach Authors.
2+
//
3+
// Use of this software is governed by the Business Source License
4+
// included in the file licenses/BSL.txt.
5+
//
6+
// As of the Change Date specified in that file, in accordance with
7+
// the Business Source License, use of this software will be governed
8+
// by the Apache License, Version 2.0, included in the file
9+
// licenses/APL.txt.
10+
11+
package sql
12+
13+
import (
14+
"context"
15+
16+
"github.com/cockroachdb/cockroach/pkg/sql/pgrepl/lsn"
17+
"github.com/cockroachdb/cockroach/pkg/sql/pgrepl/lsnutil"
18+
"github.com/cockroachdb/cockroach/pkg/sql/pgrepl/pgrepltree"
19+
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
20+
)
21+
22+
type identifySystemNode struct {
23+
optColumnsSlot
24+
clusterID string
25+
database string
26+
lsn lsn.LSN
27+
shown bool
28+
}
29+
30+
func (s *identifySystemNode) startExec(params runParams) error {
31+
return nil
32+
}
33+
34+
func (s *identifySystemNode) Next(params runParams) (bool, error) {
35+
if s.shown {
36+
return false, nil
37+
}
38+
s.shown = true
39+
return true, nil
40+
}
41+
42+
func (s *identifySystemNode) Values() tree.Datums {
43+
db := tree.DNull
44+
if s.database != "" {
45+
db = tree.NewDString(s.database)
46+
}
47+
return tree.Datums{
48+
tree.NewDString(s.clusterID),
49+
tree.NewDInt(1), // timeline
50+
tree.NewDString(s.lsn.String()),
51+
db,
52+
}
53+
}
54+
55+
func (s *identifySystemNode) Close(ctx context.Context) {}
56+
57+
func (p *planner) IdentifySystem(
58+
ctx context.Context, n *pgrepltree.IdentifySystem,
59+
) (planNode, error) {
60+
return &identifySystemNode{
61+
// TODO(#105130): correctly populate this field.
62+
lsn: lsnutil.HLCToLSN(p.Txn().ReadTimestamp()),
63+
clusterID: p.ExecCfg().NodeInfo.LogicalClusterID().String(),
64+
database: p.SessionData().Database,
65+
}, nil
66+
}

pkg/sql/opaque.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo"
1818
"github.com/cockroachdb/cockroach/pkg/sql/opt"
1919
"github.com/cockroachdb/cockroach/pkg/sql/opt/optbuilder"
20+
"github.com/cockroachdb/cockroach/pkg/sql/pgrepl/pgrepltree"
2021
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
2122
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
2223
"github.com/cockroachdb/cockroach/pkg/sql/sem/eval"
@@ -281,6 +282,8 @@ func planOpaque(ctx context.Context, p *planner, stmt tree.Statement) (planNode,
281282
return p.Truncate(ctx, n)
282283
case *tree.Unlisten:
283284
return p.Unlisten(ctx, n)
285+
case *pgrepltree.IdentifySystem:
286+
return p.IdentifySystem(ctx, n)
284287
case tree.CCLOnlyStatement:
285288
plan, err := p.maybePlanHook(ctx, stmt)
286289
if plan == nil && err == nil {
@@ -397,6 +400,8 @@ func init() {
397400
&tree.Truncate{},
398401
&tree.Unlisten{},
399402

403+
&pgrepltree.IdentifySystem{},
404+
400405
// CCL statements (without Export which has an optimizer operator).
401406
&tree.AlterBackup{},
402407
&tree.AlterBackupSchedule{},

0 commit comments

Comments
 (0)