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

sql: Add INET column type and IPAddr datum #18171

Merged
merged 1 commit into from
Sep 19, 2017
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
23 changes: 13 additions & 10 deletions pkg/acceptance/psql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,30 @@ CREATE TABLE playground (
type character varying(50) NOT NULL,
color character varying(25) NOT NULL,
location character varying(25),
install_date date
install_date date,
ip inet
);

COPY playground (equip_id, type, color, location, install_date) FROM stdin;
1 slide blue south 2014-04-28
2 swing yellow northwest 2010-08-16
COPY playground (equip_id, type, color, location, install_date, ip) FROM stdin;
1 slide blue south 2014-04-28 192.168.0.1
2 swing yellow northwest 2010-08-16 ffff::ffff:12
\.
EOF
# psql does not report failures properly in its exit code, so we check
# that the value was inserted explicitly.
psql -d testdb -c "SELECT * FROM playground" | grep blue
psql -d testdb -c "SELECT * FROM playground" | grep ffff::ffff:12

# Test lack of newlines at EOF with no slash-dot.
echo 'COPY playground (equip_id, type, color, location, install_date) FROM stdin;' > import.sql
echo -n -e '3\trope\tgreen\teast\t2015-01-02' >> import.sql
echo 'COPY playground (equip_id, type, color, location, install_date, ip) FROM stdin;' > import.sql
echo -n -e '3\trope\tgreen\teast\t2015-01-02\t192.168.0.1' >> import.sql
psql -d testdb < import.sql
psql -d testdb -c "SELECT * FROM playground" | grep green
psql -d testdb -c "SELECT * FROM playground" | grep 192.168.0.1

# Test lack of newlines at EOF with slash-dot.
echo 'COPY playground (equip_id, type, color, location, install_date) FROM stdin;' > import.sql
echo -e '4\tsand\tbrown\twest\t2016-03-04' >> import.sql
echo 'COPY playground (equip_id, type, color, location, install_date, ip) FROM stdin;' > import.sql
echo -e '4\tsand\tbrown\twest\t2016-03-04\t192.168.0.1' >> import.sql
echo -n '\.' >> import.sql
psql -d testdb < import.sql
psql -d testdb -c "SELECT * FROM playground" | grep brown
Expand All @@ -75,8 +78,8 @@ psql -d testdb -c "show application_name" | grep psql

# Test that errors in COPY FROM STDIN don't screw up the connection
# See #16393
echo 'COPY playground (equip_id, type, color, location, install_date) FROM stdin;' > import.sql
echo -e '3\tjunk\tgreen\teast\t2015-01-02' >> import.sql
echo 'COPY playground (equip_id, type, color, location, install_date, ip) FROM stdin;' > import.sql
echo -e '3\tjunk\tgreen\teast\t2015-01-02\t192.168.0.1' >> import.sql
echo 'garbage' >> import.sql
echo '\.' >> import.sql
echo "SELECT 'hooray'" >> import.sql
Expand Down
5 changes: 5 additions & 0 deletions pkg/cli/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ func dumpTableData(w io.Writer, conn *sqlConn, clusterTS string, md tableMetadat
if err != nil {
return err
}
case "INET":
d, err = parser.ParseDIPAddrFromINetString(string(t))
if err != nil {
return err
}
default:
// STRING and DECIMAL types can have optional length
// suffixes, so only examine the prefix of the type.
Expand Down
30 changes: 19 additions & 11 deletions pkg/cli/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/security"
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
"github.com/cockroachdb/cockroach/pkg/util/duration"
"github.com/cockroachdb/cockroach/pkg/util/ipaddr"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
"github.com/cockroachdb/cockroach/pkg/util/randutil"
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
Expand All @@ -57,11 +58,12 @@ func TestDumpRow(t *testing.T) {
o bool,
e decimal,
u uuid,
ip inet,
tz timestamptz,
e1 decimal(2),
e2 decimal(2, 1),
s1 string(1),
FAMILY "primary" (i, f, d, t, n, o, u, tz, e1, e2, s1, rowid),
FAMILY "primary" (i, f, d, t, n, o, u, ip, tz, e1, e2, s1, rowid),
FAMILY fam_1_s (s),
FAMILY fam_2_b (b),
FAMILY fam_3_e (e)
Expand All @@ -75,6 +77,7 @@ func TestDumpRow(t *testing.T) {
true,
1.2345,
'e9716c74-2638-443d-90ed-ffde7bea7d1d',
'192.168.0.1',
'2016-01-25 10:10:10',
3.4,
4.5,
Expand Down Expand Up @@ -109,22 +112,23 @@ CREATE TABLE t (
o BOOL NULL,
e DECIMAL NULL,
u UUID NULL,
ip INET NULL,
tz TIMESTAMP WITH TIME ZONE NULL,
e1 DECIMAL(2) NULL,
e2 DECIMAL(2,1) NULL,
s1 STRING(1) NULL,
FAMILY "primary" (i, f, d, t, n, o, u, tz, e1, e2, s1, rowid),
FAMILY "primary" (i, f, d, t, n, o, u, ip, tz, e1, e2, s1, rowid),
FAMILY fam_1_s (s),
FAMILY fam_2_b (b),
FAMILY fam_3_e (e)
);

INSERT INTO t (i, f, s, b, d, t, n, o, e, u, tz, e1, e2, s1) VALUES
(1, 2.3, 'striiing', b'a1b2c3', '2016-03-26', '2016-01-25 10:10:10+00:00', '2h30m30s', true, 1.2345, 'e9716c74-2638-443d-90ed-ffde7bea7d1d', '2016-01-25 10:10:10+00:00', 3, 4.5, 's'),
(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(NULL, '+Inf', NULL, NULL, NULL, NULL, NULL, NULL, 'Infinity', NULL, NULL, NULL, NULL, NULL),
(NULL, '-Inf', NULL, NULL, NULL, NULL, NULL, NULL, '-Infinity', NULL, NULL, NULL, NULL, NULL),
(NULL, 'NaN', NULL, NULL, NULL, NULL, NULL, NULL, 'NaN', NULL, NULL, NULL, NULL, NULL);
INSERT INTO t (i, f, s, b, d, t, n, o, e, u, ip, tz, e1, e2, s1) VALUES
(1, 2.3, 'striiing', b'a1b2c3', '2016-03-26', '2016-01-25 10:10:10+00:00', '2h30m30s', true, 1.2345, 'e9716c74-2638-443d-90ed-ffde7bea7d1d', '192.168.0.1', '2016-01-25 10:10:10+00:00', 3, 4.5, 's'),
(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(NULL, '+Inf', NULL, NULL, NULL, NULL, NULL, NULL, 'Infinity', NULL, NULL, NULL, NULL, NULL, NULL),
(NULL, '-Inf', NULL, NULL, NULL, NULL, NULL, NULL, '-Infinity', NULL, NULL, NULL, NULL, NULL, NULL),
(NULL, 'NaN', NULL, NULL, NULL, NULL, NULL, NULL, 'NaN', NULL, NULL, NULL, NULL, NULL, NULL);
`

if string(out) != expect {
Expand Down Expand Up @@ -357,7 +361,8 @@ func TestDumpRandom(t *testing.T) {
s string,
b bytes,
u uuid,
PRIMARY KEY (rowid, i, f, d, m, n, o, e, s, b, u)
ip inet,
PRIMARY KEY (rowid, i, f, d, m, n, o, e, s, b, u, ip)
);
`, nil); err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -416,6 +421,8 @@ func TestDumpRandom(t *testing.T) {
t.Fatal(err)
}

ip := ipaddr.RandIPAddr(rnd)

vals := []driver.Value{
_i,
i,
Expand All @@ -428,15 +435,16 @@ func TestDumpRandom(t *testing.T) {
string(s),
b,
[]byte(u.String()),
ip,
}
if err := conn.Exec("INSERT INTO d.t VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", vals); err != nil {
if err := conn.Exec("INSERT INTO d.t VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", vals); err != nil {
t.Fatal(err)
}
generatedRows = append(generatedRows, vals[1:])
}

check := func(table string) {
q := fmt.Sprintf("SELECT i, f, d, m, n, o, e, s, b, u FROM %s ORDER BY rowid", table)
q := fmt.Sprintf("SELECT i, f, d, m, n, o, e, s, b, u, ip FROM %s ORDER BY rowid", table)
nrows, err := conn.Query(q, nil)
if err != nil {
t.Fatal(err)
Expand Down
31 changes: 31 additions & 0 deletions pkg/cmd/generate-binary/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ var defaultVals = map[string][]string{
"timestamp": timestampInputs,
"timestamptz": timestampInputs,
"date": dateInputs,
"inet": inetInputs,
}

var decimalInputs = []string{
Expand Down Expand Up @@ -178,6 +179,36 @@ var dateInputs = []string{
"1996-02-29",
}

var inetInputs = []string{
"0.0.0.0",
"0.0.0.0/20",
"0.0.0.0/0",
"255.255.255.255",
"255.255.255.255/10",
"::0/0",
"::0/64",
"::0",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/10",
"0.0.0.1",
"111::fff/120",
"127.0.0.1/10",
"192.168.1.2",
"192.168.1.2/16",
"192.168.1.2/10",
"2001:4f8:3:ba::/64",
"2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128",
"::ffff:1.2.3.1/120",
"::ffff:1.2.3.1/128",
"::ffff:1.2.3.1/120",
"::ffff:1.2.3.1/20",
"::1",
"192/10",
"192.168/23",
"192.168./10",
}

func makeEncodingFunc(typName string) generateEnc {
return func(addr, val string) ([]byte, error) {
conn, err := net.Dial("tcp", addr)
Expand Down
6 changes: 6 additions & 0 deletions pkg/internal/rsg/rsg.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/internal/rsg/yacc"
"github.com/cockroachdb/cockroach/pkg/sql/parser"
"github.com/cockroachdb/cockroach/pkg/util/duration"
"github.com/cockroachdb/cockroach/pkg/util/ipaddr"
"github.com/cockroachdb/cockroach/pkg/util/syncutil"
"github.com/cockroachdb/cockroach/pkg/util/uuid"
)
Expand Down Expand Up @@ -239,6 +240,11 @@ func (r *RSG) GenerateRandomArg(typ parser.Type) string {
case parser.TypeUUID:
u := uuid.MakeV4()
v = fmt.Sprintf(`'%s'`, u)
case parser.TypeINet:
r.lock.Lock()
ipAddr := ipaddr.RandIPAddr(r.src)
r.lock.Unlock()
v = fmt.Sprintf(`'%s'`, ipAddr)
case parser.TypeOid,
parser.TypeRegClass,
parser.TypeRegNamespace,
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ func (n *copyNode) addRow(ctx context.Context, line []byte) error {
case parser.TypeBytes,
parser.TypeDate,
parser.TypeInterval,
parser.TypeINet,
parser.TypeString,
parser.TypeTimestamp,
parser.TypeTimestampTZ,
Expand Down
13 changes: 8 additions & 5 deletions pkg/sql/copy_in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func TestCopyNullInfNaN(t *testing.T) {
o BOOL NULL,
e DECIMAL NULL,
u UUID NULL,
ip INET NULL,
tz TIMESTAMP WITH TIME ZONE NULL
);
`); err != nil {
Expand All @@ -71,10 +72,10 @@ func TestCopyNullInfNaN(t *testing.T) {
}

input := [][]interface{}{
{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, math.Inf(1), nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, math.Inf(-1), nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, math.NaN(), nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, math.Inf(1), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, math.Inf(-1), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
{nil, math.NaN(), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
}

for _, in := range input {
Expand Down Expand Up @@ -145,6 +146,7 @@ func TestCopyRandom(t *testing.T) {
s STRING,
b BYTES,
u UUID,
ip INET,
tz TIMESTAMP WITH TIME ZONE
);
`); err != nil {
Expand All @@ -156,7 +158,7 @@ func TestCopyRandom(t *testing.T) {
t.Fatal(err)
}

stmt, err := txn.Prepare(pq.CopyInSchema("d", "t", "id", "n", "o", "i", "f", "e", "t", "s", "b", "u", "tz"))
stmt, err := txn.Prepare(pq.CopyInSchema("d", "t", "id", "n", "o", "i", "f", "e", "t", "s", "b", "u", "ip", "tz"))
if err != nil {
t.Fatal(err)
}
Expand All @@ -171,6 +173,7 @@ func TestCopyRandom(t *testing.T) {
sqlbase.ColumnType_STRING,
sqlbase.ColumnType_BYTES,
sqlbase.ColumnType_UUID,
sqlbase.ColumnType_INET,
sqlbase.ColumnType_TIMESTAMPTZ,
}

Expand Down
1 change: 1 addition & 0 deletions pkg/sql/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,7 @@ func checkResultType(typ parser.Type) error {
case parser.TypeTimestampTZ:
case parser.TypeInterval:
case parser.TypeUUID:
case parser.TypeINet:
case parser.TypeNameArray:
case parser.TypeOid:
case parser.TypeRegClass:
Expand Down
Loading