Compare commits

...

63 Commits

Author SHA1 Message Date
Rafa de la Torre
7d106e68b0 Merge pull request #161 from CartoDB/160-add-drop-function-if-exists
Add DROP FUNCTION back to allow migrations #160
2015-09-24 18:26:30 +02:00
Rafa de la Torre
567e815fd0 Add DROP FUNCTION back to allow migrations #160 2015-09-24 17:56:00 +02:00
Rafa de la Torre
255618f57d Merge pull request #159 from CartoDB/fix-type-already-exists
Fix creation of type _cdb_has_usable_geom_record
2015-09-21 14:50:44 +02:00
Rafa de la Torre
5ea1b7d4d7 Fix creation of type _cdb_has_usable_geom_record
Fix the ERROR:  type "_cdb_has_usable_geom_record" already exists by
checking for existence before. Duly noted for upgrades.
2015-09-21 14:16:32 +02:00
Rafa de la Torre
0c14df5f89 Fix upgrade from 0.10.0 to 0.10.1 2015-09-16 14:40:18 +02:00
Rafa de la Torre
c2780773d2 Update NEWS.md and version to 0.10.1 2015-09-16 12:40:14 +02:00
Rafa de la Torre
14508ff5f3 Merge pull request #152 from CartoDB/141-fix-table-multiple-geometry-columns
141 fix table multiple geometry columns
2015-09-16 12:22:49 +02:00
Rafa de la Torre
6ba809e798 Remove usage of _CDB_Geometry_SRID #154
This is only used from _CDB_Has_Usable_Geom. It doesn't do what's
promised in the comment. The effect is that a column is taken as valid
when it actually needs setting its SRID restriction so better not use
it as it will need rewrite anyway.
2015-09-16 12:17:40 +02:00
Rafa de la Torre
c8e3cf5500 Add test courtesy of Paul #154 2015-09-16 12:17:35 +02:00
Rafa de la Torre
d268497030 Add expectation for new test #141 2015-09-15 19:14:06 +02:00
Rafa de la Torre
fa514a3b7c Add a couple of NOTICE's to expectations #141 2015-09-15 18:49:59 +02:00
Rafa de la Torre
0ebd12a0eb Avoid double-escaping of reloid::text #141 2015-09-15 18:49:59 +02:00
Rafa de la Torre
e7c974e957 Fix silly typo #141 2015-09-15 18:49:59 +02:00
Rafa de la Torre
789e89a5d2 Create a return type for _cdb_has_usable_geom_record #141 2015-09-15 18:49:59 +02:00
Rafa de la Torre
3fdce65368 Move column renaming out of _CDB_Has_Usable_Geom #141 2015-09-15 18:49:59 +02:00
Rafa de la Torre
5caddc6cc7 Fix for MultiPoint geometry issue #141 2015-09-15 18:49:59 +02:00
Rafa de la Torre
9d8d79eb40 Slightly improve the test #141 2015-09-14 17:55:30 +02:00
Rafa de la Torre
1596bd56d8 Improve another EXECUTE+FOUND #141 2015-09-14 17:54:35 +02:00
Rafa de la Torre
dfd0454be3 Improve comment #141 2015-09-14 17:53:34 +02:00
Rafa de la Torre
731ee0a9ba Fix the_geom_webmercator already exists #141 2015-09-14 17:06:24 +02:00
Rafa de la Torre
e3bba2ee4b Fix the_geom already exists error #141 2015-09-14 17:05:14 +02:00
Rafa de la Torre
581835d4ff Extract query into _cdb_geom_candidate_columns #141 2015-09-14 11:50:10 +02:00
Rafa de la Torre
9ec24c1aff Fix FOUND in _CDB_Geometry_SRID #141 2015-09-14 11:18:12 +02:00
Rafa de la Torre
e546c15770 Test for failing scenario #141 2015-09-11 16:16:54 +02:00
Rafa de la Torre
c12ae7f4a8 Merge pull request #146 from CartoDB/138-fix-cartodbfy-no-default-seq-value3
138 fix cartodbfy no default seq value3
2015-09-11 11:00:04 +02:00
Rafa de la Torre
7a247c1ab2 Recover usage of cartodb id if has_usable_primary_key #138 2015-09-10 18:20:52 +02:00
Rafa de la Torre
85b206fdba Improve test about existing cartodb_id values #138 2015-09-10 18:18:13 +02:00
Rafa de la Torre
75b37d5a88 Improve tests #138 2015-09-09 18:34:55 +02:00
Rafa de la Torre
ef21128099 Explicitly check if there's a sequence on PK #138 2015-09-09 18:33:06 +02:00
Rafa de la Torre
497034c285 Add test for failing scenario #138 2015-09-09 18:33:06 +02:00
Rafa de la Torre
6e4a5b5635 Add CASCADE to DROP SCHEMA... in tear_down #138 2015-09-09 18:33:06 +02:00
Raul Ochoa
d67f097703 Merge pull request #145 from CartoDB/fix-cdb_stats-test
Do not use random() for the distribution to test CDB_Stats functions
2015-09-09 17:12:07 +02:00
Alejandro Martínez
c460b59c07 Merge pull request #143 from CartoDB/readd-update-updated-at
Readd update_updated_at function (still used by old tables)
2015-09-09 17:09:06 +02:00
Raul Ochoa
1853ee6306 Do not use random() for the distribution to test CDB_Stats functions
Fixes #144
2015-09-09 17:08:32 +02:00
Alejandro Martínez
9ec5d9000a Readd update_updated_at function (still used by old tables) 2015-09-09 14:56:34 +02:00
Raul Ochoa
0ec579984b Stubs next version 2015-09-07 13:17:22 +02:00
Raul Ochoa
c6f2903221 Release 0.10.0 2015-09-07 13:16:27 +02:00
Raul Ochoa
03f42e36c9 Update news and bump version 2015-09-07 13:02:05 +02:00
Raul Ochoa
af546b35ab Merge pull request #134 from CartoDB/cdb_querytables_quoted
Quote schema and table names returned by CDB_QueryTables
2015-09-07 12:20:17 +02:00
Raul Ochoa
5abe6e0b3d Merge branch 'master' into cdb_querytables_quoted
Conflicts:
	test/extension/test.sh
2015-09-07 12:17:36 +02:00
Raul Ochoa
1eabc5e880 Merge pull request #131 from CartoDB/column-regclass-functions
Column regclass
2015-09-07 12:11:59 +02:00
Raul Ochoa
c6cdaea626 Merge pull request #124 from CartoDB/add-kurtosis
Add kurtosis and skewness
2015-09-07 12:11:34 +02:00
Andy Eschbacher
b5a9fb9fcf Merge branch 'add-kurtosis' of https://github.com/CartoDB/cartodb-postgresql into add-kurtosis 2015-09-03 22:44:06 -04:00
Andy Eschbacher
83b7f47617 removing raise notices and lower test bounds 2015-09-03 22:43:25 -04:00
Raul Ochoa
25cf48d4a4 Raise min message so we don't have to validate notices 2015-09-04 00:02:30 +02:00
Raul Ochoa
29efdf2ee7 Fix symlink for CDB_Stats.sql 2015-09-04 00:00:30 +02:00
Raul Ochoa
4be7d4a497 Use quote_ident to quote schema and table names when necessary
Fixes #133
2015-09-03 13:12:29 +02:00
Raul Ochoa
350c76f847 Add option to run tests by prefix
`bash test/extension/test.sh test_cdb_querytables`
will run all tests that start with test_cdb_querytables
2015-09-03 12:59:20 +02:00
Andy Eschbacher
d00e71309d really add tests 2015-09-02 22:35:03 -04:00
Andy Eschbacher
07280321ab adding tests 2015-09-02 22:19:07 -04:00
Raul Ochoa
e28b6344aa Assert it's not possible to get column names from a table without permissions 2015-09-02 12:32:43 +02:00
Raul Ochoa
2867a6fbad Assert user can use its schema to retrieve column names 2015-09-02 12:32:34 +02:00
Raul Ochoa
afecef0e31 Removing redundant ::regclass casting 2015-09-02 12:25:44 +02:00
Raul Ochoa
7582f2cbc5 CDB_ColumnType uses schema and table from regclass
Fixes #130
2015-09-02 12:06:04 +02:00
Raul Ochoa
4b5c5dd275 CDB_ColumnNames uses schema and table name from regclass
Fixes #122
2015-09-02 12:04:52 +02:00
Raul Ochoa
eb6fc4fefb Use CDB_ColumnType and CDB_ColumnNames in bash tests 2015-09-02 12:01:43 +02:00
Rafa de la Torre
4fe85a6a76 Merge pull request #129 from CartoDB/120-fix-extension-upgrade
Do not remove old function #120
2015-08-31 14:05:55 +02:00
Rafa de la Torre
2269dc0cb5 Add explanation in NEWS file #120
as suggested in PR.
2015-08-31 12:56:16 +02:00
Rafa de la Torre
0ba57f436a Do not remove old function #120
The `DROP FUNCTION IF EXISTS` was added as transient code and not needed
anymore. See the ticket #120 for more information on this.
2015-08-31 12:01:04 +02:00
Andy Eschbacher
14e2a65523 adding symlink 2015-08-25 23:11:09 -04:00
Andy Eschbacher
d723487f67 updated definition 2015-08-25 23:10:26 -04:00
Andy Eschbacher
db323f3e13 adding skewness 2015-08-25 22:58:31 -04:00
Andy Eschbacher
49c4cea4e7 adding kurtosis 2015-08-25 22:45:55 -04:00
16 changed files with 414 additions and 105 deletions

View File

@@ -1,7 +1,7 @@
# cartodb/Makefile
EXTENSION = cartodb
EXTVERSION = 0.9.4
EXTVERSION = 0.10.2
SED = sed
@@ -47,6 +47,9 @@ UPGRADABLE = \
0.9.2 \
0.9.3 \
0.9.4 \
0.10.0 \
0.10.1 \
0.10.2 \
$(EXTVERSION)dev \
$(EXTVERSION)next \
$(END)

22
NEWS.md
View File

@@ -1,3 +1,25 @@
next (2015-mm-dd)
-----------------
0.10.2 (2015-09-24)
-------------------
* Add back the `DROP FUNCTION IF EXISTS CDB_UserTables(text);` to be able to upgrade from `0.7.3` upward [#160](https://github.com/CartoDB/cartodb-postgresql/issues/160)
0.10.1 (2015-09-16)
-------------------
* Get back the `update_updated_at` function (still used by old tables) [#143](https://github.com/CartoDB/cartodb-postgresql/pull/143)
* Fix for CDB_StatsTest.sql test failing randomly [#144](https://github.com/CartoDB/cartodb-postgresql/issues/144)
* Fix for table cartodbfy'ed without default seq value [#138](https://github.com/CartoDB/cartodb-postgresql/issues/138)
* Fix for cartodbfy error column `the_geom` already exists [#141](https://github.com/CartoDB/cartodb-postgresql/issues/141)
* Fix for columns with geometry cartodbfy'ed without SRID [#154](https://github.com/CartoDB/cartodb-postgresql/issues/154)
0.10.0 (2015-09-07)
-----------------
* Quote schema and table names returned by CDB_QueryTables [#134](https://github.com/CartoDB/cartodb-postgresql/pull/134). Use quote_ident to quote schema and table names when necessary.
* Fixed CDB_ColumnNames [#122](https://github.com/CartoDB/cartodb-postgresql/issues/122) and CDB_ColumnType [#130](https://github.com/CartoDB/cartodb-postgresql/issues/130) should honor regclass, returning columns for just the table in the schema and not in any other one [#131](https://github.com/CartoDB/cartodb-postgresql/pull/131).
* Add kurtosis and skewness [#124](https://github.com/CartoDB/cartodb-postgresql/pull/124).
* Removed `DROP FUNCTION IF EXISTS cdb_usertables(text);` [#129](https://github.com/CartoDB/cartodb-postgresql/pull/129). This was needed for upgrading between 0.7.4 to 0.8.0 but is no longer needed.
0.9.4 (2015-08-28)
------------------
* Fixed issue with indices when renaming tables [#123](https://github.com/CartoDB/cartodb-postgresql/issues/123)

View File

@@ -91,6 +91,7 @@ select pg_sleep(.1);
(1 row)
alter table c.t3 rename column the_geom_webmercator to webmerc;
NOTICE: column "the_geom_webmercator" of relation "t3" does not exist, skipping
NOTICE: event trigger "cdb_on_relation_create" does not exist, skipping
NOTICE: event trigger "cdb_on_relation_drop" does not exist, skipping
NOTICE: event trigger "cdb_on_alter_column" does not exist, skipping
@@ -115,6 +116,7 @@ select pg_sleep(.1);
(1 row)
alter table c.t3 rename column the_geom_webmercator to webmerc2;
NOTICE: column "the_geom_webmercator" of relation "t3" does not exist, skipping
NOTICE: event trigger "cdb_on_relation_create" does not exist, skipping
NOTICE: event trigger "cdb_on_relation_drop" does not exist, skipping
NOTICE: event trigger "cdb_on_alter_column" does not exist, skipping

View File

@@ -280,6 +280,16 @@ BEGIN
END;
$$ LANGUAGE plpgsql VOLATILE;
--- Trigger to update the updated_at column. No longer added by default
--- but kept here for compatibility with old tables which still have this behavior
--- and have it added
CREATE OR REPLACE FUNCTION _CDB_update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at := now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql VOLATILE;
-- Auxiliary function
CREATE OR REPLACE FUNCTION cartodb._CDB_is_raster_table(schema_name TEXT, reloid REGCLASS)
@@ -497,30 +507,6 @@ BEGIN
END;
$$ LANGUAGE 'plpgsql';
-- Return the geometry SRID from the column metadata or
-- the geometry of the very first entry in a given column.
CREATE OR REPLACE FUNCTION _CDB_Geometry_SRID(reloid REGCLASS, columnname TEXT)
RETURNS INTEGER
AS $$
DECLARE
rec RECORD;
BEGIN
RAISE DEBUG 'CDB(%): %', '_CDB_Geometry_SRID', 'entered function';
EXECUTE Format('SELECT ST_SRID(%I) AS srid FROM %s LIMIT 1', columnname, reloid::text)
INTO rec;
IF FOUND THEN
RETURN rec.srid;
END IF;
RETURN 0;
END;
$$ LANGUAGE 'plpgsql';
-- Find out if the table already has a usable primary key
@@ -654,9 +640,72 @@ END;
$$ LANGUAGE 'plpgsql';
DROP FUNCTION IF EXISTS _CDB_Has_Usable_Geom(regclass);
CREATE OR REPLACE FUNCTION _CDB_Has_Usable_PK_Sequence(reloid REGCLASS)
RETURNS BOOLEAN
AS $$
DECLARE
seq TEXT;
const RECORD;
has_sequence BOOLEAN = false;
BEGIN
const := _CDB_Columns();
SELECT pg_get_serial_sequence(reloid::text, const.pkey)
INTO STRICT seq;
has_sequence := seq IS NOT NULL;
RETURN has_sequence;
END;
$$ LANGUAGE 'plpgsql';
-- Return a set of columns that can be candidates to be the_geom[webmercator]
-- with some extra information to analyze them.
CREATE OR REPLACE FUNCTION _cdb_geom_candidate_columns(reloid REGCLASS)
RETURNS TABLE (attname name, srid integer, typname name, desired_attname text, desired_srid integer)
AS $$
DECLARE
const RECORD;
BEGIN
const := _CDB_Columns();
RETURN QUERY
SELECT
a.attname,
CASE WHEN t.typname = 'geometry' THEN postgis_typmod_srid(a.atttypmod) ELSE NULL END AS srid,
t.typname,
f.desired_attname, f.desired_srid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid,
(VALUES (const.geomcol, 4326), (const.mercgeomcol, 3857) ) as f(desired_attname, desired_srid)
WHERE c.oid = reloid
AND a.attnum > 0
AND NOT a.attisdropped
AND postgis_typmod_srid(a.atttypmod) IN (4326, 3857, 0)
ORDER BY t.oid ASC;
END;
$$ LANGUAGE 'plpgsql';
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '_cdb_has_usable_geom_record') THEN
CREATE TYPE _cdb_has_usable_geom_record
AS (has_usable_geoms boolean,
text_geom_column boolean,
text_geom_column_name text,
text_geom_column_srid boolean,
has_geom boolean,
has_geom_name text,
has_mercgeom boolean,
has_mercgeom_name text);
END IF;
END$$;
DROP FUNCTION IF EXISTS _CDB_Has_Usable_Geom(REGCLASS);
CREATE OR REPLACE FUNCTION _CDB_Has_Usable_Geom(reloid REGCLASS)
RETURNS RECORD
RETURNS _cdb_has_usable_geom_record
AS $$
DECLARE
r1 RECORD;
@@ -688,20 +737,7 @@ BEGIN
-- Do we have a column we can use?
FOR r1 IN
SELECT
a.attname,
CASE WHEN t.typname = 'geometry' THEN postgis_typmod_srid(a.atttypmod) ELSE NULL END AS srid,
t.typname,
f.desired_attname, f.desired_srid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid,
(VALUES (const.geomcol, 4326), (const.mercgeomcol, 3857) ) as f(desired_attname, desired_srid)
WHERE c.oid = reloid
AND a.attnum > 0
AND NOT a.attisdropped
AND postgis_typmod_srid(a.atttypmod) IN (4326, 3857, 0)
ORDER BY t.oid ASC
SELECT * FROM _cdb_geom_candidate_columns(reloid)
LOOP
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %', Format('checking column ''%s''', r1.attname);
@@ -756,7 +792,7 @@ BEGIN
-- If it's the right SRID, we can use it in place without
-- transforming it!
IF r1.srid = r1.desired_srid OR _CDB_Geometry_SRID(reloid, r1.attname) = r1.desired_srid THEN
IF r1.srid = r1.desired_srid THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %', Format('found acceptable ''%s''', r1.attname);
@@ -769,7 +805,7 @@ BEGIN
END IF;
-- If it's an unknown SRID, we need to know that too
ELSIF r1.srid = 0 OR _CDB_Geometry_SRID(reloid, r1.attname) = 0 THEN
ELSIF r1.srid = 0 THEN
-- Unknown SRID, we'll have to fill it in later
text_geom_column_srid := true;
@@ -780,23 +816,13 @@ BEGIN
END LOOP;
-- If geom is the wrong name, just rename it.
IF has_geom AND has_geom_name != const.geomcol THEN
sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %s', reloid::text, has_geom_name, const.geomcol);
PERFORM _CDB_SQL(sql,'_CDB_Has_Usable_Geom');
END IF;
-- If mercgeom is the wrong name, just rename it.
IF has_mercgeom AND has_mercgeom_name != const.mercgeomcol THEN
sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %s', reloid::text, has_mercgeom_name, const.mercgeomcol);
PERFORM _CDB_SQL(sql,'_CDB_Has_Usable_Geom');
END IF;
SELECT
-- If table is perfect (no transforms required), return TRUE!
has_geom AND has_mercgeom AS has_usable_geoms,
-- If the geometry column is hiding in a text field, return enough info to deal w/ it.
text_geom_column, text_geom_column_name, text_geom_column_srid
text_geom_column, text_geom_column_name, text_geom_column_srid,
-- Return enough info to rename geom columns if needed
has_geom, has_geom_name, has_mercgeom, has_mercgeom_name
INTO rv;
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %', Format('returning %s', rv);
@@ -806,6 +832,7 @@ BEGIN
END;
$$ LANGUAGE 'plpgsql';
-- Create a copy of the table. Assumes that the "Has usable" functions
-- have already been run, so that if there is a 'cartodb_id' column, it is
-- a "good" one, and the same for the geometry columns. If all the required
@@ -840,6 +867,7 @@ DECLARE
geom_srid INTEGER;
has_usable_primary_key BOOLEAN;
has_usable_pk_sequence BOOLEAN;
BEGIN
@@ -867,35 +895,58 @@ BEGIN
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): has_usable_primary_key %', has_usable_primary_key;
-- See if the candidate primary key column has a sequence for default
-- values. No usable pk implies has_usable_pk_sequence = false.
has_usable_pk_sequence := false;
IF has_usable_primary_key THEN
SELECT _CDB_Has_Usable_PK_Sequence(reloid)
INTO STRICT has_usable_pk_sequence;
END IF;
-- See if the geometry columns we need are already available
-- on the table. If they are, we don't need to do any bulk
-- transformation of the table, we can just ensure proper
-- indexes are in place and apply a rename
SELECT *
FROM _CDB_Has_Usable_Geom(reloid)
AS (has_usable_geoms boolean,
text_geom_column boolean,
text_geom_column_name text,
text_geom_column_srid boolean)
INTO STRICT gc;
-- If geom is the wrong name, just rename it.
IF gc.has_geom AND gc.has_geom_name != const.geomcol THEN
sql := Format('ALTER TABLE %s DROP COLUMN IF EXISTS %I', reloid::text, const.geomcol);
PERFORM _CDB_SQL(sql,'_CDB_Rewrite_Table');
sql := Format('ALTER TABLE %s RENAME COLUMN %I TO %I', reloid::text, gc.has_geom_name, const.geomcol);
PERFORM _CDB_SQL(sql,'_CDB_Rewrite_Table');
END IF;
-- If mercgeom is the wrong name, just rename it.
IF gc.has_mercgeom AND gc.has_mercgeom_name != const.mercgeomcol THEN
sql := Format('ALTER TABLE %s DROP COLUMN IF EXISTS %I', reloid::text, const.mercgeomcol);
PERFORM _CDB_SQL(sql,'_CDB_Rewrite_Table');
sql := Format('ALTER TABLE %s RENAME COLUMN %I TO %I', reloid::text, gc.has_mercgeom_name, const.mercgeomcol);
PERFORM _CDB_SQL(sql,'_CDB_Rewrite_Table');
END IF;
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): has_usable_geoms %', gc.has_usable_geoms;
-- We can only avoid a rewrite if both the key and
-- geometry are usable
-- No table re-write is required, BUT a rename is required to
-- No table re-write is required, BUT a rename is required to
-- a destination schema, so do that now
IF has_usable_primary_key AND gc.has_usable_geoms AND destschema != relschema THEN
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): perfect table needs to be moved to schema (%)', destschema;
PERFORM _CDB_SQL(Format('ALTER TABLE %s SET SCHEMA %I', reloid::text, destschema), '_CDB_Rewrite_Table');
RETURN true;
IF has_usable_primary_key AND has_usable_pk_sequence AND gc.has_usable_geoms THEN
IF destschema != relschema THEN
-- Don't move anything, just make sure our destination information is set right
ELSIF has_usable_primary_key AND gc.has_usable_geoms AND destschema = relschema THEN
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): perfect table needs to be moved to schema (%)', destschema;
PERFORM _CDB_SQL(Format('ALTER TABLE %s SET SCHEMA %I', reloid::text, destschema), '_CDB_Rewrite_Table');
ELSE
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): perfect table in the perfect place';
END IF;
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): perfect table in the perfect place';
RETURN true;
END IF;
@@ -1029,15 +1080,11 @@ BEGIN
)
SELECT ', ST_Transform('
|| t.missing_srid_start || t.attname || t.missing_srid_end
|| ',4326)::Geometry('
|| t.geomtype
|| ',4326) AS '
|| ',4326)::Geometry(GEOMETRY,4326) AS '
|| const.geomcol
|| ', cartodb.CDB_TransformToWebmercator('
|| t.missing_srid_start || t.attname || t.missing_srid_end
|| ')::Geometry('
|| t.geomtype
|| ',3857) AS '
|| ')::Geometry(GEOMETRY,3857) AS '
|| const.mercgeomcol,
t.attname
INTO geom_transform_sql, geom_column_source
@@ -1094,27 +1141,24 @@ BEGIN
-- Set up the primary key sequence
-- If we copied the primary key from the original data, we need
-- to set the sequence to the maximum value of that key
IF has_usable_primary_key THEN
EXECUTE Format('SELECT max(%s) FROM %s',
const.pkey, copyname)
INTO destseqmax;
IF FOUND AND destseqmax IS NOT NULL THEN
PERFORM _CDB_SQL(Format('SELECT setval(''%s'', %s)', destseq, destseqmax), '_CDB_Rewrite_Table');
END IF;
EXECUTE Format('SELECT max(%s) FROM %s',
const.pkey, copyname)
INTO destseqmax;
IF destseqmax IS NOT NULL THEN
PERFORM _CDB_SQL(Format('SELECT setval(''%s'', %s)', destseq, destseqmax), '_CDB_Rewrite_Table');
END IF;
-- Make the primary key use the sequence as its default value
sql := Format('ALTER TABLE %s ALTER COLUMN %s SET DEFAULT nextval(''%s'')',
-- Make the primary key use the sequence as its default value
sql := Format('ALTER TABLE %s ALTER COLUMN %s SET DEFAULT nextval(''%s'')',
copyname, const.pkey, destseq);
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
-- Make the sequence owned by the table, so when the table drops,
-- Make the sequence owned by the table, so when the table drops,
-- the sequence does too
sql := Format('ALTER SEQUENCE %s OWNED BY %s.%s', destseq, copyname, const.pkey);
PERFORM _CDB_SQL(sql,'_CDB_Rewrite_Table');
-- We just made a copy, so we can drop the original now
sql := Format('DROP TABLE %s', reloid::text);

View File

@@ -3,11 +3,12 @@ CREATE OR REPLACE FUNCTION CDB_ColumnNames(REGCLASS)
RETURNS SETOF information_schema.sql_identifier
AS $$
SELECT column_name
FROM information_schema.columns
WHERE
table_name IN (SELECT CDB_UserTables())
AND table_name = '' || $1 || '';
SELECT c.column_name
FROM information_schema.columns c, pg_class _tn, pg_namespace _sn
WHERE table_name = _tn.relname
AND table_schema = _sn.nspname
AND _tn.oid = $1::oid
AND _sn.oid = _tn.relnamespace;
$$ LANGUAGE SQL;

View File

@@ -3,12 +3,13 @@ CREATE OR REPLACE FUNCTION CDB_ColumnType(REGCLASS, TEXT)
RETURNS information_schema.character_data
AS $$
SELECT data_type
FROM information_schema.columns
WHERE
table_name IN (SELECT CDB_UserTables())
AND table_name = '' || $1 || ''
AND column_name = '' || quote_ident($2) || '';
SELECT c.data_type
FROM information_schema.columns c, pg_class _tn, pg_namespace _sn
WHERE table_name = _tn.relname
AND table_schema = _sn.nspname
AND column_name = $2
AND _tn.oid = $1::oid
AND _sn.oid = _tn.relnamespace;
$$ LANGUAGE SQL;

View File

@@ -41,11 +41,11 @@ BEGIN
xpath('//x:Relation-Name/text()', exp, ARRAY[ARRAY['x', 'http://www.postgresql.org/2009/explain']]) as x,
xpath('//x:Relation-Name/../x:Schema/text()', exp, ARRAY[ARRAY['x', 'http://www.postgresql.org/2009/explain']]) as s
)
SELECT unnest(x) as p, unnest(s) as sc from inp
SELECT unnest(x)::text as p, unnest(s)::text as sc from inp
LOOP
-- RAISE DEBUG 'tab: %', rec2.p;
-- RAISE DEBUG 'sc: %', rec2.sc;
tables := array_append(tables, (rec2.sc || '.' || rec2.p));
tables := array_append(tables, format('%s.%s', quote_ident(rec2.sc), quote_ident(rec2.p)));
END LOOP;
-- RAISE DEBUG 'Tables: %', tables;

View File

@@ -0,0 +1,47 @@
--
-- Calculate basic statistics of a given dataset
--
-- @param in_array A numeric array of numbers
--
-- Returns: statistical quantity chosen
--
-- References: http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
--
-- Calculate kurtosis
CREATE OR REPLACE FUNCTION CDB_Kurtosis ( in_array NUMERIC[] ) RETURNS NUMERIC as $$
DECLARE
a numeric;
c numeric;
s numeric;
k numeric;
BEGIN
SELECT AVG(e), COUNT(e)::numeric, stddev(e) INTO a, c, s FROM ( SELECT unnest(in_array) e ) x;
EXECUTE 'SELECT sum(power($1 - e, 4)) / ( $2 * power($3, 4)) - 3
FROM (SELECT unnest($4) e ) x'
INTO k
USING a, c, s, in_array;
RETURN k;
END;
$$ language plpgsql IMMUTABLE;
-- Calculate skewness
CREATE OR REPLACE FUNCTION CDB_Skewness ( in_array NUMERIC[] ) RETURNS NUMERIC as $$
DECLARE
a numeric;
c numeric;
s numeric;
sk numeric;
BEGIN
SELECT AVG(e), COUNT(e)::numeric, stddev(e) INTO a, c, s FROM ( SELECT unnest(in_array) e ) x;
EXECUTE 'SELECT sum(power($1 - e, 3)) / ( $2 * power($3, 3))
FROM (SELECT unnest($4) e ) x'
INTO sk
USING a, c, s, in_array;
RETURN sk;
END;
$$ language plpgsql IMMUTABLE;

View File

@@ -5,7 +5,7 @@
--
-- Currently accepted permissions are: 'public', 'private' or 'all'
--
DROP FUNCTION IF EXISTS cdb_usertables(text);
DROP FUNCTION IF EXISTS CDB_UserTables(text);
CREATE OR REPLACE FUNCTION CDB_UserTables(perm text DEFAULT 'all')
RETURNS SETOF name
AS $$

View File

@@ -0,0 +1 @@
../scripts-available/CDB_Stats.sql

View File

@@ -225,6 +225,63 @@ SELECT CDB_CartodbfyTable('original');
DROP TABLE original_renamed;
DROP TABLE original;
-- Table always have a default seq value after cartodbfy #138
CREATE TABLE bug_empty_table_no_seq (
cartodb_id integer,
the_geom geometry(Geometry,4326),
the_geom_webmercator geometry(Geometry,3857),
name text,
description text
);
SELECT CDB_CartodbfyTableCheck('bug_empty_table_no_seq', 'Table always have a default seq value after cartodbfy #138');
INSERT INTO bug_empty_table_no_seq DEFAULT VALUES;
DROP TABLE bug_empty_table_no_seq;
-- Existing cartodb_id values are respected
CREATE table existing_cartodb_id (
cartodb_id integer,
the_geom geometry(Geometry,4326),
the_geom_webmercator geometry(Geometry,3857),
name text,
description text
);
INSERT INTO existing_cartodb_id (cartodb_id, description) VALUES
(10, 'a'),
(20, 'b'),
(30, 'c');
SELECT CDB_CartodbfyTableCheck('existing_cartodb_id', 'Existing cartodb_id values are respected #138');
SELECT * from existing_cartodb_id;
DROP TABLE existing_cartodb_id;
-- Table with both the_geom and wkb_geometry
CREATE TABLE many_geometry_columns (
the_geom geometry,
wkb_geometry geometry(MultiPoint,4326),
description varchar
);
INSERT INTO many_geometry_columns (the_geom, wkb_geometry) VALUES
('0104000020E61000000100000001010000007108B023698052C03CEEA53A2E5D4440', '0104000020E61000000100000001010000007108B023698052C03CEEA53A2E5D4440'),
('0104000020E6100000010000000101000000864C9E57618052C0994F0C7F3C5B4440', '0104000020E6100000010000000101000000864C9E57618052C0994F0C7F3C5B4440');
SELECT CDB_CartodbfyTableCheck('many_geometry_columns', 'Table with both the_geom and wkb_geometry #141');
SELECT * FROM many_geometry_columns;
DROP TABLE many_geometry_columns;
-- Many colliding geom columns
CREATE TABLE many_colliding_columns (
the_geom varchar,
the_geom_webmercator varchar,
my_geom geometry,
my_mercgeom geometry(Point, 3857),
cartodb_id varchar,
my_pk integer primary key
);
INSERT INTO many_colliding_columns VALUES (
'foo', 'bar', 'SRID=4326;POINT(0 0)', 'SRID=3857;POINT(0 0)', 'nerf', 1
);
SELECT CDB_CartodbfyTableCheck('many_colliding_columns', 'Many colliding columns #141');
DROP TABLE many_colliding_columns;
-- TODO: table with existing custom-triggered the_geom
DROP FUNCTION CDB_CartodbfyTableCheck(regclass, text);

View File

@@ -58,5 +58,26 @@ CREATE TABLE
original
DROP TABLE
DROP TABLE
CREATE TABLE
Table always have a default seq value after cartodbfy #138 cartodbfied fine
INSERT 0 1
DROP TABLE
CREATE TABLE
INSERT 0 3
Existing cartodb_id values are respected #138 cartodbfied fine
10|||a|
20|||b|
30|||c|
DROP TABLE
CREATE TABLE
INSERT 0 2
Table with both the_geom and wkb_geometry #141 cartodbfied fine
1|0104000020E61000000100000001010000007108B023698052C03CEEA53A2E5D4440|0104000020110F00000100000001010000004A9F662B456D5FC11392690DC3F75241|
2|0104000020E6100000010000000101000000864C9E57618052C0994F0C7F3C5B4440|0104000020110F00000100000001010000002858E0EC376D5FC1CAE8DB4B95F55241|
DROP TABLE
CREATE TABLE
INSERT 0 1
Many colliding columns #141 cartodbfied fine
DROP TABLE
DROP FUNCTION
DROP FUNCTION

13
test/CDB_StatsTest.sql Normal file
View File

@@ -0,0 +1,13 @@
-- continuous uniform distribution has kurtosis = -6/5, skewness = 0.0
-- http://mathworld.wolfram.com/UniformDistribution.html
set client_min_messages to ERROR;
WITH dist AS (
SELECT generate_series(0,10000)::numeric / 10000.0 i
)
SELECT
abs(CDB_Kurtosis(array_agg(i)) + 1.2) < 1e-3 AS kurtosis,
abs(CDB_Skewness(array_agg(i))) < 1e-3 AS skewness
FROM dist;
set client_min_messages to NOTICE;

View File

@@ -0,0 +1,3 @@
SET
t|t
SET

View File

@@ -1,4 +1,6 @@
SET SCHEMA 'cartodb';
\i scripts-available/CDB_Quota.sql
\i scripts-available/CDB_TableMetadata.sql
\i scripts-available/CDB_ColumnNames.sql
\i scripts-available/CDB_ColumnType.sql
SET SCHEMA 'public';

View File

@@ -123,7 +123,7 @@ function create_role_and_schema() {
function drop_role_and_schema() {
local ROLE=$1
sql "DROP SCHEMA \"${ROLE}\";"
sql "DROP SCHEMA \"${ROLE}\" CASCADE;"
sql "REVOKE CONNECT ON DATABASE \"${DATABASE}\" FROM \"${ROLE}\";"
sql "DROP ROLE \"${ROLE}\";"
}
@@ -178,6 +178,7 @@ function setup() {
sql "CREATE SCHEMA cartodb;"
sql "GRANT USAGE ON SCHEMA cartodb TO public;"
sql "CREATE EXTENSION postgis;"
sql "CREATE EXTENSION plpythonu;"
log_info "########################### BOOTSTRAP ###########################"
${CMD} -d ${DATABASE} -f scripts-available/CDB_Organizations.sql
@@ -209,8 +210,8 @@ function tear_down() {
sql "DROP SCHEMA cartodb CASCADE"
log_info "########################### TEAR DOWN ###########################"
sql 'DROP SCHEMA cdb_testmember_1;'
sql 'DROP SCHEMA cdb_testmember_2;'
sql 'DROP SCHEMA cdb_testmember_1 CASCADE;'
sql 'DROP SCHEMA cdb_testmember_2 CASCADE;'
sql "REVOKE CONNECT ON DATABASE \"${DATABASE}\" FROM cdb_testmember_1;"
sql "REVOKE CONNECT ON DATABASE \"${DATABASE}\" FROM cdb_testmember_2;"
@@ -227,7 +228,12 @@ function run_tests() {
local TESTS
if [[ $# -ge 1 ]]
then
TESTS="$@"
if [[ $# -eq 1 ]]
then
TESTS=`cat $0 | grep -o "$1[^\(]*"`
else
TESTS="$@"
fi
else
TESTS=`cat $0 | perl -n -e'/function (test.*)\(\)/ && print "$1\n"'`
fi
@@ -337,6 +343,92 @@ function test_cdb_tablemetadatatouch_fails_from_user_without_permission() {
sql postgres "REVOKE ALL ON CDB_TableMetadata FROM cdb_testmember_1;"
}
function test_cdb_column_names() {
sql cdb_testmember_1 'CREATE TABLE cdb_testmember_1.table_cnames(c int, a int, r int, t int, o int);'
sql cdb_testmember_2 'CREATE TABLE cdb_testmember_2.table_cnames(d int, b int);'
sql cdb_testmember_1 "SELECT string_agg(c,'') from (SELECT cartodb.CDB_ColumnNames('table_cnames') c) as s" should "carto"
sql cdb_testmember_2 "SELECT string_agg(c,'') from (SELECT cartodb.CDB_ColumnNames('table_cnames') c) as s" should "db"
sql postgres "SELECT string_agg(c,'') from (SELECT cartodb.CDB_ColumnNames('cdb_testmember_1.table_cnames'::regclass) c) as s" should "carto"
sql postgres "SELECT string_agg(c,'') from (SELECT cartodb.CDB_ColumnNames('cdb_testmember_2.table_cnames') c) as s" should "db"
# Using schema from owner
sql cdb_testmember_1 "SELECT string_agg(c,'') from (SELECT cartodb.CDB_ColumnNames('cdb_testmember_1.table_cnames') c) as s" should "carto"
## it's not possible to get column names from a table where you don't have permissions
sql cdb_testmember_2 "SELECT string_agg(c,'') from (SELECT cartodb.CDB_ColumnNames('cdb_testmember_1.table_cnames') c) as s" fails
sql cdb_testmember_1 'DROP TABLE cdb_testmember_1.table_cnames'
sql cdb_testmember_2 'DROP TABLE cdb_testmember_2.table_cnames'
}
function test_cdb_column_type() {
sql cdb_testmember_1 'CREATE TABLE cdb_testmember_1.table_ctype(c int, a int, r int, t int, o int);'
sql cdb_testmember_2 'CREATE TABLE cdb_testmember_2.table_ctype(c text, a text, r text, t text, o text);'
sql cdb_testmember_1 "SELECT cartodb.CDB_ColumnType('table_ctype', 'c')" should "integer"
sql cdb_testmember_2 "SELECT cartodb.CDB_ColumnType('table_ctype', 'c')" should "text"
sql postgres "SELECT cartodb.CDB_ColumnType('cdb_testmember_1.table_ctype', 'c')" should "integer"
sql postgres "SELECT cartodb.CDB_ColumnType('cdb_testmember_2.table_ctype', 'c')" should "text"
sql cdb_testmember_1 'DROP TABLE cdb_testmember_1.table_ctype'
sql cdb_testmember_2 'DROP TABLE cdb_testmember_2.table_ctype'
}
function test_cdb_querytables_schema_and_table_names_with_dots() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
sql postgres 'CREATE SCHEMA "foo.bar";'
sql postgres 'CREATE TABLE "foo.bar"."c.a.r.t.o.d.b" (a int);'
sql postgres 'INSERT INTO "foo.bar"."c.a.r.t.o.d.b" values (1);'
sql postgres 'SELECT a FROM "foo.bar"."c.a.r.t.o.d.b";' should 1
sql postgres 'SELECT CDB_QueryTablesText($q$select * from "foo.bar"."c.a.r.t.o.d.b"$q$);' should '{"\"foo.bar\".\"c.a.r.t.o.d.b\""}'
sql postgres 'SELECT CDB_QueryTables($q$select * from "foo.bar"."c.a.r.t.o.d.b"$q$);' should '{"\"foo.bar\".\"c.a.r.t.o.d.b\""}'
sql postgres 'DROP TABLE "foo.bar"."c.a.r.t.o.d.b";'
sql postgres 'DROP SCHEMA "foo.bar";'
}
function test_cdb_querytables_table_name_with_dots() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
sql postgres 'CREATE TABLE "w.a.d.u.s" (a int);';
sql postgres 'SELECT CDB_QueryTablesText($q$select * from "w.a.d.u.s"$q$);' should '{"public.\"w.a.d.u.s\""}'
sql postgres 'SELECT CDB_QueryTables($q$select * from "w.a.d.u.s"$q$);' should '{"public.\"w.a.d.u.s\""}'
sql postgres 'DROP TABLE "w.a.d.u.s";';
}
function test_cdb_querytables_happy_cases() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
sql postgres 'CREATE TABLE wadus (a int);';
sql postgres 'CREATE TABLE "FOOBAR" (a int);';
sql postgres 'CREATE SCHEMA foo;'
sql postgres 'CREATE TABLE foo.wadus (a int);';
## See how it does NOT quote anything here
sql postgres 'SELECT CDB_QueryTablesText($q$select * from wadus$q$);' should '{public.wadus}'
sql postgres 'SELECT CDB_QueryTablesText($q$select * from foo.wadus$q$);' should '{foo.wadus}'
sql postgres 'SELECT CDB_QueryTables($q$select * from wadus$q$);' should '{public.wadus}'
sql postgres 'SELECT CDB_QueryTables($q$select * from foo.wadus$q$);' should '{foo.wadus}'
## But it quotes when it's needed even if table name has no dots but was created with quotes
sql postgres 'SELECT CDB_QueryTablesText($q$select * from "FOOBAR"$q$);' should '{"public.\"FOOBAR\""}'
sql postgres 'DROP TABLE wadus;'
sql postgres 'DROP TABLE "FOOBAR";'
sql postgres 'DROP TABLE foo.wadus;'
sql postgres 'DROP SCHEMA foo;'
}
#################################################### TESTS END HERE ####################################################
run_tests $@