Skip to content

Commit

Permalink
Revamp send/receive and test it.
Browse files Browse the repository at this point in the history
Follow ltree's example by prepending a version and using the pg_msg functions.
Add tests. A little hinky to use `\copy` to write to a file and then read it
back in, but it is the only way I could figure out to test the receive
function, which binary COPY FROM uses.

Increment to v0.32.0, update the copyright date, and test on Postgres 15.
  • Loading branch information
theory committed Oct 18, 2022
1 parent ab13f60 commit e30b8b0
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
build:
strategy:
matrix:
pg: [14, 13, 12, 11, 10, 9.6, 9.5, 9.4, 9.3, 9.2]
pg: [15, 14, 13, 12, 11, 10, 9.6, 9.5, 9.4, 9.3, 9.2]
name: 🐘 PostgreSQL ${{ matrix.pg }}
runs-on: ubuntu-latest
container: pgxn/pgxn-tools
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ regression.out
/semver-*
/latest-changes.md
/src/*.bc
/semver_binary_copy.bin
/.vscode
4 changes: 3 additions & 1 deletion Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Revision history for PostgreSQL extension semver.

0.31.3
0.32.0
- Add support for binary input (receive) and output (send) functions.
Thanks to Anna Clemens for the pull request (#61)!

0.31.2 2021-09-28T02:03:35Z
- Add an overflow check and properly compare the max size of INT32
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2010-2021 The pg-semver Maintainers: David E. Wheeler, Sam
Copyright (c) 2010-2022 The pg-semver Maintainers: David E. Wheeler, Sam
Vilain, Tom Davis, and Xavier Caron.

This module is free software; you can redistribute it and/or modify it under
Expand Down
4 changes: 2 additions & 2 deletions META.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "semver",
"abstract": "A semantic version data type",
"description": "A Postgres data type for the Semantic Version format with support for btree and hash indexing.",
"version": "0.31.2",
"version": "0.32.0",
"maintainer": [
"David E. Wheeler <[email protected]>",
"Sam Vilain <[email protected]>",
Expand All @@ -15,7 +15,7 @@
"abstract": "A semantic version data type",
"file": "sql/semver.sql",
"docfile": "doc/semver.mmd",
"version": "0.31.2"
"version": "0.32.0"
}
},
"prereqs": {
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
semver 0.31.2
semver 0.32.0
=============

[![PGXN version](https://badge.fury.io/pg/semver.svg)](https://badge.fury.io/pg/semver)
Expand Down Expand Up @@ -78,7 +78,7 @@ for testing, PL/pgSQL.
Copyright and License
---------------------

Copyright (c) 2010-2021 The pg-semver Maintainers: David E. Wheeler, Sam
Copyright (c) 2010-2022 The pg-semver Maintainers: David E. Wheeler, Sam
Vilain, Tom Davis, and Xavier Caron.

This module is free software; you can redistribute it and/or modify it under
Expand Down
4 changes: 2 additions & 2 deletions doc/semver.mmd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
semver 0.31.2
semver 0.32.0
=============

Synopsis
Expand Down Expand Up @@ -342,7 +342,7 @@ Authors
Copyright and License
---------------------

Copyright (c) 2010-2021 The pg-semver Maintainers: David E. Wheeler, Sam
Copyright (c) 2010-2022 The pg-semver Maintainers: David E. Wheeler, Sam
Vilain, Tom Davis, and Xavier Caron.

This module is free software; you can redistribute it and/or modify it under
Expand Down
2 changes: 1 addition & 1 deletion semver.control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# semver extension
comment = 'Semantic version data type'
default_version = '0.31.2'
default_version = '0.32.0'
module_pathname = '$libdir/semver'
relocatable = true
13 changes: 13 additions & 0 deletions sql/semver--0.31.2--0.32.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE OR REPLACE FUNCTION semver_recv(internal)
RETURNS semver
AS 'semver'
LANGUAGE C STRICT IMMUTABLE;

CREATE OR REPLACE FUNCTION semver_send(semver)
RETURNS bytea
AS 'semver'
LANGUAGE C STRICT IMMUTABLE;

ALTER TYPE semver SET
RECEIVE = semver_recv,
SEND = semver_send;
72 changes: 44 additions & 28 deletions src/semver.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* + Tom Davis <[email protected]>
* + Xavier Caron <[email protected]>
*
* Copyright 2010-2021 The pg-semver Maintainers. This program is Free
* Copyright 2010-2022 The pg-semver Maintainers. This program is Free
* Software; see the LICENSE file for the license conditions.
*/

Expand Down Expand Up @@ -343,42 +343,58 @@ semver_out(PG_FUNCTION_ARGS) {
PG_RETURN_CSTRING(result);
}

PG_FUNCTION_INFO_V1(semver_recv);
/*
* semver type send function
*
* The type is sent as text in binary mode, so this is almost the same as the
* output function, but it's prefixed with a version number so we can change the
* binary format sent in future if necessary. For now, only version 1 is
* supported.
*/
PG_FUNCTION_INFO_V1(semver_send);
Datum
semver_recv(PG_FUNCTION_ARGS) {
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
const int len = buf->len - buf->cursor;
char* str = palloc(len + 1);
bool bad = false;
semver* result;

pq_copymsgbytes(buf, str, len);
str[len] = 0;

result = parse_semver(str, false, true, &bad);
semver_send(PG_FUNCTION_ARGS) {
semver *result = PG_GETARG_SEMVER_P(0);
char *str = emit_semver(result);
char version = 1;

StringInfoData buf;
pq_begintypsend(&buf);
pq_sendbyte(&buf, version);
pq_sendtext(&buf, str, strlen(str));
pfree(str);
if (!result) PG_RETURN_NULL();

PG_RETURN_POINTER(result);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

PG_FUNCTION_INFO_V1(semver_send);
/*
* semver type recv function
*
* The type is sent as text in binary mode, so this is almost the same as the
* input function, but it's prefixed with a version number so we can change the
* binary format sent in future if necessary. For now, only version 1 is
* supported.
*/
PG_FUNCTION_INFO_V1(semver_recv);
Datum
semver_send(PG_FUNCTION_ARGS) {
bytea* output;

semver* version = PG_GETARG_SEMVER_P(0);
char* str = emit_semver(version);
int len = strlen(str);

output = palloc(VARHDRSZ + len);

memcpy(VARDATA(output), str, len);
SET_VARSIZE(output, VARHDRSZ + len);
semver_recv(PG_FUNCTION_ARGS) {
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
char version = pq_getmsgbyte(buf);
char *str;
int nbytes;
bool bad = false;
semver *result;

if (version != 1) {
elog(ERROR, "unsupported semver type version number %d", version);
}

str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
result = parse_semver(str, false, true, &bad);
pfree(str);

PG_RETURN_BYTEA_P(output);
if (!result) PG_RETURN_NULL();
PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(text_to_semver);
Expand Down
24 changes: 23 additions & 1 deletion test/expected/base.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
\set ECHO none
1..312
1..334
ok 1 - Type semver should exist
ok 2 - semvers should be NULLable
ok 3 - "1.2.2" is a valid semver
Expand Down Expand Up @@ -312,3 +312,25 @@ ok 309 - Should properly format a 32 character semver
ok 310 - Should properly format a 33 character semver
ok 311 - Should propery format a prerelease with a hyphen
ok 312 - Should get distinct values via hash aggregation
ok 313 - Function semver_send() should exist
ok 314 - Function semver_send(semver) should exist
ok 315 - Function semver_send() should return bytea
ok 316 - Function semver_recv() should exist
ok 317 - Function semver_recv(internal) should exist
ok 318 - Function semver_recv() should return semver
ok 319 - semver_send('0.9.9-a1.1+1234')
ok 320 - semver_send('0.9.9-a1.2.3')
ok 321 - semver_send('0.9.9-a1.2')
ok 322 - semver_send('0.9.9')
ok 323 - semver_send('1.0.0+99')
ok 324 - semver_send('1.0.0-1')
ok 325 - semver_send('1.2.2')
ok 326 - semver_send('9999.9999999.823823')
ok 327 - semver_send('1.0.0-beta1')
ok 328 - semver_send('1.0.0-1')
ok 329 - semver_send('1.0.0-alpha+d34dm34t')
ok 330 - semver_send('1.0.0+d34dm34t')
ok 331 - semver_send('20110204.0.0')
ok 332 - semver_send('1.0.0-0AEF')
ok 333 - semver_send(NULL)
ok 334 - Should have binary copied all of the semvers
40 changes: 39 additions & 1 deletion test/sql/base.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ BEGIN;
\i test/pgtap-core.sql
\i sql/semver.sql

SELECT plan(312);
SELECT plan(334);
--SELECT * FROM no_plan();

SELECT has_type('semver');
Expand Down Expand Up @@ -514,5 +514,43 @@ SELECT bag_eq(
'Should get distinct values via hash aggregation'
);

-- Test send and receive.
SELECT has_function('semver_send');
SELECT has_function('semver_send', ARRAY['semver']);
SELECT function_returns('semver_send', 'bytea');
SELECT has_function('semver_recv');
SELECT has_function('semver_recv', ARRAY['internal']);
SELECT function_returns('semver_recv', 'semver');

-- Set up some values to copy.
INSERT INTO vs VALUES
('1.2.2'::semver),
('9999.9999999.823823'),
('1.0.0-beta1'),
('1.0.0-1'),
('1.0.0-alpha+d34dm34t'),
('1.0.0+d34dm34t'),
('20110204.0.0'),
('1.0.0-0AEF'),
(NULL)
;

-- Test semver_send().
SELECT is(
semver_send(version), '\x01' || version::bytea,
'semver_send(' || COALESCE(quote_literal(version::text), 'NULL') || ')'
) FROM vs;

-- Cannot test semver_recv() directly, so instead copy to a file and back into
-- another table.
CREATE TABLE vs_recv(version semver);
\copy vs TO semver_binary_copy.bin WITH BINARY;
\copy vs_recv from semver_binary_copy.bin with binary;
SELECT bag_eq(
'SELECT * FROM vs',
'SELECT * FROM vs_recv',
'Should have binary copied all of the semvers'
);

SELECT * FROM finish();
ROLLBACK;

0 comments on commit e30b8b0

Please sign in to comment.