Merge pull request #592 from CartoDB/498-pgtypes

Retrieve exact Pg field type information in JSON format
This commit is contained in:
Daniel G. Aubert 2019-06-04 11:51:43 +02:00 committed by GitHub
commit a075965214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 232 additions and 6 deletions

View File

@ -9,6 +9,7 @@ Announcements:
* Improve batch-queries draining while exiting the process #582
* Implement a mechanism to short out hung connections in copy-from endpoints.
* Implement POST method for copy-to endpoint.
* Retrieve the exact PG field type information in JSON format responses.
## 3.0.0

View File

@ -14,7 +14,7 @@ JsonFormat.prototype = new Pg('json');
JsonFormat.prototype._contentType = "application/json; charset=utf-8";
// jshint maxcomplexity:9
// jshint maxcomplexity:10
JsonFormat.prototype.formatResultFields = function(flds) {
flds = flds || [];
var nfields = {};
@ -22,6 +22,7 @@ JsonFormat.prototype.formatResultFields = function(flds) {
var f = flds[i];
var cname = this.client.typeName(f.dataTypeID);
var tname;
if ( ! cname ) {
tname = 'unknown(' + f.dataTypeID + ')';
} else {
@ -44,7 +45,14 @@ JsonFormat.prototype.formatResultFields = function(flds) {
tname += '[]';
}
}
nfields[f.name] = { type: tname };
if (['geography', 'geometry', 'raster'].includes(cname)) {
let { wkbtype, ndims, srid } = this.client.typeModInfo(f.dataTypeModifier);
nfields[f.name] = { type: tname, wkbtype, dims: ndims, srid };
} else {
nfields[f.name] = { type: tname, pgtype: cname };
}
}
return nfields;
};

166
test/acceptance/pg-types.js Normal file
View File

@ -0,0 +1,166 @@
'use strict';
require('../helper');
const server = require('../../app/server')();
const assert = require('../support/assert');
const querystring = require('querystring');
const okResponse = {
status: 200
};
describe('PG field type information', function () {
it('should return type info while requesting json format', function (done) {
assert.response(
server,
{
url: `/api/v1/sql?${querystring.stringify({ q: 'select * from pgtypes_table'})}`,
headers: { host: 'vizzuality.cartodb.com' },
method: 'GET'
},
okResponse,
function (err, res) {
const body = JSON.parse(res.body);
assert.deepEqual(body.fields, {
geography_point_4326: {
type: 'geography', wkbtype: 'Point', dims: 2, srid: 4326
},
geometry_point_4326: {
type: 'geometry', wkbtype: 'Point', dims: 2, srid: 4326
},
geometry_point_3857: {
type: 'geometry', wkbtype: 'Point', dims: 2, srid: 3857
},
geometry_pointz_4326: {
type: 'geometry', wkbtype: 'Point', dims: 3, srid: 4326
},
geometry_pointzm_4326: {
type: 'geometry', wkbtype: 'Point', dims: 4, srid: 4326
},
geography_line_4326: {
type: 'geography', wkbtype: 'LineString', dims: 2, srid: 4326
},
geometry_line_4326: {
type: 'geometry', wkbtype: 'LineString', dims: 2, srid: 4326
},
geometry_line_3857: {
type: 'geometry', wkbtype: 'LineString', dims: 2, srid: 3857
},
geometry_linez_4326: {
type: 'geometry', wkbtype: 'LineString', dims: 3, srid: 4326
},
geometry_linezm_4326: {
type: 'geometry', wkbtype: 'LineString', dims: 4, srid: 4326
},
geography_polygon_4326: {
type: 'geography', wkbtype: 'Polygon', dims: 2, srid: 4326
},
geometry_polygon_4326: {
type: 'geometry', wkbtype: 'Polygon', dims: 2, srid: 4326
},
geometry_polygon_3857: {
type: 'geometry', wkbtype: 'Polygon', dims: 2, srid: 3857
},
geometry_polygonz_4326: {
type: 'geometry', wkbtype: 'Polygon', dims: 3, srid: 4326
},
geometry_polygonzm_4326: {
type: 'geometry', wkbtype: 'Polygon', dims: 4, srid: 4326
},
geography_multipoint_4326: {
type: 'geography', wkbtype: 'MultiPoint', dims: 2, srid: 4326
},
geometry_multipoint_4326: {
type: 'geometry', wkbtype: 'MultiPoint', dims: 2, srid: 4326
},
geometry_multipoint_3857: {
type: 'geometry', wkbtype: 'MultiPoint', dims: 2, srid: 3857
},
geometry_multipointz_4326: {
type: 'geometry', wkbtype: 'MultiPoint', dims: 3, srid: 4326
},
geometry_multipointzm_4326: {
type: 'geometry', wkbtype: 'MultiPoint', dims: 4, srid: 4326
},
geography_multilinestring_4326: {
type: 'geography', wkbtype: 'MultiLineString', dims: 2, srid: 4326
},
geometry_multilinestring_4326: {
type: 'geometry', wkbtype: 'MultiLineString', dims: 2, srid: 4326
},
geometry_multilinestring_3857: {
type: 'geometry', wkbtype: 'MultiLineString', dims: 2, srid: 3857
},
geometry_multilinestringz_4326: {
type: 'geometry', wkbtype: 'MultiLineString', dims: 3, srid: 4326
},
geometry_multilinestringzm_4326: {
type: 'geometry', wkbtype: 'MultiLineString', dims: 4, srid: 4326
},
geography_multipolygon_4326: {
type: 'geography', wkbtype: 'MultiPolygon', dims: 2, srid: 4326
},
geometry_multipolygon_4326: {
type: 'geometry', wkbtype: 'MultiPolygon', dims: 2, srid: 4326
},
geometry_multipolygon_3857: {
type: 'geometry', wkbtype: 'MultiPolygon', dims: 2, srid: 3857
},
geometry_multipolygonz_4326: {
type: 'geometry', wkbtype: 'MultiPolygon', dims: 3, srid: 4326
},
geometry_multipolygonzm_4326: {
type: 'geometry', wkbtype: 'MultiPolygon', dims: 4, srid: 4326
},
raster: {
type: 'raster', dims: 4, srid: -1
},
boolean: {
type: 'boolean', pgtype: 'bool'
},
smallint: {
type: 'number', pgtype: 'int2'
},
integer: {
type: 'number', pgtype: 'int4'
},
bigint: {
type: 'number', pgtype: 'int8'
},
float: {
type: 'number', pgtype: 'float8'
},
real: {
type: 'number', pgtype: 'float4'
},
varchar: {
type: 'string', pgtype: 'varchar'
},
text: {
type: 'string', pgtype: 'text'
},
time: {
type: 'date', pgtype: 'time'
},
date: {
type: 'date', pgtype: 'date'
},
timestamp: {
type: 'date', pgtype: 'timestamp'
},
timestamptz: {
type: 'date', pgtype: 'timestamptz'
},
money: {
type: 'money', pgtype: 'money'
}
});
done();
}
);
});
});

View File

@ -40,10 +40,6 @@ describe('stream-responses', function() {
function(err, res) {
var parsedBody = JSON.parse(res.body);
assert.equal(parsedBody.rows.length, 2);
assert.deepEqual(parsedBody.fields, {
the_geom: { type: "geometry" },
cdb_ratio: { type: "number" }
});
assert.deepEqual(parsedBody.error, ["division by zero"]);
done();
}

View File

@ -231,3 +231,58 @@ CREATE TABLE copy_endpoints_test (
);
GRANT ALL ON TABLE copy_endpoints_test TO :TESTUSER;
GRANT ALL ON TABLE copy_endpoints_test TO :PUBLICUSER;
DROP TABLE IF EXISTS pgtypes_table;
CREATE TABLE pgtypes_table (
-- postgis type
geography_point_4326 geography(point,4326),
geometry_point_4326 geometry(point,4326),
geometry_point_3857 geometry(point,3857),
geometry_pointz_4326 geometry(pointz,4326),
geometry_pointzm_4326 geometry(pointzm,4326),
geography_line_4326 geography(linestring,4326),
geometry_line_4326 geometry(linestring,4326),
geometry_line_3857 geometry(linestring,3857),
geometry_linez_4326 geometry(linestringz,4326),
geometry_linezm_4326 geometry(linestringzm,4326),
geography_polygon_4326 geography(polygon,4326),
geometry_polygon_4326 geometry(polygon,4326),
geometry_polygon_3857 geometry(polygon,3857),
geometry_polygonz_4326 geometry(polygonz,4326),
geometry_polygonzm_4326 geometry(polygonzm,4326),
geography_multipoint_4326 geography(multipoint,4326),
geometry_multipoint_4326 geometry(multipoint,4326),
geometry_multipoint_3857 geometry(multipoint,3857),
geometry_multipointz_4326 geometry(multipointz,4326),
geometry_multipointzm_4326 geometry(multipointzm,4326),
geography_multilinestring_4326 geography(multilinestring,4326),
geometry_multilinestring_4326 geometry(multilinestring,4326),
geometry_multilinestring_3857 geometry(multilinestring,3857),
geometry_multilinestringz_4326 geometry(multilinestringz,4326),
geometry_multilinestringzm_4326 geometry(multilinestringzm,4326),
geography_multipolygon_4326 geography(multipolygon,4326),
geometry_multipolygon_4326 geometry(multipolygon,4326),
geometry_multipolygon_3857 geometry(multipolygon,3857),
geometry_multipolygonz_4326 geometry(multipolygonz,4326),
geometry_multipolygonzm_4326 geometry(multipolygonzm,4326),
raster raster,
-- common postgres types
boolean boolean,
smallint smallint,
integer integer,
bigint bigint,
float double precision,
real real,
varchar varchar,
text text,
time time,
date date,
timestamp timestamp,
timestamptz timestamptz,
money money
);
GRANT ALL ON TABLE pgtypes_table TO :PUBLICUSER;
GRANT ALL ON TABLE pgtypes_table TO :TESTUSER;
INSERT INTO CDB_TableMetadata (tabname, updated_at) VALUES ('pgtypes_table'::regclass, '2015-01-01T23:31:30.123Z');